2.1 Nginx 目錄結構分析
在使用Nginx之前,我們先對安裝好的Nginx目錄文件進行一個分析,在這塊給大家介紹一個工具tree,通過tree我們可以很方面的去查看centos系統上的文件目錄結構,當然,如果想使用tree工具,就得先通過yum install -y tree來進行安裝,安裝成功后,可以通過執行tree /usr/local/nginx(tree后面跟的是Nginx的安裝目錄),獲取的結果如下:

-
conf:nginx所有配置文件目錄
-
CGI(Common Gateway Interface)通用網關【接口】,主要解決的問題是從客戶端發送一個請求和數據,服務端獲取到請求和數據后可以調用調用CGI【程序】處理及相應結果給客戶端的一種標准規范。
-
-
fastcgi.conf:fastcgi相關配置文件
-
fastcgi.conf.default:fastcgi.conf的備份文件
-
fastcgi_params:fastcgi的參數文件
-
fastcgi_params.default:fastcgi的參數備份文件
-
scgi_params:scgi的參數文件
-
scgi_params.default:scgi的參數備份文件
-
uwsgi_params:uwsgi的參數文件
-
uwsgi_params.default:uwsgi的參數備份文件
-
mime.types:記錄的是HTTP協議中的Content-Type的值和文件后綴名的對應關系
-
mime.types.default:mime.types的備份文件
-
nginx.conf:這個是Nginx的核心配置文件,這個文件非常重要,也是我們即將要學習的重點
-
nginx.conf.default:nginx.conf的備份文件
-
koi-utf、koi-win、win-utf這三個文件都是與編碼轉換映射相關的配置文件,用來將一種編碼轉換成另一種編碼
-
html:存放nginx自帶的兩個靜態的html頁面
-
50x.html:訪問失敗后的失敗頁面
-
index.html:成功訪問的默認首頁
-
-
logs:記錄入門的文件,當nginx服務器啟動后,這里面會有 access.log error.log 和nginx.pid三個文件出現。
-
sbin:是存放執行程序文件nginx
-
nginx是用來控制Nginx的啟動和停止等相關的命令。
-
2.2 Nginx 服務器啟停命令
Nginx安裝完成后,接下來我們要學習的是如何啟動、重啟和停止Nginx的服務。
對於Nginx的啟停在linux系統中也有很多種方式,介紹兩種方式:
-
Nginx服務的信號控制
-
Nginx的命令行控制
2.2.1 Nginx服務的信號控制
前面在提到Nginx的高性能,其實也和它的架構模式有關。Nginx默認采用的是多進程的方式來工作的,當將Nginx啟動后,我們通過ps -ef | grep nginx命令可以查看到如下內容:

從上圖中可以看到,Nginx后台進程中包含一個master進程和多個worker進程,master進程主要用來管理worker進程,包含接收外界的信息,並將接收到的信號發送給各個worker進程,監控worker進程的狀態,當worker進程出現異常退出后,會自動重新啟動新的worker進程。
而worker進程則是專門用來處理用戶請求的,各個worker進程之間是平等的並且相互獨立,處理請求的機會也是一樣的。nginx的進程模型,我們可以通過下圖來說明下:

我們現在作為管理員,只需要通過給master進程發送信號就可以來控制Nginx,這個時候我們需要有兩個前提條件,一個是要操作的master進程,一個是信號。
(1)要想操作Nginx的master進程,就需要獲取到master進程的進程號ID。獲取方式簡單介紹兩個,
-
方式一:通過
ps -ef | grep nginx; -
方式二:在講解nginx的
./configure的配置參數的時候,有一個參數是--pid-path=PATH默認是/usr/local/nginx/logs/nginx.pid,所以可以通過查看該文件來獲取nginx的master進程ID.
(2)信號
| 信號 | 作用 |
|---|---|
| TERM/INT | 立即關閉整個服務 |
| QUIT | "優雅"地關閉整個服務 |
| HUP | 重讀配置文件並使用服務對新配置項生效 |
| USR1 | 重新打開日志文件,可以用來進行日志切割 |
| USR2 | 平滑升級到最新版的nginx |
| WINCH | 所有子進程不在接收處理新連接,相當於給work進程發送QUIT指令 |
調用命令為kill -signal PID
signal:即為信號;PID即為獲取到的master線程ID
-
發送TERM/INT信號給master進程,會將Nginx服務立即關閉。
kill -TERM PID
kill -TERM `cat /usr/local/nginx/logs/nginx.pid`
kill -INT PID
kill -INT `cat /usr/local/nginx/logs/nginx.pid`
-
發送QUIT信號給master進程,master進程會控制所有的work進程不再接收新的請求,等所有請求處理完后,在把進程都關閉掉。
kill -QUIT PID
kill -TERM `cat /usr/local/nginx/logs/nginx.pid`
-
發送HUP信號給master進程,master進程會把控制舊的work進程不再接收新的請求,等處理完請求后將舊的work進程關閉掉,然后根據nginx的配置文件重新啟動新的work進程
kill -HUP PID
kill -TERM `cat /usr/local/nginx/logs/nginx.pid`
-
發送USR1信號給master進程,告訴Nginx重新開啟日志文件
kill -USR1 PID
kill -TERM `cat /usr/local/nginx/logs/nginx.pid`
-
發送USR2信號給master進程,告訴master進程要平滑升級,這個時候,會重新開啟對應的master進程和work進程,整個系統中將會有兩個master進程,並且新的master進程的PID會被記錄在
/usr/local/nginx/logs/nginx.pid而之前的舊的master進程PID會被記錄在/usr/local/nginx/logs/nginx.pid.oldbin文件中,接着再次發送QUIT信號給舊的master進程,讓其處理完請求后再進行關閉
kill -USR2 PID
kill -USR2 `cat /usr/local/nginx/logs/nginx.pid`
kill -QUIT PID
kill -QUIT `cat /usr/local/nginx/logs/nginx.pid.oldbin`

-
發送WINCH信號給master進程,讓master進程控制不讓所有的work進程在接收新的請求了,請求處理完后關閉work進程。注意master進程不會被關閉掉
kill -WINCH PID
kill -WINCH`cat /usr/local/nginx/logs/nginx.pid`
2.2.2 Nginx的命令行控制
此方式是通過Nginx安裝目錄下的sbin下的可執行文件nginx來進行Nginx狀態的控制,我們可以通過nginx -h來查看都有哪些參數可以用:

-?和-h:顯示幫助信息
-v:打印版本號信息並退出
-V:打印版本號信息和配置信息並退出
-t:測試nginx的配置文件語法是否正確並退出
-T:測試nginx的配置文件語法是否正確並列出用到的配置文件信息然后退出
-q:在配置測試期間禁止顯示非錯誤消息
-s:signal信號,后面可以跟 :
stop[快速關閉,類似於TERM/INT信號的作用]
quit[優雅的關閉,類似於QUIT信號的作用]
reopen[重新打開日志文件類似於USR1信號的作用]
reload[類似於HUP信號的作用]
-p:prefix,指定Nginx的prefix路徑,(默認為: /usr/local/nginx/)
-c:filename,指定Nginx的配置文件路徑,(默認為: conf/nginx.conf)
-g:用來補充Nginx配置文件,向Nginx服務指定啟動時應用全局的配置
2.3 Nginx 服務器版本升級和新增模塊
如果想對Nginx的版本進行更新,或者要應用一些新的模塊,最簡單的做法就是停止當前的Nginx服務,然后開啟新的Nginx服務。但是這樣會導致在一段時間內,用戶是無法訪問服務器。為了解決這個問題,我們就需要用到Nginx服務器提供的平滑升級功能。這個也是Nginx的一大特點,使用這種方式,就可以使Nginx在7*24小時不間斷的提供服務了。接下來我們分析下需求:
需求:Nginx的版本最開始使用的是Nginx-1.18.0,由於服務升級,需要將Nginx的版本升級到Nginx-1.20.1,要求Nginx不能中斷提供服務。
為了應對上述的需求,這里我們給大家提供兩種解決方案:
-
方案一:使用Nginx服務信號完成Nginx的升級
-
方案二:使用Nginx安裝目錄的make命令完成升級
2.3.1 環境准備
(1)先准備兩個版本的Nginx分別是 1.18.0和1.20.1
(2)使用Nginx源碼安裝的方式將1.18.0版本安裝成功並正確訪問
cd /root/nginx-1.18.0
./configure
make && make install
(3)將Nginx1.20.1進行參數配置和編譯,不需要進行安裝。
cd /root/nginx-1.20.1
./configure
make
2.3.2 使用Nginx服務信號進行升級

第一步:將1.18.0版本的sbin目錄下的nginx進行備份
cd /usr/local/nginx/sbin
mv nginx nginx-old
第二步:將Nginx1.16.1安裝目錄編譯后的objs目錄下的nginx文件,拷貝到原來/usr/local/nginx/sbin目錄下
cd /root/nginx-1.20.1/objs
cp nginx /usr/local/nginx/sbin
第三步:發送信號USR2給Nginx的1.18.0版本對應的master進程
kill -USR2 `cat /usr/local/nginx/logs/nginx.pid`
第四步:發送信號QUIT給Nginx的1.18.0版本對應的master進程
kill -QUIT `more /usr/local/nginx/logs/nginx.pid.oldbin`

2.3.3 使用Nginx安裝目錄的make命令完成升級
第一步:將1.18.0版本的sbin目錄下的nginx進行備份
cd /usr/local/nginx/sbin
mv nginx nginx-old
第二步:將Nginx1.20.1安裝目錄編譯后的objs目錄下的nginx文件,拷貝到原來/usr/local/nginx/sbin目錄下
cd /root/nginx-1.20.1/objs
cp nginx /usr/local/nginx/sbin
第三步:進入到安裝目錄,執行make upgrade
cd /root/nginx-1.20.1/
make upgrade

第四步:查看是否更新成功
./nginx -v

在整個過程中,其實Nginx是一直對外提供服務的。並且當Nginx的服務器啟動成功后,我們是可以通過瀏覽器進行直接訪問的,同時我們可以通過更改html目錄下的頁面來修改我們在頁面上所看到的內容
2.4 Nginx 核心配置文件結構
2.4.1 全局塊
Nginx的核心配置文件默認是放在/usr/local/nginx/conf/nginx.conf,介紹下nginx.conf的內容和基本配置方法。
讀取Nginx自帶的Nginx配置文件,我們將其中的注釋部分刪除掉后,就剩下下面內容:
cd /usr/local/nginx/conf/
# 清除所有空行和注釋
cat nginx.conf | grep -v "#" | grep -v "^$" > nginx2.conf
worker_processes 1;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
server {
listen 80;
server_name localhost;
location / {
root html;
index index.html index.htm;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
}
簡單小結下:
-
nginx.conf配置文件中默認有三大塊:全局塊、events塊、http塊
-
http塊中可以配置多個server塊,每個server塊又可以配置多個location塊。
(1)user指令
user:用於配置運行Nginx服務器的worker進程的用戶和用戶組。
| 語法 | user user [group] |
|---|---|
| 默認值 | nobody |
| 位置 | 全局塊 |
該屬性也可以在編譯的時候指定,語法如下./configure --user=user --group=group,如果兩個地方都進行了設置,最終生效的是配置文件中的配置。
該指令的使用步驟:
1)設置一個用戶信息"www"
sed -i "1i user gudu;" nginx.conf

2)創建一個用戶
useradd gudu

3)修改user屬性
user gudu;
4)創建/root/html/index.html頁面,添加如下內容
mkdir -p /root/html/
cat <<EOF> /root/html/index.heml
5)修改nginx.conf
location / {
root /root/html;
index index.html index.htm;
}
6)測試啟動訪問
頁面會報403拒絕訪問的錯誤

7)分析原因
因為當前用戶沒有訪問/root/html目錄的權限
8)將文件創建到 /home/gudu/html/index.html,修改配置
location / {
root /home/gudu/html;
index index.html index.htm;
}
9)再次測試啟動訪問
能正常訪問。
綜上所述,使用user指令可以指定啟動運行工作進程的用戶及用戶組,這樣對於系統的權限訪問控制的更加精細,也更加安全。
(2)work process指令
master_process:用來指定是否開啟工作進程。
| 語法 | master_process on|off; |
|---|---|
| 默認值 | master_process on; |
| 位置 | 全局塊 |
worker_processes:用於配置Nginx生成工作進程的數量,這個是Nginx服務器實現並發處理服務的關鍵所在。理論上來說workder process的值越大,可以支持的並發處理量也越多,但事實上這個值的設定是需要受到來自服務器自身的限制,建議將該值和服務器CPU的內核數保存一致。
| 語法 | worker_processes num/auto; |
|---|---|
| 默認值 | 1 |
| 位置 | 全局塊 |
如果將worker_processes設置成2,則會看到如下內容:

(3)其他指令
1)daemon:設定Nginx是否以守護進程的方式啟動。
守護式進程是linux后台執行的一種服務進程,特點是獨立於控制終端,不會隨着終端關閉而停止。
| 語法 | daemon on|off; |
|---|---|
| 默認值 | daemon on; |
| 位置 | 全局塊 |
2)pid:用來配置Nginx當前master進程的進程號ID存儲的文件路徑。
| 語法 | pid file; |
|---|---|
| 默認值 | 默認為:/usr/local/nginx/logs/nginx.pid |
| 位置 | 全局塊 |
該屬性可以通過./configure --pid-path=PATH來指定
error_log:用來配置Nginx的錯誤日志存放路徑
| 語法 | error_log file [日志級別]; |
|---|---|
| 默認值 | error_log logs/error.log error; |
| 位置 | 全局塊、http、server、location |
該屬性可以通過./configure --error-log-path=PATH來指定
其中日志級別的值有:debug|info|notice|warn|error|crit|alert|emerg,翻譯過來為試|信息|通知|警告|錯誤|臨界|警報|緊急,這塊建議大家設置的時候不要設置成info以下的等級,因為會帶來大量的磁盤I/O消耗,影響Nginx的性能。
3)include:用來引入其他配置文件,使Nginx的配置更加靈活
| 語法 | include file; |
|---|---|
| 默認值 | 無 |
| 位置 | any |
2.4.2 events塊
(1)accept_mutex:用來設置Nginx網絡連接序列化
| 語法 | accept_mutex on|off; |
|---|---|
| 默認值 | accept_mutex on; |
| 位置 | events |
這個配置主要可以用來解決常說的"驚群"問題。大致意思是在某一個時刻,客戶端發來一個請求連接,Nginx后台是以多進程的工作模式,也就是說有多個worker進程會被同時喚醒,但是最終只會有一個進程可以獲取到連接,如果每次喚醒的進程數目太多,就會影響Nginx的整體性能。
如果將上述值設置為on(開啟狀態),將會對多個Nginx進程接收連接進行序列號,一個個來喚醒接收,就防止了多個進程對連接的爭搶。

(2)multi_accept:用來設置是否允許同時接收多個網絡連接
| 語法 | multi_accept on|off; |
|---|---|
| 默認值 | multi_accept off; |
| 位置 | events |
如果multi_accept被禁止了,nginx一個工作進程只能同時接受一個新的連接。否則,一個工作進程可以同時接受所有的新連接
(3)worker_connections:用來配置單個worker進程最大的連接數
| 語法 | worker_connections number; |
|---|---|
| 默認值 | worker_commections 512; |
| 位置 | events |
這里的連接數不僅僅包括和前端用戶建立的連接數,而是包括所有可能的連接數。另外,number值不能大於操作系統支持打開的最大文件句柄數量。
(4)use:用來設置Nginx服務器選擇哪種事件驅動來處理網絡消息。
| 語法 | use method; |
|---|---|
| 默認值 | 根據操作系統定 |
| 位置 | events |
注意:此處所選擇事件處理模型是Nginx優化部分的一個重要內容,method的可選值有select/poll/epoll/kqueue等,之前在准備centos環境的時候,我們強調過要使用linux內核在2.6以上,就是為了能使用epoll函數來優化Nginx。
另外這些值的選擇,我們也可以在編譯的時候使用
--with-select_module
--without-select_module
--with-poll_module
--without-poll_module
來設置是否需要將對應的事件驅動模塊編譯到Nginx的內核。
events指令配置實例
打開Nginx的配置文件 nginx.conf,添加如下配置
events{
accept_mutex on;
multi_accept on;
worker_commections 1024;
use epoll;
}
啟動測試
./nginx -t
./nginx -s reload
2.4.3 http塊
(1)定義MIME-Type
我們都知道瀏覽器中可以顯示的內容有HTML、XML、GIF等種類繁多的文件、媒體等資源,瀏覽器為了區分這些資源,就需要使用MIME Type。所以說MIME Type是網絡資源的媒體類型。Nginx作為web服務器,也需要能夠識別前端請求的資源類型。
在Nginx的配置文件中,默認有兩行配置
include mime.types;
default_type application/octet-stream;
default_type:用來配置Nginx響應前端請求默認的MIME類型。
| 語法 | default_type mime-type; |
|---|---|
| 默認值 | default_type text/plain; |
| 位置 | http、server、location |
在default_type之前還有一句include mime.types,include之前我們已經介紹過,相當於把mime.types文件中MIMT類型與相關類型文件的文件后綴名的對應關系加入到當前的配置文件中。
舉例說明:
有些時候請求某些接口的時候需要返回指定的文本字符串或者json字符串,如果邏輯非常簡單或者干脆是固定的字符串,那么可以使用nginx快速實現,這樣就不用編寫程序響應請求了,可以減少服務器資源占用並且響應性能非常快。
如何實現:
location /get_text {
#這里也可以設置成text/plain
default_type text/html;
return 200 "This is nginx's text";
}
location /get_json{
default_type application/json;
return 200 '{"name":"TOM","age":18}';
}
(2)自定義服務日志
Nginx中日志的類型分access.log、error.log。
-
access.log:用來記錄用戶所有的訪問請求。
-
error.log:記錄nginx本身運行時的錯誤信息,不會記錄用戶的訪問請求。
Nginx服務器支持對服務日志的格式、大小、輸出等進行設置,需要使用到兩個指令,分別是access_log和log_format指令。
1)access_log:用來設置用戶訪問日志的相關屬性。
| 語法 | access_log path[format[buffer=size]] |
|---|---|
| 默認值 | access_log logs/access.log combined; |
| 位置 | http, server, location |
2)log_format:用來指定日志的輸出格式。
| 語法 | log_format name [escape=default|json|none] string....; |
|---|---|
| 默認值 | log_format combined "..."; |
| 位置 | http |
(3)其他配置指令
1)sendfile:用來設置Nginx服務器是否使用sendfile()傳輸文件,該屬性可以大大提高Nginx處理靜態資源的性能
| 語法 | sendfile on|off; |
|---|---|
| 默認值 | sendfile off; |
| 位置 | http、server、location |
2)keepalive_timeout:用來設置長連接的超時時間。
我們都知道HTTP是一種無狀態協議,客戶端向服務端發送一個TCP請求,服務端響應完畢后斷開連接。
如何客戶端向服務端發送多個請求,每個請求都需要重新創建一次連接,效率相對來說比較多,使用keepalive模式,可以告訴服務器端在處理完一個請求后保持這個TCP連接的打開狀態,若接收到來自這個客戶端的其他請求,服務端就會利用這個未被關閉的連接,而不需要重新創建一個新連接,提升效率,但是這個連接也不能一直保持,這樣的話,連接如果過多,也會是服務端的性能下降,這個時候就需要我們進行設置其的超時時間。
| 語法 | keepalive_timeout time; |
|---|---|
| 默認值 | keepalive_timeout 75s; |
| 位置 | http、server、location |
3)keepalive_requests:用來設置一個keep-alive連接使用的次數。
| 語法 | keepalive_requests number; |
|---|---|
| 默認值 | keepalive_requests 100; |
| 位置 | http、server、location |
2.4.4 server塊和location塊
server塊和location塊都是我們要重點講解和學習的內容,因為我們后面會對Nginx的功能進行詳細講解,所以這塊內容就放到靜態資源部署的地方給大家詳細說明。
主要來認識下Nginx默認給的nginx.conf中的相關內容,以及server塊與location塊在使用的時候需要注意的一些內容。
server {
listen 80;
server_name localhost;
location / {
root html;
index index.html index.htm;
}
error_page 500 502 503 504 404 /50x.html;
location = /50x.html {
root html;
}
}
