Nginx(全)
文章目錄
- 一、Nginx
- 1、概念
- 1、工作原理
- 2、Nginx模塊
- Nginx rewrite概述
- 3、Nginx 的進程模型
- 二、Nginx優點
- 1、優點
- 2、正向代理和反向代理的區別
- 1)正向代理
- 2)反向代理
- 3、Nginx如何處理HTTP請求的?
- 1)多進程機制(單線程)
- 2)異步非阻塞機制
- 4、Nginx的master和worker
- 5、Nginx 常用命令
- 6、Nginx狀態碼
- 1)3開頭
- 2)4開頭
- 3)5開頭
- 7、Nginx 壓縮
- 8、Nginx 和 Apache、Tomcat 之間的不同點
- Nginx和Apache區別:
- 9、Nginx動靜態資源分離
- 10、ngx_http_upstream_module
- 11、限流了解嗎,怎么限流的?
- 1、控制速率
- 2、控制并發連接數
- 12、nginx重定向,重寫URL
- 13、nginx是如何實現高并發的?
- 14、使用nginx代理后,獲取用戶真實ip
- 三、Nginx的優化
- 1、隱藏版本號
- 2、修改用戶與組
- 3、配置網頁緩存時間
- 4、日志分割
- 5、設置連接超時
- 6、更改進程數
- 7、配置網頁壓縮
- 8、配置防盜鏈
- 9、FPM參數優化
- 10、內核優化
- 四、Nginx負載均衡
- 1、四層和七層
- 2、熱備
- 3、負載均衡策略(算法)
- 4、負載均衡狀態
- 六、FastCG、php-fpm
- 1、Nginx+FastCGI運行原理
- 2、缺省安裝的Nginx+php-fpm環境
- 3、已知nginx和php-fpm安裝在同一臺服務器上,nginx連接php-fpm有兩種方式:一種是類似127.0.0.1:9000的TCP socket,另一種是類似/tmp/php-fpm.sock的Unix domain socket,請問如何選擇?需要注意什么?
一、Nginx
1、概念
Nginx是一個 Web 服務器和反向代理服務器用于 HTTP、HTTPS、SMTP、POP3 和 IMAP 協議。因它的穩定性、豐富的功能集、示例配置文件和低系統資源的消耗而聞名
1、工作原理
Nginx 由內核和模塊組成。
Nginx 本身做的工作實際很少,當它接到一個 HTTP 請求時, 它僅僅是通過查找配置文件將此次請求映射到一個 location 模塊,而此 location 中所配 置的各個指令則會啟動不同的模塊去完成工作,因此模塊可以看做 Nginx 真正的勞動工作者。
通常一個 location 中的指令會涉及一個 handler 模塊和多個 filter 模塊(當然,多個 location 可以復用同一個模塊)。handler 模塊負責處理請求,完成響應內容的生成,而 filter 模塊對響應內容進行處理。 用戶根據自己的需要所開發的模塊都屬于第三方模塊。正是有了這么多模塊的支撐, Nginx 的功能才會如此強大。
2、Nginx模塊
https://www.w3cschool.cn/nginx/
vim /etc/nginx/conf.d/default.conf
vim /usr/local/nginx/conf/nginx.conf
nginx模塊分為兩種,官方和第三方,我們通過命令 nginx -V 查看 nginx已經安裝的模塊!
如果需要添加某個模塊,需要將工作目錄切換至nginx的源碼包中,執行“nginx -V”命令查看之前配置時的選項進行復制,然后增加需要添加的模塊配置項,進行配置并編譯,將新生成的nginx命令覆蓋掉原有的nginx命令,然后重載nginx服務,即可實現在線添加模塊。
[root@localhost ~]# nginx -V
nginx version: nginx/1.15.9 built by gcc 4.8.5 20150623 (Red Hat 4.8.5-39) (GCC) configure arguments: --prefix=/usr/local/nginx --user=nginx --group=nginx --with-http_stub_status_module| ngx_http_access_module | 四層基于IP的訪問控制,可以通過匹配客戶端源IP地址進行限制 |
| ngx_http_auth_basic_module | 狀態頁,使用basic機制進行用戶認證,在編譯安裝nginx的時候需要添加編譯參數–withhttp_stub_status_module,否則配置完成之后監測會是提示語法錯誤 |
| ngx_http_stub_status_module | 狀態統計模塊 |
| ngx_http_gzip_module | 文件的壓縮功能 |
| ngx_http_gzip_static_module | 靜態壓縮模塊 |
| ngx_http_ssl_module | nginx 的https 功能 |
| ngx_http_rewrite_module | 實現URL地址重寫,URL看起來更規范、合理 |
| ngx_http_referer_module | 防盜鏈功能,基于訪問安全考慮 |
| ngx_http_proxy_module | 將客戶端的請求以http協議轉發至指定服務器進行處理 |
| ngx_stream_proxy_module | tcp負載,將客戶端的請求以tcp協議轉發至指定服務器處理 |
| ngx_http_fastcgi_module | 將客戶端對php的請求以fastcgi協議轉發至指定服務器助理 |
| ngx_http_uwsgi_module | 將客戶端對Python的請求以uwsgi協議轉發至指定服務器處理 |
| ngx_http_headers_module | 可以實現對頭部報文添加指定的key與值 |
| ngx_http_upstream_module | 負載均衡模塊,提供服務器分組轉發、權重分配、狀態監測、調度算法等高級功能 |
| ngx_stream_upstream_module | 后端服務器分組轉發、權重分配、狀態監測、調度算法等高級功能 |
| ngx_http_fastcgi_module | 實現通過fastcgi協議將指定的客戶端請求轉發至php-fpm處理 |
| ngx_http_flv_module | 為flv偽流媒體服務端提供支持 |
1、Nginx 的模塊從結構上分為核心模塊、基礎模塊和第三方模塊
核心模塊:HTTP 模塊、EVENT 模塊和 MAIL 模塊;
基礎模塊:HTTP Access 模塊、HTTP FastCGI 模塊、HTTP Proxy 模塊和 HTTP Rewrite 模塊;
第三方模塊:HTTP Upstream Request Hash 模塊、Notice 模塊和 HTTP Access Key 模 塊。
2、Nginx 的模塊從功能上分為如下三類:
Handlers(處理器模塊):此類模塊直接處理請求,并進行輸出內容和修改 headers 信息等操作。Handlers 處理器模塊一般只能有一個;
Filters(過濾器模塊):此類模塊主要對其他處理器模塊輸出的內容進行修改操作,最后由 Nginx 輸出;Proxies(代理類模塊):此類模塊是 Nginx 的 HTTP
Upstream 之類的模塊,這些模塊主要與后端一些服務比如 FastCGI 等進行交互,實現服務代理和負載均衡等功能。
Nginx rewrite概述
https://blog.csdn.net/July_jojo/article/details/109739494
3、Nginx 的進程模型
在工作方式上,Nginx 分為單工作進程和多工作進程兩種模式。
1、在單工作進程模式下,除主進程外,還有一個工作進程,工作進程是單線程的;
2、在多工作進程模式下,每個工作進程包含多個線程。Nginx 默認為單工作進程模式。
Nginx 在啟動后,會有一個 master 進程和多個 worker 進程。
master 進程主要用來管理 worker 進程,主要包含:接收來自外界的信號,向各 worker 進程發送信號,監控 worker 進程的運行狀態,當 worker 進程退出后(異常情況下),會自動 重新啟動新的 worker 進程。 master 進程充當整個進程組與用戶的交互接口,同時對進程進行監護。它不需要處理網絡事件,不負責業務的執行,只會通過管理worker 進程來實現重啟服務、平滑升級、更換日志文件、配置文件實時生效等功能。
二、Nginx優點
1、優點
跨平臺、配置簡單。
非阻塞、高并發連接
處理 2-3 萬并發連接數,官方監測能支持 5 萬并發。
內存消耗小
開啟 10 個 Nginx 才占 150M 內存
成本低廉,且開源。
穩定性高,宕機的概率非常小。
主要功能:
1)正向、反向代理
2)負載均衡、分流
2)充當一個虛擬主機(綁定host)
1、工作在網絡的7層之上,可以針對http應用做一些分流的策略,比如針對域名、目錄結構,它的正則規則比HAProxy更為強大和靈活,這也是它目前廣泛流行的主要原因之一,Nginx單憑這點可利用的場合就遠多于LVS了。2、Nginx對網絡穩定性的依賴非常小,理論上能ping通就就能進行負載功能,這個也是它的優勢之一3、Nginx安裝和配置比較簡單,測試起來比較方便,它基本能把錯誤用日志打印出來。4、可以承擔高負載壓力且穩定,在硬件不差的情況下一般能支撐幾萬次的并發量,負載度較小 (比LVS)5、Nginx可以通過端口檢測到服務器內部的故障,比如根據服務器處理網頁返回的狀態碼、超時等等,并且會把返回錯誤的請求重新提交到另一個節點,不過其中缺點就是不支持url來檢測。比如用戶正在上傳一個文件,而處理該上傳的節點剛好在上傳過程中出現故障,Nginx會把上傳切到另一臺服務器重新處理6、Nginx不僅僅是一款優秀的負載均衡器/反向代理軟件,它同時也是功能強大的Web應用服務器。LNMP也是近幾年非常流行的web架構,在高流量的環境中穩定性也很好。7、Nginx現在作為Web反向加速緩存越來越成熟了,速度比傳統的Squid服務器更快,可以用作為反向代理加速器。8、Nginx可作為中層反向代理使用,這一層面Nginx基本上無對手,唯一可以對比Nginx的就只有 lighttpd了,不過 lighttpd目前還沒有做到Nginx完全的功能,配置也不那么清晰易讀,社區資料也遠遠沒Nginx活躍。9、Nginx也可作為靜態網頁和圖片服務器,這方面的性能也無對手。還有Nginx社區非常活躍,第三方模塊也很多。缺點
Nginx的缺點是: Nginx僅能支持http、https和Email協議,這樣就在適用范圍上面小些,這個是它的缺點。 對后端服務器的健康檢查,只支持通過端口來檢測,不支持通過url來檢測。不支持Session的直接保持,但能通過ip_hash來解決。2、正向代理和反向代理的區別
1)正向代理
是一個位于客戶端和目標服務器之間的服務器,為了從目標服務器取得內容,客戶端向代理發送一個請求并指定目標服務器,然后代理向目標服務器轉交請求并將獲得的內容返回給客戶端。代理服務器和客戶端處于同一個局域網內。
比如說fanqiang。我知道我要訪問谷歌,于是我就告訴它讓它幫我轉發。
2)反向代理
up
實際運行方式是代理服務器接受網絡上的連接請求。它將請求轉發給內部網絡上的服務器,并將從服務器上得到的結果返回給網絡上請求連接的客戶端 。代理服務器和目標服務器處于同一個局域網內。
比如說我要訪問taobao,對我來說不知道圖片、json、css 是不是同一個服務器返回回來的,但是我不關心,是反向代理 處理的,我不知道目標服務器。
反向代理配置:vim /etc/nginx/nginx.conf
stream {log_format main '$remote_addr $upstream_addr - [$time_local] $status $upstream_bytes_sent';access_log /var/log/nginx/k8s-access.log main;upstream k8s-apiserver {server 192.168.195.149:6443;server 192.168.195.131:6443;}server {listen 6443;proxy_pass k8s-apiserver;}}3、Nginx如何處理HTTP請求的?
它結合多進程機制(單線程)和異步非阻塞方式。
1)多進程機制(單線程)
服務器每當收到一個客戶端時,就有 服務器主進程 ( master process )生成一個 子進程( worker process )出來和客戶端建立連接進行交互,直到連接斷開,該子進程就結束了。
2)異步非阻塞機制
每個工作進程 使用 異步非阻塞方式 ,可以處理 多個客戶端請求 。 運用了epoll模型,提供了一個隊列,排隊解決。
當某個 工作進程 接收到客戶端的請求以后,調用 IO 進行處理,如果不能立即得到結果,就去 處理其他請求 (即為 非阻塞 );而 客戶端 在此期間也 無需等待響應 ,可以去處理其他事情(即為 異步 )。
當 IO 返回時,就會通知此 工作進程 ;該進程得到通知,暫時 掛起 當前處理的事務去 響應客戶端請求
4、Nginx的master和worker
這跟Nginx的多進程、單線程有關。(一個進程只有一個主線程)。
為什么要用單線程?
采用單線程來異步非阻塞處理請求(管理員可以配置Nginx主進程的工作進程的數量),不會為每個請求分配cpu和內存資源,節省了大量資源,同時也減少了大量的CPU的上下文切換,所以才使得Nginx支持更高的并發。
簡單過程:
主程序 Master process 啟動后,通過一個 for 循環來 接收 和 處理外部信號 ;
主進程通過 fork() 函數產生 worker 子進程 ,每個子進程執行一個 for循環來實現Nginx服務器對事件的接收和處理 。
詳細過程:
1、Nginx 在啟動后,會有一個 master 進程和多個相互獨立的 worker 進程。 2、master 接收來自外界的信號,先建立好需要 listen 的 socket(listenfd) 之后,然后再 fork 出多個 worker 進程,然后向各worker進程發送信號,每個進程都有可能來處理這個連接。 3、所有 worker 進程的 listenfd 會在新連接到來時變得可讀 ,為保證只有一個進程處理該連接,所有 worker 進程在注冊 listenfd 讀事件前搶占 accept_mutex ,搶到互斥鎖的那個進程注冊 listenfd 讀事件 ,在讀事件里調用 accept 接受該連接。 4、當一個 worker 進程在 accept 這個連接之后,就開始讀取請求、解析請求、處理請求,產生數據后,再返回給客戶端 ,最后才斷開連接。
5、Nginx 常用命令
啟動 nginx 。
停止 nginx -s stop 或 nginx -s quit 。
重啟 nginx -s reload 或 service nginx reload 。
重載指定配置文件 .nginx -c /usr/local/nginx/conf/nginx.conf 。
查看 nginx 版本 nginx -v 。
6、Nginx狀態碼
https://www.php.cn/course/1020.html
1)3開頭
301:請求資源已被永久移動位置 302:請求的資源現在臨時從不同的URL響應請求 303:查看其他,對應當前請求的響應可以在另一個URI上被找到 305:使用代理。被請求的資源必須通過指定的代理才能被訪問 307:臨時跳轉。被請求的資源在臨時從不同的URL響應請求2)4開頭
400:錯誤請求。 402:需要付款。該狀態碼是為了將來可能需求而預留的,用于一些數字貨幣或者微支付 403:禁止訪問。服務器已理解請求,但是拒絕執行它 404:找不到對象,請求失敗,資源不存在 406:不可接受的,請求的資源的內容特性無法滿足請求頭中的條件,因而無法生成響應實體 408:請求超時; 409:沖突。由于和被請求的資源的當前狀態之間存在沖突,請求無法完成; 410:遺失的。被請求的資源在服務器上已經不再可用,而且沒有任何已知的轉發地址; 413:響應實體太大。服務器拒絕處理當前請求,請求超過服務器所能處理和允許的最大值。 417:期望失敗。在請求頭 Expect 中指定的預期內容無法被服務器滿足; 418:我是一個茶壺。超文本咖啡罐控制協議,但是并沒有被實際的HTTP服務器實現 420:方法失效。 422:不可處理的實體。請求格式正確,但是由于含有語義錯誤,無法響應;3)5開頭
500:Internal Server Error 內部服務錯誤,比如腳本錯誤,編程語言語法錯誤。 502:Bad Gateway錯誤,網關錯誤。比如服務器當前連接太多,響應太慢,頁面素材太多、帶寬慢。 503:Service Temporarily Unavailable,服務不可用,web服務器不能處理HTTP請求,可能是臨時超載或者是服務器進行停機維護。 504:Gateway timeout 網關超時,程序執行時間過長導致響應超時,例如程序需要執行20秒,而nginx最大響應等待時間為10秒,這樣就會出現超時。7、Nginx 壓縮
為什么要開啟壓縮?
開啟nginx gzip壓縮后,圖片、css、js等靜態資源的大小會減小,可節省帶寬,提高傳輸效率,但是會消耗CPU資源。
開啟:
? # 開啟gzip
gzip off;? # 啟用gzip壓縮的最小文件,小于設置值的文件將不會壓縮
gzip_min_length 1k;? # gzip 壓縮級別,1-9,數字越大壓縮的越好,也越占用CPU時間
gzip_comp_level 1;? # 進行壓縮的文件類型。javascript有多種形式。其中的值可以在 mime.types 文件中找到。
gzip_types text/plain application/javascript application/x-javascript text/css application/xml text/javascript application/x-httpd-php image/jpeg image/gif image/png application/vnd.ms-fontobject font/ttf font/opentype font/x-woff image/svg+xml;8、Nginx 和 Apache、Tomcat 之間的不同點
1、Nginx/Apache 是Web Server,而Apache Tomact是一個servlet container
2、tomcat可以對jsp進行解析,nginx和apache只是web服務器,可以簡單理解為只能提供html靜態文件服務。
Nginx和Apache區別:
1)Nginx輕量級,同樣起web 服務,比apache占用更少的內存及資源 。
2)Nginx 抗并發,nginx 處理請求是異步非阻塞的,而apache 則是阻塞型的,在高并發下nginx 能保持低資源低消耗高性能 。
3)Nginx提供負載均衡,可以做做反向代理,前端服務器
4)Nginx多進程單線程,異步非阻塞;Apache多進程同步,阻塞。
9、Nginx動靜態資源分離
動態資源、靜態資源分離,是讓動態網站里的動態網頁根據一定規則把不變的資源和經常變的資源區分開來
比如說 js、css、hrml從A服務器返回。圖片 從B服務器返回,其他請求從Tomcat服務器C返回。
后臺應用分開部署,提高用戶訪問靜態代碼的速度。而且現在還有CDN服務,不需要限制于服務器的帶寬。
10、ngx_http_upstream_module
ngx_http_upstream_module模塊用于將多個服務器定義成服務器組,可通過fastcgi傳遞、proxy傳遞、uwsgi傳遞、memcached傳遞和scgi傳遞指令來引用的服務器組。
比如訪問www.a.com 緩存+調度:
http{ proxy_cache_path /var/cache/nginx/proxy_cache levels=1:2:2 keys_zone=proxycache:20m inactive=120s max_size=1g; #緩存 upstream mysqlsrvs{ ip_hash; #源地址hash調度方法 寫了backup就不可用 server 172.18.99.1:80 weight=2; #weight權重 server 172.18.99.2:80; #標記down,配合ip_hash使用,實現灰度發布 server 172.18.99.3:80 backup; #backup將服務器標記為“備用”,即所有服務器均不可用時才啟用 }}server{ server_name www.a.com; proxy_cache proxycache; proxy_cache_key $request_uri; proxy_cache_valid 200 302 301 1h; proxy_cache_valid any 1m; location / { proxy_pass http://mysqlsrvs; }}11、限流了解嗎,怎么限流的?
Nginx 提供兩種限流方式,一是控制速率,二是控制并發連接數。
1、控制速率
ngx_http_limit_req_module 模塊提供了漏桶算法(leaky bucket),可以限制單個IP的請求處理頻率。
如:
1.1 正常限流:
http {limit_req_zone 192.168.1.1 zone=myLimit:10m rate=5r/s; }server {location / {limit_req zone=myLimit;rewrite / http://www.hac.cn permanent; }}參數解釋:
key: 定義需要限流的對象。
zone: 定義共享內存區來存儲訪問信息。
rate: 用于設置最大訪問速率。
表示基于客戶端192.168.1.1進行限流,定義了一個大小為10M,名稱為myLimit的內存區,用于存儲IP地址訪問信息。rate設置IP訪問頻率,rate=5r/s表示每秒只能處理每個IP地址的5個請求。Nginx限流是按照毫秒級為單位的,也就是說1秒處理5個請求會變成每200ms只處理一個請求。如果200ms內已經處理完1個請求,但是還是有有新的請求到達,這時候Nginx就會拒絕處理該請求。
1.2 突發流量限制訪問頻率
上面rate設置了 5r/s,如果有時候流量突然變大,超出的請求就被拒絕返回503了,突發的流量影響業務就不好了。
這時候可以加上burst 參數,一般再結合 nodelay 一起使用。
server {location / {limit_req zone=myLimit burst=20 nodelay;rewrite / http://www.hac.cn permanent; }}burst=20 nodelay 表示這20個請求立馬處理,不能延遲,相當于特事特辦。不過,即使這20個突發請求立馬處理結束,后續來了請求也不會立馬處理。burst=20 相當于緩存隊列中占了20個坑,即使請求被處理了,這20個位置這只能按 100ms一個來釋放。
2、控制并發連接數
ngx_http_limit_conn_module 提供了限制連接數功能。
limit_conn_zone $binary_remote_addr zone=perip:10m;limit_conn_zone $server_name zone=perserver:10m;server { ... limit_conn perip 10; limit_conn perserver 100;}limit_conn perip 10 作用的key 是 $binary_remote_addr,表示限制單個IP同時最多能持有10個連接。
limit_conn perserver 100 作用的key是 $server_name,表示虛擬主機(server) 同時能處理并發連接的總數。
注:limit_conn perserver 100 作用的key是 $server_name,表示虛擬主機(server) 同時能處理并發連接的總數。
拓展:
如果不想做限流,還可以設置白名單:
利用 Nginx ngx_http_geo_module 和 ngx_http_map_module 兩個工具模塊提供的功能。
##定義白名單ip列表變量
geo $limit { default 1; 10.0.0.0/8 0; 192.168.0.0/10 0; 81.56.0.35 0;}map $limit $limit_key { 0 ""; 1 $binary_remote_addr;}# 正常限流設置
limit_req_zone $limit_key zone=myRateLimit:10m rate=10r/s;geo 對于白名單 將返回0,不限流;其他IP將返回1,進行限流。
具體參考:http://nginx.org/en/docs/http/ngx_http_geo_module.html
除此之外:
ngx_http_core_module 還提供了限制數據傳輸速度的能力(即常說的下載速度)
location /flv/ { flv; limit_rate_after 500m; limit_rate 50k;}針對每個請求,表示客戶端下載前500m的大小時不限速,下載超過了500m后就限速50k/s。
12、nginx重定向,重寫URL
URL重寫有利于網站首選域的確定,對于同一資源頁面多條路徑的301重定向有助于URL權重的集中
處理高并發:
https://blog.csdn.net/asqi1/article/details/41478111
單個Nginx并發盡量不要超過2w,如果你的并發都達到10w了,是時候做DNS分流了,還不行的話,就應該像Google那樣直接從網卡驅動層分流了
13、nginx是如何實現高并發的?
答:nginx之所以可以實現高并發,與它采用的epoll模型有很大的關系。epoll模型采用異步非阻塞的事件處理機制。這種機制可讓nginx進程同時監控多個事件。
簡單來說,就是異步非阻塞,使用了epoll模型和大量的底層代碼優化。如果深入一點的話,就是nginx的特殊進程模型和事件模型的設計,才使其可以實現高并發。
進程模型
它是采用一個master進程和多個worker進程的工作模式。1、master進程主要負責收集、分發請求。當一個請求過來時,master拉起一個worker進程負責處理這個請求。;2、master進程也要負責監控worker的狀態,保證高可靠性;3、worker進程議案設置為和CPU核心數一致或者其二倍。nginx的worker進程和Apache的不一樣。apache的進程在同一時間只能處理一個請求,所以它會開啟很多個進程,幾百甚至幾千個。而nginx的worker進程在同一時間可以處理的請求數只受內存限制,因此可以處理更多請求。事件模型
nginx是異步非阻塞的。
一個master進程,多個worker進程,每個worker進程可以處理多個請求。每進來一個request,都會有worker進程去處理。但不是全程的處理,那么處理到的程度就是可能發生阻塞的地方,比如向后端服務器轉發request,并等待請求返回。那么,在等待期間,這個處理的worker不會這么傻等著,他會在發送完請求后,注冊一個事件:“如果upstream返回了,告訴我一聲,我再接著干”。于是它就去休息了,此時,如果再有request進來,它就可以很快再按這種方式處理。而一旦后端服務器返回了,就會觸發這個事件,worker才會來接手,這個request才會接著往下走。
由于nginx的的這個工作性質決定了每個請求大部分的生命都是在網絡傳輸中,所以實際上花費在nginx 服務器上的時間并不多,這就是它幾進程就能解決高并發的秘密所在。
14、使用nginx代理后,獲取用戶真實ip
使用nginx轉發請求時,應用中獲取到的用戶ip 都是127.0.0.1,獲取真實ip必須重寫一些頭部才行。通常在WSGI環境中經常使用的變量:REMOTE_ADDR ,在nginx轉發時設置頭部攜帶這個變量
nginx設置
server { listen 80; server_name _; location / { .................. proxy_pass http://127.0.0.1:8000/; # $host 變量,Host 為變量名 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_add_x_forwarded_for中獲取到用戶的真實IP,
也可以通過后臺的程序,從請求的header里獲取X-Forwarded-For,然后取起一個值即可,使用正則匹配獲取第一個即可,如下:
location / { proxy_set_header Host $host; set $Real $proxy_add_x_forwarded_for; if (Real ~ ( d+) i. (1d+) i. (sd+) i. (d+),(.*) ){ set$Real $1.$2.$3.$4; } proxy_set_header X-real-ip $Real; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;}proxy_set_header 和add_header 的區別
區別: proxy_set_header是Nginx設置請求頭信息給上游服務器, add_header是Nginx設置響應頭信息給瀏覽器。
proxy_set_header
假如Nginx請求上游服務器時,添加額外的請求頭,就需要使用proxy_set_header。
三、Nginx的優化
配置nginx的proxy緩存;
對靜態頁面開啟壓縮功能,如br壓縮或者gzip壓縮;
調整nginx運行工作進程個數,最多開啟8個,8個以上話性能就不會再提升了,而且穩定性變得更低,所以8個足夠用了;
調整nginx運行CPU的親和力;
修改nginx最多可打開的文件數,若超過系統限制的最多打開文件數(ulimit -n命令查看系統的最多打開文件數),還需要修改系統默認的文件數;
修改單個worker的最大連接數;
開啟高效傳輸;
設置連接超時時間,以便保護服務器資源,因為建立連接也是需要消耗資源的;
優化fastCGI的一個超時時間,也可以根據實際情況對其配置緩存動態頁面;
expires緩存調優,主要針對圖片、css、js等元素更改較少的情況下使用。
配置防盜鏈;
優化內核參數,如進程可以同時打開的最大句柄數;開啟tcp重用機制,以便允許TIME_WAIT sockets重新用于新的TCP連接…
1、隱藏版本號
隱藏Nginx版本號有兩種方式:
第一種是修改Nginx源碼文件,指定不顯示版本號
第二種是修改Nginx的主配置文件
[root@localhost ~]# curl -I http://20.0.0.6 ### 查看網站版本號HTTP/1.1 200 OK Server: nginx/1.15.9 ### 版本號Date: Sun, 06 Sep 2020 05:52:47 GMT1)修改配置文件方式
將Nginx的配置文件中的server_tokens選項值設置為off,如果有該配置項,加上即可
[root@localhost ~]# vi /usr/local/nginx/conf/nginx.confhttp { include mime.types; default_type application/octet-stream; server_tokens off; ###此處新增代碼,含義是將版本號關閉 [root@localhost ~]# nginx -t ### 檢查配置是否正常nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is oknginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful[root@localhost ~]# systemctl restart nginx.service ### 重啟服務測試:然后用Wireshark抓包軟件抓包測試一下,版本號還能看到嗎
2)設置版本信息
Nginx源碼文件/opt/nginx-1.15.9/src/core/nginx.h包含了版本信息,可以隨意設置,然后重新編譯安裝,隱藏版本信息。
[root@localhost ~]# vi /opt/nginx-1.15.9/src/core/nginx.h #define NGINX_VERSION "1.1.1" ### 修改版本號#define NGINX_VER "IIS" NGINX_VERSION ### 修改服務器類型[root@localhost ~]# cd /opt/nginx-1.15.9/[root@localhost nginx-1.15.9]# ./configure \--prefix=/usr/local/nginx \--user=nginx \--group=nginx \--with-http_stub_status_module[root@localhost nginx-1.15.9]# make -j3 && make install[root@localhost nginx-1.15.9]# cd /usr/local/nginx/conf/[root@localhost conf]# vi nginx.confhttp { include mime.types; default_type application/octet-stream; server_tokens on; ### 打開版本號[root@localhost conf]# systemctl restart nginx.service ###重啟[root@localhost conf]# curl -I http://20.0.0.6HTTP/1.1 200 OKServer: IIS 1.1.1 ### 版本號和服務器類型已經更改Date: Sun, 06 Sep 2020 06:34:21 GMTContent-Type: text/htmlContent-Length: 612Last-Modified: Sun, 06 Sep 2020 06:14:14 GMTConnection: keep-aliveETag: "5f547e36-264"Accept-Ranges: bytes2、修改用戶與組
1)指定用戶與組參數
configure編譯過程中指定用戶和組參數為nginx
[root@localhost ~]# cd /opt/nginx-1.15.9/[root@localhost nginx-1.15.9]# ./configure \--prefix=/usr/local/nginx \--user=nginx \--group=nginx \--with-http_stub_status_module2)配置用戶與組
修改Nginx配置文件的Nginx指定用戶與組
[root@localhost opt]# cd /usr/local/nginx/conf/[root@localhost conf]# vi nginx.confuser nginx nginx; ### 修改用戶為nginx,組為nginx[root@localhost conf]# systemctl restart nginx[root@localhost conf]# ps aux |grep nginxroot 23044 0.0 0.0 20560 628 ? Ss 02:40 0:00 nginx: master process /usr/local/nginx/sbin/nginxnginx 23045 0.0 0.0 23100 1396 ? S 02:40 0:00 nginx: worker processroot 23059 0.0 0.0 112708 976 pts/0 S+ 02:41 0:00 grep --color=auto nginx重啟Nginx查看進程運行情況,主進程由root賬戶創建,子進程由Nginx創建。
3、配置網頁緩存時間
1、以圖片作為緩存對象,上傳51xit.jpg圖片到/usr/local/nginx/html的工作目錄,訪問http://20.0.0.6/51xit.jpg,用wireshark工具進行抓包,查看響應報文,沒有圖片的緩存信息查看報文沒有緩存信息
2、修改Nginx的配置文件,在新location段加入expires參數,指定緩存的時間1d一天
[root@localhost ~]# vi /usr/local/nginx/conf/nginx.conf location ~ \.(gif|jpg|jepg|png|bmp|ico)$ { root html; expires 1d; ### 指定緩存時間1天 }3、重啟Nginx服務,訪問wireshark抓包
[root@localhost ~]# systemctl restart nginx ### 重啟nginx服務
測試:在/usr/local/nginx/html里面添加一張51xit.jpg圖片,然后wireshark抓包查看一下緩存時間對不對
4、日志分割
日志切割 隨著Nginx運行時間的增加, 產生的日志也會逐漸增加,為了方便掌握Nginx的運行 狀態, 需要時刻關注Nginx日志文件。太大的日志文件對監控是一個大災難,不便于分析排查,需要定期的進行日志文件的切割。
##編寫腳本/opt/feng e.sh##
把Nginx的日志文件/usr/local/nginx/logs/access.log移動到, 目錄/var/log/ng in x下面, 以當前時間做為日志文件的名稱, 然后用kill-USR1創建新的日志文件/usr/local/nginx/logs/access.log, 最后刪除30天之前的日志文件。
[root@localhost ~]# vi /opt/fenge.sh#!/bin/bash# Filename: fenge.shd=$(date -d "-1 day" "+%Y%m%d")logs_path="/var/log/nginx"pid_path="/usr/local/nginx/logs/nginx.pid"[ -d $logs_path ] || mkdir -p $logs_pathmv /usr/local/nginx/logs/access.log ${logs_path}/test.com-access.log-$dkill -USR1 $(cat $pid_path)find $logs_path -mtime +30 |xargs rm -rf---------------上面解釋----------------------------------------------------------------
#!/bin/bash# Filename: fenge.shd=$(date -d "-1 day" "+%Y%m%d")logs_path="/var/log/nginx" ###分割到nginx目錄去pid_path="/usr/local/nginx/logs/nginx.pid" ###重新生成新的日志文件[ -d $logs_path ] || mkdir -p $logs_path ###如果沒有nginx目錄就會創建mv /usr/local/nginx/logs/access.log ${logs_path}/test.com-access.log-$d ###把原有路徑的日志文件移出來,改成那天的日期名字kill -USR1 $(cat $pid_path) ###結束當時的進程,生成一個新pid,然后生成新的日志文件find $logs_path -mtime +30 |xargs rm -rf ###找到30天之前的刪除掉------------------------------------------------------------------------------------------
[root@localhost ~]# chmod +x /opt/fenge.sh ###給執行權限[root@localhost opt]# ./fenge.sh ### 執行分割腳本[root@localhost opt]# ls /var/log/nginx/test.com-access.lo test.com-access.log-20200905 ###按日期分割了日志文件[root@localhost opt]# cat /usr/local/nginx/logs/access.log ###原來的位置文件重新創建########設置crotab任務,定期執行腳本自動進行日志分割#########[root@localhost opt]# crontab -e30 1 * * * /opt/fenge.sh5、設置連接超時
在企業網站中,為了避免同一個客戶長時間占用連接,造成資源浪費,可設置相應的連 接超時參數, 實現控制連接訪問時間。可以修改配置文件nginx.conf, 設置keepalive_timeout 超時時間。
[root@localhost opt]# vi /usr/local/nginx/conf/nginx.conf keepalive_timeout 65 180; ### 默認65秒,設置超時180秒 client_header_timeout 80; client_body_timeout 80;[root@localhost opt]# systemctl restart nginx ###重啟nginx服務測試:瀏覽器輸入20.0.0.6,然后wireshark抓包查看一下連接超時時間
##########深入優化##############
6、更改進程數
在高并發環境中,需要啟動更多的Nginx進程以保證快速響應,用以處理用戶的請求,避免造成阻塞。使用ps aux命令查看Nginx運行進程的個數。
[root@localhost ~]# ps aux |grep nginxroot 76128 0.0 0.0 20560 628 ? Ss 03:26 0:00 nginx: master process /usr/local/nginx/sbin/nginxnginx 76129 0.0 0.0 23100 1652 ? S 03:26 0:00 nginx: worker processroot 76201 0.0 0.0 112708 972 pts/0 S+ 03:33 0:00 grep --color=auto nginx其中master是Nginx的主進程,開啟了1個,worker 是子進程,進程也是開啟了1個。
修改Nginx的配置文件的worker_processes參數, 一般設為CPU的個數或者核數, 在高并發的情況下可設置為CPU個數或者核數的2倍, 可以查看CPU的核數以確定參數
[root@localhost ~]# cat /proc/cpuinfo |grep -c "physical" ###查看CPU的核數以確定參數。8[root@localhost ~]# vi /usr/local/nginx/conf/nginx.confworker_processes 8; ###根據剛剛查的核數,把數字改成8.修改完后,重啟服務,使用ps aux查看運行進程數的變化情況。[root@localhost ~]# ps aux|grep nginx ### 可以看到現在是8個進程root 76329 0.0 0.0 20560 700 ? Ss 03:40 0:00 nginx: master process /usr/local/nginx/sbin/nginxnginx 76330 0.0 0.0 23100 1404 ? S 03:40 0:00 nginx: worker processnginx 76331 0.0 0.0 23100 1404 ? S 03:40 0:00 nginx: worker processnginx 76332 0.0 0.0 23100 1404 ? S 03:40 0:00 nginx: worker processnginx 76333 0.0 0.0 23100 1404 ? S 03:40 0:00 nginx: worker processnginx 76334 0.0 0.0 23100 1404 ? S 03:40 0:00 nginx: worker processnginx 76335 0.0 0.0 23100 1404 ? S 03:40 0:00 nginx: worker processnginx 76336 0.0 0.0 23100 1404 ? S 03:40 0:00 nginx: worker processnginx 76337 0.0 0.0 23100 1404 ? S 03:40 0:00 n7、配置網頁壓縮
[root@localhost ~]# vi /usr/local/nginx/conf/nginx.conf gzip on; gzip_buffers 4 64k; gzip_http_version 1.1; gzip_comp_level 2; gzip_min_length 1k; gzip_vary on; gzip_types text/plain text/javascript application/x-javascript text/css text/xml application/xml application/xml+rss;###上面的配置解釋###
gzip on:開啟gzip壓縮輸出; gzip_min_length 1k:用于設置允許壓縮的頁面最小字節數;gzip_buffers 416k:表示申請4個單位為16k的內存作為壓縮結果流緩存,默認值 是申請與原始數據大小相同的內存空間來存儲gzip壓縮結果; Zip_http_version 1.0:用于設置識別http協議版本, 默認是1.1,目前大部分瀏覽 器已經支持gzip解壓,但處理最慢,也比較消耗服務器CPU資源; Gzip_comp_level 2:用來指定gzip壓縮比, 1壓縮比最小, 處理速度最快; 9壓縮 比最大,傳輸速度快,但處理速度最慢,使用默認即可;Gzip_types text/plain:壓縮類型, 是對哪些網頁文檔啟用壓縮功能;Gzip_vary on:選項可以讓前端的緩存服務器緩存經過gzip壓縮的頁面[root@localhost ~]# vi /usr/local/nginx/html/index.html
xxxxxx
###在這里面隨便加東西,讓index.html大于1k就行測試:瀏覽器輸入20.0.0.6/index.html,然后wireshark抓包查看一下壓縮情況。
8、配置防盜鏈
###防盜鏈需要準備兩臺主機模擬盜鏈###
20.0.0.6 www.51xit.top 源主機
20.0.0.5 www.52xit.top 盜鏈主機
### 修改windows的 C:\Windows\System32\drivers\etc\host文件,設置域名和映射關系
20.0.0.6 www.51xit.top
20.0.0.5 www.52xit.top
###在盜鏈主機的工作目錄編寫盜鏈頁面index.html,即盜源主機的圖片###
[root@localhost ~]# cd /usr/local/httpd/htdocs/[root@localhost htdocs]# vi index.html <html><head><title>--盜圖測試--</title></head><body><h1>盜圖頁面</h1><img src=http://20.0.0.6/51xit.jpg /></body></html>測試:瀏覽器輸入20.0.0.5,查看能不能正常盜鏈
###在主機配置Nginx防盜鏈###
[root@localhost ~]# cd /usr/local/nginx/conf/[root@localhost conf]# vi nginx.conf location ~* \.(gif|jpg|jepg|png|bmp|ico)$ { valid_referers none blocked *.51xit.top 51xit.top; if ($invalid_referer) { rewrite ^/ https://ss3.bdstatic.com/70cFv8Sh_Q1YnxGkpoWK1HF6hhy/it/u=202451072,4165552475&fm=26&gp=0.jpg; }}[root@localhost conf]# systemctl restart nginx測試:瀏覽器輸入20.0.0.5,查看能不能防止盜鏈!!!
9、FPM參數優化
####################安裝PHP環境#####
yum -y install \libjpeg \libjpeg-devel \libpng libpng-devel \freetype freetype-devel \libxml2 \libxml2-devel \zlib zlib-devel \curl curl-devel \openssl openssl-devel#######上傳php-7.1.10.tar.bz2包到opt目錄下#####
cd /opttar xjvf php-7.1.10.tar.bz2cd php-7.1.10./configure \--prefix=/usr/local/php \--with-apxs2=/usr/local/httpd/bin/apxs \--with-mysql-sock=/usr/local/mysql/mysql.sock \--with-mysqli \--with-zlib \--with-curl \--with-gd \--with-jpeg-dir \--with-png-dir \--with-freetype-dir \--with-openssl \--enable-mbstring \--enable-xml \--enable-session \--enable-ftp \--enable-pdo \--enable-tokenizer \--enable-zip make -j3 && make installcp php.ini-development /usr/local/php/lib/php.inivi /usr/local/php/lib/php.inimysqli.default_socket = /usr/local/mysql/mysql.sockdate.timezone = Asia/Shanghai[root@localhost php-7.1.10]# /usr/local/php/bin/php -m //驗證安裝的模塊[root@localhost php-7.1.10]# vi /etc/httpd.conf //在合適位置新增AddType application/x-httpd-php .php ###添加AddType application/x-httpd-php-source .phps ###添加<IfModule dir_module> DirectoryIndex index.php index.html ###找到這個添加</IfModule>[root@localhost php-7.1.10]# rm -f /usr/local/httpd/htdocs/index.html ###刪除[root@localhost php-7.1.10]# vi /usr/local/httpd/htdocs/index.php ###創建新的<?phpphpinfo();?>[root@localhost php-7.1.10]# systemctl restart httpd.service測試:20.0.0.6#####FPM參數優化###
[root@localhost php-7.1.10]# cd /usr/local/php/etc/php-fpm.d[root@localhost etc]# vi www.confpm=dynamicpm.max_children=20pm.start_servers=5pm.min_spare_servers=2pm.max_spare_servers=8FPM啟動時有5個進程,最小空閑2個進程,最大空閑8個進程,最多可以有20個進程存在。
一、pm.max_children多大合適?
這個值原則上是越大越好, php-cgi的進程多了就會處理的很快, 排隊的請求就會很少。
設置”max children”也需要根據服務器的性能進行設定。
計算方式如下:
一般來說一臺服務器正常情況下每一個php-cgi所耗費的內存在20M~30M左右, 因此我的”max_children”我設置成40個,
20M*40=800M也就是說在峰值的時候所有PHP-CGI所耗內存在800M以內, 低于我的有效內存2Gb。
而如果我的”max_children”設置的較小, 比如5-10個, 那么php-cgi就會“很累“, 處理速度也很慢, 等待的時間也較長,占用的CPU也很高。
如果長時間沒有得到處理的請求就會出現504 Gateway Time-out這個錯誤, 而正在處理的很累的那幾個php-cgi如果遇到了問題就會出現502Bad gateway這個錯誤。
max_children較好的設置方式根據req/s(吞吐率, 單位時間里服務器處理的最大請求數, 單位req/s) 來設置, 若程序是100D req/s的處理能力, 那么就設置100比較好, 這是動態來調整的。
10、內核優化
默認的Linux內核參數考慮的是最通用的場景,不符合用于支持高并發訪問的Web服務器的定義,所以需要修改Linux內核參數,使得Nginx可以擁有更高的性能。
內核優化基本上會根據業務特點來進行調整,當Nginx作為靜態Web內容服務器、反向代理服務器或是提供圖片縮略功能(實時壓縮圖片)的服務器時,其內核參數的調整都是不同的。這里只針對最通用的、使Nginx支持更多并發請求的TCP網絡參數做簡單說明。
首先,需要修改/etc/sysctl.conf來更改內核參數
net.ipv4.tcp_max_tw_buckets = 6000 timewait 的數量,默認是180000。net.ipv4.ip_local_port_range = 1024 65000 允許系統打開的端口范圍。net.ipv4.tcp_tw_recycle = 1 啟用timewait 快速回收。net.ipv4.tcp_tw_reuse = 1 開啟重用。允許將TIME-WAIT sockets 重新用于新的TCP 連接。net.ipv4.tcp_syncookies = 1 開啟SYN Cookies,當出現SYN 等待隊列溢出時,啟用cookies 來處理。net.core.somaxconn = 262144web 應用中listen 函數的backlog 默認會給我們內核參數的net.core.somaxconn 限制到128,而nginx 定義的NGX_LISTEN_BACKLOG 默認為511,所以有必要調整這個值。net.core.netdev_max_backlog = 262144 每個網絡接口接收數據包的速率比內核處理這些包的速率快時,允許送到隊列的數據包的最大數目。net.ipv4.tcp_max_orphans = 262144 系統中最多有多少個TCP 套接字不被關聯到任何一個用戶文件句柄上。如果超過這個數字,孤兒連接將即刻被復位并打印出警告信息。這個限制僅僅是為了防止簡單的DoS 攻擊,不能過分依靠它或者人為地減小這個值,更應該增加這個值(如果增加了內存之后)。net.ipv4.tcp_max_syn_backlog = 262144 記錄的那些尚未收到客戶端確認信息的連接請求的最大值。對于有128M 內存的系統而言,缺省值是1024,小內存的系統則是128。net.ipv4.tcp_timestamps = 0 時間戳可以避免序列號的卷繞。一個1Gbps 的鏈路肯定會遇到以前用過的序列號。時間戳能夠讓內核接受這種“異常”的數據包。這里需要將其關掉。net.ipv4.tcp_synack_retries = 1 為了打開對端的連接,內核需要發送一個SYN 并附帶一個回應前面一個SYN 的ACK。也就是所謂三次握手中的第二次握手。這個設置決定了內核放棄連接之前發送SYN+ACK 包的數量。net.ipv4.tcp_syn_retries = 1 在內核放棄建立連接之前發送SYN 包的數量。net.ipv4.tcp_fin_timeout = 1 如果套接字由本端要求關閉,這個參數決定了它保持在FIN-WAIT-2 狀態的時間。對端可以出錯并永遠不關閉連接,甚至意外當機。缺省值是60 秒。2.2 內核的通常值是180 秒,3你可以按這個設置,但要記住的是,即使你的機器是一個輕載的WEB 服務器,也有因為大量的死套接字而內存溢出的風險,FIN- WAIT-2 的危險性比FIN-WAIT-1 要小,因為它最多只能吃掉1.5K 內存,但是它們的生存期長些。net.ipv4.tcp_keepalive_time = 30 當keepalive 起用的時候,TCP 發送keepalive 消息的頻度。缺省是2 小時。下面貼一個完整的內核優化設置:
vi /etc/sysctl.conf CentOS5.5中可以將所有內容清空直接替換為如下內容:
net.ipv4.ip_forward = 0net.ipv4.conf.default.rp_filter = 1net.ipv4.conf.default.accept_source_route = 0kernel.sysrq = 0kernel.core_uses_pid = 1net.ipv4.tcp_syncookies = 1kernel.msgmnb = 65536kernel.msgmax = 65536kernel.shmmax = 68719476736kernel.shmall = 4294967296net.ipv4.tcp_max_tw_buckets = 6000net.ipv4.tcp_sack = 1net.ipv4.tcp_window_scaling = 1net.ipv4.tcp_rmem = 4096 87380 4194304net.ipv4.tcp_wmem = 4096 16384 4194304net.core.wmem_default = 8388608net.core.rmem_default = 8388608net.core.rmem_max = 16777216net.core.wmem_max = 16777216net.core.netdev_max_backlog = 262144net.core.somaxconn = 262144net.ipv4.tcp_max_orphans = 3276800net.ipv4.tcp_max_syn_backlog = 262144net.ipv4.tcp_timestamps = 0net.ipv4.tcp_synack_retries = 1net.ipv4.tcp_syn_retries = 1net.ipv4.tcp_tw_recycle = 1net.ipv4.tcp_tw_reuse = 1net.ipv4.tcp_mem = 94500000 915000000 927000000net.ipv4.tcp_fin_timeout = 1net.ipv4.tcp_keepalive_time = 30net.ipv4.ip_local_port_range = 1024 65000使配置立即生效可使用如下命令: /sbin/sysctl -p
四、Nginx負載均衡
1、四層和七層
1)四層負載四層就是基于IP+端口的負載均衡,通過虛擬IP+端口接收請求,然后再分配到真實的服務器;2)七層負載七層就是基于URL等應用層信息的負載均衡,通過虛擬的URL或主機名接收請求,然后再分配到真實的服務器。3)二層、三層負載基于MAC地址的二層負載均衡:二層負載均衡會通過一個虛擬MAC地址接收請求,然后再分配到真實的MAC地址;基于IP地址的三層負載均衡:三層負載均衡會通過一個虛擬IP地址接收請求,然后再分配到真實的IP地址;2、熱備
如果你有2臺服務器,當一臺服務器發生事故時,才啟用第二臺服務器給提供服務。服務器處理請求的順序:AAAAAA突然A掛啦,BBBBBBBBBBBBBB…
upstream mysvr { server 127.0.0.1:7878; server 192.168.10.121:3333 backup; #熱備 }3、負載均衡策略(算法)
Nginx 默認提供的負載均衡策略:
1)輪詢(默認)round_robin
每個請求按時間順序逐一分配到不同的后端服務器,如果后端服務器down掉,能自動剔除。
雖然這種方式簡便、成本低廉。但缺點是:可靠性低和負載分配不均衡。
例如:
upstream backserver { server 192.168.0.14; server 192.168.0.15; }2)權重 weight
weight的值越大分配到的訪問概率越高,主要用于后端每臺服務器性能不均衡的情況下,達到合理的資源利用率。
配置方式:
upstream backserver { server 192.168.0.14 weight=8; server 192.168.0.15 weight=10; }3)IP 哈希 ip_hash
ip_hash: 來自同一個IP的請求會分發到相同的后端服務器
每個請求按訪問 ip 的 hash 結果分配,這樣每個訪客固定訪問一個后端服務器,可以解決 session 共享的問題。
當然,實際場景下,一般不考慮使用 ip_hash 解決 session 共享。
例如:
upstream backserver { ip_hash; server 192.168.0.14:88; server 192.168.0.15:80; }4)最少連接 least_conn
把請求轉發給連接數較少的后端服務器。輪詢算法是把請求平均的轉發給各個后端,使它們的負載大致相同;但是,有些請求占用的時間很長,會導致其所在的后端負載較高。這種情況下,least_conn這種方式就可以達到更好的負載均衡效果。
#動態服務器組 upstream backserver { least_conn; #把請求轉發給連接數較少的后端服務器 server localhost:8080 weight=2; #tomcat 7.0 server localhost:8081; #tomcat 8.0 server localhost:8082 backup; #tomcat 8.5 server localhost:8083 max_fails=3 fail_timeout=20s; #tomcat 9.0 }5)fair(第三方)
按后端服務器的響應時間來分配請求,響應時間短的優先分配。
6)url_hash(第三方)
按訪問url的hash結果來分配請求,使每個url定向到同一個后端服務器,后端服務器為緩存時比較有效。
補充:
sticky:通過nginx-sticky模塊,來實現cookie黏貼的方式將來自同一個客戶端的請求發送到同一個后端服務器上處理,這樣一定程度上可以解決多個后端服務器的session會話同步的問題;round-robin(RR):輪詢,每個請求按時間順序依次分配到不同的后端服務器,如果后端某臺服務器死機,自動剔除故障系統,使用戶訪問不受影響;weight:輪詢權重,weight的值越大分配到的訪問概率就越高,主要用于后端每臺服務器性能不均衡的情況下,或者僅僅為在主從的情況下設置不同的權重,達到合理有效的利用主機資源。least_conn:請求被發送到當前活躍連接最少的realserver上,會考慮到weight的值;ip_hash:每個請求按照IP的哈希結果分配,使來自同一個IP的訪客固定訪問后端服務器,可以有效的解決動態網頁存在的session共享問題。fair:比weight、ip_hash更加智能的負載均衡算法,fair算法可以根據頁面的大小和加載時間長短智能地進行負載均衡,也就是根據后端服務器的響應時間來分配請求,相應時間短的優先分配。nginx本身不支持fair,如果需要使用這種調度算法,則必須安裝upstream_fair模塊。url_hash:按訪問的URL的哈希結果來分配請求,使每個URL定向到后端服務器,可以進一步提高后端緩存服務器的效率。同樣,nginx本身不支持url_hash,如果需要這種調度算法,則必須安裝nginx的hash軟件包。4、負載均衡狀態
在nginx upstream模塊中,可以設定每臺后端服務器在負載均衡調度中的狀態。
常用的狀態有:down:表示當前的server暫時不參與負載均衡;backup:預留的備份機器。當其他所有的非backup機器出現故障或者繁忙的時候,才會請求backup機器,因此這臺機器的訪問壓力最低;max_fails:允許請求失敗的次數,默認為1,當超過最大次數時,返回proxy_next_upstraem模塊定義的錯誤;fail_timeout:請求失敗超時時間,在經歷了max_fails次失敗后,暫停服務的時間。max_fails和fail_timeout可以一起使用。六、FastCG、php-fpm
1、Nginx+FastCGI運行原理
Nginx 不支持對外部程序的直接調用或者解析,所有的外部程序(包括 PHP)必須通過FastCGI 接口來調用。FastCGI 接口在 Linux 下是 socket(這個 socket 可以是文件 socket, 也可以是 ip socket)。 wrapper 為了調用 CGI 程序,還需要一個 FastCGI 的 wrapper(wrapper 可以理解為用于啟動另一個程序的程序),這個 wrapper 綁定在某個固定 socket 上,如端口或者文件 socket。當 Nginx 將 CGI 請求發送給這個 socket 的時候,通過 FastCGI 接口,wrapper 接收到請求,然后 Fork(派生)出一個新的線程,這個線程調用解釋器或者外部程序處理腳本并讀取返回數據;接著 wrapper 再將返回的數據通過 FastCGI 接口,沿著固定的 socket傳遞給 Nginx;最后 Nginx 將返回的數據(html 頁面或者圖片)發送給客戶端。
2、缺省安裝的Nginx+php-fpm環境
假設用戶瀏覽一個耗時的網頁,但是卻在服務端渲染頁面的中途中關閉了瀏覽器,那么請問服務端的PHP腳本是繼續執行還是退出執行?
答:正常情況下,如果client異常退出了,Server端的程序還是會繼續執行,直到與IO進行了兩次交互操作。Server端發現client端已經斷開連接,這個時候會出發一個User_abort,如果這個沒有設置ignore_user_abort,那么這個php-fpm的程序才會被中斷。
fpm模塊,對接nginx處理動態請求,端口9000PHP-FPM(FastCGI Process Manager:FastCGI進程管理器)是一個PHPFastCGI管理器,對于PHP 5.3.3之前的php來說,是一個補丁包 [1] ,旨在將FastCGI進程管理整合進PHP包中。如果你使用的是PHP5.3.3之前的PHP的話,就必須將它patch到你的PHP源代碼中,在編譯安裝PHP后才可以使用。相對Spawn-FCGI,PHP-FPM在CPU和內存方面的控制都更勝一籌,而且前者很容易崩潰,必須用crontab進行監控,而PHP-FPM則沒有這種煩惱。3、已知nginx和php-fpm安裝在同一臺服務器上,nginx連接php-fpm有兩種方式:一種是類似127.0.0.1:9000的TCP socket,另一種是類似/tmp/php-fpm.sock的Unix domain socket,請問如何選擇?需要注意什么?
Unix domain socket的流程不會走到TCP那層,直接以文件的形式,以stream socket通信。如果是TCP Socket,則需要走到IP層。說的通俗一點,追求可靠性就是選擇TCP(需要占用一個端口,更穩定,如:127.0.0.1:9000),追求高性能就是Unix Socket(不需要占用端口,更快,但可靠性不如TCP的方式)。
總結
- 上一篇: Linux(全)
- 下一篇: Nginx —— 检查配置文件ngi