深入理解Nginx模塊開發與架構解析

一、研究Nginx前的準備工作

1.Nginx特點:更快、高擴展性、高可靠性、低內存消耗、單機支持10萬以上的並發連接、熱部署、最自由的BSD許可協議

2.退出nginx

  • nginx -s stop
  • nginx -s quit

3.日誌回滾:nginx -s reopen

二、Nginx的配置

A.運行中的Nginx進程間的關係

  1. 一般情況下,worker進程的數量與伺服器上的CPU數量相等

B.Nginx服務的基本配置

1.用於調試進程和定位問題的配置項

  • daemon on | off;:是否以守護進程方式運行Nginx,默認on
  • master_process on | off;:是否以master/worker方式工作,默認on
  • error_log pathfile level;:error日誌的設置
  • debug_points [stop|abort]:幫助用戶跟蹤調試nginx,一般不用
  • debug_connection [IP | CIDR]:僅對指定的客戶端輸出debug級別的日誌,對定位高並發請求下發生的問題有用,需要configure時加入參數--with-debug
  • worker_rlimit_core size;:限制coredump核心轉儲文件的大小
  • working_directory path;:指定coredump文件生成的目錄

2.正常運行的配置項

  • evn VAR|VAR=VALUE:讓用戶直接設置操作系統上的環境變數
  • include pathfile;:嵌入其他配置文件
  • pid path/file;pid文件的路徑
  • user username [groupname];:Nginx worker進程運行的用戶及用戶組
  • worker_rlimit_nofile limit;:指定Nginx worker進程可以打開的最大句柄描述符個數
  • worker_rlimit_sigpending limit;:限制信號隊列

3.優化性能的配置

  • worker_processes number;:定義worker進程的個數
  • worder_cpu_affinity cpumask [cpumask...];:綁定worker進程到指定的CPU內核
  • ssl_engine device;:SSL硬體加速
  • timer_resolution t;:系統調用gettimeofday的執行頻率
  • worker_priority nice;:worker進程優先順序設置

4.事件類配置項

  • accept_mutex [on | off];:是否打開accept鎖,可以讓多個worker進程輪流地、序列化地與新的客戶端建立TCP連接
  • lock_file path/file;:lock文件的路徑
  • accept_mutex_delay ms;:使用accept鎖後到真正建立連接之間的延遲時間
  • multi_accept on | off;:批量建立新連接
  • use [kqueue|rtsig|epoll|/dev/poll|select|poll|eventport];:選擇事件模型
  • worker_connections number;:每個worker的最大連接數

C.用HTTP核心模塊配置一個靜態Web伺服器

1.虛擬主機與請求的分發

  • listen address:port[default|default_server|[backlog=num|rcvbuf=size|sndbuf=size|accept_filter=filter|deferred|bind|ipv6only=[on|off]|ssl]];:監聽埠,配置在server塊
  • server_name name[...];:主機名稱,配置在server塊
  • server_names_hash_bucket_size size;:設置每個散列表佔用的內存大小,nginx使用散列表來存儲server_name
  • server_names_hash_max_size size;:影響散列表的衝突率,越大消耗的內存越多,但散列key的衝突則會降低,檢索速度也快
  • server_name_in_redirect on|off;:重定向主機名稱的處理
  • location [=|~|~*|^~|@]/uri/{...}:根據請求的URI來匹配進入location{}塊中的配置來處理用戶請求,配置在server塊

2.文件路徑的定義

  • root path;:以root方式設置資源路徑
  • alias path;:別名,將uri映射到真實的磁碟文件上,只能在location塊中
  • index file ...;:訪問首頁
  • error_page code[code...][=|=answer-code]uri|@named_location:根據HTTP返回碼重定向頁面
  • recursive_error_pages [on|off];:是否允許遞歸使用error_page
  • try_files path1[path2]uri;:嘗試按照順序訪問每一個path

3.內存及磁碟資源的分配

  • client_body_in_file_only on|clean|off;:HTTP包體只存儲到磁碟文件中
  • client_body_in_single_buffer on|off;:HTTP包體盡量寫入到一個內存buffer中
  • client_header_buffer_size size;:存儲HTTP頭部的內存buffer大小
  • large_client_header_buffers number size;:定義了Nginx接收一個超大HTTP頭部請求的buffer個數和每個buffer的大小
  • client_body_buffer_size size;:存儲HTTP包體的內存buffer大小
  • client_body_temp_path dir-path[level1[level2[level3]]];:HTTP包體的臨時存放目錄
  • connection_pool_size size;:Nginx對於每個建立成功的TCP連接會預先分配一個內存池,這個配置將指定個內存池的初始大小,用於減少內核對於小塊內存的分配次數
  • request_pool_size size;:Nginx會為每個請求分配一個內存池,配置將指定這個內存池的初始大小

4.網路連接的設置

  • client_header_timeout time:讀取HTTP頭部的超時時間
  • client_body_timeout time:讀取HTTP包體的超時時間
  • send_timeout time;:發送響應的超時時間
  • reset_timeout_connection on|off;:連接超時後將通過向客戶端發送RST包來直接重置連接,這個選項打開後,Nginx將直接向用戶發送RST重置包,不再等待用戶應答,直接釋放緩存
  • lingering_close off|on|always;:控制Nginx關閉用戶連接的方式
  • lingering_time time;:對上傳大文件很有用,當超過時間後,不管是否仍在上傳,都會關閉連接
  • ligering_timeout time;:在lingering_close生效後,在關閉連接前,會檢測是否有用戶發送的數據到達伺服器,如果超過時間後還沒有數據可讀,就直接關閉連接
  • keepalive_disable [msie6|safari|none]...:對某些瀏覽器禁用keepalive功能
  • keepalive_timeout time time:keepalive超時時間
  • keepalive_requests n;:一個keepalive長連接上允許承載的請求最大數
  • tcp_nodelay on|off;:確定對keepalive連接是否使用TCP_NODELAY選項
  • tcp_nopush on|off;:在打開sendfile選項時,確定是否開啟FreeBSD系統上的TCP_NOPUSH或Linux系統上的TCP_CORK功能

5.MIME類型的設置

  • type{...};:MIME type與文件擴展的映射
  • default_type MIME-type;:默認MIME type
  • types_hash_bucket_size size;:設置散列表佔用的內存大小
  • types_hash_max_size size;:影響散列表的衝突率

6.對客戶端請求的限制

  • limit_except method...{...}:按HTTP方法名限制用戶請求
  • client_max_body_size size;:HTTP請求包體的最大值
  • limit_rate speed;:對客戶端請求限制每秒傳輸的位元組數
  • limit_rate_after time;:表示nginx向客戶端發磅的響應長度超過limit_rate_after後才開始限速

7.文件操作的優化

  • sendfile on|off;:啟用sendfile系統調用來發送文件
  • aio on|off;:表示是否在FreeBSD或Linux系統上啟用內核級別的非同步I/O功能,與sendfile是互斥的
  • directio size|off;:在FreeBSD和Linux系統上使用O_DIRECT選項去讀取文件,與sendfile互斥
  • directio_alignment size;:與directio配合,指定directio方式讀取文件時的對齊方式
  • open_file_cache max=N[inactive=time]|off;:打開文件緩存
  • open_file_cache_errors on|off;:是否緩存打開文件錯誤的信息
  • open_file_cache_min_uses number;:不被淘汰的最小訪問次數,與open_file_cache的inactive配合使用,如果超過了,則不會被淘汰出緩存
  • open_file_cache_valid time;:檢驗緩存中元素有效性的頻率

8.對客戶端請求的特殊處理

  • ignore_invalid_headers on|off;:忽略不合法的HTTP頭部
  • underscores_in_headers on|off;:HTTP頭部是否允許下劃線
  • if_modified_since [off|exact|before];:對If-Modified-Since頭部的處理策略
  • log_not_found on|off;:文件未找到時是否記錄到error日誌
  • merge_slashes on|off;:是否合併相鄰的/
  • resolver address...;:廢黜DNS名字解析伺服器的地址
  • resolver_timeout time;:DNS解析超時時間
  • server_tokens on|off;:返回錯誤頁面時是否在Server中註明Nginx版本

D.用HTTP proxy module配置一個反向代理伺服器

1.負載均衡的基本配置

  • upstream name {...}:定義了一個上游伺服器的集群,便於反向代理中的proxy_pass使用,配置在http塊
  • server name [weight=number,max_fails=number,fail_timeout=time,down,backup]:指定一台上游伺服器的名字,可以是域名、ip地址埠、UNIX句柄等,配置在upstream塊中
  • ip_hash;:根據客戶IP地址將請求始終落在固定的一台上游伺服器中,與weight配置不可同時使用

2.反向代理的基本配置

  • proxy_pass URL;:將當前請求反向代理到URL參數指定的伺服器上,URL可使用是域名、ip地址埠、UNIX句柄或upstream塊,配置在location、if塊中
  • proxy_set_header Host $host;:轉發請求中的Host頭,默認proxy_pass不轉發
  • proxy_method method;:轉發時的協議方法名
  • proxy_hide_header the_header;:可以指定哪些HTTP頭部欄位不能被轉發
  • proxy_pass_header the_header;:與proxy_hide_header相反
  • proxy_pass_request_body on|off;:確定是否向上游伺服器發送HTTP包體部分
  • proxy_pass_request_headers on|off;:確定是否轉發HTTP頭部
  • proxy_redirect [default|off|redirect replacement];:當上游伺服器返回重定向或刷新請求時,可以重設HTTP頭部的location或refresh欄位
  • proxy_next_upstream [ errpo,timeout,invalid_header,http500,http_502,http503,http_504,http_404,off]:當一台上游伺服器轉發請求出現錯誤時,繼續換一台處理這個請求

三、開發一個簡單的HTTP模塊

1.整型的封裝:ngx_int_t、ngx_uint_t

2.字元串:ngx_str_t

3.鏈表容器:ngx_list_t

4.key/value對:ngx_table_elt_t

5.緩衝區:ngx_buf_t

6.與ngx_buf_t配合使用的鏈接結構:ngx_chain_t

四、配置、error日誌和請求上下文

五、訪問第三方服務

1.upstream可以保證在與第三方伺服器交互時(包括三次握手建立TCP連接、發送請求、接收響應、四次握手關閉TCP連接等)不會阻塞Nginx進程處理其他請求

2.subrequest是分解複雜請求的一種設計模式,最終也是基於upstream實現的

3.當我們希望把第三方服務的內容幾乎原封不動地返回給用戶時,一般使用upstream方式,可以非常高效地透傳HTTP;如果訪問第三方服務只是為了獲取某些信息,再依據這些信息來構造 響應並傳送給客戶,應該使用subrequest方式

六、開發一個簡單的HTTP過濾模塊

七、Nginx提供的高級數據結構

八、Nginx基礎架構

九、事件模塊

十、HTTP框架的初始化

十一、HTTP框架的執行流程

十二、upstream機制的設計與實現

十三、郵件代理模塊

十四、進程間的通信機制

十五、變數

十六、slab共享內存


推薦閱讀:

為什麼中國程序員對待外國人抱怨和對待國人抱怨採取截然不同的態度?
給小白的 Nginx 30分鐘入門指南
Nginx 教程 #3:SSL 設置
Nginx 多進程模型是如何實現高並發的?
微軟的 Web 伺服器為何能屹立不倒?

TAG:Nginx | 深入理解Nginx書籍 | 讀書筆記 |