1. 程式人生 > 其它 >解除/配置 linux/nginx 的 tcp 連線(nginx配置檔案日常配置推薦)

解除/配置 linux/nginx 的 tcp 連線(nginx配置檔案日常配置推薦)

nginx 文件 引數介紹:

http://shouce.jb51.net/nginx-doc/Text/3.1_httpcore.html

nginx 優化

由於業務場景需要,近期將生產環境由阿里雲的 SLB 更換為自建 nginx,之前在測試環境使用了一段時間一直沒有問題,但是上週上到生產後出現了一系列問題,因此對 nginx 做了一些優化,記錄下以備以後需要。

高併發優化

生產環境相對於測試環境訪問量多了很多,併發量大的時候會出現部分請求 502 的情況,因此對高併發進行了一點優化,主要分兩方面,一方面是系統層面,一方面是 nginx 層面。

系統核心層面

檔案控制代碼限制
在linux下編寫網路伺服器程式的朋友肯定都知道每一個tcp連線都要佔一個檔案描述符,一旦這個檔案描述符使用完了,新的連線到來返回給我們的錯誤是“Socket
/File:Can’t open so many files”。 這時你需要明白作業系統對可以開啟的最大檔案數的限制。 程序限制 執行 ulimit -n 輸出 1024,說明對於一個程序而言最多隻能開啟1024個檔案,所以你要採用此預設配置最多也就可以併發上千個TCP連線。 臨時修改:ulimit -n 1000000,但是這種臨時修改只對當前登入使用者目前的使用環境有效,系統重啟或使用者退出後就會失效。 重啟後失效的修改(不過我在CentOS 6.5下測試,重啟後未發現失效):編輯 /etc/security/limits.conf 檔案, 修改後內容為 * soft nofile 102400 * hard nofile 102400

修改/etc/sysctl.conf核心引數。

fs.file-max = 999999
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_keepalive_time = 15
net.ipv4.tcp_fin_timeout = 15
net.ipv4.tcp_max_tw_buckets = 5000
net.core.netdev_max_backlog = 262144
net.ipv4.tcp_max_orphans = 262144
net.ipv4.tcp_tw_reuse = 1

使配置生效

sysctl -p

引數說明:

  • fs.file-max:999999

    這個引數表示程序(比如一個worker程序)可以同時開啟的最大控制代碼數,這 個引數直接限制最大併發連線數,需根據實際情況配置。

  • net.ipv4.tcp_tw_reuse:

    這個引數設定為1,表示允許將TIME-WAIT狀態的socket重新用於新的 TCP連線,這對於伺服器來說很有意義,因為伺服器上總會有大量TIME-WAIT狀態的連線。

  • net.ipv4.tcp_keepalive_time:

    這個引數表示當keepalive啟用時,TCP傳送keepalive訊息的頻度。 預設是2小時,若將其設定得小一些,可以更快地清理無效的連線。

  • net.ipv4.tcp_fin_timeout:

    這個引數表示當伺服器主動關閉連線時,socket保持在FIN-WAIT-2狀態的最大時間。

  • net.ipv4.tcp_max_tw_buckets:

    這個引數表示作業系統允許TIME_WAIT套接字數量的最大值, 如果超過這個數字,TIME_WAIT套接字將立刻被清除並列印警告資訊。該引數預設為 180000,過多的TIME_WAIT套接字會使Web伺服器變慢。

  • net.core.netdev_max_backlog = 262144

    每個網路介面接收資料包的速率比核心處理這些包的速率快時,允許送到佇列的資料包的最大數目。

  • net.ipv4.tcp_max_orphans = 262144

    系統中最多有多少個TCP套接字不被關聯到任何一個使用者檔案控制代碼上。如果超過這個數字,孤兒連線將即刻被複位並打印出警告資訊。這個限制僅僅是為了防止簡單的DoS攻擊,不能過分依靠它或者人為地減小這個值,更應該增加這個值(如果增加了記憶體之後)。

  • net.ipv4.tcp_tw_reuse = 1

    表示開啟重用。允許將TIME-WAIT sockets重新用於新的TCP連線,預設為0,表示關閉

Nginx 配置方面

  • worker_processes 4

    nginx程序數,建議按照cpu數目來指定,一般跟cpu核數相同或為它的倍數。

  • worker_cpu_affinity 00000001 00000010 00000100 00001000 ;

    為每個程序分配cpu,上例中將4個程序分配到4個cpu,當然可以寫多個,或者將一個程序分配到多個cpu。

  • worker_rlimit_nofile

    這個指令是指當一個nginx程序開啟的最多檔案描述符數目,理論值應該是系統的最多開啟檔案數(ulimit -n)與nginx程序數相除,但是nginx分配請求並不是那麼均勻,所以最好與ulimit -n的值保持一致。

  • use epoll;

    使用epoll的I/O模型,用這個模型來高效處理非同步事件

  • worker_connections 65535;

    每個程序允許的最多連線數,理論上每臺nginx伺服器的最大連線數為worker_processesworker_connections。這個值太小的後果就是你的系統會報:too many open files 等錯誤,導致你的系統死掉。一般給到伺服器後最好通過 ulimit 命令結合修改 /etc/security/limits.conf(增加 soft nofile = * hard nofile=)兩個配置值,將其設定的更大些。

  • keepalive_timeout 30;

    http連線超時時間,預設是60s,功能是使客戶端到伺服器端的連線在設定的時間內持續有效,當出現對伺服器的後繼請求時,該功能避免了建立或者重新建立連線。切記這個引數也不能設定過大!否則會導致許多無效的http連線佔據著nginx的連線數,終nginx崩潰!

  • client_header_buffer_size 4k;

    客戶端請求頭部的緩衝區大小,這個可以根據你的系統分頁大小來設定,一般一個請求的頭部大小不會超過1k,不過由於一般系統分頁都要大於1k,所以這裡設定為分頁大小。分頁大小可以用命令getconf PAGESIZE取得。

  • open_file_cache max=102400 inactive=20s;

    這個引數將為開啟檔案指定快取,預設是沒有啟用的,max指定快取數量,建議和開啟檔案數一致,inactive是指經過多長時間檔案沒被請求後刪除快取。

  • open_file_cache_valid 30s;

    指多長時間檢查一次快取的有效資訊。

  • open_file_cache_min_uses 1

    open_file_cache指令中的inactive引數時間內檔案的最少使用次數,如果超過這個數字,檔案描述符一直是在快取中開啟的,如上例,如果有一個檔案在inactive時間內一次沒被使用,它將被移除。

  • sendfile on;

    sendfile()可以在磁碟和TCP socket之間互相拷貝資料(或任意兩個檔案描述符)。Pre-sendfile是傳送資料之前在使用者空間申請資料緩衝區。之後用read()將資料從檔案拷貝到這個緩衝區,write()將緩衝區資料寫入網路。sendfile()是立即將資料從磁碟讀到OS快取。因為這種拷貝是在核心完成的,sendfile()要比組合read()和write()以及開啟關閉丟棄緩衝更加有效(更多有關於sendfile)。

  • tcp_nopush on;

    告訴nginx在一個數據包裡傳送所有標頭檔案,而不一個接一個的傳送。就是說資料包不會馬上傳送出去,等到資料包最大時,一次性的傳輸出去,這樣有助於解決網路堵塞。

  • tcp_nodelay on;

    告訴nginx不要快取資料,而是一段一段的傳送–當需要及時傳送資料時,就應該給應用設定這個屬性,這樣傳送一小塊資料資訊時就不能立即得到返回值。

upstream 容錯配置說明

  1. 判斷節點失效狀態
    Nginx預設判斷失敗節點狀態以connect refuse和time out狀態為準,不以HTTP錯誤狀態進行判斷失敗,因為HTTP只要能返回狀態說明該節點還可以正常連線,所以nginx判斷其還是存活狀態;除非添加了proxy_next_upstream指令設定對404、502、503、504、500和time out等錯誤進行轉到備機處理,在next_upstream過程中,會對fails進行累加,如果備用機處理還是錯誤則直接返回錯誤資訊(但404不進行記錄到錯誤數,如果不配置錯誤狀態也不對其進行錯誤狀態記錄),綜述,nginx記錄錯誤數量只記錄timeout 、connect refuse、502、500、503、504這6種狀態,timeout和connect refuse是永遠被記錄錯誤狀態,而502、500、503、504只有在配置proxy_next_upstream後nginx才會記錄這4種HTTP錯誤到fails中,當fails大於等於max_fails時,則該節點失效;
  2. nginx 處理節點失效和恢復的觸發條件
    nginx可以通過設定max_fails(最大嘗試失敗次數)和fail_timeout(失效時間,在到達最大嘗試失敗次數後,在fail_timeout的時間範圍內節點被置為失效,除非所有節點都失效,否則該時間內,節點不進行恢復)對節點失敗的嘗試次數和失效時間進行設定,當超過最大嘗試次數或失效時間未超過配置失效時間,則nginx會對節點狀會置為失效狀態,nginx不對該後端進行連線,直到超過失效時間或者所有節點都失效後,該節點重新置為有效,重新探測

  3. 所有節點失效後nginx將重新恢復所有節點進行探測
    如果探測所有節點均失效,備機也為失效時,那麼nginx會對所有節點恢復為有效,重新嘗試探測有效節點,如果探測到有效節點則返回正確節點內容,如果還是全部錯誤,那麼繼續探測下去,當沒有正確資訊時,節點失效時預設返回狀態為502,但是下次訪問節點時會繼續探測正確節點,直到找到正確的為止。

  4. 通過proxy_next_upstream實現容災和重複處理問題
    ngx_http_proxy_module 模組中包括proxy_next_upstream指令
    語法: proxy_next_upstream error | timeout | invalid_header | http_500 | http_502 | http_503 | http_504 |http_404 | off …;
    預設值: proxy_next_upstream error timeout; 上下文: http, server, location

其中:
error   表示和後端伺服器建立連線時,或者向後端伺服器傳送請求時,或者從後端伺服器接收響應頭時,出現錯誤。
timeout   表示和後端伺服器建立連線時,或者向後端伺服器傳送請求時,或者從後端伺服器接收響應頭時,出現超時。
invalid_header   表示後端伺服器返回空響應或者非法響應頭
http_500   表示後端伺服器返回的響應狀態碼為500
http_502   表示後端伺服器返回的響應狀態碼為502
http_503   表示後端伺服器返回的響應狀態碼為503
http_504   表示後端伺服器返回的響應狀態碼為504
http_404   表示後端伺服器返回的響應狀態碼為404
off   表示停止將請求傳送給下一臺後端伺服器

常用 nginx 標準配置(僅供參考)

user www-data;
worker_processes 8; # 預設與cpu合數相同, 最多配置為雙倍
worker_cpu_affinity 00000001 00000010 00000100 00001000 00010000 00100000 01000000; # 與上面執行緒數量一致, 如果改為4,請刪除4 個
error_log   /www/log/nginx_error.log   crit;
pid         /usr/local/nginx/nginx.pid;
worker_rlimit_nofile 65535;

events
{
   use epoll;
   worker_connections 65535;
}

http
{
   include       mime.types;
   default_type   application/octet-stream;

   charset   utf-8;

   server_names_hash_bucket_size 128;
   client_header_buffer_size 2k;
   large_client_header_buffers 4 4k;
   client_max_body_size 8m;

   sendfile on;
   tcp_nopush     on;

   keepalive_timeout 60;

   fastcgi_cache_path /usr/local/nginx/fastcgi_cache levels=1:2
                 keys_zone=TEST:10m
                 inactive=5m;
   fastcgi_connect_timeout 300;
   fastcgi_send_timeout 300;
   fastcgi_read_timeout 300;
   fastcgi_buffer_size 16k;
   fastcgi_buffers 16 16k;
   fastcgi_busy_buffers_size 16k;
   fastcgi_temp_file_write_size 16k;
   fastcgi_cache TEST;
   fastcgi_cache_valid 200 302 1h;
   fastcgi_cache_valid 301 1d;
   fastcgi_cache_valid any 1m;
   fastcgi_cache_min_uses 1;
   fastcgi_cache_use_stale error timeout invalid_header http_500; 
   open_file_cache max=204800 inactive=20s;
   open_file_cache_min_uses 1;
   open_file_cache_valid 30s; 

   tcp_nodelay on;

   gzip on;
   gzip_min_length   1k;
   gzip_buffers     4 16k;
   gzip_http_version 1.0;
   gzip_comp_level 2;
   gzip_types       text/plain application/x-javascript text/css application/xml;
   gzip_vary on;

 upstream  test {
        server 192.168.5.34:9083 max_fails=3  fail_timeout=5s;
        server 192.168.5.35:9083 max_fails=3  fail_timeout=5s;
        server 192.168.5.36:9083 max_fails=3  fail_timeout=5s;
    }
   server
   {
     listen       80;
     server_name   www.test.com;
     index index.php index.htm;
     root   /www/html/;

   location /
     {
        proxy_pass http://test;
            proxy_set_header   Host    $host;
            proxy_set_header   X-Real-IP   $remote_addr;
            proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
     }
     location /status
     {
         stub_status on;
     }

     location ~ .*\.(php|php5)?$
     {
         fastcgi_pass 127.0.0.1:9000;
         fastcgi_index index.php;
         include fcgi.conf;
     }

     location ~ .*\.(gif|jpg|jpeg|png|bmp|swf|js|css)$
     {
       expires       30d;
     }

     log_format   access   '$remote_addr - $remote_user [$time_local] "$request" '
               '$status $body_bytes_sent "$http_referer" '
               '"$http_user_agent" $http_x_forwarded_for';
     access_log   /www/log/access.log   access;
       }
}

引數詳細介紹請看文件:

http://shouce.jb51.net/nginx-doc/Text/3.1_httpcore.html