天天看點

Nginx優化

一、Nginx優化思路

1、優化目的

标準情況下,軟體預設的參數都是對安裝軟體的硬體标準(最低配置)來設定的,目前我們伺服器的硬體資源遠遠大于要求的标準,是以為了讓伺服器性能更加出衆,充分利用伺服器的硬體資源,我們一般需要優化APP的并發數來提升伺服器的性能。

  總結來說:1.伺服器大并發實作;2.提升使用者體驗;3.為公司省錢。

二、工作程序優化

1、優化方案

Nginx是主程序+工作程序模型,也就是一個主程序會挂幾個工作程序。

  • worker_processes 1; 該指令指定工作程序數量

    一般按照CPU的總核心數調整,優化思想是:保證一個程序跑在一個核上,将每個核充分利用起來。如果CPU的壓力依然很小,可以設定保證一個核兩個程序。

  • worker_cpu_affinity 0010 0100 1000; 該指令調整CPU的親和力

    要保證一個核心上一個程序,這需要設定CPU的親和力,這裡用二進制掩碼來計算數字是幾。

  • worker_connections 1024; 一個工作程序的并發數

    這裡設定是一個工作程序可以處理多少個連接配接,也就是并發數設定。

2、方案驗證

(1)首先檢視确認目前server核心數

$ cat /proc/cpuinfo | grep "flags" | wc -l
4
           

(2)并發優化,配置修改nginx.conf如下所示:

worker_processes 4;
worker_cpu_affinity 0001 0010 0100 1000;   # 依次代表從1到4這四個核
events {
    worker_connections 10240;   # 這個值一般先設比較小,觀察程序消耗再決定是否增加并發數
}
           

(3)nginx服務檢查

# 檢視程序及程序是否處于對應核心上
$ ps -eo psr,pid,args | grep "nginx"
  0  13977 nginx: master process /usr/local/nginx/sbin/nginx      # 父程序
  0  13978 nginx: worker process
  1  13979 nginx: worker process
  2  13980 nginx: worker process
  3  13981 nginx: worker process
  0  14284 grep --color=auto nginx

# 檢視nginx連接配接數
$ netstat -antpl | grep nginx
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      13977/nginx: master

# 檢視nginx目前連接配接的人數
$ netstat -antpl | grep nginx | grep ESTABLISHED | wc -l
0
           

三、長連接配接

1、什麼是長連接配接,為什麼要使用長連接配接?

nginx這種web伺服器軟體都是屬于TCP協定的軟體,TCP協定的特點就在于每次連接配接時要進行三次握手,握手成功後再通訊資料,通訊結束後四次揮手斷開連接配接。

  而http協定是一個無狀态協定, 每次進行通訊都要三次握手四次揮手,那伺服器就需要經常去維護握手和斷開。 伺服器壓力過大、浪費的資源也過多。

  是以一般都需要開啟長連接配接,在第一個請求結束後,等一段時間,如果這個時間内,再有請求過來,則不斷開連接配接,直接将資料發送給用戶端。這樣就降低了握手和揮手的次數和頻率。

2、長連接配接配置方法

# 關閉長連接配接:0代表關閉 
keepalive_timeout 0; 

# 開啟長連接配接
# keepalive_timeout 65;

# 一個長連接配接處理最大請求數(定期釋放記憶體,防止記憶體溢出)
# keepalive_requests 8192;
           

3、長連接配接狀态檢視

(1)伺服器上檢視連接配接狀态

關閉長連接配接時:

# 浏覽器通路完立刻進入TIME_WAIT狀态(主動關閉)
$ netstat -antpl
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name    
tcp        0      0 127.0.0.1:25            0.0.0.0:*               LISTEN      1317/master         
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      14698/nginx: master 
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      1095/sshd           
tcp        0      0 192.168.31.42:80        192.168.31.28:64977     TIME_WAIT   -                   
tcp        0      0 192.168.31.42:80        192.168.31.28:64978     TIME_WAIT   -                   
tcp        0      0 192.168.31.42:80        192.168.31.28:64979     TIME_WAIT   -                   
tcp        0      0 192.168.31.42:22        192.168.31.28:64678     ESTABLISHED 14636/sshd: root@pt 
tcp6       0      0 ::1:25                  :::*                    LISTEN      1317/master         
tcp6       0      0 :::22                   :::*                    LISTEN      1095/sshd

# 一段時間後連接配接消息消失
$ netstat -antpl
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name    
tcp        0      0 127.0.0.1:25            0.0.0.0:*               LISTEN      1317/master         
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      14698/nginx: master 
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      1095/sshd           
tcp        0      0 192.168.31.42:22        192.168.31.28:64678     ESTABLISHED 14636/sshd: root@pt 
tcp6       0      0 ::1:25                  :::*                    LISTEN      1317/master         
tcp6       0      0 :::22                   :::*                    LISTEN      1095/sshd
           

開啟長連接配接時:

# 由于前面設定長連接配接逾時時間是65秒,這段時間内一直保持在ESTABLISHED狀态:
$ netstat -antpl 
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name    
tcp        0      0 127.0.0.1:25            0.0.0.0:*               LISTEN      1317/master         
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      14828/nginx: master 
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      1095/sshd           
tcp        0      0 192.168.31.42:80        192.168.31.28:51700     ESTABLISHED 14829/nginx: worker 
tcp        0      0 192.168.31.42:22        192.168.31.28:50373     ESTABLISHED 14777/sshd: root@pt 
tcp        0      0 192.168.31.42:22        192.168.31.28:64678     ESTABLISHED 14636/sshd: root@pt 
tcp        0      0 192.168.31.42:80        192.168.31.28:51701     ESTABLISHED 14829/nginx: worker 
tcp6       0      0 ::1:25                  :::*                    LISTEN      1317/master         
tcp6       0      0 :::22                   :::*                    LISTEN      1095/sshd 

# 時間逾時長連接配接斷開
$ netstat -antpl 
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name    
tcp        0      0 127.0.0.1:25            0.0.0.0:*               LISTEN      1317/master         
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      14828/nginx: master 
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      1095/sshd           
tcp        0      0 192.168.31.42:22        192.168.31.28:50373     ESTABLISHED 14777/sshd: root@pt 
tcp        0      0 192.168.31.42:22        192.168.31.28:64678     ESTABLISHED 14636/sshd: root@pt 
tcp6       0      0 ::1:25                  :::*                    LISTEN      1317/master         
tcp6       0      0 :::22                   :::*                    LISTEN      1095/sshd 
           

(2)浏覽器上檢視連接配接狀态

Nginx優化
Nginx優化

四、壓縮優化(資料壓縮)

gzip(GNU-ZIP)是一種壓縮技術。經過gzip壓縮後頁面大小可以變為原來的30%甚至更小,這樣,使用者浏覽頁面的時候速度會塊得多。gzip的壓縮頁面需要浏覽器和伺服器雙方都支援,實際上就是伺服器端壓縮,傳到浏覽器後浏覽器解壓并解析。浏覽器那裡不需要我們擔心,因為目前的巨大多數浏覽器都支援解析gzip過的頁面。

  Nginx的壓縮輸出有一組gzip壓縮指令來實作。相關指令位于http{….}兩個大括号之間。

1、nginx配置gzip

gzip on;        # 啟動gzip壓縮功能
gzip_proxied any;    # nginx做前端代理時啟用該選項,表示無論後端伺服器的headers傳回什麼資訊,都無條件啟用壓縮
gzip_min_length 1k;   # 小于1k的小檔案不壓縮(小檔案可能會越壓縮越大)
gzip_buffers 4 8k;     # 設定系統擷取幾個機關的緩存用于存儲gzip的壓縮結果資料流,按照原始資料大小以8k為機關申請4倍記憶體空間
gzip_comp_level 6;    # gzip壓縮級别,1壓縮比最小處理速度最快,9壓縮比最大處理最慢也最消耗CPU,一般設定為3即可
gzip_types text/plain text/css application/x-javascript application/javascript application/xml;   # 什麼類型的頁面或文檔啟用壓縮
gzip_vary on;         # 開啟在http header中添加Vary:Accept-Encoding
           

2、字段詳解

  • gzip off(on);

    該指令用于開啟或關閉gzip子產品(on/off)

  • gzip_min_length 1k;

    啟用gzip壓縮的最小檔案,小于設定值的檔案将不會壓縮。頁面位元組數從header頭得content-length中進行擷取。預設值是0,不管頁面多大都壓縮。建議設定成大于1k的位元組數,小于1k可能會越壓越大。

  • gzip_comp_level 1;

    gzip 壓縮級别,1-9,數字越大壓縮的越好,也越占用CPU時間。是以會有傳輸快慢和CPU消耗大小平衡的問題。

  • 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;

    進行壓縮的檔案類型。javascript有多種形式。其中的值可以在 mime.types 檔案中找到。

  • gzip_vary on;

    是否在http header中添加Vary: Accept-Encoding,建議開啟。給代理伺服器用的,有的浏覽器支援壓縮,有的不支援,是以避免浪費不支援的也壓縮,是以根據用戶端的HTTP頭來判斷,是否需要壓縮

  • gzip_disable "MSIE [1-6].";

    禁用IE 6 gzip

  • gzip_buffers 32 4k;

    設定壓縮所需要的緩沖區大小;32 4k代表以4k為機關,安裝原始資料大小以4k為機關的32倍申請記憶體。

  • gzip_http_version 1.0;

    設定gzip壓縮針對的HTTP協定版本(1.0 / 1.1)

五、用戶端緩存優化

1、文法和配置方法

文法:expires [time|epoch|max|off]

  預設值:expires off

  作用域:http,server,location

location ~* \.(js|css)?$ {
    expires 1h;
}
           

2、實作示例

server {
    listen       80;
    server_name  localhost;
    location / {
        root   html/web1;
        index  index.html index.htm;
    }
    # 用戶端緩存設定:png或gif檔案在用戶端緩存一個小時
    location ~* \.(png|gif)$ {
        expires 1h;
    }
           

測試浏覽器重新整理以Chrome為例:

  • ctrl+f5

    清空本地緩存從伺服器拿資料

  • F5或者 點選 浏覽器的重新整理圖示

    優先從本地找,然後去找伺服器核對資訊是否一緻。一緻則傳回304,從本地拿資料

  • 回車

    從本地緩存拿資料

六、思考

公司網站日常PV 60萬,Nginx伺服器該如何優化?