前言:
1:介紹下linux內(nèi)核的整個(gè)知識體系,(學(xué)會它,你肯定對linux內(nèi)核有不一樣的理解。)
2:談?wù)凩inux內(nèi)核參數(shù)優(yōu)化

一:linux內(nèi)核技術(shù)點(diǎn)
Linux內(nèi)核知識體系分為五個(gè)部分
1:linux內(nèi)核開發(fā)環(huán)境搭建
linux內(nèi)核研習(xí)與項(xiàng)目實(shí)戰(zhàn)專欄介紹
linux內(nèi)核編譯與升級
linux內(nèi)核學(xué)習(xí)方法
2:跨越進(jìn)程的障礙,實(shí)現(xiàn)進(jìn)程通信(一)
進(jìn)程間6種通信方式
多個(gè)進(jìn)程之間通信,如何實(shí)現(xiàn)通信組件
內(nèi)核模塊操作
進(jìn)程通信組件,架構(gòu)實(shí)現(xiàn)
系統(tǒng)調(diào)用的過程剖析
3:跨越進(jìn)程的障礙,實(shí)現(xiàn)進(jìn)程通信(二)
主次設(shè)備號與private-data的作用
insmod與模塊初始化的流程
模塊open的流程
rmmod與模塊退出的流程
模塊write的流程與實(shí)現(xiàn)
poll的實(shí)現(xiàn)原理與等待隊(duì)列wait-queue
模塊編譯與Makefile編寫
4:網(wǎng)卡驅(qū)動的實(shí)現(xiàn)
內(nèi)核模塊安裝與mknod
應(yīng)用程序編程與內(nèi)核模塊調(diào)試
Docker的虛擬網(wǎng)卡與網(wǎng)卡的作用
網(wǎng)卡作用于網(wǎng)卡驅(qū)動的運(yùn)行環(huán)境
如何設(shè)計(jì)適配市面上網(wǎng)卡的nic子系統(tǒng)
nic網(wǎng)卡驅(qū)動的架構(gòu)實(shí)現(xiàn)
nic網(wǎng)卡驅(qū)動的recv與sk-buff
nic網(wǎng)卡初始化與原理分析
nic網(wǎng)卡open與stop實(shí)現(xiàn)
5:最后自主思考項(xiàng)目
nic的編譯與自主思考題,用戶態(tài)協(xié)議棧
Linux內(nèi)核參數(shù)優(yōu)化
調(diào)整參數(shù)和不調(diào)整差別非常大,默認(rèn)參數(shù)都設(shè)置比較小,在大并發(fā),高負(fù)載時(shí)基本不能滿足。調(diào)整之后,問題基本解決。
vi /etc/sysctl.conf 編輯sysctl.conf
net.ipv4.ip_local_port_range = 1024 65000
net.ipv4.tcp_timestamps=1
kernel.core_uses_pid = 1
net.ipv4.tcp_syncookies=1
net.ipv4.tcp_syn_retries=1
net.ipv4.tcp_synack_retries=1
net.ipv4.tcp_tw_recycle=1
net.ipv4.tcp_tw_reuse=1
net.ipv4.tcp_fin_timeout=5
net.ipv4.route.gc_timeout=20
net.ipv4.tcp_keepalive_time=20
net.ipv4.tcp_max_syn_backlog= 655360
net.ipv4.ip_conntrack_max = 655360
先簡單介紹下 背景吧
通 過webbench壓Nginx+memcache時(shí),被壓的服務(wù)器nginx,memcache的cpu使用非常低,而且服務(wù)器負(fù)載也很小,但是 webbench的結(jié)果卻不樂觀,失敗非常多,通過分析,壓力根本沒到nginx和memcache,可能在服務(wù)器級就擋住了壓力,并且發(fā)現(xiàn)/var /log/message里面有關(guān)于ip_conntrack_max(一個(gè)連接hash表)滿了的報(bào)錯(cuò),然后順藤摸瓜,通過查看linux的man tcp 手冊,一個(gè)參數(shù)一個(gè)參數(shù)的研究,終于總結(jié)了上面的一些配置,解決了問題。
現(xiàn)象:/var/log/message里面有關(guān)于ip_conntrack_max 如ip_conntrack: table full, dropping packet.
解決方法:
觀察鏈接跟蹤表是(/proc/net/ip_conntrack)
IP_conntrack 表示連接跟蹤數(shù)據(jù)庫(conntrack database),代表NAT機(jī)器跟蹤連接的數(shù)目,連接跟蹤表能容納多少記錄是被一個(gè)變量控制的,他可由內(nèi)核中的ip- sysctl函數(shù)配置。每一個(gè)跟蹤連接表會占用350字節(jié)的內(nèi)核存儲空間,時(shí)間一長就會把默認(rèn)的空間填滿,那么默認(rèn)是間是多少?我以redhat為例在內(nèi) 存為64MB的機(jī)器上時(shí)4096,內(nèi)存為128MB是 8192,內(nèi)存為256MB是16376,那末就能在/proc/sys/net/ipv4/ip_conntrack_max里查看、配置。
針對于我們的業(yè)務(wù)模式,比較重要的是
net.ipv4.ip_local_port_range = 1024 65000 表示用于向外連接的端口范圍。缺省情況下很小:32768到61000,改為1024到65000。
net.ipv4.tcp_tw_reuse = 1 表示開啟重用。允許將TIME-WAIT sockets重新用于新的TCP連接,默認(rèn)為0,表示關(guān)閉;
net.ipv4.tcp_tw_recycle = 1 表示開啟TCP連接中TIME-WAIT sockets的快速回收,默認(rèn)為0,表示關(guān)閉。
net.ipv4.ip_conntrack_max = 655360
net.ipv4.netfilter.ip_conntrack_tcp_timeout_established = 21600
這個(gè)值是控制 紅色數(shù)字 這個(gè)時(shí)間的,其他相關(guān)參數(shù)都在/proc/sys/net/ipv4/netfilter目錄下
cat /proc/net/ip_conntrack
udp 17 21 src=192.168.0.18 dst=211.147.6.3 sport=24889 dport=53 packets=1 bytes=71 src=211.147.6.3 dst=192.168.0.18 sport=53 dport=24889 packets=1 bytes=152 use=1
tcp 6 52 ESTABLISHED src=192.168.0.18 dst=192.168.0.17 sport=52318 dport=3306 packets=44 bytes=2474 src=192.168.0.17 dst=192.168.0.18 sport=3306 dport=52318 packets=43 bytes=2716 [ASSURED] use=1
vi /etc/modprobe.conf
options ip_conntrack hashsize=855360 更改 conntrack_buckets
===========================================================
===========================================================
我寫的不是很好,還是轉(zhuǎn)一篇寫的好多把,哈哈,文章所涉及的英文解釋,都是摘自linux man tcp的內(nèi)容
下面是摘自eve‘s blog,總結(jié)的很好,借用一下,不過有的參數(shù)可能針對的業(yè)務(wù)不同,不太一樣。
三次握手以及其中的各種狀態(tài):
SYN(Synchronize Sequence Numbers)。
同步序列編號
ACK (ACKnowledge Character)
在數(shù)據(jù)通信傳輸中,接收站發(fā)給發(fā)送站的一種傳輸控制字符。它表示確認(rèn)發(fā)來的數(shù)據(jù)已經(jīng)接受無誤。
=================================
client發(fā)送syn至server
此時(shí)客戶端的狀態(tài)變?yōu)镾YN_SENT
client(syn=j)====>server
server收到syn,并發(fā)送syn+ack到client,
這種過程server狀態(tài)由listen變?yōu)镾YN_RECV,并等待客戶端再次發(fā)來ack數(shù)據(jù)
client<=========server(syn=k,ack=j+1)
client接收到server發(fā)過來的syn+ack,并向服務(wù)端發(fā)送ACK,服務(wù)器接收后由SYN_RECV變?yōu)镋STABLISHED
client(ACK(ack=k+1))========>server
此種情況下,服務(wù)端在三次握手的變遷是
LISTEN->SYN_RECV ->ESTABLISHED
客戶端的三次握手的變遷是
SYN_SENT ->ESTABLISHED
====================================
在這種過程中要注意的
一、首先server有個(gè)用來接收client發(fā)送的syn并對syn進(jìn)行排隊(duì)的隊(duì)列,如果隊(duì)列滿了,新的請求不被接受。
此隊(duì)列長度控制參數(shù):
net.ipv4.tcp_max_syn_backlog
對應(yīng)文件(/proc/sys/net/ipv4/tcp_max_syn_backlog ) 默認(rèn)是1024
view sourceprint?
1 [root@web]# cat /proc/sys/net/ipv4/tcp_max_syn_backlog
2 1024
二、然后是SYN-ACK重傳:當(dāng)server向client發(fā)送syn+ack沒有收到相應(yīng),server將重傳,然后再重傳。。。控制這個(gè)重傳次數(shù)的參數(shù)是
tcp_synack_retries
對應(yīng)文件(/proc/sys/net/ipv4/tcp_synack_retries )默認(rèn)值是5,對應(yīng)于180秒左右時(shí)間
view sourceprint?
1 [root@web ~]# cat /proc/sys/net/ipv4/tcp_synack_retries
2 5
view sourceprint?
關(guān)于tcp_synack_retries的英文解釋:
The maximum number of times a SYN/ACK segment for a passive TCP connection will be retransmitted. This number should not be higher than 255. The default value is 5.
備注:與此相對應(yīng)的client的參數(shù)是:
tcp_syn_retries
The maximum number of times initial SYNs for an active TCP connection attempt will be retransmitted. This value should not be higher than 255. The default value is 5, which corresponds to Approximately 180 seconds.
三、關(guān)于tcp_syncookies
SYN Cookie原理及其在Linux內(nèi)核中的實(shí)現(xiàn)
http://www.ibm.com/developerworks/cn/linux/l-syncookie/?ca=dwcn-newsletter-linux
SYN Cookie是對TCP服務(wù)器端的三次握手協(xié)議作一些修改,專門用來防范SYN Flood攻擊的一種手段。它的原理是,在TCP服務(wù)器收到TCP SYN包并返回TCP SYN+ACK包時(shí),不分配一個(gè)專門的數(shù)據(jù)區(qū),而是根據(jù)這個(gè)SYN包計(jì)算出一個(gè)cookie值。在收到TCP ACK包時(shí),TCP服務(wù)器在根據(jù)那個(gè)cookie值檢查這個(gè)TCP ACK包的合法性。如果合法,再分配專門的數(shù)據(jù)區(qū)進(jìn)行處理未來的TCP連接。
view sourceprint?
1 [root@web~]# cat /proc/sys/net/ipv4/tcp_syncookies
2 1
===========================================
典型故障處理
如果服務(wù)器syn_recv的條數(shù)過多,可以采取的操作是:
減少server==>client重傳syn+ack的次數(shù)。
加大syn隊(duì)列長度,防止無法響應(yīng)新的連接
view sourceprint?
1 echo "net.ipv4.tcp_max_syn_backlog = 4096" >>/etc/sysctl.conf
2 echo "net.ipv4.tcp_synack_retries = 1" >>/etc/sysctl.conf
3 sysctl -p
當(dāng)受到syn攻擊的時(shí)候,啟用syn-cookie(默認(rèn)啟用,在/etc/sysctl.conf里本身就有參數(shù)配置)
view sourceprint?
1 echo 1 >/proc/sys/net/ipv4/tcp_syncookies
=================================================
四次握手
下面說tcp/ip的第四次握手,分析主動關(guān)閉和被動關(guān)閉兩種。
A:因?yàn)槿绻荂LIENT端主動斷掉當(dāng)前連接,那么雙方關(guān)閉這個(gè)TCP連接共需要四個(gè)packet:
setup
Client ---> FIN(M) ---> Server
client發(fā)送一個(gè)FIN給server,(說它不跟你玩了),client由ESTABLISHED->FIN_WAIT1
Client <--- ACK(M+1) <--- Server
SER VER收到fin后發(fā)送ack確認(rèn)(拿出兩人信物),狀態(tài)由ESTABLISHED->close_wait
client收到server的ack確認(rèn),只是改變狀態(tài)ESTABLISHED->FIN_WAIT1->FIN_WAIT2,繼續(xù)等server發(fā)送數(shù)據(jù)。
Client <-- FIN(N) <-- Server
server繼續(xù)發(fā)送FIN到client(好就不玩了吧),狀態(tài)ESTABLISHED->close_wait->LAST_ACK,等待client發(fā)送ack做最后的確認(rèn)
Client --> ACK(N+1) --> Server
client收到FIN,馬上發(fā)送ack確認(rèn),狀態(tài)ESTABLISHED->FIN_WAIT1->FIN_WAIT2->TIME_WAIT[2MSL超時(shí)]->closed
server收到ack確認(rèn),狀態(tài)ESTABLISHED->close_wait->LAST_ACK->CLOSED.
client關(guān)閉連接很好想,有點(diǎn)要搞清楚的是,server端什么時(shí)候會發(fā)起丟掉連接的操作:
有些是應(yīng)用程序控制的。nginx.conf為例
keepalive_timeout 0;
[root@lvs-2 ~]# curl -I http://www.XXX.com
Connection: close
keepalive_timeout 600;
[root@lvs-2 ~]# curl -I http://www.XXX.com
Connection: keep-alive
這種規(guī)定了連接時(shí)間的,到了時(shí)間連接會斷掉。
如果沒有規(guī)定的,則按照系統(tǒng)keepalived定時(shí)器的設(shè)置進(jìn)行,具體參數(shù)如下:
[root@web]# sysctl -a|grep tcp_keepalive
view sourceprint?
1 net.ipv4.tcp_keepalive_intvl = 75
2 net.ipv4.tcp_keepalive_probes = 9
3 net.ipv4.tcp_keepalive_time = 7200
4 連接兩端一直沒發(fā)送數(shù)據(jù),間隔120分鐘,兩小時(shí)后開始第一次探測,間隔75秒后第二次探測,探測9次,最后放棄連接。有四種探測的情況,詳見
四種狀況其實(shí)最后一種沒什么意義,能考慮到下面三種就行了
1 client正常,每進(jìn)行一次通訊,net.ipv4.tcp_keepalive_time重置一次。
2 一直到7200+75*9后也無法獲取client反饋信息,則認(rèn)為client已經(jīng)關(guān)閉并終止連接(連接超時(shí))
3 client重啟, 收到探測后返回一個(gè)復(fù)位(RST)信息。server收到后終止連接(連接被對方復(fù)位)