針對IPv4的內(nèi)核7個參數(shù)的配置優(yōu)化
這里提及的參數(shù)是和IPv4網(wǎng)絡(luò)有關(guān)的Linux內(nèi)核參數(shù)。我們可以將這些內(nèi)核參數(shù)的值追加到Linux系統(tǒng)的/etc/sysctl.conf文件中,然后使用如下命令使修改生效:
#/sbin/sysctl -p
這些常用的參數(shù)包括以下這些沟蔑。
** 1. net.core.netdev_max_backlog參數(shù) **
net.core.netdev_max_backlog浸锨,表示當(dāng)每個網(wǎng)絡(luò)接口接收數(shù)據(jù)包的速率比內(nèi)核處理這些包的速率快時撞牢,允許發(fā)送到隊列的數(shù)據(jù)包的最大數(shù)目。一般默認值為128(可能不同的Linux系統(tǒng)該數(shù)值也不同)臼闻。Nginx服務(wù)器中定義的NGX_LISTEN_BACKLOG默認為511.我們可以將它調(diào)整一下:
net.core.netdev_max_backlog = 262144
** 2.net.core.somaxconn參數(shù) **
該參數(shù)用于調(diào)節(jié)系統(tǒng)同時發(fā)起的TCP連接數(shù)读恃,一般默認值為128隧膘。在客戶端存在高并發(fā)請求的情況下,在默認值較小寺惫,可能導(dǎo)致鏈接超時或者重傳問題疹吃,我們可以根據(jù)實際需要結(jié)合并發(fā)請求數(shù)來調(diào)節(jié)此值。
net.core.somaxconn = 262144
** 3.net.ipv4.tcp_max_orphans參數(shù) **
該參數(shù)用于設(shè)定系統(tǒng)中最多允許存在多少TCP套接字不被關(guān)聯(lián)到任何一個用戶文件句柄上肌蜻。如果超過這個數(shù)字互墓,沒有與用戶文件句柄關(guān)聯(lián)的TCP套接字將立即被復(fù)位必尼,同時給出警告信息蒋搜。這個限制只是為了防止簡單的DoS(Denial of Service篡撵,拒絕服務(wù))攻擊。一般在系統(tǒng)內(nèi)存比較充足的情況下豆挽,可以增大這個參數(shù)的賦值:
net.ipv4.tcp_max_orphans = 262144
** 4.net.ipv4.tcp_max_syn_backlog參數(shù) **
該參數(shù)用于記錄尚未收到客戶端確認信息的連接請求的最大值育谬。對于擁有128MB內(nèi)存的系統(tǒng)而言,此參數(shù)的默認值是1024帮哈,對小內(nèi)存的系統(tǒng)則是128膛檀。一般在系統(tǒng)內(nèi)存比較充足的情況下,可以增加這個參數(shù)的賦值:
net.ipv4.tcp_max_syn_backlog = 262144
** 5.net.ipv4.tcp_timestamps參數(shù) **
該參數(shù)用于設(shè)置時間戳娘侍,這可以避免序列號的卷繞咖刃。在一個1Gb/s的鏈路上,遇到以前用過的序列號的概率很大憾筏。當(dāng)此值賦值為0時嚎杨,禁用對于TCP時間戳的支持。在默認情況下氧腰,TCP協(xié)議會讓內(nèi)核接受這種“異撤阏悖”的數(shù)據(jù)包。針對Nginx服務(wù)器來說古拴,建議將其關(guān)閉:
net.ipv4.tcp_timestamps = 0
** 6.net.ipv4.tcp_synack_retries參數(shù) **
該參數(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包,可以設(shè)置其為:
net.ipv4.tcp_synack_retries = 1
** 7.net.ipv4.tcp_syn_retries參數(shù) **
該參數(shù)的作用和上一個參數(shù)類似油额,設(shè)置內(nèi)核放棄建立連接之前發(fā)送SYN包的數(shù)量叠纷,它的賦值和上個參數(shù)一樣即可:
net.ipv4.tcp_syn_retries = 1
針對CPU的Nginx配置優(yōu)化的2個指令
在Nginx配置文件中,有這樣兩個指令:worker_processes和worker_cpu_affinity潦嘶,它們可以針對多核CPU進行配置優(yōu)化涩嚣。
** 1.worker_processes指令 **
worker_processes指令用來設(shè)置Nginx服務(wù)的進程數(shù)。官方文檔建議此指令一般設(shè)置為1即可掂僵,賦值太多會影響系統(tǒng)的IO效率航厚,降低Nginx服務(wù)器的性能。為了讓多核CPU能夠很好的并行處理任務(wù)锰蓬,我們可以將worker_processes指令的賦值適當(dāng)?shù)脑龃笠恍┽2牵詈檬琴x值為機器CPU的倍數(shù)。當(dāng)然芹扭,這個值并不是越大越好麻顶,Nginx進程太多可能增加主進程調(diào)度負擔(dān)赦抖,也可能影響系統(tǒng)的IO效率。針對雙核CPU辅肾,建議設(shè)置為2或
4队萤。如果是四核CPU,設(shè)置為:
worker_processes 4;
設(shè)置好worker_processes指令之后矫钓,就很有必要設(shè)置worker_cpu_affinity指令要尔。
** 2. worker_cpu_affinity指令 **
worker_cpu_affinity指令用來為每個進程分配CPU的工作內(nèi)核。這個指令用來為每個進程分配CPU的工作內(nèi)核新娜。這個指令的設(shè)置方法有些麻煩赵辕。
如下圖所示:
worker_cpu_affinity指令的值是由幾組二進制值表示的。其中概龄,每一組代表一個進程匆帚,每組中的每一位表示該進程使用CPU的情況,1表示使用旁钧,0表示不使用吸重。注意,二進制位排列順序和CPU的順序是相反的歪今。建議將不同的進程平均分配到不同的CPU運行內(nèi)核上嚎幸。
如果設(shè)置的Nginx服務(wù)的進程數(shù)為4,CPU為4核寄猩,因此會有四組值嫉晶,并且每組有四位,所以田篇,此指令的設(shè)置為:
worker_cpu_affinity 0001 0100 1000 0010;
四組二進制數(shù)值分別對應(yīng)4個進程替废,第一個進程對應(yīng)0001,表示使用第一個CPU內(nèi)核泊柬。第二個進程對應(yīng)0010椎镣,表示使用第二個CPU內(nèi)核,以此類推兽赁。
如果將worker_processes指令的值賦值為8状答,即賦值為CPU內(nèi)核個數(shù)的兩倍,則worker_cpu_affinity指令的設(shè)置可以是:
worker_cup_affinity 001 0010 0100 1000 0001 0010 0100 1000;
如果一臺機器的CPU是八核CPU刀崖,并且worker_processes指令的值賦值為8惊科,那么worker_cpu_affinity指令的設(shè)置可以是:
worker_cpu_affinity 0000001 00000010 00000100 00001000 00010000 00100000 01000000 10000000;
與網(wǎng)絡(luò)連接相關(guān)的配置的4個指令
** 1.keepalive_timeout指令 **
該指令用于設(shè)置Nginx服務(wù)器與客戶端保持連接的超時時間。
這個指令支持兩個選項亮钦,中間用空格隔開馆截。第一個選項指定客戶端連接保持活動的超時時間,在這個時間之后蜂莉,服務(wù)器會關(guān)閉此連接蜡娶。第二個選項可選堪唐,其指定了使用Keep-Alive消息頭保持活動的有效時間,如果不設(shè)置它翎蹈,Nginx服務(wù)器不會向客戶端發(fā)送Keep-Alive消息頭以保持與客戶端某些瀏覽器(如Mozilla、Konqueror等)的連接男公,超過設(shè)置的時間后荤堪,客戶端就可以關(guān)閉連接,而不需要服務(wù)器關(guān)閉了枢赔。你可以根據(jù)自己的實際情況設(shè)置此值澄阳,建議從服務(wù)器的訪問數(shù)量、處理速度以及網(wǎng)絡(luò)狀態(tài)方面考慮踏拜。下面是此指令的設(shè)置示例:
keepalive_timeout 60 50;
該設(shè)置表示Nginx服務(wù)器與客戶端連接保持活動的時間是60s碎赢,60s后服務(wù)器與客戶端斷開連接。使用Keep-Alive消息頭保持與客戶端某些瀏覽器(如Mozilla速梗、Konqueror等)的連接時間為50s肮塞,50s后瀏覽器主動與服務(wù)器斷開連接。
** 2.send_timeout指令 **
該指令用于設(shè)置Nginx服務(wù)器響應(yīng)客戶端的超時時間姻锁,這個超時時間僅針對兩個客戶端和服務(wù)器之間建立連接后枕赵,某次活動之間的時間。如果這個時間后客戶端沒有任何活動位隶,Nginx服務(wù)器將會關(guān)閉連接拷窜。此指令的設(shè)置需要考慮服務(wù)器訪問數(shù)量和網(wǎng)絡(luò)狀況等方面。下面是此指令的設(shè)置示例:
send_timeout 10s;
該設(shè)置表示Nginx服務(wù)器與客戶端建立連接后涧黄,某次會話中服務(wù)器等待客戶端響應(yīng)超時10s篮昧,就會自動關(guān)閉連接。
** 3.client_header_buffer_size指令 **
該指令用于設(shè)置Nginx服務(wù)器允許的客戶端請求頭部的緩沖區(qū)大小笋妥,默認為1KB懊昨。此指令的賦值可以根據(jù)系統(tǒng)分頁大小來設(shè)置。分頁大小可以用以下命令取得:
#getconf PAGESIZE
有過Nginx服務(wù)器工作經(jīng)驗的可能遇到Nginx服務(wù)器返回400錯誤的情況春宣。查找Nginx服務(wù)器的400錯誤原因比較困難疚颊,因為此錯誤并不是每次都會出現(xiàn),出現(xiàn)錯誤的時候信认,通常在瀏覽器和日志里也看不到任何有關(guān)提示信息材义。根據(jù)實際的經(jīng)驗來看,有很大一部分情況是客戶端的請求頭部過大造成的嫁赏。請求頭部過大其掂,通常是客戶單cookie中寫入了較大的值引起的。于是適當(dāng)增大此指令的賦值潦蝇,允許Nginx服務(wù)器接收較大的請求頭部款熬,可以改善服務(wù)器對客戶端的支持能力深寥。一般將此指令賦值為4KB大小,即:
client_header_buffer_size 4k;
** 4.multi_accept指令 **
該指令用于配置Nginx服務(wù)器是否盡可能多的接收客戶端的網(wǎng)絡(luò)連接請求贤牛,默認值為off惋鹅。
與事件驅(qū)動模型相關(guān)的配置的8個指令
本節(jié)涉及的指令與Nginx服務(wù)器的事件驅(qū)動模型密切相關(guān)。
- use指令
use指令用于指定Nginx服務(wù)器使用的事件驅(qū)動模型殉簸。 - worker_connections指令
該指令用于設(shè)置Nginx服務(wù)器的每個工作進程允許同時連接客戶端的最大數(shù)量闰集,語法為:
worker_connections number
其中,number為設(shè)置的最大數(shù)量般卑。結(jié)合worker_processes指令武鲁,我們可以計算出Nginx服務(wù)器允許同時連接的客戶端最大數(shù)量Client = worker_processes * worker_connections / 2;
在使用Nginx服務(wù)器的過程中,筆者曾經(jīng)遇到過無法訪問Nginx服務(wù)器的情況蝠检,查看日志發(fā)現(xiàn)一直在報如下錯誤:
[alert] 24082#0: 1024 worker_connections is not enough while accepting new connection on 0.0.0.:01
根據(jù)報錯信息沐鼠,推測可能是Nginx服務(wù)器的最大訪問連接數(shù)設(shè)置小了。此指令設(shè)置的就是Nginx服務(wù)器能接受的最大訪問量叹谁,其中包括前端用戶連接也包括其他連接饲梭,這個值在理論上等于此指令的值與它允許開啟的工作進程最大數(shù)的乘積。此指令一般設(shè)置為65535:
worker_connections 65535;
此指令的賦值與linux操作系統(tǒng)中進程可以打開的文件句柄數(shù)量有關(guān)系焰檩。按照以上設(shè)置修改此項賦值以后排拷,Nginx服務(wù)器報以下錯誤:
[warn]: 8192 worker_connections are more than open file resource limit:1024
究其原因,Linux系統(tǒng)中有一個系統(tǒng)指令open file resource limit锅尘,它設(shè)置了進程可以打開的文件句柄數(shù)量监氢。worker_connections指令的賦值當(dāng)然不能超過open file resource limit的賦值√傥ィ可以使用以下命令查看在你的Linux系統(tǒng)中open file resource limit的賦值浪腐。
# cat /proc/sys/fs/file-max
可以通過一下命令將open file resource limit指令的值設(shè)為2390251:
#echo "2390251" > /proc/sys/fs/file-max;sysctl -p
這樣,Nginx的worker_connections指令賦值為65535就沒問題了顿乒。
- worker_rlimit_sigpending指令
該指令用于設(shè)置Linux 2.6.6-mm2版本之后Linux平臺的事件信號隊列長度上線议街。其語法結(jié)構(gòu)為:
worker_rlimit_sigpending limit
其中,limit為Linux平臺事件信號隊列的長度上限值璧榄。
該指令主要影響事件驅(qū)動模型中rfsig模型可以保存的最大信號數(shù)特漩。Nginx服務(wù)器的每一個工作進程有自己的事件信號隊列用于暫存客戶端請求發(fā)生信號,如果超過長度上線骨杂,Nginx服務(wù)器自動轉(zhuǎn)用poll模型處理未處理器的客戶端請求涂身。為了保證Nginx服務(wù)器對客戶端請求的高效處理,請大家根據(jù)實際的客戶端并發(fā)請求數(shù)量和服務(wù)器運行環(huán)境的處理能力設(shè)定該值搓蚪。設(shè)置示例為:
worker_rlimit_sigpending 1024;
- devpoll_changes和devpoll_events指令
這兩個指令用于設(shè)置在/dev/poll事件驅(qū)動模式下Nginx服務(wù)器可以與內(nèi)核之間傳遞事件的數(shù)量蛤售,前者設(shè)置傳遞給內(nèi)核的事件數(shù)量,后者設(shè)置從內(nèi)核獲取的事件數(shù)量,語法結(jié)構(gòu)為:
devpoll_changes number
devpoll_events number
其中悴能,number為要設(shè)置的數(shù)量揣钦,默認值均為32。
- kqueue_changes和kqueue_events指令
這兩個指令用于設(shè)置在kqueue事件驅(qū)動模式下Nginx服務(wù)器可以與內(nèi)核之間傳遞事件的數(shù)量漠酿,前者設(shè)置傳遞給內(nèi)核的事件數(shù)量冯凹,后者設(shè)置從內(nèi)核獲取的事件數(shù)量,其語法結(jié)構(gòu)為:
kqueue_changes number
kqueue_events number
其中炒嘲,number為要設(shè)置的數(shù)量宇姚,默認值均為512.
使用kequeue_changes方式,可以設(shè)置與內(nèi)核之間傳遞事件的數(shù)量摸吠。
- epoll_events指令
該指令用于設(shè)置在epoll事件驅(qū)動模式下Nginx服務(wù)器可以與內(nèi)核之間傳遞事件的數(shù)量,其語法結(jié)構(gòu)為:
epoll_changes number
其中嚎花,number為要設(shè)置的數(shù)量寸痢,默認值均為512。
注意
與其他事件驅(qū)動模型不同紊选,在epoll事件驅(qū)動模式下Nginx服務(wù)器向內(nèi)核傳遞事件的數(shù)量和從內(nèi)核傳遞的事件數(shù)量是相等的啼止,因此沒有類似epoll_changes這樣的指令。
7.rtsig_signo指令
該指令用于設(shè)置rtsig模式使用的兩個信號中的第一個兵罢,第二個信號是在第一個信號的編號上加1献烦,語法為:
rtsig_signo signo
默認的第一個信號設(shè)置為SIGRTMIN+10。
提示
在Linux中可以使用一下命令查看系統(tǒng)支持的SIGRTMIN有哪些卖词。
kill -l | grep SIGRTMIN
8.rtsig_overflow_* 指令
該指令代表三個具體的指令巩那,分別為rtsig_overflow_events指令、rtsig_overflow_test指令和rtsig_overflow_threshold指令此蜈。這些指令用來控制當(dāng)rtsig模式中信號隊列溢出時Nginx服務(wù)器的處理方式即横,語法結(jié)構(gòu)為:
rtsig_overflow_* number
其中,number是要設(shè)定的值裆赵。
rtsig_overflow_events指令指定隊列溢出時使用poll庫處理的事件數(shù)东囚,默認值為16。
rtsig_overflow_test指令設(shè)定poll庫處理完第幾件事件后將清空rtsig模型使用的信號隊列战授,默認值為32页藻。
rtsig_overflow_threshold指令指定rtsig模式使用的信號隊列中的事件超過多少時就需要清空隊列了。