控制nginx
信號可以用來控制nginx。nginx的主進程ID號默認寫入/usr/local/nginx/logs/nginx.pid文件,可以在配置階段修改文件名,或者在nginx.conf中使用pid指令進行修改。主進程支持以下信號:
- TERM, INT 立即關閉
- QUIT 正常關閉
- HUP 修改配置,保持變更的時區(僅對於FreeBSD和Linux),以新的配置啟動新的工作進程,並正常關閉舊的工作進程。
- USR1 重新打開日志文件
- USR2 更新可執行文件
- WINCH 正常關閉工作進程
單獨的工作進程也能被信號控制,盡管這不是必須的。支持的信號有:
- TERM, INT 立即關閉
- QUIT 正常關閉
- USR1 重新打開日志文件
- WINCH 因調試異常中止 (需要啟用debug_points)
修改配置文件
發送HUP信號到主進程,nginx將重新讀取配置文件。主進程在接受到HUP信號后,先檢驗配置文件的語法正確性,再嘗試應用新的配置,即打開日志文件和新的監聽套接字。若應用配置文件失敗,回滾到先前的配置;若應用成功,啟動新的工作進程,並發送消息給舊的工作進程要求它們正常關閉。舊的工作進程關閉監聽的套接字並繼續為舊的客戶端服務。所有客戶端被新的工作進程服務以后,舊的工作進程被關閉。
舉個例子,假設nginx在FreeBSD 4.x下運行,執行以下命令:
ps axw -o pid,ppid,user,%cpu,vsz,wchan,command | egrep '(nginx|PID)'
生成以下輸出:
PID PPID USER %CPU VSZ WCHAN COMMAND 33126 1 root 0.0 1148 pause nginx: master process /usr/local/nginx/sbin/nginx 33127 33126 nobody 0.0 1380 kqread nginx: worker process (nginx) 33128 33126 nobody 0.0 1364 kqread nginx: worker process (nginx) 33129 33126 nobody 0.0 1364 kqread nginx: worker process (nginx)
編號為33129的舊工作進程仍然繼續工作,一段時間后退出:
PID PPID USER %CPU VSZ WCHAN COMMAND 33126 1 root 0.0 1164 pause nginx: master process /usr/local/nginx/sbin/nginx 33134 33126 nobody 0.0 1368 kqread nginx: worker process (nginx) 33135 33126 nobody 0.0 1368 kqread nginx: worker process (nginx) 33136 33126 nobody 0.0 1368 kqread nginx: worker process (nginx)
滾動日志文件
為了滾動日志文件,需要先重命名日志文件,再發送USR1信號到主進程。主進程將會重新打開當前已打開的所有日志文件,並標示它們未授權的用戶身份(工作進程運行的權限)。在重新打開成功后,主進程關閉所有打開的文件,發送消息給工作進程要求它們重新打開文件。於是工作進程立即打開新的文件並關閉舊的文件。因此,舊的文件幾乎能立即響應post處理,例如壓縮。
動態更新可執行文件
為了更新服務器可執行文件,需要先用新的可執行文件替代舊的,再發送USR2信號給主進程。主進程重命名它的進程ID文件,以.oldbin作為后綴,例如:/usr/local/nginx/logs/nginx.pid.oldbin,接着啟動新的可執行文件,並相應地啟動新的工作進程。
PID PPID USER %CPU VSZ WCHAN COMMAND 33126 1 root 0.0 1164 pause nginx: master process /usr/local/nginx/sbin/nginx 33134 33126 nobody 0.0 1368 kqread nginx: worker process (nginx) 33135 33126 nobody 0.0 1380 kqread nginx: worker process (nginx) 33136 33126 nobody 0.0 1368 kqread nginx: worker process (nginx) 36264 33126 root 0.0 1148 pause nginx: master process /usr/local/nginx/sbin/nginx 36265 36264 nobody 0.0 1364 kqread nginx: worker process (nginx) 36266 36264 nobody 0.0 1364 kqread nginx: worker process (nginx) 36267 36264 nobody 0.0 1364 kqread nginx: worker process (nginx)
在這之后所有的工作進程(新的和舊的)繼續接受請求。如果發送WINCH信號到第一個主進程,它將發送消息給它的工作進程,請求它們正常關閉,接着這些工作進程開始退出:
PID PPID USER %CPU VSZ WCHAN COMMAND 33126 1 root 0.0 1164 pause nginx: master process /usr/local/nginx/sbin/nginx 33135 33126 nobody 0.0 1380 kqread nginx: worker process is shutting down (nginx) 36264 33126 root 0.0 1148 pause nginx: master process /usr/local/nginx/sbin/nginx 36265 36264 nobody 0.0 1364 kqread nginx: worker process (nginx) 36266 36264 nobody 0.0 1364 kqread nginx: worker process (nginx) 36267 36264 nobody 0.0 1364 kqread nginx: worker process (nginx)
當在Linux下使用“rtsig”方法時,在發送WINCH信號給舊的主進程后,新的進程可能不會接受任何連接請求。如果是這樣,需要同步發送USR1信號給新的主進程,直到新的進程開始接受連接請求。
一段時間后,只有新的工作進程將會處理請求:
PID PPID USER %CPU VSZ WCHAN COMMAND 33126 1 root 0.0 1164 pause nginx: master process /usr/local/nginx/sbin/nginx 36264 33126 root 0.0 1148 pause nginx: master process /usr/local/nginx/sbin/nginx 36265 36264 nobody 0.0 1364 kqread nginx: worker process (nginx) 36266 36264 nobody 0.0 1364 kqread nginx: worker process (nginx) 36267 36264 nobody 0.0 1364 kqread nginx: worker process (nginx)
注意,舊的主進程不會關閉它所監聽的套接字,在需要的情況下它能再次啟動它的工作進程。如果由於某些原因新的可執行文件在執行時有誤,可以按照下面的方式來解決:
- 發送HUP信號給舊的主進程,舊的主進程不需要重新讀取配置便啟動新的工作進程。啟動完成后,所有新的進程可以被正常關閉,通過發送QUIT信號給新的主進程。
- 發送TERM信號給新的主進程。它將發送消息給它的工作進程請求立即退出,工作進程幾乎在同時會立即退出。(如果新的進程由於一些原因不能退出,發送KILL信號強制它們退出。)當新的主進程退出,舊的主進程可以自動啟動新的工作進程。
如果新的主進程退出,舊的主進程將會撤消進程ID文件的.oldbin后綴。
如果更新成功,需要發送QUIT信號給舊的主進程,僅保留新的進程:
PID PPID USER %CPU VSZ WCHAN COMMAND 36264 1 root 0.0 1148 pause nginx: master process /usr/local/nginx/sbin/nginx 36265 36264 nobody 0.0 1364 kqread nginx: worker process (nginx) 36266 36264 nobody 0.0 1364 kqread nginx: worker process (nginx) 36267 36264 nobody 0.0 1364 kqread nginx: worker process (nginx)
連接處理方法
nginx支持各種連接處理方法。對於每種特定的方法都需要有平台的支持,在支持多種方法的平台下nginx會自動選用最高效的方法。然而,如有需要,可以使用use指令顯式指定所采用的連接處理方法。
以下的連接處理方法為nginx所支持的:
- select —— 標准方法。在缺少更多高效方法的平台下這個模塊是被自動編譯的。--with-select_module以及--without-select_module配置參數可以被用來強制啟用或禁用對這個模塊的編譯。
- poll —— 標准方法。在缺少更多高效方法的平台下這個模塊是被自動編譯的。--with-poll_module和--without-poll_module配置參數可以被用來強制啟用或禁用對這個模塊的編譯。
- kqueue —— 用在FreeBSD 4.1+,OpenBSD 2.9+,NetBSD 2.0以及Mac OS X下的高效模塊。
- epoll —— 用在Linux 2.6+下的高效模塊。
一些老的分發版像SuSE 8.2提供添加epoll支持到2.4內核的補丁。
- rtsig —— 實時信號,用在Linux 2.2.19+的高效模塊。系統默認提供的事件隊列限制在1024個信號。在負載服務器上可能有必要修改/proc/sys/kernel/rtsig-max內核參數來提高這個限制。然而,在Linux 2.66-mm2里不存在這個參數,現在所有進程有它自己的事件隊列。每個隊列的大小通過RLIMIT_SIGPENDING來指定,並可以通過worker_rlimit_sigpending來改變。
隊列溢出時,nginx取消隊列並回到利用poll連接請求方法,直到情況正常為止。
- /dev/poll —— 用在Solaris 77 11/99+,HP/UX 11.22+(eventport),IRIX 6.5.15+以及Tru64 UNIX 5.1A+下的高效模塊。
- eventport —— 事件端口,用在Solaris 10下的高效方法。
設置hashes
為了快速處理靜態數據集例如服務器名稱、map指令的值、MIME類型、請求頭字符串的名稱,nginx使用hash表。在啟動和每次重新配置過程中,nginx選擇最小可能的hash表大小,例如桶大小,可以用來保存鍵和相同大小的hash值而不超過配置參數(hash桶大小)。hash表的大小以桶來表示。持續校准直到表大小超過hash最大值參數。大多數hash有對應的指令可以用來改變這些參數,例如,對於服務器名稱,它們是server_names_hash_max_size和server_names_hash_bucket_size。
hash桶大小參數指定的大小是處理器cache大小的倍數。在現代處理器中這會減少內存訪問次數,從而加快hash鍵的查找。如果hash桶大小同處理器cache大小相等,那么在最壞的情況下對鍵的查找中訪存次數為2次——第一次計算桶地址,第二次在桶中查詢鍵。因此,如果nginx發出增加hash最大值或hash桶大小的消息,那第一個參數將會被首先增加。
調試日志
要啟用調試日志,nginx需要在編譯時配置為支持調試:
./configure --with-debug...
接着使用error_log指令設置調試級別:
error_log /path/to/log debug;
Windows下的nginx二進制版本通常被編譯為支持調試日志,因此只需要設置調試級別就可以了。
重新定義日志而沒有指定調試級別將會禁用調試日志。在下面的例子中,在server級別上重新定義日志會禁用這個服務器的調試日志。
error_log /path/to/log debug; http { server { error_log /path/to/log; ...
為了防止這個,可以注釋掉重定義日志的那行,或者添加調試級別的說明:
error_log /path/to/log debug; http { server { error_log /path/to/log debug; ...
也可以僅為selected_client_addresses啟用調試日志:
error_log /path/to/log; events { debug_connection 192.168.1.1; debug_connection 192.168.10.0/24; }
配置文件計量單元
大小可以指定為bytes、kilobytes(后綴為k和K)或者megabytes(后綴為m和M),例如:“1024”、“8k”或“1M”。
時間間隔可以指定為毫秒、秒、分、時、天等等,使用以下后綴:
- ms 毫秒
- s 秒
- m 分
- h 時
- d 天
- w 周
- M 月,30天
- y 年,365天
計量單位可以合並為單個數值,按照從大到小的順序指定,可以選擇用空格分割,例如:“1h 30m”可以指定為“90m”或者“5400s”。沒有后綴的值表示秒。推薦使用后綴指定。
一些時間間隔僅可以用秒來指定。
Windows版nginx
Windows版的nginx使用原生的Win32 API(不是采用Cygwin模擬層)。現在只有select()連接處理方法被使用,因此高性能和可擴展性是不被期望的。因為這以及一些其他大家知道的原因,Windows版本的nginx被認為是beta版。在Windows下nginx的beta版,除了XSLT過濾、圖像過濾、GeoIP模塊和內置的Perl語言,它幾乎提供了UNIX版nginx的所有功能。
安裝windows下的nginx,下載最新開發版本(1.3.15),因為nginx開發分支包含所有已知的修正。解壓分發版,進入nginx-1.3.15目錄,運行nginx。以下是驅動器C:根目錄下的例子:
cd c:\ unzip nginx-1.3.15.zip cd nginx-1.3.15 start nginx
運行tasklist命令行組件來查看nginx進程:
C:\nginx-1.3.15>tasklist /fi "imagename eq nginx.exe" Image Name PID Session Name Session# Mem Usage =============== ======== ============== ========== ============ nginx.exe 652 Console 0 2 780 K nginx.exe 1332 Console 0 3 112 K
其中之一為主進程,另外一個是工作進程。如果nginx無法啟動,可以在錯誤日志文件logs\error.log里查看原因。如果日志文件已經被創建,錯誤原因可以在Windows事件日志里查看。如果顯示的是錯誤頁面而不是期望的頁面,也可以在logs\error.log文件里查看原因。
Windows下nginx使用它運行時的目錄作為配置中相對路徑的前綴。對於上面的例子,前綴為C:\nginx-1.3.15\。另外,配置文件中路徑的指定必須采用UNIX風格,即使用斜杠:
access_log logs/site.log; root C:/web/html;
Windows下nginx以標准控制台程序運行(不是服務),而且可以通過以下命令管理:
- nginx -s stop 立即關閉
- nginx -s quit 正常關閉
- nginx -s reload 修改配置,用新的配置啟動新的工作進程,正常關閉舊的工作進程
- nginx -s reopen 重新打開日志文件
已知問題
- 盡管可以啟動多個工作進程,但是實際只有其中一個工作。
- 一個工作進程可以同時處理不多於1024個連接。
- 需要共享內存支持的cache模塊和其他模塊在Windows Vista以及更高版本下無法工作,因為在這些Windows版本中啟用了地址空間布局隨機化。
未來可能的改進
- 以服務運行
- 使用I/O完成端口作為連接處理方法
- 在單個工作進程里使用多個工作線程
介紹篇中還未翻譯的有以下三篇,之后會額外進行翻譯。PS:初次翻譯,問題肯定有很多,歡迎拍磚!