nginx高并發(fā)下的優(yōu)化

寫在前面


最近在進行服務(wù)器的優(yōu)化创肥,正好在看nginx相關(guān)的知識,所以把一些知識整理一下值朋。參考資料為《Nginx高性能web服務(wù)器詳解》叹侄,建議大家都去讀讀這本書。
我的機器為四核CPU昨登,16G內(nèi)存趾代。

內(nèi)核參數(shù)優(yōu)化


把如下的參數(shù)追加到Linux系統(tǒng)的/etc/sysctl.conf文件中,然后使用如下命令使修改生效:/sbin/sysctl -p

net.core.netdev_max_backlog = 262144
net.core.somaxconn = 262144
net.ipv4.tcp_max_orphans = 262144
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.core.netdev_max_backlog參數(shù)

參數(shù)net.core.netdev_max_backlog,表示當每個網(wǎng)絡(luò)接口接受數(shù)據(jù)包的速率比內(nèi)核處理這些包的速率快時篙骡,允許發(fā)送隊列的數(shù)據(jù)包的最大數(shù)目稽坤,我們調(diào)整為262144.

net.core.somaxconn

該參數(shù)用于調(diào)節(jié)系統(tǒng)同時發(fā)起的TCP連接數(shù),一般默認值為128糯俗,在客戶端高并發(fā)的請求的情況下尿褪,該默認值較小,可能導致連接超時或者重傳問題得湘,我們可以根據(jù)實際情況結(jié)合并發(fā)數(shù)來調(diào)節(jié)此值杖玲。

net.ipv4.tcp_max_orphans

該參數(shù)用于設(shè)定系統(tǒng)中最多允許存在多少TCP套接字不被關(guān)聯(lián)到任何一個用戶文件句柄上,如果超過這個數(shù)字淘正,沒有與用戶文件句柄關(guān)聯(lián)到TCP套接字將立即被復(fù)位摆马,同時發(fā)出警告信息,這個限制只是為了簡單防治Dos攻擊鸿吆,一般系統(tǒng)內(nèi)存充足的情況下囤采,可以增大這個參數(shù)。

net.ipv4.tcp_max_syn_backlog

該參數(shù)用于記錄尚未收到客戶端確認信息的連接請求的最大值惩淳,對于擁有128內(nèi)存的系統(tǒng)而言蕉毯,此參數(shù)的默認值為1024乓搬,對小內(nèi)存的系統(tǒng)則是128,一般在系統(tǒng)內(nèi)存比較充足的情況下代虾,可以增大這個參數(shù)的賦值进肯。

net.ipv4.tcp_timestamps

該參數(shù)用于設(shè)置時間戳,這個可以避免序列號的卷繞棉磨,在一個1Gb/s的鏈路上江掩,遇到以前用過的序列號概率很大,當此值賦值為0時乘瓤,警用對于TCP時間戳的支持环形,默認情況下,TCP協(xié)議會讓內(nèi)核接受這種異常的數(shù)據(jù)包馅扣,針對Nginx服務(wù)器來說斟赚,建議將其關(guān)閉。

net.ipv4.tcp_synack_retries

該參數(shù)用于設(shè)置內(nèi)核放棄TCP連接之前向客戶端發(fā)送SYN+ACK包的數(shù)量差油,為了建立對端的連接服務(wù),服務(wù)器和客戶端需要進行三次握手任洞,第二次握手期間蓄喇,內(nèi)核需要發(fā)送SYN并附帶一個回應(yīng)前一個SYN的ACK,這個參數(shù)主要影響這個過程交掏,一般賦予值為1妆偏,即內(nèi)核放棄連接之前發(fā)送一次SYN+ACK包。

net.ipv4.tcp_syn_retries

該參數(shù)的作用與上一個參數(shù)類似盅弛,設(shè)置內(nèi)核放棄建立連接之前發(fā)送SYN包的數(shù)量钱骂,賦值為1。

nginx優(yōu)化


nginx的配置文件如下:

user www-data;
pid /run/nginx.pid;

worker_processes 4;
worker_cpu_affinity 0001 0010 0100 1000;
worker_rlimit_nofile 65535;

events {
        use epoll;
        worker_connections 65535;
        accept_mutex off;
        multi_accept off;

}

http {

        ##
        # Basic Settings
        ##

        sendfile on;
        tcp_nopush on;
        tcp_nodelay on;
        keepalive_timeout 60 50;
        send_timeout 10s;
        types_hash_max_size 2048;
        client_header_buffer_size 4k;
        client_max_body_size 8m;

        include /etc/nginx/mime.types;
        default_type application/octet-stream;

        ##
        # Logging Settings
        ##

        access_log /var/log/nginx/access.log;
        error_log /var/log/nginx/error.log;

        ##
        # Gzip Settings
        ##

        gzip on;
        gzip_disable "msie6";
        gzip_min_length 1024;
        gzip_vary on;
        gzip_comp_level 2;
        gzip_buffers 32 4k;
        gunzip_static on;
        gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript;

        ##
        # Virtual Host Configs
        ##

        include /etc/nginx/conf.d/*.conf;
        include /etc/nginx/sites-enabled/*;
}

worker_processes

worker_processes用來設(shè)置Nginx服務(wù)的進程數(shù)挪鹏。推薦是CPU內(nèi)核數(shù)或者內(nèi)核數(shù)的倍數(shù)见秽,推薦使用CPU內(nèi)核數(shù),因為我的CPU為4核的讨盒,所以設(shè)置為4解取。

worker_cpu_affinity

默認情況下,Nginx的多個進程有可能跑在某一個CPU或CPU的某一核上返顺,導致Nginx進程使用硬件的資源不均禀苦,因此綁定Nginx進程到不同的CPU上是為了充分利用硬件的多CPU多核資源的目的。

worker_cpu_affinity用來為每個進程分配CPU的工作內(nèi)核遂鹊,參數(shù)有多個二進制值表示振乏,每一組代表一個進程,每組中的每一位代表該進程使用CPU的情況秉扑,1代表使用慧邮,0代表不使用。所以我們使用worker_cpu_affinity 0001 0010 0100 1000;來讓進程分別綁定不同的核上。

worker_connections

設(shè)置一個進程理論允許的最大連接數(shù)赋咽,理論上越大越好旧噪,但不可以超過worker_rlimit_nofile的值。還有個問題脓匿,linux系統(tǒng)中有個指令open file resource limit淘钟,它設(shè)置了進程可以打開的文件句柄數(shù)量,可以用下面的指令查看你的linux系統(tǒng)中open file resource limit指令的值陪毡,cat /proc/sys/fs/file-max
可以將該指令設(shè)置為23900251

echo "2390251" > /proc/sys/fs/file-max; sysctl -p

worker_rlimit_nofile

設(shè)置毎個進程的最大文件打開數(shù)米母。如果不設(shè)的話上限就是系統(tǒng)的ulimit –n的數(shù)字,一般為65535毡琉。

use epoll

設(shè)置事件驅(qū)動模型使用epoll铁瞒。事件驅(qū)動模型有select、poll桅滋、epoll等慧耍。

  • select先創(chuàng)建事件的描述符集合,對于一個描述符丐谋,可以關(guān)注其上面的Read事件芍碧、Write事件以及Exception事件,所以要創(chuàng)建三類事件描述符集合号俐,分別用來處理Read事件的描述符泌豆、Write事件的描述符、Exception事件的描述符吏饿,然后調(diào)用底層的select()函數(shù)踪危,等待事件發(fā)生,輪詢所有事件描述符集合的每一個事件描述符猪落,檢查是否有事件發(fā)生贞远,有的話就處理。select效率低许布,主要是輪詢效率低兴革,而且還要分別輪詢?nèi)齻€事件描述符的集合。

  • poll方法與select類似蜜唾,都是先創(chuàng)建一個關(guān)注事件的描述符集合杂曲,再去等待這些事件發(fā)生,然后再輪詢描述符集合袁余,檢查有無事件發(fā)生擎勘,如果有,就去處理颖榜。不同點是poll為Read事件棚饵、Write事件以及Exception事件只創(chuàng)建一個集合煤裙,在每個描述符對應(yīng)的結(jié)構(gòu)上分別設(shè)置Read事件、Write事件以及Exception事件噪漾。最后輪詢的時候硼砰,可以同時檢察權(quán)這三個事件是否發(fā)生⌒琅穑可以說,poll庫是select庫的優(yōu)化實現(xiàn)诈胜。

  • epoll是Nginx支持的高性能事件驅(qū)動庫之一豹障。是公認的非常優(yōu)秀的事件驅(qū)動模型。和poll庫跟select庫有很大的不同焦匈,最大區(qū)別在于效率血公。我們知道poll庫跟select庫都是創(chuàng)建一個待處理的事件列表,然后把這個列表發(fā)給內(nèi)核缓熟,返回的時候累魔,再去輪詢檢查這個列表,以判斷事件是否發(fā)生荚虚。這樣在描述符多的應(yīng)用中薛夜,效率就顯得比較低下了。一種比較好的方式是把列表的管理交由內(nèi)核負責版述,一旦某種事件發(fā)生,內(nèi)核就把發(fā)生事件的描述符列表通知給進程寞冯,這樣就避免了輪詢整個描述符列表渴析。首先,epoll庫通過相關(guān)調(diào)用同志內(nèi)核創(chuàng)建一個有N個描述符的事件列表吮龄,然后給這些描述符設(shè)置所關(guān)注的事件俭茧,并把它添加到內(nèi)核的事件列表中去。完成設(shè)置以后漓帚,epoll庫就開始等待內(nèi)核通知事件發(fā)生了母债,某一事件發(fā)生后,內(nèi)核講發(fā)生事件的描述符列表上報給epoll庫尝抖,得到事件列表的epoll庫毡们,就可以進行事件處理了。epoll庫在linux平臺是高效的昧辽,它支持一個進程打開大數(shù)目的事件描述符衙熔,上限是系統(tǒng)可以打開文件的最大數(shù)目;同時搅荞,epoll庫的IO效率不隨描述符數(shù)量的增加而線性下降红氯,因為它只會對內(nèi)核上報的活躍的描述符進行操作框咙。

accept_mutex

這個牽扯到《UNIX網(wǎng)絡(luò)編程》第一卷中提到的“驚群”問題(Thundering herd problem),大致意思是當某一時刻只有一個網(wǎng)絡(luò)連接到來時痢甘,多個睡眠進程會被同時叫醒喇嘱,但只有一個進程可獲得連接,如果每次喚醒的進程數(shù)目太多塞栅,會影響一部分系統(tǒng)性能者铜。在Nginx服務(wù)器的多進程下,就可能出現(xiàn)這個問題构蹬,為了解決這個問題王暗,Nginx配置了包含這樣一條指令accept_mutex,當其設(shè)置為開啟的時候庄敛,將會對多個Nginx進程接受連接進行序列化俗壹,防止多個進程對連接的爭搶。當服務(wù)器連接數(shù)不多時藻烤,開啟這個參數(shù)會讓負載有一定程度的降低绷雏。但是當服務(wù)器的吞吐量很大時,為了效率怖亭,請關(guān)閉這個參數(shù)涎显;并且關(guān)閉這個參數(shù)的時候也可以讓請求在多個worker間的分配更均衡。所以我們設(shè)置accept_mutex off;

multi_accept

sendfile


使用開啟或關(guān)閉是否使用sendfile()傳輸文件兴猩,普通應(yīng)用應(yīng)該設(shè)為on期吓,下載等IO重負荷的應(yīng)用應(yīng)該設(shè)為off,因為大文件不適合放到buffer中倾芝。
傳統(tǒng)文件傳輸中(read/write方式)在實現(xiàn)上3其實是比較復(fù)雜的讨勤,需要經(jīng)過多次上下文切換,當需要對一個文件傳輸時晨另,傳統(tǒng)方式是:

  • 調(diào)用read函數(shù)潭千,文件數(shù)據(jù)被copy到內(nèi)核緩沖區(qū)
  • read函數(shù)返回,數(shù)據(jù)從內(nèi)核緩沖區(qū)copy到用戶緩沖區(qū)
  • write函數(shù)調(diào)用借尿,將文件數(shù)據(jù)從用戶緩沖區(qū)copy到內(nèi)核與socket相關(guān)的緩沖區(qū)
  • 數(shù)據(jù)從socket緩沖區(qū)copy到相關(guān)協(xié)議引擎

從上面可以看出來刨晴,傳統(tǒng)readwrite進行網(wǎng)絡(luò)文件傳輸?shù)姆绞剑谶^程中經(jīng)歷了四次copy操作路翻。
硬盤->內(nèi)核buffer->用戶buffer->socket相關(guān)緩沖區(qū)->協(xié)議引擎
而sendfile系統(tǒng)調(diào)用則提供了一種減少多次copy狈癞,提高文件傳輸性能的方法。流程如下:

  • sendfile系統(tǒng)效用帚桩,文件數(shù)據(jù)被copy至內(nèi)核緩沖區(qū)
  • 記錄數(shù)據(jù)文職和長度相關(guān)的數(shù)據(jù)保存到socket相關(guān)緩存區(qū)
  • 實際數(shù)據(jù)由DMA模塊直接發(fā)送到協(xié)議引擎
tcp_nopush

sendfile為on時這里也應(yīng)該設(shè)為on亿驾,數(shù)據(jù)包會累積一下再一起傳輸,可以提高一些傳輸效率账嚎。

tcp_nodelay

小的數(shù)據(jù)包不等待直接傳輸莫瞬。默認為on儡蔓。
看上去是和tcp_nopush相反的功能,但是兩邊都為on時nginx也可以平衡這兩個功能的使用疼邀。

keepalive_timeout

HTTP連接的持續(xù)時間喂江。設(shè)的太長會使無用的線程變的太多。這個根據(jù)自己服務(wù)器訪問數(shù)量旁振、處理速度以及網(wǎng)絡(luò)狀況方面考慮获询。

send_timeout

設(shè)置Nginx服務(wù)器響應(yīng)客戶端的超時時間,這個超時時間只針對兩個客戶端和服務(wù)器建立連接后拐袜,某次活動之間的時間吉嚣,如果這個時間后,客戶端沒有任何活動蹬铺,Nginx服務(wù)器將關(guān)閉連接尝哆,將其設(shè)置為10s,Nginx與客戶端建立連接后甜攀,某次會話中服務(wù)器等待客戶端響應(yīng)超過10s秋泄,就會自動關(guān)閉。

types_hash_max_size

types_hash_max_size影響散列表的沖突率规阀。types_hash_max_size越大恒序,就會消耗更多的內(nèi)存,但散列key的沖突率會降低谁撼,檢索速度就更快歧胁。types_hash_max_size越小,消耗的內(nèi)存就越小厉碟,但散列key的沖突率可能上升与帆。

client_header_buffer_size

該指令用于設(shè)置Nginx服務(wù)器允許的客戶端請求頭部的緩沖區(qū)大小,默認為1KB墨榄,此指令的賦值可以根據(jù)系統(tǒng)分頁大小來設(shè)置,分頁大小可以用以下命令獲取getconf PAGESIZE勿她。

client_max_body_size 8m

客戶端上傳的body的最大值袄秩。超過最大值就會發(fā)生413(Request Entity Too Large)錯誤。默認為1m逢并,最好根據(jù)自己的情況改大一點之剧。

gzip on

啟用gzip,對響應(yīng)數(shù)據(jù)進行在線實時壓縮,減少數(shù)據(jù)傳輸量砍聊。

gzip_disable

Nginx服務(wù)器在響應(yīng)這些種類的客戶端請求時背稼,不使用Gzip功能緩存應(yīng)用數(shù)據(jù),gzip_disable "msie6"對IE6瀏覽器的數(shù)據(jù)不進行GZIP壓縮玻蝌。

gzip_min_length

Gzip壓縮功能對大數(shù)據(jù)的壓縮效果明顯蟹肘,但是如果壓縮很小的數(shù)據(jù)词疼,可能出現(xiàn)越壓縮數(shù)據(jù)量越大的情況,因此應(yīng)該根據(jù)相應(yīng)頁面的大小帘腹,選擇性開啟或者關(guān)閉Gzip功能贰盗。建議將值設(shè)置為1KB。

gzip_comp_level

設(shè)置壓縮程度阳欲,包括級別1到級別9舵盈,級別1表示壓縮程度最低,壓縮效率最高球化;級別9表示壓縮程度最高秽晚,壓縮效率最低,最費時間筒愚。

gzip_vary

用于設(shè)置在使用Gzip功能時是否發(fā)送帶有“Vary:Accept-Encoding”頭域的響應(yīng)頭部赴蝇,該頭域的主要功能是告訴接收方發(fā)送的數(shù)據(jù)經(jīng)過了壓縮處理,開啟后端效果是在響應(yīng)頭部Accept-Encoding: gzip锨能,對于本身不支持Gzip的壓縮的客戶端瀏覽器是有用的扯再。

gzip_buffers;

該指令用于設(shè)置Gzip壓縮文件使用存儲空間的大小,
語法gzip_buffers number size;number址遇,指定Nginx服務(wù)器需要向系統(tǒng)申請存儲空間的個數(shù)熄阻,size,指定每個緩存空間的大小倔约。根據(jù)配置項秃殉,Nginx服務(wù)器在對響應(yīng)輸出數(shù)據(jù)進行Gzip壓縮時需向系統(tǒng)申請numbersize大小的空間用于存儲壓縮數(shù)據(jù)。默認情況下浸剩,numbersize的值為128钾军,其中size的值為系統(tǒng)內(nèi)存頁一頁的大小,用getconf PAGESIZE來獲取

gunzip_static

開啟時绢要,如果客戶端瀏覽器不支持Gzip處理吏恭,Nginx服務(wù)器將返回解壓后的數(shù)據(jù),如果客戶端瀏覽器支持Gzip處理重罪,Nginx服務(wù)器忽略該指令設(shè)置樱哼。仍然返回壓縮數(shù)據(jù)。

gzip_types

Nginx服務(wù)器可以根據(jù)MIME類型選擇性開啟Gzip壓縮功能剿配。該指令涌來設(shè)置MIME類型搅幅。

轉(zhuǎn)載https://segmentfault.com/a/1190000011405320

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市呼胚,隨后出現(xiàn)的幾起案子茄唐,更是在濱河造成了極大的恐慌,老刑警劉巖蝇更,帶你破解...
    沈念sama閱讀 211,194評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件沪编,死亡現(xiàn)場離奇詭異呼盆,居然都是意外死亡,警方通過查閱死者的電腦和手機漾抬,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,058評論 2 385
  • 文/潘曉璐 我一進店門宿亡,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人纳令,你說我怎么就攤上這事挽荠。” “怎么了平绩?”我有些...
    開封第一講書人閱讀 156,780評論 0 346
  • 文/不壞的土叔 我叫張陵圈匆,是天一觀的道長。 經(jīng)常有香客問我捏雌,道長跃赚,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,388評論 1 283
  • 正文 為了忘掉前任性湿,我火速辦了婚禮纬傲,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘肤频。我一直安慰自己叹括,他們只是感情好,可當我...
    茶點故事閱讀 65,430評論 5 384
  • 文/花漫 我一把揭開白布宵荒。 她就那樣靜靜地躺著汁雷,像睡著了一般。 火紅的嫁衣襯著肌膚如雪报咳。 梳的紋絲不亂的頭發(fā)上侠讯,一...
    開封第一講書人閱讀 49,764評論 1 290
  • 那天,我揣著相機與錄音暑刃,去河邊找鬼厢漩。 笑死,一個胖子當著我的面吹牛岩臣,可吹牛的內(nèi)容都是我干的袁翁。 我是一名探鬼主播,決...
    沈念sama閱讀 38,907評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼婿脸,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了柄驻?” 一聲冷哼從身側(cè)響起狐树,我...
    開封第一講書人閱讀 37,679評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎鸿脓,沒想到半個月后抑钟,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體涯曲,經(jīng)...
    沈念sama閱讀 44,122評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,459評論 2 325
  • 正文 我和宋清朗相戀三年在塔,在試婚紗的時候發(fā)現(xiàn)自己被綠了幻件。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,605評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡蛔溃,死狀恐怖绰沥,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情贺待,我是刑警寧澤徽曲,帶...
    沈念sama閱讀 34,270評論 4 329
  • 正文 年R本政府宣布,位于F島的核電站麸塞,受9級特大地震影響秃臣,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜哪工,卻給世界環(huán)境...
    茶點故事閱讀 39,867評論 3 312
  • 文/蒙蒙 一奥此、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧雁比,春花似錦稚虎、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,734評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至鸭限,卻和暖如春蜕径,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背败京。 一陣腳步聲響...
    開封第一講書人閱讀 31,961評論 1 265
  • 我被黑心中介騙來泰國打工兜喻, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人赡麦。 一個月前我還...
    沈念sama閱讀 46,297評論 2 360
  • 正文 我出身青樓朴皆,卻偏偏與公主長得像,于是被迫代替她去往敵國和親泛粹。 傳聞我的和親對象是個殘疾皇子遂铡,可洞房花燭夜當晚...
    茶點故事閱讀 43,472評論 2 348

推薦閱讀更多精彩內(nèi)容

  • 寫在前面 最近在進行服務(wù)器的優(yōu)化,正好在看nginx相關(guān)的知識晶姊,所以把一些知識整理一下扒接。參考資料為《Nginx高性...
  • 寫在前面 最近在進行服務(wù)器的優(yōu)化,正好在看nginx相關(guān)的知識,所以把一些知識整理一下钾怔。參考資料為《Nginx高性...
    魔曦帝天閱讀 407評論 0 2
  • 內(nèi)核參數(shù)優(yōu)化 把如下的參數(shù)追加到Linux系統(tǒng)的/etc/sysctl.conf文件中碱呼,然后使用如下命令使修改生效...
    baker_dai閱讀 303評論 0 1
  • 轉(zhuǎn)載別人的文章,nginx調(diào)優(yōu)宗侦。鏈接如下:http://blog.csdn.net/xifeijian/artic...
    Alex_ct閱讀 949評論 0 1
  • 寧靜的早晨 周遭一片寂靜 慢跑的響動的腳步 驚嚇了早起的鳥兒 于是 便發(fā)出了清脆的回應(yīng) 偶爾 撲撲撲 飛上枝頭輕快...
    空谷幽蘭草閱讀 149評論 0 2