書接上回,聊一聊nginx的必知必會!??! 前言:從該教程往后,涉及到nginx的功能將越來越生產(chǎn)化,因此某些測試必須是基于web架構(gòu)平臺,所以在看本教程之前,建議先安裝好LNMP或者LAMP架構(gòu),以便測試驗證。其次該技術(shù)文檔的測試是基于前端nginx反向代理與后端LNMP架構(gòu)來測試的,后端LNMP主要是提供測試的訪問頁面而已,重點(diǎn)還是前端Nginx的設(shè)置
測試環(huán)境: 前端代理: OS:CentOS6.5x64 hostname:test1. ip:10.0.10.11 后端LNMP: OS:CentOS6.5x64 hostname:test2. ip:10.0.10.12 注意:未做特別說明,則所有配置均在前端代理上進(jìn)行配置 1.nginx信號機(jī)制,平滑重啟和平滑升級 nginx本身提供了5種信號機(jī)制,通過該信號機(jī)制能夠?qū)崿F(xiàn)nginx的平滑重啟,平滑升級,日志切割等功能。 nginx信號機(jī)制: HUP:實現(xiàn)平滑重啟nginx,所謂平滑重啟就是不重啟nginx的master進(jìn)程,關(guān)閉原有worker進(jìn)程,打開新的worker進(jìn)程,這個過程不會中斷用戶的請求 USR1:用于實現(xiàn)nginx日志的切割,使用該信號可以在不重啟nginx進(jìn)程的情況下,重新打開一個nginx日志文件 USR2:用來平滑升級nginx的可執(zhí)行文件 WINCH:用來從容關(guān)閉nginx的worker進(jìn)程,使用可信號不會立即結(jié)束nginx的worker進(jìn)程,而是當(dāng)worker進(jìn)程處理完所有的連接后在關(guān)閉worker進(jìn)程 QUIT:用來關(guān)閉nginx的master進(jìn)程,在升級nginx時,會等所有的worker進(jìn)程都結(jié)束后,從容的關(guān)閉nginx的舊版master進(jìn)程 1)平滑重啟: #kill -HUP `cat /usr/local/nginx/logs/nginx.pid` 除此之外還有一種方式也可以達(dá)到平滑重啟的目的: #service nginx reload or /usr/local/nginx/sbin/nginx -s reload 驗證: 查看當(dāng)前nginx的進(jìn)程,并記住進(jìn)程號 [root@test1 sbin]# ps aux | grep nginx root 1244 0.0 0.1 22276 900 ? Ss 13:44 0:00 nginx: master process /usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf nginx 1246 0.0 0.2 22660 1504 ? S 13:44 0:00 nginx: worker process 平滑重啟nginx: [root@test1 sbin]# kill -HUP `cat /usr/local/nginx/logs/nginx.pid` [root@test1 sbin]# ps aux | grep nginx root 1244 0.0 0.4 22408 2292 ? Ss 13:44 0:00 nginx: master process /usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf nginx 1254 0.0 0.3 22796 1656 ? S 13:48 0:00 nginx: worker process [root@test1 sbin]# service nginx reload nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful Reloading nginx: [ OK ] [root@test1 sbin]# ps aux | grep nginx root 1244 0.0 0.4 22408 2304 ? Ss 13:44 0:00 nginx: master process /usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf nginx 1271 0.0 0.3 22804 1668 ? S 13:48 0:00 nginx: worker process 通過上面的對比,發(fā)現(xiàn)平滑重啟后,nginx的master進(jìn)程都保持不變,而worker進(jìn)程每次都在變化 2)平滑升級 nginx的平滑升級功能是nginx的一大優(yōu)勢,通常軟件在升級的時候都必然會導(dǎo)致重啟服務(wù)而中斷用戶的請求服務(wù)。而nginx的平滑升級卻可以實現(xiàn)熱升級,在不中斷用戶請求服務(wù)的情況下就 可以完美實現(xiàn)版本的升級。 其次:要知道所謂軟件的升級,通常升級的都是可執(zhí)行文件,nginx也是一樣,升級的是nginx的可執(zhí)行文件 升級過程: 查看nginx當(dāng)前版本: [root@test1 nginx-1.7.4]# /usr/local/nginx/sbin/nginx -v nginx version: nginx/1.6.1 [root@test1 nginx-1.7.4]# 可知,目前使用的版本是nginx1.6的,而要升級的是nginx1.7.4的版本
查看nginx編譯的參數(shù): [root@test1 nginx-1.7.4]# /usr/local/nginx/sbin/nginx -V nginx version: nginx/1.6.1 built by gcc 4.4.7 20120313 (Red Hat 4.4.7-4) (GCC) TLS SNI support enabled configure arguments: --prefix=/usr/local/nginx/ --with-pcre --with-http_ssl_module --with-openssl=/root/soft/openssl-1.0.1i --with-http_gzip_static_module --with-http_realip_module --with-http_stub_status_module --http-client-body-temp-path=/usr/local/nginx/client_body_temp/ --http-proxy-temp-path=/usr/local/nginx/proxy_temp/ --http-fastcgi-temp-path=/usr/local/nginx/fastcgi_temp/ --http-uwsgi-temp-path=/usr/local/nginx/uwsgi_temp/ --http-scgi-temp-path=/usr/local/nginx/scgi_temp/ 由上面的信息可知nginx的編譯參數(shù) 開始編譯新版本的nginx: [root@test1 nginx-1.7.4]# ./configure --prefix=/usr/local/nginx/ --with-pcre --with-http_ssl_module --with-openssl=/root/soft/openssl-1.0.1i --with-http_gzip_static_module --with-http_realip_module --with-http_stub_status_module --http-client-body-temp-path=/usr/local/nginx/client_body_temp/ --http-proxy-temp-path=/usr/local/nginx/proxy_temp/ --http-fastcgi-temp-path=/usr/local/nginx/fastcgi_temp/ --http-uwsgi-temp-path=/usr/local/nginx/uwsgi_temp/ --http-scgi-temp-path=/usr/local/nginx/scgi_temp/ configure若沒有錯誤,顯示如下信息: Configuration summary + using system PCRE library + using OpenSSL library: /root/soft/openssl-1.0.1i + md5: using OpenSSL library + sha1: using OpenSSL library + using system zlib library nginx path prefix: "/usr/local/nginx/" nginx binary file: "/usr/local/nginx//sbin/nginx" nginx configuration prefix: "/usr/local/nginx//conf" nginx configuration file: "/usr/local/nginx//conf/nginx.conf" nginx pid file: "/usr/local/nginx//logs/nginx.pid" nginx error log file: "/usr/local/nginx//logs/error.log" nginx http access log file: "/usr/local/nginx//logs/access.log" nginx http client request body temporary files: "/usr/local/nginx/client_body_temp/" nginx http proxy temporary files: "/usr/local/nginx/proxy_temp/" nginx http fastcgi temporary files: "/usr/local/nginx/fastcgi_temp/" nginx http uwsgi temporary files: "/usr/local/nginx/uwsgi_temp/" nginx http scgi temporary files: "/usr/local/nginx/scgi_temp/" [root@test1 nginx-1.7.4]# make //注意:這里千萬不要make install ,因為make install會全新安裝nginx,而不是熱升級了。如果沒有什么報錯,則說明make基本是成功了。接下來就是熱升級的關(guān)鍵部分了 備份舊的可執(zhí)行文件為nginx.old,拷貝新的可執(zhí)行文件到/usr/local/nginx/sbin/目錄下 [root@test1 nginx-1.7.4]# mv /usr/local/nginx/sbin/nginx /usr/local/nginx/sbin/nginx.old [root@test1 nginx-1.7.4]# cp objs/ng nginx nginx.8 ngx_auto_config.h ngx_auto_headers.h ngx_modules.c ngx_modules.o [root@test1 nginx-1.7.4]# cp -p objs/nginx /usr/local/nginx/sbin/ [root@test1 nginx-1.7.4]# ls -l /usr/local/nginx/sbin total 14544 -rwxr-xr-x. 1 root root 7515939 Aug 26 14:32 nginx -rwxr-xr-x. 1 root root 7376337 Aug 21 16:03 nginx.old 測試新版的nginx可執(zhí)行程序是否正常: [root@test1 nginx-1.7.4]# cd /usr/local/nginx/sbin/ [root@test1 sbin]# ls nginx nginx.old [root@test1 sbin]# ./nginx -t -c /usr/local/nginx/conf/nginx.conf nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful [root@test1 sbin]# 如上信息所示,nginx執(zhí)行文件正常 升級nginx可執(zhí)行文件: [root@test1 sbin]# kill -USR2 `cat /usr/local/nginx/logs/nginx.pid` [root@test1 sbin]# ps aux | grep nginx root 1244 0.0 0.4 22408 2316 ? Ss 13:44 0:00 nginx: master process /usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf nginx 16086 0.0 0.3 22796 1664 ? S 14:49 0:00 nginx: worker process root 16094 0.0 0.5 22296 2728 ? S 14:50 0:00 nginx: master process /usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf nginx 16095 0.0 0.3 22676 1512 ? S 14:50 0:00 nginx: worker process root 16100 0.0 0.1 103244 848 pts/1 S+ 14:50 0:00 grep nginx [root@test1 sbin]# ls -l /usr/local/nginx/logs/ total 92 -rw-r--r--. 1 root root 9064 Aug 25 10:47 access.log -rw-r--r--. 1 root root 51603 Aug 26 14:50 error.log -rw-r--r--. 1 root root 14158 Aug 25 10:47 host.access.log -rw-r--r--. 1 root root 6 Aug 26 14:50 nginx.pid -rw-r--r--. 1 root root 5 Aug 26 13:44 nginx.pid.oldbin 如上信息可見,系統(tǒng)中現(xiàn)在有兩個nginx的主進(jìn)程和各自的worker進(jìn)程,而nginx的pid號也有兩個,其中一個變成了nginx.pid.oldbin,這說明此時舊版nginx和新版nginx在共存。 查看80端口的請求連接: [root@test1 sbin]#netstat -nultp | grep 80 由于是實驗,無法演示效果,在生產(chǎn)環(huán)境中,你可以看到如果當(dāng)前還有正在處理的請求,一定是舊版的nginx worker進(jìn)程在處理,等處理完了,只剩下監(jiān)聽狀態(tài)的時候就可以從容關(guān)閉舊版nginx的worker進(jìn)程,不再處理請求 從容關(guān)閉worker進(jìn)程: [root@test1 sbin]# kill -WINCH `cat /usr/local/nginx/logs/nginx.pid.oldbin` [root@test1 sbin]# ps aux | grep nginx root 1244 0.0 0.4 22408 2316 ? Ss 13:44 0:00 nginx: master process /usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf root 16094 0.0 0.5 22296 2728 ? S 14:50 0:00 nginx: master process /usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf nginx 16095 0.0 0.3 22676 1512 ? S 14:50 0:00 nginx: worker process 由上面的信息可見,舊版的worker進(jìn)程已經(jīng)關(guān)閉。 從容關(guān)閉舊版的master進(jìn)程: [root@test1 sbin]# kill -QUIT `cat /usr/local/nginx/logs/nginx.pid.oldbin` [root@test1 sbin]# ps aux | grep nginx root 16094 0.0 0.5 22296 2728 ? S 14:50 0:00 nginx: master process /usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf nginx 16095 0.0 0.3 22676 1512 ? S 14:50 0:00 nginx: worker process root 16112 0.0 0.1 103244 848 pts/1 S+ 14:58 0:00 grep nginx [root@test1 sbin]# ls -l /usr/local/nginx/logs/ total 88 -rw-r--r--. 1 root root 9064 Aug 25 10:47 access.log -rw-r--r--. 1 root root 52115 Aug 26 14:58 error.log -rw-r--r--. 1 root root 14158 Aug 25 10:47 host.access.log -rw-r--r--. 1 root root 6 Aug 26 14:50 nginx.pid [root@test1 sbin]# 由上面的對比可見,此時只剩下新版的nginx進(jìn)程了,而且舊版的nginx的pid文件也自動消失了。。 查看nginx的版本號確認(rèn): [root@test1 sbin]# /usr/local/nginx/sbin/nginx -v nginx version: nginx/1.7.4 [root@test1 sbin]# 由此可見此時nginx的版本已經(jīng)升級到1.7.4了。而在這個過程中,從未中斷過用戶的請求。接下來,刪除舊的nginx的可執(zhí)行文件即可 2.日志配置以及日志切割 在生產(chǎn)環(huán)境中,日志的收集分析也是很重的環(huán)節(jié)。對于一個web站點(diǎn),通過日志可以基本的分析出pv,uv,ip以及流量等信息。為了對日志進(jìn)行統(tǒng)一的管理,就必須事先設(shè)定好日志的格式, 以及日志的保存方式。
日志配置: 通常情況下使用nginx的默認(rèn)日志配置即可,所有日志段都是nginx的內(nèi)置變量組成的,如果想擴(kuò)展nginx的日志,只需要添加你想要的變量即可。 log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"'; 關(guān)于日志變量的分析,這里不在贅述,可以查看nginx配置文件分析一章 日志切割: 日積月累,日志文件的大小會越來越大,為了方便統(tǒng)計和管理,常見的是對日志進(jìn)行每天切割保存。 nginx日志切割的原理是利用其USR1的信號機(jī)制,該信號可以使用nginx在不重啟的情況下就打開一個新的日志文件 測試; [root@test1 nginx]# cd /usr/local/nginx/logs/ //切換到日志目錄下 [root@test1 logs]# ls //查看日志文件 access.log error.log host.access.log nginx.pid [root@test1 logs]# pwd /usr/local/nginx/logs [root@test1 logs]# ps aux | grep nginx //查看現(xiàn)在的nginx進(jìn)程好,一定要記住 root 16188 0.0 0.1 22276 900 ? Ss 15:12 0:00 nginx: master process /usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf nginx 16190 0.0 0.3 22660 1844 ? S 15:12 0:00 nginx: worker process root 16208 0.0 0.1 103244 844 pts/1 S+ 15:22 0:00 grep nginx [root@test1 logs]# mv access.log access.log.bak //移動當(dāng)前的日志文件為bak [root@test1 logs]# kill -USR1 `cat /usr/local/nginx/logs/nginx.pid` //重新生成日志文件 [root@test1 logs]# ls access.log access.log.bak error.log host.access.log nginx.pid //查看此時的日志文件,發(fā)現(xiàn)既有bak文件也有新生產(chǎn)的access.log文件 [root@test1 logs]# ps aux | grep nginx //查看此時的nginx進(jìn)程號 root 16188 0.0 0.2 22276 1032 ? Ss 15:12 0:00 nginx: master process /usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf nginx 16190 0.0 0.3 22660 1856 ? S 15:12 0:00 nginx: worker process root 16213 0.0 0.1 103244 844 pts/1 S+ 15:23 0:00 grep nginx [root@test1 logs]# 從上面的信息可以看出,nginx前后的進(jìn)程號沒有發(fā)生任何的變化,因此可知USR1該信號可以在不重新nginx進(jìn)程的情況下,重新生成日志文件 日志切割計劃任務(wù)部署: 切割腳本: #vim /root/shellscripts/lognginx.sh #!/bin/bash logPath=/usr/local/nginx/logs //nginx日志的路徑 logBackupPath=/root/logs //nginx日志備份的路徑 oldLog=access.log //定義nginx的日志名 newLog=access-`date +%F`.log //定義nginx備份的日志文件名 pidPath=/usr/local/nginx/logs/nginx.pid //定義nginx的進(jìn)程號文件 mv $logPath/$oldLog $logBackupPath/$newLog kill -USR1 `cat $pidPath`
計劃任務(wù): #vim /etc/crontab //添加一條如下內(nèi)容,每天的凌晨進(jìn)行日志切割 0 0 * * * root /root/shellscripts/lognginx.sh #service crontab restart //重啟守護(hù)進(jìn)程 OK,到此nignx的日志切割也完成了。 3.關(guān)閉nginx版本號的顯示 為了加強(qiáng)服務(wù)器的安全,隱藏軟件版本也是其中的一個手段,默認(rèn)情況下訪問nginx出錯時,會提示錯誤,但是也會顯示nginx的版本號 測試; http://10.0.10.11/index.html2 //在瀏覽器中隨便輸入一個不存在的url,此時nginx抱如下錯誤
由上面的信息,可以很直觀的看出服務(wù)器使用了nginx,并且版本號是1.6.1. 對于高級的攻擊者,根據(jù)版本好就可能找出相關(guān)的漏洞,因此必須要隱藏版本號 設(shè)置; 在nginx.conf配置文件的http{}段中,增加一條指令 server_tokens off; 重啟nginx服務(wù)器,再次訪問:
發(fā)現(xiàn)此時再次訪問,雖然報錯,但是已經(jīng)沒有nginx的版本信息了。 如果nginx后php整合了,建議同時取消fastcgi.param中的nginx版本信息:
4.基于ip和http基本認(rèn)證的權(quán)限配置 nginx本身也提供了一系列的安全防護(hù)功能,基本的有ip權(quán)限控制和用戶認(rèn)證控制 基于ip的認(rèn)證: 基于ip的認(rèn)證涉及到兩個指令:allow deny。allow表示允許訪問,deny表示不允許訪問 測試: 修改nginx.conf配置文件,在location /里面添加deny 和allow指令 location / { root html; index index.html index.htm; deny 10.0.10.12; //決絕該ip訪問 allow all; //允許其他所有的ip地址訪問 } 注意;allow,deny的匹配順序是次序匹配,匹配到則結(jié)束 在10.0.10.12虛擬機(jī)上訪問:
可以看到,訪問被拒絕。 在宿主機(jī)上進(jìn)行訪問,此時發(fā)現(xiàn)可以正常訪問,顯示如下內(nèi)容:
基于用戶的認(rèn)證: nginx可以實現(xiàn)基本的用戶認(rèn)證 測試: 修改nginx.conf配置文件,修改內(nèi)容如下: location / { root html; index index.html index.htm; auth_basic "relam authentication"; //auth_basci就表示開啟用戶身份認(rèn)證功能 auth_basic_user_file /usr/local/nginx/htpasswd; } 創(chuàng)建htpasswd文件:
//注:這里的htpasswd命令要借助于http-tool軟件包,沒安裝得要安裝一下
測試: http://10.0.10.11/
如上圖所示,填入用戶名和密碼,點(diǎn)擊確定即可訪問。
5.nginx status查看 nginx提供了基本狀態(tài)信息查看機(jī)制,該模塊默認(rèn)沒有啟用,要想啟用該功能必須在編譯nginx的時候手動添加;--with-http_stub_status_module 配置: 修改nginx.conf配置文件,在server{}段中添加一個location 訪問:
Active connections:表示當(dāng)前活躍的連接數(shù), 第二行的三個數(shù)字表示分別表示:nginx總共接受了多少個連接,成功建立了多少個連接,總共處理了多少個請求數(shù) 最后一行的Reading表示Nginx讀取到客戶端Header信息數(shù), Writing表示Nginx返回給客戶端的Header信息數(shù),“Waiting”表示Nginx已經(jīng)處理完,正在等候下一次請求指令時的駐留連接數(shù)
6.nginx 錯誤頁面的配置 在客戶端的訪問過程中,肯定會出現(xiàn)這樣或那樣的錯誤,為了使體驗更加的人性化,可以根據(jù)需要設(shè)計自己的錯誤頁面,然后通過nginx中error_page選項來調(diào)用錯誤頁面 error_page:用來設(shè)置錯誤的狀態(tài)碼轉(zhuǎn)換到對應(yīng)的錯誤頁面 格式; error_page status_code page; 但是光設(shè)置這個還沒有用,還必須配置location來指定該頁面所在的路徑,才能正確的調(diào)用 測試案例; 在還沒有配置的情況下,訪問一個不存在的頁面,會報 404 not found的錯誤
接下來配置nginx的404錯誤頁面: #echo "<h1>this is 404 error page</h1>" > /usr/local/nginx/html/404.html 重啟nginx進(jìn)程,然后再次使用:http://10.0.10.11/index.html2 ,此時會顯示預(yù)先定義的錯誤頁面內(nèi)容.
轉(zhuǎn)換流程: 客戶端訪問頁面時,如果發(fā)生了一個404的錯誤,此時服務(wù)器端會自動將url地址轉(zhuǎn)換為:http://10.0.10.11/404.html 此時就匹配了location的設(shè)置,從/usr/local/nginx/html目錄下 查找404.html文件,將其中的內(nèi)容返回給客戶端。。 7.nginx gzip的配置 為了加速頁面的響應(yīng)速度,nginx提供了對靜態(tài)文本實現(xiàn)gzip的壓縮功能,也提供了帶寬的利用率。 注:nginx默認(rèn)不支持gzip的功能,要想開啟該功能,必須在編譯安裝的時候手動添加--with-http_gzip_static_module來開啟該功能 gzip相關(guān)的配置: gzip on; 開啟gzip壓縮 gzip_min_length 1k; 設(shè)置允許壓縮的頁面最小字節(jié)數(shù),默認(rèn)為0,不管頁面多大都壓縮,建議設(shè)置成大于1k,要特別注意壓縮的最小單位限制 gzip_buffers 4 16k; 設(shè)置允許多大的內(nèi)存空間來壓縮的緩存,默認(rèn)值是申請與原始數(shù)據(jù)大小相同的空間來壓縮。 gzip_http_version 1.1; 設(shè)置識別http協(xié)議版本 gzip_comp_level 2; 用來指定gzip的壓縮比,1壓縮比最小,處理最快,9壓縮比最大,處理最慢,也比較消耗cpu gzip_types text/plain application/x-javascript text/css application/xml; 用來指定壓縮的類型,無論是否指定,text/html類型總是會被壓縮。 gzip_vary on; 可以讓前端的緩存服務(wù)器緩存經(jīng)過GZIP壓縮的頁面,例如用squid緩存經(jīng)過nginx壓縮的數(shù)據(jù)。
以上即為gzip的常用設(shè)置,在這里需要說明一下的是gzip_types,該選項指定了要壓縮文件的類型,如果你不知道,最好的辦法是通過瀏覽器的調(diào)試功能來獲取某類文件的類型。通過查看瀏覽器調(diào)試功能,開啟網(wǎng)絡(luò)調(diào)試,在頁面的響應(yīng)頭中有一個Content-type的字段,該字段顯示的就是此類文本的類型 example: 哈哈,圖片截大了,拉小有點(diǎn)變形了,不過還是能看到的.... 8.nginx 反向代理配置 nginx反向代理功能使用的是nginx的proxy模塊,該模塊默認(rèn)已經(jīng)支持。 測試案例: 在后端服務(wù)器10.0.10.12上創(chuàng)建好測試頁面:index.html #echo "<h1>this is a proxy test</h1>" > /usr/local/nginx/html/index.html
配置前端nginx代理功能: 相關(guān)配置如下:
#service nginx configtest //測試配置文件是否有錯誤 #service nginx restart //重啟nginx服務(wù)器 訪問測試:
可以訪問此時頁面已經(jīng)被代理到后端的服務(wù)器上了。到此一個簡單的反向代理功能就實現(xiàn)了,根據(jù)自己的需要,可以實現(xiàn)各種反向代理功能,比如匹配某個特定的url進(jìn)行代理等. 反向代理的優(yōu)化: 以下內(nèi)容可以放在某個server{}段內(nèi),也可以放在http{}段內(nèi),對所有的server都生效 proxy_connect_timeout 90; proxy_send_timeout 90; proxy_read_timeout 90; proxy_buffer_size 4k; proxy_buffers 4 32k; proxy_busy_buffers_size 64k; proxy_temp_file_write_size 64k;
相關(guān)選項含義: proxy_set_header:設(shè)置由后端的服務(wù)器獲取用戶的主機(jī)名或者真實IP地址,以及代理者的真實IP地址。 proxy_connect_timeout:表示與后端服務(wù)器連接的超時時間,即發(fā)起握手等候響應(yīng)的超時時間。 proxy_send_timeout:表示后端服務(wù)器的數(shù)據(jù)回傳時間,即在規(guī)定時間之內(nèi)后端服務(wù)器必須傳完所有的數(shù)據(jù),否則,Nginx將斷開這個連接。 proxy_read_timeout:設(shè)置Nginx從代理的后端服務(wù)器獲取信息的時間,表示連接建立成功后,Nginx等待后端服務(wù)器的響應(yīng)時間,其實是Nginx已經(jīng)進(jìn)入后端的排隊之中等候處理的時間。 proxy_buffer_size:設(shè)置緩沖區(qū)大小, 默認(rèn),該緩沖區(qū)大小等于指令proxy_buffers設(shè)置的大小。 proxy_buffers:設(shè)置緩沖區(qū)的數(shù)量和大小。nginx從代理的后端服務(wù)器獲取的響應(yīng)信息,會放置到緩沖區(qū)。 proxy_busy_buffers_size:用于設(shè)置系統(tǒng)很忙時可以使用的proxy_buffers大小,官方推薦的大小為proxy_buffers*2。 proxy_temp_file_write_size:指定proxy緩存臨時文件的大小 proxy_next_upstream:該選項設(shè)置當(dāng)客戶端訪問頁面時,如果后端服務(wù)器返回該選項后面設(shè)置的錯誤時,則自動將請求轉(zhuǎn)發(fā)到負(fù)載均衡中的下一臺服務(wù)器,實現(xiàn)故障轉(zhuǎn)移 接下來聊一聊upstream upstream指令用來設(shè)置上游服務(wù)器,并且根據(jù)需要可以設(shè)置一些策略: 樣例: upstream backend { ip_hash; 設(shè)置nginx的負(fù)載均衡方法。 server 192.168.12.133:80; server 192.168.12.134:80 down; server 192.168.12.135:8009 max_fails=3 fail_timeout=20s; server 192.168.12.136:8080; server 192.168.12.137:8080 backup; } Nginx的負(fù)載均衡模塊目前支持4種調(diào)度算法,下面進(jìn)行分別介紹,其中后兩項屬于第三方的調(diào)度方法。 輪詢(默認(rèn))。每個請求按時間順序逐一分配到不同的后端服務(wù)器,如果后端某臺服務(wù)器宕機(jī),故障系統(tǒng)被自動剔除,使用戶訪問不受影響。 Weight。指定輪詢權(quán)值,Weight值越大,分配到的訪問機(jī)率越高,主要用于后端每個服務(wù)器性能不均的情況下。 ip_hash。每個請求按訪問IP的hash結(jié)果分配,這樣來自同一個IP的訪客固定訪問一個后端服務(wù)器,有效解決了動態(tài)網(wǎng)頁存在的session共享問題。 fair。比上面兩個更加智能的負(fù)載均衡算法。此種算法可以依據(jù)頁面大小和加載時間長短智能地進(jìn)行負(fù)載均衡,也就是根據(jù)后端服務(wù)器的響應(yīng)時間來分配請求,響應(yīng)時間短的優(yōu)先分配。Nginx本身是不支持fair的,如果需要使用這種調(diào)度算法,必須下載Nginx的upstream_fair模塊。 url_hash。按訪問url的hash結(jié)果來分配請求,使每個url定向到同一個后端服務(wù)器,可以進(jìn)一步提高后端緩存服務(wù)器的效率。Nginx本身是不支持url_hash的,如果需要使用這種調(diào)度算法,必須安裝Nginx 的hash軟件包。 在HTTP Upstream模塊中,可以通過server指令指定后端服務(wù)器的IP地址和端口,同時還可以設(shè)定每個后端服務(wù)器在負(fù)載均衡調(diào)度中的狀態(tài)。常用的狀態(tài)有: down,表示當(dāng)前的server暫時不參與負(fù)載均衡。 backup,預(yù)留的備份機(jī)器。當(dāng)其他所有的非backup機(jī)器出現(xiàn)故障或者忙的時候,才會請求backup機(jī)器,因此這臺機(jī)器的壓力最輕。 max_fails,允許請求失敗的次數(shù),默認(rèn)為1。當(dāng)超過最大次數(shù)時,返回proxy_next_upstream 模塊定義的錯誤。 fail_timeout,在經(jīng)歷了max_fails次失敗后,暫停服務(wù)的時間。max_fails可以和fail_timeout一起使用。 注意 當(dāng)負(fù)載調(diào)度算法為ip_hash時,后端服務(wù)器在負(fù)載均衡調(diào)度中的狀態(tài)不能是backup 測試upstream的某些功能: 1)測試默認(rèn)的負(fù)載均衡 為了測試實驗效果,在前端代理10.0.10.11主機(jī)上再裝一個httpd軟件,搭建一個本地的web站點(diǎn) #yum -y install httpd #vim /etc/httpd/conf/httpd.conf 修改內(nèi)容: Listen 8080 //修改其監(jiān)聽端口為8080,因為此時nginx的監(jiān)聽端口為80,不修改會沖突 #service httpd start //啟動httpd服務(wù) #echo "<h1>this is 10.0.10.11 website</h1>" > /var/www/html/index.html 配置完成后你可以先用瀏覽器或者links測試一下http是否能夠正常提供服務(wù): http://10.0.10.11:8080 links --dump http://10.0.10.11:8080 配置前端代理nginx: 修改配置文件的location /和upstreamd的配置使其達(dá)到測試的需求: location / { proxy_redirect off; proxy_pass http://backend; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded_For $proxy_add_x_forwarded_for; } upstream backend { server 10.0.10.11:8080; server 10.0.10.12:80; } 說明:將請求代理到后端服務(wù)器組backend,此時的backend中有兩臺服務(wù)器,采用的是默認(rèn)的輪詢負(fù)載均衡規(guī)則
#service nginx configtest #service nginx restart 創(chuàng)建測試頁面,以便區(qū)別: 10.0.10.12: #echo "<h1>this is 10.0.10.12 website</h1>" > /usr/local/nginx/html/index.html 注意:這里為了測試效果,所以測試頁面的內(nèi)容不一樣,真正在生產(chǎn)環(huán)境中,兩臺服務(wù)器的內(nèi)容應(yīng)該是一摸一樣的 測試: 第一次訪問:
第二次訪問:
由上面的信息可知,nginx可以正常的切換。你在測試時可以多刷新幾次查看效果。 2)測試ip_hash ip_hash的效果是對ip地址進(jìn)行hash,同一個ip地址會發(fā)送到同一臺后端服務(wù)器,因此當(dāng)設(shè)置了ip_hash之后,測試頁面時,同一個ip地址訪問無論怎么刷新,頁面都不會變化。 配置nginx.conf文件:
upstream backend { ip_hash; server 10.0.10.11:8080; server 10.0.10.12:80; } #service nginx configtest #service nginx restart 自行測試效果。。。。 3)測試backup的功能 backup的功能是做冗余備份來使用,默認(rèn)情況下backup主機(jī)是不參與負(fù)載均衡請求,當(dāng)其他主機(jī)都出現(xiàn)故障無法響應(yīng)時,backup才會響應(yīng)客戶端的請求 配置nginx.conf文件: upstream backend { server 10.0.10.11:8080; server 10.0.10.12:80 backup; } 注意:backup不能和ip_hash一起使用 #service nginx configtest #service nginx restart 測試: 多次訪問頁面: [root@test1 conf]# links --dump http://10.0.10.11 this is 10.0.10.11 website [root@test1 conf]# links --dump http://10.0.10.11 this is 10.0.10.11 website [root@test1 conf]# links --dump http://10.0.10.11 this is 10.0.10.11 website [root@test1 conf]# 由上面的信息發(fā)現(xiàn),不管怎么訪問,返回的都是同一個頁面 此時,停止10.0.10.11上的站點(diǎn):
再次訪問: [root@test1 conf]# links --dump http://10.0.10.11 this is 10.0.10.12 website [root@test1 conf]# links --dump http://10.0.10.11 this is 10.0.10.12 website [root@test1 conf]# links --dump http://10.0.10.11 this is 10.0.10.12 website [root@test1 conf]# links --dump http://10.0.10.11 this is 10.0.10.12 website [root@test1 conf]# 由上面的信息進(jìn)行對比,可見backup已經(jīng)生效。。。 4)測試proxy_next_upstream故障轉(zhuǎn)移的功能 修改nginx.conf的配置文件如下: location / { proxy_redirect off; proxy_pass http://backend; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded_For $proxy_add_x_forwarded_for; proxy_next_upstream http_500 http_502 http_503 error timeout invalid_header; } upstream backend { server 10.0.10.11:8080; server 10.0.10.12:80; }
#service nginx configtest #service nginx restart 測試: 從上面的配置看,upstream現(xiàn)在是默認(rèn)的輪詢負(fù)載均衡機(jī)制,默認(rèn)情況下,會輪詢到兩臺服務(wù)器上,現(xiàn)在要模擬proxy_next_upstream中的一個錯誤來看效果。我這里采用在10.0.10.12后端主機(jī)上使用iptables禁止80端口的訪問,測試當(dāng)輪詢到10.0.10.12這臺主機(jī)上時,由于禁止訪問會導(dǎo)致超時,此時會返回10.0.10.11上的站點(diǎn)內(nèi)容 [root@test1 log]# links --dump http://10.0.10.11 this is 10.0.10.11 website [root@test1 log]# links --dump http://10.0.10.11 this is 10.0.10.11 website [root@test1 log]# 由上面的信息可知,測試效果已經(jīng)生效。。。。第二次的請求時會有一個超時的時間需要等待一會,但畢竟是實驗環(huán)境,線上環(huán)境時不可能這么長,但足以說明效果是達(dá)到了。。。 注:upstream的相關(guān)功能就測試這么幾個,其他的內(nèi)容都是一樣的測試機(jī)制,如果有需要請自行測試。。。 9.nginx fastcgi配置 nginx的fastcgi接口是用來整合php,將客戶端對php的頁面請求,轉(zhuǎn)發(fā)到后端的php服務(wù)器上,由php程序進(jìn)行解析并返回結(jié)果 基本的配置: location ~ \.php$ { root /usr/local/nginx/html; fastcgi_pass 127.0.0.1:9000; fastcgi_index index.php; # fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; 以上配置說明,將php文件轉(zhuǎn)發(fā)給后端的php服務(wù)器,這里的fastcig_pass指定的是本地,如果nginx和php服務(wù)器不是同一臺,則要修改php的監(jiān)聽地址,然后將這里的地址該為php服務(wù)器的地址。具體測試這里不在贅述,在LNMP中都有... fastcgi的優(yōu)化: fastcgi_connect_timeout 300; fastcgi_send_timeout 300; fastcgi_read_timeout 300; fastcgi_buffer_size 64k; fastcgi_buffers 4 64k; fastcgi_busy_buffers_size 128k; fastcgi_temp_file_write_size 128k; 以上內(nèi)容可以放在http{}段,也可以放在location{}段 fastcgi cache設(shè)置: fastcgi_temp_path /usr/local/nginx/fastcgi_temp; fastcgi_cache_path /usr/local/nginx/fastcgi_cache levels=1:2 keys_zone=TEST:10m inactive=5m max_size=10g; 以上兩行內(nèi)容必須放在http{}段 下面的內(nèi)容放在server{}段中 fastcgi_cache TEST; fastcgi_cache_valid 200 302 1h; fastcgi_cache_valid 301 1d; fastcgi_cache_valid any 1m; fastcgi_cache_key $host$request_uri; fastcgi_cache_methods GET HEAD; fastcgi_cache_min_uses 1; fastcgi_cache_use_stale error timeout invalid_header http_500; fastcgi_ignore_client_abort on; 相關(guān)解釋: fastcgi_cache_path:該選項用來定義fastcgi的緩存目錄的信息。/usr/local/nginx/fastcgi_cache 這是緩存的目錄文件 levels 設(shè)置緩存目錄的子目錄級別1:2 表示允許二級子目錄,通常一級子目錄允許16個,二級子目錄允許256個,以此類推,keys_zone用來設(shè)置內(nèi)層緩存區(qū)的緩存名和緩存大小 inactive 用來設(shè)置緩存的過期時間,max_size 表示允許使用硬盤作為緩存的最大空間 fastcgi_cache_valid:定義哪些狀態(tài)碼的請求要緩存 fastcgi_cache_min_uses:URL經(jīng)過多少次請求將被緩存 fastcgi_cache_use_stale:定義哪些情況下用過期緩存 fastcgi_cache_key:定義fastcgi_cache的key,示例中就以請求的URI作為緩存的key,Nginx會取這個key的md5作為緩存文件,如果設(shè)置了緩存哈希目錄,Nginx會從后往前取相應(yīng)的位數(shù)做為目錄 fastcgi_cache:用哪個緩存空間 注意:設(shè)置不是一定的,可以根據(jù)自己的需要進(jìn)行調(diào)整。。。。此外fastcgi還有很多其他的設(shè)置,更多的請看官方手冊 為了給大家一個直觀的感受,我這里還是測試一下fastcgi的緩存效果。。。 修改前端代理nginx.conf: http{}段增加: fastcgi_temp_path /usr/local/nginx/fastcgi_temp; fastcgi_cache_path /usr/local/nginx/fastcgi_cache levels=1:2 keys_zone=TEST:10m inactive=5m max_size=10g; add_header X-Cache-TEST "$upstream_cache_status - $upstream_response_time"; //用來在瀏覽器響應(yīng)頭部中查看緩存是否命中 server段{}中: location ~ \.php$ { root html; fastcgi_pass 10.0.10.12:9000; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_cache TEST; fastcgi_cache_valid 200 302 1h; fastcgi_cache_valid 301 1d; fastcgi_cache_valid any 1m; fastcgi_cache_key $host$request_uri; fastcgi_cache_methods GET HEAD; fastcgi_cache_min_uses 1; fastcgi_cache_use_stale error timeout invalid_header http_500; fastcgi_ignore_client_abort on; include fastcgi_params; } #service nginx configtest #service nginx restart #mkdir /usr/local/nginx/fastcgi_cache //創(chuàng)建緩存目錄 配置后端10.0.10.12服務(wù)器: 修改/usr/local/php55/etc/php-fpm.conf: #listen = 127.0.0.1:9000 listen = 10.0.10.12:9000 #pkill php-fpm #/usr/local/php55/sbin/php-fpm //重啟php-fpm進(jìn)程 測試:
從上面的信息可以看出,第一次訪問時,狀態(tài)為MISS,但是緩存目錄已經(jīng)有緩存產(chǎn)生了,第二次訪問時,顯示HIT,說明緩存命中
10.nginx proxy_cache緩存配置 nginx本身支持proxy_cache的緩存設(shè)置,通常可以用來將后端服務(wù)器的靜態(tài)頁面,圖片文件等緩存到本地的一個目錄中,在緩存失效期間內(nèi),當(dāng)客戶端再次請求時,會直接從緩存中響應(yīng),而 不需要從后端服務(wù)器再次獲取。 exmaple: proxy_temp_path /usr/local/nginx/proxy_temp; proxy_cache_path /usr/local/nginx/proxy_cache levels=1:2 keys_zone=cache_one:200m inactive=1d max_size=30g; location ~ .*\.(gif|jpg|png|htm|html|css|js|flv|ico|swf)(.*) { proxy_pass http://backend; proxy_redirect off; proxy_set_header Host $host; proxy_cache cache_one; proxy_cache_valid 200 302 1h; proxy_cache_valid 301 1d; proxy_cache_valid any 1m; expires 30d; //這個是設(shè)置客戶端瀏覽器對匹配的內(nèi)容緩存的時間,跟proxy_cache無多大關(guān)系 } 測試的方法和fastcgi_path類似,這里不在贅述,有問題留言。。。
注:經(jīng)過網(wǎng)友的多翻測試,對于頁面緩存的設(shè)置,通常要考慮兩個方面的內(nèi)容,一個是后端源服務(wù)器頁面頭部設(shè)置的緩存,二個是nginx自身設(shè)置的緩存策略。通常能設(shè)置緩存策略的對象有,nginx inactive,nginx expires,源服務(wù)器exipres,源服務(wù)器max-age,nginx proxy_cache_valid 這些選項都能對緩存的過期時間產(chǎn)生影響,其影響過期時間的優(yōu)先級是:inactive,源服務(wù)器expires,源服務(wù)器max-age,nginx proxy_cache_valid .
注意:當(dāng)nginx expires 和源服務(wù)器的expires沖突時,對于客戶端而言,將以nginx的expires為準(zhǔn),而對于nginx而言緩存文件的expires時間以源服務(wù)器的expires設(shè)置為準(zhǔn) 11.nginx 內(nèi)核優(yōu)化配置 為了使nginx所在的服務(wù)器能夠提供更好的性能,不得不根據(jù)實際情況對內(nèi)核進(jìn)行優(yōu)化。。下面的優(yōu)化是網(wǎng)上的一個見的比較多的設(shè)置,你喜歡就用吧。。 net.ipv4.ip_forward = 0 net.ipv4.conf.default.rp_filter = 1 net.ipv4.conf.default.accept_source_route = 0 kernel.sysrq = 0 kernel.core_uses_pid = 1 net.ipv4.tcp_syncookies = 1 kernel.msgmnb = 65536 kernel.msgmax = 65536 kernel.shmmax = 68719476736 kernel.shmall = 4294967296 net.ipv4.tcp_max_tw_buckets = 6000 net.ipv4.tcp_sack = 1 net.ipv4.tcp_window_scaling = 1 net.ipv4.tcp_rmem = 4096 87380 4194304 net.ipv4.tcp_wmem = 4096 16384 4194304 net.core.wmem_default = 8388608 net.core.rmem_default = 8388608 net.core.rmem_max = 16777216 net.core.wmem_max = 16777216 net.core.netdev_max_backlog = 262144 net.core.somaxconn = 262144 net.ipv4.tcp_max_orphans = 3276800 net.ipv4.tcp_max_syn_backlog = 262144 net.ipv4.tcp_timestamps = 0 net.ipv4.tcp_synack_retries = 1 net.ipv4.tcp_syn_retries = 1 net.ipv4.tcp_tw_recycle = 1 net.ipv4.tcp_tw_reuse = 1 net.ipv4.tcp_mem = 94500000 915000000 927000000 net.ipv4.tcp_fin_timeout = 1 net.ipv4.tcp_keepalive_time = 30 net.ipv4.ip_local_port_range = 1024 65000
12.nginx 防盜鏈的配置 Nginx的防盜鏈功能也非常強(qiáng)大。在默認(rèn)情況下,只需要進(jìn)行簡單的配置,即可實現(xiàn)防盜鏈處理。 要實現(xiàn)防盜鏈,就需要使用valid_referers指令,官方的樣例: valid_referers none blocked server_names *.example.com example.* www./galleries/ ~\.google\.;
if ($invalid_referer) { return 403; } 解釋: valid_referers :用來設(shè)置符合條件的域名或URL none:表示referer字段為空的 blocked:來源頭部的referer不為空,但是被防火墻和代理給刪除了,這些都不是以http://或者h(yuǎn)ttps://開頭的 server_names:表示referer字段中包含了本地域名 string:任何正則表達(dá)式在域名中匹配的域名 如果域名不符合valid_referers中設(shè)置的,invalid_referer變量的值就為1,此時就會執(zhí)行if中的語句 具體解釋請看官網(wǎng) 一個簡單的模擬案例: 前端nginx設(shè)置:
如上圖所示,在主server{}中增加一個別名c. 然后在server{}段中添加一個額關(guān)于jpg的location設(shè)置: location ~* .*\.(jpg)?$ { proxy_redirect off; proxy_pass http://backend; valid_referers none blocked *.; if ($invalid_referer) { #return 403; rewrite ^/ http://10.0.10.12/error.html; } 表示匹配jpg的圖片都轉(zhuǎn)發(fā)到后端,并且設(shè)置了防盜鏈規(guī)則 #service nginx configtest #service nginx restart 后端服務(wù)器:10.0.10.12 修改/usr/local/nginx/html/index.html內(nèi)容如下:
注意:這里做了一個picture的連接,使用的是c. 在創(chuàng)建一個error.html文件:
在上傳一個圖片error.jpg的測試圖片到/usr/local/nginx/html/error.jpg(圖片內(nèi)容隨你自己) 測試: 第一次:http://a./error.jpg 直接訪問圖片,此時是以域名a.來訪問的,可以訪問
第二次:http://c. 此時返回的是帶有picture連接的頁面,點(diǎn)擊picture連接,返回的是error.html的頁面內(nèi)容,說明訪問被拒絕并且頁面做了重寫規(guī)則 注:要做更加復(fù)雜的防盜鏈處理,可以使用Nginx的HttpAccessKeyModule,通過這個模塊可以實現(xiàn)功能更強(qiáng)大的防盜鏈處理,更詳細(xì)的參考官方文檔。
13.nginx 重寫規(guī)則 rewrite常用的正則匹配: * ~ 為區(qū)分大小寫匹配 * ~* 為不區(qū)分大小寫匹配 * !~和!~*分別為區(qū)分大小寫不匹配及不區(qū)分大小寫不匹配 下面是可以用來判斷的表達(dá)式: -f和!-f用來判斷是否存在文件 -d和!-d用來判斷是否存在目錄 -e和!-e用來判斷是否存在文件或目錄 -x和!-x用來判斷文件是否可執(zhí)行
rewrite標(biāo)記: last – 該標(biāo)記表示重寫url,但是重寫之后還會重新發(fā)起server段的請求,因此使用該標(biāo)記之后,一定要注意會不會引起url重寫的死循環(huán) break – 該標(biāo)記表示重寫url,但是重寫當(dāng)前url規(guī)則后,就終止后續(xù)rewrite的執(zhí)行 redirect – 返回臨時重定向的HTTP狀態(tài)302,瀏覽器中的url地址會跳轉(zhuǎn) permanent – 返回永久重定向的HTTP狀態(tài)301,瀏覽器中的url地址會跳轉(zhuǎn) 下面是可以用作判斷的全局變量 例:http://localhost:80/test1/test2/test.php $host:localhost $server_port:88 $request_uri:http://localhost:80/test1/test2/test.php $document_uri:/test1/test2/test.php $document_root:D:\nginx/html $request_filename:D:\nginx/html/test1/test2/test.php 案例: server { listen 80; server_name a.; index index.html index.php; root html; if ($host !~ “.*\.lxm\.com") { rewrite ^(.*) http://10.0.10.12/error.html last; } } 基本上rewrite就是這樣的用法,主要的是要知道不同的變量所代表的函數(shù)以及正則表達(dá)式的書寫,根據(jù)需要自行測試 14.nginx 防惡意解析 為了防止域名惡意解析攻擊,可以給nginx設(shè)置一個默認(rèn)的虛擬主機(jī)來匹配這些非正常的解析,但是該虛擬主機(jī)必須放在所有server{}段的首部 配置: server { listen 80 default_server; return 403; //這里也可以使用rewrite等其他方法 } 測試:隨便使用一個未設(shè)置的主機(jī)名 由上面可知,訪問被拒絕,防止惡意解析生效。。。。 到此,nginx基本的必知必會就聊到這里了,聊的好累,本人都是全程文本測試,為了給大家展示還截了各種奇葩的圖,你說你怎么謝我吧。。。。。哈哈。 結(jié)束?。。?/span> 笨蛋的技術(shù)------不怕你不會?。。?! 本文出自 “生死如夢莫多情” 博客,請務(wù)必保留此出處http://mingyang.blog.51cto.com/2807508/1545785
|