[code.nginx] Nginx服務(wù)器高級(jí)配置

針對(duì)IPv4的內(nèi)核7個(gè)參數(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)每個(gè)網(wǎng)絡(luò)接口接收數(shù)據(jù)包的速率比內(nèi)核處理這些包的速率快時(shí),允許發(fā)送到隊(duì)列的數(shù)據(jù)包的最大數(shù)目。一般默認(rèn)值為128(可能不同的Linux系統(tǒng)該數(shù)值也不同)。Nginx服務(wù)器中定義的NGX_LISTEN_BACKLOG默認(rèn)為511.我們可以將它調(diào)整一下:

net.core.netdev_max_backlog = 262144

** 2.net.core.somaxconn參數(shù) **
該參數(shù)用于調(diào)節(jié)系統(tǒng)同時(shí)發(fā)起的TCP連接數(shù),一般默認(rèn)值為128。在客戶(hù)端存在高并發(fā)請(qǐng)求的情況下,在默認(rèn)值較小,可能導(dǎo)致鏈接超時(shí)或者重傳問(wèn)題,我們可以根據(jù)實(shí)際需要結(jié)合并發(fā)請(qǐng)求數(shù)來(lái)調(diào)節(jié)此值。

net.core.somaxconn = 262144

** 3.net.ipv4.tcp_max_orphans參數(shù) **
該參數(shù)用于設(shè)定系統(tǒng)中最多允許存在多少TCP套接字不被關(guān)聯(lián)到任何一個(gè)用戶(hù)文件句柄上。如果超過(guò)這個(gè)數(shù)字,沒(méi)有與用戶(hù)文件句柄關(guān)聯(lián)的TCP套接字將立即被復(fù)位,同時(shí)給出警告信息。這個(gè)限制只是為了防止簡(jiǎn)單的DoS(Denial of Service,拒絕服務(wù))攻擊。一般在系統(tǒng)內(nèi)存比較充足的情況下,可以增大這個(gè)參數(shù)的賦值:

net.ipv4.tcp_max_orphans = 262144

** 4.net.ipv4.tcp_max_syn_backlog參數(shù) **
該參數(shù)用于記錄尚未收到客戶(hù)端確認(rèn)信息的連接請(qǐng)求的最大值。對(duì)于擁有128MB內(nèi)存的系統(tǒng)而言,此參數(shù)的默認(rèn)值是1024,對(duì)小內(nèi)存的系統(tǒng)則是128。一般在系統(tǒng)內(nèi)存比較充足的情況下,可以增加這個(gè)參數(shù)的賦值:

net.ipv4.tcp_max_syn_backlog = 262144

** 5.net.ipv4.tcp_timestamps參數(shù) **
該參數(shù)用于設(shè)置時(shí)間戳,這可以避免序列號(hào)的卷繞。在一個(gè)1Gb/s的鏈路上,遇到以前用過(guò)的序列號(hào)的概率很大。當(dāng)此值賦值為0時(shí),禁用對(duì)于TCP時(shí)間戳的支持。在默認(rèn)情況下,TCP協(xié)議會(huì)讓內(nèi)核接受這種“異常”的數(shù)據(jù)包。針對(duì)Nginx服務(wù)器來(lái)說(shuō),建議將其關(guān)閉:

net.ipv4.tcp_timestamps = 0

** 6.net.ipv4.tcp_synack_retries參數(shù) **
該參數(shù)用于設(shè)置內(nèi)核放棄TCP連接之前向客戶(hù)端發(fā)送SYN+ACK包的數(shù)量。為了建立對(duì)端的連接服務(wù),服務(wù)器和客戶(hù)端需要進(jìn)行三次握手,第二次握手期間,內(nèi)核需要發(fā)送SYN并附帶一個(gè)回應(yīng)前一個(gè)SYN的ACK,這個(gè)參數(shù)主要影響這個(gè)進(jìn)程,一般賦值為1,即內(nèi)核放棄連接之前發(fā)送一次SYN+ACK包,可以設(shè)置其為:

net.ipv4.tcp_synack_retries = 1

** 7.net.ipv4.tcp_syn_retries參數(shù) **
該參數(shù)的作用和上一個(gè)參數(shù)類(lèi)似,設(shè)置內(nèi)核放棄建立連接之前發(fā)送SYN包的數(shù)量,它的賦值和上個(gè)參數(shù)一樣即可:

net.ipv4.tcp_syn_retries = 1

針對(duì)CPU的Nginx配置優(yōu)化的2個(gè)指令

在Nginx配置文件中,有這樣兩個(gè)指令:worker_processes和worker_cpu_affinity,它們可以針對(duì)多核CPU進(jìn)行配置優(yōu)化。
** 1.worker_processes指令 **
worker_processes指令用來(lái)設(shè)置Nginx服務(wù)的進(jìn)程數(shù)。官方文檔建議此指令一般設(shè)置為1即可,賦值太多會(huì)影響系統(tǒng)的IO效率,降低Nginx服務(wù)器的性能。為了讓多核CPU能夠很好的并行處理任務(wù),我們可以將worker_processes指令的賦值適當(dāng)?shù)脑龃笠恍詈檬琴x值為機(jī)器CPU的倍數(shù)。當(dāng)然,這個(gè)值并不是越大越好,Nginx進(jìn)程太多可能增加主進(jìn)程調(diào)度負(fù)擔(dān),也可能影響系統(tǒng)的IO效率。針對(duì)雙核CPU,建議設(shè)置為2或
4。如果是四核CPU,設(shè)置為:

worker_processes 4;

設(shè)置好worker_processes指令之后,就很有必要設(shè)置worker_cpu_affinity指令。

** 2. worker_cpu_affinity指令 **
worker_cpu_affinity指令用來(lái)為每個(gè)進(jìn)程分配CPU的工作內(nèi)核。這個(gè)指令用來(lái)為每個(gè)進(jìn)程分配CPU的工作內(nèi)核。這個(gè)指令的設(shè)置方法有些麻煩。
如下圖所示:


worker_cpu_affinity指令

worker_cpu_affinity指令的值是由幾組二進(jìn)制值表示的。其中,每一組代表一個(gè)進(jìn)程,每組中的每一位表示該進(jìn)程使用CPU的情況,1表示使用,0表示不使用。注意,二進(jìn)制位排列順序和CPU的順序是相反的。建議將不同的進(jìn)程平均分配到不同的CPU運(yùn)行內(nèi)核上。
如果設(shè)置的Nginx服務(wù)的進(jìn)程數(shù)為4,CPU為4核,因此會(huì)有四組值,并且每組有四位,所以,此指令的設(shè)置為:

worker_cpu_affinity 0001 0100 1000 0010;

四組二進(jìn)制數(shù)值分別對(duì)應(yīng)4個(gè)進(jìn)程,第一個(gè)進(jìn)程對(duì)應(yīng)0001,表示使用第一個(gè)CPU內(nèi)核。第二個(gè)進(jìn)程對(duì)應(yīng)0010,表示使用第二個(gè)CPU內(nèi)核,以此類(lèi)推。
如果將worker_processes指令的值賦值為8,即賦值為CPU內(nèi)核個(gè)數(shù)的兩倍,則worker_cpu_affinity指令的設(shè)置可以是:

worker_cup_affinity 001 0010 0100 1000 0001 0010 0100 1000;

如果一臺(tái)機(jī)器的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個(gè)指令

** 1.keepalive_timeout指令 **
該指令用于設(shè)置Nginx服務(wù)器與客戶(hù)端保持連接的超時(shí)時(shí)間。
這個(gè)指令支持兩個(gè)選項(xiàng),中間用空格隔開(kāi)。第一個(gè)選項(xiàng)指定客戶(hù)端連接保持活動(dòng)的超時(shí)時(shí)間,在這個(gè)時(shí)間之后,服務(wù)器會(huì)關(guān)閉此連接。第二個(gè)選項(xiàng)可選,其指定了使用Keep-Alive消息頭保持活動(dòng)的有效時(shí)間,如果不設(shè)置它,Nginx服務(wù)器不會(huì)向客戶(hù)端發(fā)送Keep-Alive消息頭以保持與客戶(hù)端某些瀏覽器(如Mozilla、Konqueror等)的連接,超過(guò)設(shè)置的時(shí)間后,客戶(hù)端就可以關(guān)閉連接,而不需要服務(wù)器關(guān)閉了。你可以根據(jù)自己的實(shí)際情況設(shè)置此值,建議從服務(wù)器的訪(fǎng)問(wèn)數(shù)量、處理速度以及網(wǎng)絡(luò)狀態(tài)方面考慮。下面是此指令的設(shè)置示例:

keepalive_timeout 60 50;

該設(shè)置表示Nginx服務(wù)器與客戶(hù)端連接保持活動(dòng)的時(shí)間是60s,60s后服務(wù)器與客戶(hù)端斷開(kāi)連接。使用Keep-Alive消息頭保持與客戶(hù)端某些瀏覽器(如Mozilla、Konqueror等)的連接時(shí)間為50s,50s后瀏覽器主動(dòng)與服務(wù)器斷開(kāi)連接。

** 2.send_timeout指令 **
該指令用于設(shè)置Nginx服務(wù)器響應(yīng)客戶(hù)端的超時(shí)時(shí)間,這個(gè)超時(shí)時(shí)間僅針對(duì)兩個(gè)客戶(hù)端和服務(wù)器之間建立連接后,某次活動(dòng)之間的時(shí)間。如果這個(gè)時(shí)間后客戶(hù)端沒(méi)有任何活動(dòng),Nginx服務(wù)器將會(huì)關(guān)閉連接。此指令的設(shè)置需要考慮服務(wù)器訪(fǎng)問(wèn)數(shù)量和網(wǎng)絡(luò)狀況等方面。下面是此指令的設(shè)置示例:

send_timeout 10s;

該設(shè)置表示Nginx服務(wù)器與客戶(hù)端建立連接后,某次會(huì)話(huà)中服務(wù)器等待客戶(hù)端響應(yīng)超時(shí)10s,就會(huì)自動(dòng)關(guān)閉連接。

** 3.client_header_buffer_size指令 **
該指令用于設(shè)置Nginx服務(wù)器允許的客戶(hù)端請(qǐng)求頭部的緩沖區(qū)大小,默認(rèn)為1KB。此指令的賦值可以根據(jù)系統(tǒng)分頁(yè)大小來(lái)設(shè)置。分頁(yè)大小可以用以下命令取得:

#getconf PAGESIZE

有過(guò)Nginx服務(wù)器工作經(jīng)驗(yàn)的可能遇到Nginx服務(wù)器返回400錯(cuò)誤的情況。查找Nginx服務(wù)器的400錯(cuò)誤原因比較困難,因?yàn)榇隋e(cuò)誤并不是每次都會(huì)出現(xiàn),出現(xiàn)錯(cuò)誤的時(shí)候,通常在瀏覽器和日志里也看不到任何有關(guān)提示信息。根據(jù)實(shí)際的經(jīng)驗(yàn)來(lái)看,有很大一部分情況是客戶(hù)端的請(qǐng)求頭部過(guò)大造成的。請(qǐng)求頭部過(guò)大,通常是客戶(hù)單cookie中寫(xiě)入了較大的值引起的。于是適當(dāng)增大此指令的賦值,允許Nginx服務(wù)器接收較大的請(qǐng)求頭部,可以改善服務(wù)器對(duì)客戶(hù)端的支持能力。一般將此指令賦值為4KB大小,即:

client_header_buffer_size 4k;

** 4.multi_accept指令 **
該指令用于配置Nginx服務(wù)器是否盡可能多的接收客戶(hù)端的網(wǎng)絡(luò)連接請(qǐng)求,默認(rèn)值為off。

與事件驅(qū)動(dòng)模型相關(guān)的配置的8個(gè)指令

本節(jié)涉及的指令與Nginx服務(wù)器的事件驅(qū)動(dòng)模型密切相關(guān)。

  1. use指令
    use指令用于指定Nginx服務(wù)器使用的事件驅(qū)動(dòng)模型。
  2. worker_connections指令
    該指令用于設(shè)置Nginx服務(wù)器的每個(gè)工作進(jìn)程允許同時(shí)連接客戶(hù)端的最大數(shù)量,語(yǔ)法為:
worker_connections number

其中,number為設(shè)置的最大數(shù)量。結(jié)合worker_processes指令,我們可以計(jì)算出Nginx服務(wù)器允許同時(shí)連接的客戶(hù)端最大數(shù)量Client = worker_processes * worker_connections / 2;
在使用Nginx服務(wù)器的過(guò)程中,筆者曾經(jīng)遇到過(guò)無(wú)法訪(fǎng)問(wèn)Nginx服務(wù)器的情況,查看日志發(fā)現(xiàn)一直在報(bào)如下錯(cuò)誤:

[alert] 24082#0: 1024 worker_connections is not enough while accepting new connection on 0.0.0.:01

根據(jù)報(bào)錯(cuò)信息,推測(cè)可能是Nginx服務(wù)器的最大訪(fǎng)問(wèn)連接數(shù)設(shè)置小了。此指令設(shè)置的就是Nginx服務(wù)器能接受的最大訪(fǎng)問(wèn)量,其中包括前端用戶(hù)連接也包括其他連接,這個(gè)值在理論上等于此指令的值與它允許開(kāi)啟的工作進(jìn)程最大數(shù)的乘積。此指令一般設(shè)置為65535:

worker_connections 65535;

此指令的賦值與linux操作系統(tǒng)中進(jìn)程可以打開(kāi)的文件句柄數(shù)量有關(guān)系。按照以上設(shè)置修改此項(xiàng)賦值以后,Nginx服務(wù)器報(bào)以下錯(cuò)誤:

[warn]: 8192 worker_connections are more than open file resource limit:1024

究其原因,Linux系統(tǒng)中有一個(gè)系統(tǒng)指令open file resource limit,它設(shè)置了進(jìn)程可以打開(kāi)的文件句柄數(shù)量。worker_connections指令的賦值當(dāng)然不能超過(guò)open file resource limit的賦值??梢允褂靡韵旅畈榭丛谀愕腖inux系統(tǒng)中open file resource limit的賦值。

# cat /proc/sys/fs/file-max

可以通過(guò)一下命令將open file resource limit指令的值設(shè)為2390251:

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

這樣,Nginx的worker_connections指令賦值為65535就沒(méi)問(wèn)題了。

  1. worker_rlimit_sigpending指令
    該指令用于設(shè)置Linux 2.6.6-mm2版本之后Linux平臺(tái)的事件信號(hào)隊(duì)列長(zhǎng)度上線(xiàn)。其語(yǔ)法結(jié)構(gòu)為:
worker_rlimit_sigpending limit

其中,limit為L(zhǎng)inux平臺(tái)事件信號(hào)隊(duì)列的長(zhǎng)度上限值。
該指令主要影響事件驅(qū)動(dòng)模型中rfsig模型可以保存的最大信號(hào)數(shù)。Nginx服務(wù)器的每一個(gè)工作進(jìn)程有自己的事件信號(hào)隊(duì)列用于暫存客戶(hù)端請(qǐng)求發(fā)生信號(hào),如果超過(guò)長(zhǎng)度上線(xiàn),Nginx服務(wù)器自動(dòng)轉(zhuǎn)用poll模型處理未處理器的客戶(hù)端請(qǐng)求。為了保證Nginx服務(wù)器對(duì)客戶(hù)端請(qǐng)求的高效處理,請(qǐng)大家根據(jù)實(shí)際的客戶(hù)端并發(fā)請(qǐng)求數(shù)量和服務(wù)器運(yùn)行環(huán)境的處理能力設(shè)定該值。設(shè)置示例為:

worker_rlimit_sigpending 1024;
  1. devpoll_changes和devpoll_events指令
    這兩個(gè)指令用于設(shè)置在/dev/poll事件驅(qū)動(dòng)模式下Nginx服務(wù)器可以與內(nèi)核之間傳遞事件的數(shù)量,前者設(shè)置傳遞給內(nèi)核的事件數(shù)量,后者設(shè)置從內(nèi)核獲取的事件數(shù)量,語(yǔ)法結(jié)構(gòu)為:
devpoll_changes number
devpoll_events number

其中,number為要設(shè)置的數(shù)量,默認(rèn)值均為32。

  1. kqueue_changes和kqueue_events指令
    這兩個(gè)指令用于設(shè)置在kqueue事件驅(qū)動(dòng)模式下Nginx服務(wù)器可以與內(nèi)核之間傳遞事件的數(shù)量,前者設(shè)置傳遞給內(nèi)核的事件數(shù)量,后者設(shè)置從內(nèi)核獲取的事件數(shù)量,其語(yǔ)法結(jié)構(gòu)為:
kqueue_changes number
kqueue_events number

其中,number為要設(shè)置的數(shù)量,默認(rèn)值均為512.
使用kequeue_changes方式,可以設(shè)置與內(nèi)核之間傳遞事件的數(shù)量。

  1. epoll_events指令
    該指令用于設(shè)置在epoll事件驅(qū)動(dòng)模式下Nginx服務(wù)器可以與內(nèi)核之間傳遞事件的數(shù)量,其語(yǔ)法結(jié)構(gòu)為:
epoll_changes number

其中,number為要設(shè)置的數(shù)量,默認(rèn)值均為512。

注意
與其他事件驅(qū)動(dòng)模型不同,在epoll事件驅(qū)動(dòng)模式下Nginx服務(wù)器向內(nèi)核傳遞事件的數(shù)量和從內(nèi)核傳遞的事件數(shù)量是相等的,因此沒(méi)有類(lèi)似epoll_changes這樣的指令。

7.rtsig_signo指令
該指令用于設(shè)置rtsig模式使用的兩個(gè)信號(hào)中的第一個(gè),第二個(gè)信號(hào)是在第一個(gè)信號(hào)的編號(hào)上加1,語(yǔ)法為:

rtsig_signo signo

默認(rèn)的第一個(gè)信號(hào)設(shè)置為SIGRTMIN+10。

提示
在Linux中可以使用一下命令查看系統(tǒng)支持的SIGRTMIN有哪些。

kill -l | grep SIGRTMIN

8.rtsig_overflow_* 指令
該指令代表三個(gè)具體的指令,分別為rtsig_overflow_events指令、rtsig_overflow_test指令和rtsig_overflow_threshold指令。這些指令用來(lái)控制當(dāng)rtsig模式中信號(hào)隊(duì)列溢出時(shí)Nginx服務(wù)器的處理方式,語(yǔ)法結(jié)構(gòu)為:

rtsig_overflow_* number

其中,number是要設(shè)定的值。
rtsig_overflow_events指令指定隊(duì)列溢出時(shí)使用poll庫(kù)處理的事件數(shù),默認(rèn)值為16。
rtsig_overflow_test指令設(shè)定poll庫(kù)處理完第幾件事件后將清空rtsig模型使用的信號(hào)隊(duì)列,默認(rèn)值為32。

rtsig_overflow_threshold指令指定rtsig模式使用的信號(hào)隊(duì)列中的事件超過(guò)多少時(shí)就需要清空隊(duì)列了。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容