Nginx是一款高性能的web服務器、反向代理服務器及電子郵件(IMAP/POP3)代理服務器,具有佔用內存少,併發能力強等優點。
一、nginx相關網站
官方文檔:http://nginx.org/en/docs/
中文文檔:http://tengine.taobao.org/nginx_docs/cn/docs/
二、nginx的功能與特性
1、基本功能及特性
①作爲靜態資源的web服務器,能緩存打開的文件描述符;
②作爲反向代理服務器,可做緩存、負載均衡;
③支持FastCGI
④模塊化,非DSO機制(不能動態裝卸載),過濾器gzip,SSI和圖像大小調整等
⑤支持SSL
2、擴展功能:
①基於名稱和IP做虛擬主機
②支持keepalive
③支持平滑配置更新或程序版本升級
④定製訪問日誌,支持使用日誌緩存以提高性能
⑤支持url rewrite
⑥支持路徑別名
⑦支持基於IP及用戶的認證;
⑧支持速率限制,併發限制等;
三、nginx的進程模型
傳統上基於進程或線程模型架構的web服務通過每進程或每線程處理併發連接請求,生成一個新的進程/線程需要事先備好其運行時環境,這包括爲其分配堆內存和棧內存,以及爲其創建新的執行上下文等。這些操作都需要佔用CPU,過多的進程/線程還會帶來線程抖動或頻繁的上下文切換,系統性能也會由此進一步下降。
◆nginx會運行一個主進程(master)和若干個由其fork出來的工作進程(worker),配置了緩存時還會有緩存加載器進程(cache loader)和緩存管理器進程(cache manager)等。所有進程均是僅含有一個線程,並主要通過“共享內存”的機制實現進程間通信。連接請求就由爲數不多的幾個僅包含一個線程的worker進程以高效的迴環(run-loop)機制進行處理,這樣就不會引起很多的進程/線程上下文切換,從而降低了系統開銷。每個線程內部對socket的管理方式是異步非阻塞的,使用epoll事件驅動機制來實現對大量socket描述符的管理,當描述符多的時候也只是會佔用較多的內存而已,而不會造成佔用大量cpu時間,這就是nginx併發能力強的原因。每個worker可以並行處理數千個的併發連接及請求。
每個worker進程是平等的,當有連接請求進來,交由哪個worker處理呢?master進程在建立需要listen的socket之後,fork出若干個worker進程,所有worker進程會搶互斥鎖,搶到的的接受並處理連接請求,返回數據給客戶端,最後斷開連接,一個請求只在由一個worker處理。
worker數是可以設置的:如果負載以CPU密集型應用爲主,如SSL或壓縮應用,則worker數應與CPU數相同;如果負載以IO密集型爲主,如響應大量內容給客戶端,則worker數應該爲CPU個數的1.5或2倍。
主進程以root用戶身份運行,而worker、cache loader和cache manager均應以非特權用戶身份運行。
主進程主要完成如下工作:
①讀取並驗正配置信息;
②創建、綁定及關閉套接字;
③啓動、終止及維護worker進程的個數;
④無須中止服務而重新配置工作特性;
⑤控制非中斷式程序升級,啓用新的二進制程序並在需要時回滾至老版本;
⑥重新打開日誌文件,實現日誌滾動;
⑦編譯嵌入式perl腳本;
worker進程主要完成的任務包括:
①接收、傳入並處理來自客戶端的連接;
②提供反向代理及過濾功能;
③nginx任何能完成的其它任務;
cache loader進程主要完成的任務包括:
①檢查緩存存儲中的緩存對象;
②使用緩存元數據建立內存數據庫;
cache manager進程的主要任務:
①緩存的失效及過期檢驗;
◆nginx支持sendfile和mmap
sendfile():
在傳統的網絡文件傳輸方式中,文件數據實際上是經過了四次copy操作:
硬盤—>內核buffer—>用戶buffer—>socket相關緩衝區—>協議引擎
而sendfile系統調用則提供了一種減少以上多次copy,提升文件傳輸性能的方法:
硬盤—>內核buffer—>socket相關緩衝區—>協議引擎
在內核版本2.4之後,sendfile實現了更簡單的方式,系統調用方式仍然一樣,細節與2.1版本的不同之處在於,當文件數據被複制到內核緩衝區時,不再將所有數據copy到socket相關的緩衝區,而是僅僅將記錄數據位置和長度相關的數據保存到socket相關的緩存,而實際數據將由DMA模塊直接發送到協議引擎,再次減少了一次copy操作。
mmap():內存映射
進程訪問文件的傳統方法是,先由進程向內核發起系統調用,內核將文件由磁盤加載到內核緩衝區,再copy一個副本到進程空間(用戶空間),如果有多個進程訪問同一個文件, 則每一個進程在自己的地址空間都包含有該文件的副本,這不必要地浪費了存儲空間。
mmap()系統調用使得進程之間通過映射同一個普通文件實現共享內存。內核緩衝區中的普通文件被映射到進程地址空間後,進程可以向訪問普通內存一樣對文件進行訪問,不必再調用read(),write()等操作。
四、nginx的模塊和工作原理
nginx代碼是由內核和一系列的模塊組成, nginx內核主要用於提供Web Server的基本功能,以及Web和Mail反向代理的功能;還用於啓用網絡協議,創建必要的運行時環境以及確保不同的模塊之間平滑地進行交互。不過,大多跟協議相關的功能和某應用特有的功能都是由nginx的模塊實現的。
◆nginx模塊從結構上分爲:
核心模塊
http模塊
http標準模塊
http可選模塊
如 http_stub_status_module,http_ssl_module,http_gzip_static_module
郵件模塊
第三方擴展模塊
◆nginx模塊從功能上分爲:
handlers:此類模塊直接處理請求,並生成內容
filter:此類模塊對其它handlers生成的內容進行修改,最後由nginx輸出
proxies:此類模塊主要與後端服務如fastcgi進行交互,實現服務代理和負載均衡等功能
nginx內核僅僅是通過查找配置文件將http請求映射到一個location block,而此location中所配置的各個指令則會啓動不同的模塊去完成工作,可以說nginx模塊纔是真正的勞動者。
模塊化設計是nginx的一個重要特點。要注意的是:nginx的模塊是靜態的,添加和刪除模塊都要對nginx進行重新編譯,這一點與Apache的動態模塊不同
五、nginx編譯安裝
1、解決依賴關係
yum -y groupinstall "Development Tools" "Server Platform Development"
yum -y install gcc pcre-devel openssl-devel zlib-devel
nginx的rewrite模塊和http核心模塊會用到PCRE正則表達式語法,所以要安裝pcre-devel,PCRE(Perl Compatible Regular Expressions)是一個輕量級的Perl函數庫
2、添加用戶nginx,實現以之運行nginx服務進程
useradd -r -s /sbin/nologin nginx
3、到官網下載源碼包,解壓並編譯、安裝
tar xf nginx-1.10.2.tar.gz
cd nginx-1.10.2
./configure \
--prefix=/usr/local/nginx-1.10.2 \
--error-log-path=/var/log/nginx/error.log \
--http-log-path=/var/log/nginx/access.log \
--pid-path=/var/run/nginx/nginx.pid \
--lock-path=/var/lock/nginx.lock \
--user=nginx \ #指定以什麼身份運行worker進程
--group=nginx \
--with-http_ssl_module \
--with-http_flv_module \ #流媒體模塊
--with-http_stub_status_module \ #監控運行狀態的模塊
--with-http_gzip_static_module \
--http-client-body-temp-path=/usr/local/nginx/client \ #臨時包體的暫存路徑
--http-proxy-temp-path=/usr/local/nginx/proxy \
--http-fastcgi-temp-path=/usr/local/nginx/fcgi \
--http-uwsgi-temp-path=/usr/local/nginx/uwsgi \
--http-scgi-temp-path=/usr/local/nginx/scgi \
--with-pcre
make && make install
ln -s /usr/local/nginx-1.10.2 /usr/local/nginx
◆說明:
①Nginx可以使用Tmalloc(快速、多線程的malloc庫及優秀性能分析工具)來加速內存分配,使用此功能需要事先安裝gperftools,而後在編譯nginx添加--with-google_perftools_module選項即可。
②如果想使用nginx的perl模塊,可以通過爲configure腳本添加--with-http_perl_module選項來實現,但目前此模塊仍處於實驗性使用階段,可能會在運行中出現意外
4、提供服務腳本並添加開機自動啓動
vim /etc/rc.d/init.d/nginx
...
chmod +x /etc/rc.d/init.d/nginx
chkconfig --add nginx
chkconfig on nginx
其它操作:
vim /etc/profile.d/nginx.sh
export PATH=$PATH:/usr/local/nginx/sbin #更新PATH環境變量
ln -s /usr/local/nginx/conf /etc/nginx/conf #創建配置文件目錄的軟鏈接,便於訪問
5、啓動服務
service nginx start
6、nginx命令
用法:nginx [option]...
常用選項:
-p prefix:set prefix path,默認是安裝時指定的路徑
-c filename:指定配置文件,默認從安裝時指定的路徑下尋找
-t:配置文件檢查
-v:顯示nginx版本
-V:顯示nginx版本及安裝時配置的參數
[root@node1 ~]# yum -y groupinstall "Development Tools" "Server Platform Development" ... [root@node1 ~]# yum -y install pcre-devel ... [root@node1 ~]# useradd -r nginx [root@node1 ~]# id nginx uid=496(nginx) gid=493(nginx) groups=493(nginx) [root@node1 ~]# tar xf nginx-1.10.2.tar.gz [root@node1 ~]# cd nginx-1.10.2 [root@node1 nginx-1.10.2]# ls auto CHANGES CHANGES.ru conf configure contrib html LICENSE man README src [root@node1 nginx-1.10.2]# ./configure --prefix=/usr/local/nginx-1.10.2 \ > --error-log-path=/var/log/nginx/error.log \ > --http-log-path=/var/log/nginx/access.log \ > --pid-path=/var/run/nginx/nginx.pid \ > --lock-path=/var/lock/nginx.lock \ > --user=nginx \ > --group=nginx \ > --with-http_ssl_module \ > --with-http_flv_module \ > --with-http_stub_status_module \ > --with-http_gzip_static_module \ > --http-client-body-temp-path=/usr/local/nginx/client \ > --http-proxy-temp-path=/usr/local/nginx/proxy \ > --http-fastcgi-temp-path=/usr/local/nginx/fcgi \ > --http-uwsgi-temp-path=/usr/local/nginx/uwsgi \ > --http-scgi-temp-path=/usr/local/nginx/scgi \ > --with-pcre ... [root@node1 nginx-1.10.2]# make && make install ... [root@node1 nginx-1.10.2]# ln -s /usr/local/nginx-1.10.2 /usr/local/nginx [root@node1 nginx-1.10.2]# cd /usr/local/nginx/ [root@node1 nginx]# ls conf html sbin [root@node1 nginx]# ls conf fastcgi.conf fastcgi_params koi-utf mime.types nginx.conf scgi_params uwsgi_params win-utf fastcgi.conf.default fastcgi_params.default koi-win mime.types.default nginx.conf.default scgi_params.default uwsgi_params.default [root@node1 nginx]# ls sbin nginx #主程序 [root@node1 nginx]# ls html/ 50x.html index.html [root@node1 nginx]# vim /etc/profile.d/nginx.sh export PATH=$PATH:/usr/local/nginx/sbin [root@node1 nginx]# source !$ [root@node1 nginx]# ln -s /usr/local/nginx/conf /etc/nginx/conf [root@node1 nginx]# vim /etc/rc.d/init.d/nginx ... [root@node1 nginx]# chmod +x !$ chmod +x /etc/rc.d/init.d/nginx [root@node1 nginx]# chkconfig --add nginx [root@node1 nginx]# chkconfig nginx on [root@node1 nginx]# service nginx start Starting nginx: [ OK ] [root@node1 nginx]# ss -tnl State Recv-Q Send-Q Local Address:Port Peer Address:Port ... LISTEN 0 128 *:80 *:* [root@node1 nginx]# nginx -v nginx version: nginx/1.10.2