前言:
1:介紹下linux內核的整個知識體系,(學會它,你肯定對linux內核有不一樣的理解。)
2:談談Linux內核參數優化
一:linux內核技術點
Linux內核知識體系分為五個部分
1:linux內核開發環境搭建
linux內核研習與項目實戰專欄介紹
linux內核編譯與升級
linux內核學習方法
2:跨越進程的障礙,實現進程通信(一)
進程間6種通信方式
多個進程之間通信,如何實現通信組件
內核模塊操作
進程通信組件,架構實現
系統調用的過程剖析
3:跨越進程的障礙,實現進程通信(二)
主次設備號與private-data的作用
insmod與模塊初始化的流程
模塊open的流程
rmmod與模塊退出的流程
模塊write的流程與實現
poll的實現原理與等待隊列wait-queue
模塊編譯與Makefile編寫
4:網卡驅動的實現
內核模塊安裝與mknod
應用程序編程與內核模塊調試
Docker的虛擬網卡與網卡的作用
網卡作用于網卡驅動的運行環境
如何設計適配市面上網卡的nic子系統
nic網卡驅動的架構實現
nic網卡驅動的recv與sk-buff
nic網卡初始化與原理分析
nic網卡open與stop實現
5:最后自主思考項目
nic的編譯與自主思考題,用戶態協議棧
Linux內核參數優化
調整參數和不調整差別非常大,默認參數都設置比較小,在大并發,高負載時基本不能滿足。調整之后,問題基本解決。
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時,被壓的服務器nginx,memcache的cpu使用非常低,而且服務器負載也很小,但是 webbench的結果卻不樂觀,失敗非常多,通過分析,壓力根本沒到nginx和memcache,可能在服務器級就擋住了壓力,并且發現/var /log/message里面有關于ip_conntrack_max(一個連接hash表)滿了的報錯,然后順藤摸瓜,通過查看linux的man tcp 手冊,一個參數一個參數的研究,終于總結了上面的一些配置,解決了問題。
現象:/var/log/message里面有關于ip_conntrack_max 如ip_conntrack: table full, dropping packet.
解決方法:
觀察鏈接跟蹤表是(/proc/net/ip_conntrack)
IP_conntrack 表示連接跟蹤數據庫(conntrack database),代表NAT機器跟蹤連接的數目,連接跟蹤表能容納多少記錄是被一個變量控制的,他可由內核中的ip- sysctl函數配置。每一個跟蹤連接表會占用350字節的內核存儲空間,時間一長就會把默認的空間填滿,那么默認是間是多少?我以redhat為例在內 存為64MB的機器上時4096,內存為128MB是 8192,內存為256MB是16376,那末就能在/proc/sys/net/ipv4/ip_conntrack_max里查看、配置。
針對于我們的業務模式,比較重要的是
net.ipv4.ip_local_port_range = 1024 65000 表示用于向外連接的端口范圍。缺省情況下很小:32768到61000,改為1024到65000。
net.ipv4.tcp_tw_reuse = 1 表示開啟重用。允許將TIME-WAIT sockets重新用于新的TCP連接,默認為0,表示關閉;
net.ipv4.tcp_tw_recycle = 1 表示開啟TCP連接中TIME-WAIT sockets的快速回收,默認為0,表示關閉。
net.ipv4.ip_conntrack_max = 655360
net.ipv4.netfilter.ip_conntrack_tcp_timeout_established = 21600
這個值是控制 紅色數字 這個時間的,其他相關參數都在/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
===========================================================
===========================================================
我寫的不是很好,還是轉一篇寫的好多把,哈哈,文章所涉及的英文解釋,都是摘自linux man tcp的內容
下面是摘自eve‘s blog,總結的很好,借用一下,不過有的參數可能針對的業務不同,不太一樣。
三次握手以及其中的各種狀態:
SYN(Synchronize Sequence Numbers)。
同步序列編號
ACK (ACKnowledge Character)
在數據通信傳輸中,接收站發給發送站的一種傳輸控制字符。它表示確認發來的數據已經接受無誤。
=================================
client發送syn至server
此時客戶端的狀態變為SYN_SENT
client(syn=j)====>server
server收到syn,并發送syn+ack到client,
這種過程server狀態由listen變為SYN_RECV,并等待客戶端再次發來ack數據
client<=========server(syn=k,ack=j+1)
client接收到server發過來的syn+ack,并向服務端發送ACK,服務器接收后由SYN_RECV變為ESTABLISHED
client(ACK(ack=k+1))========>server
此種情況下,服務端在三次握手的變遷是
LISTEN->SYN_RECV ->ESTABLISHED
客戶端的三次握手的變遷是
SYN_SENT ->ESTABLISHED
====================================
在這種過程中要注意的
一、首先server有個用來接收client發送的syn并對syn進行排隊的隊列,如果隊列滿了,新的請求不被接受。
此隊列長度控制參數:
net.ipv4.tcp_max_syn_backlog
對應文件(/proc/sys/net/ipv4/tcp_max_syn_backlog ) 默認是1024
view sourceprint?
1 [root@web]# cat /proc/sys/net/ipv4/tcp_max_syn_backlog
2 1024
二、然后是SYN-ACK重傳:當server向client發送syn+ack沒有收到相應,server將重傳,然后再重傳。。。控制這個重傳次數的參數是
tcp_synack_retries
對應文件(/proc/sys/net/ipv4/tcp_synack_retries )默認值是5,對應于180秒左右時間
view sourceprint?
1 [root@web ~]# cat /proc/sys/net/ipv4/tcp_synack_retries
2 5
view sourceprint?
關于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.
備注:與此相對應的client的參數是:
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.
三、關于tcp_syncookies
SYN Cookie原理及其在Linux內核中的實現
http://www.ibm.com/developerworks/cn/linux/l-syncookie/?ca=dwcn-newsletter-linux
SYN Cookie是對TCP服務器端的三次握手協議作一些修改,專門用來防范SYN Flood攻擊的一種手段。它的原理是,在TCP服務器收到TCP SYN包并返回TCP SYN+ACK包時,不分配一個專門的數據區,而是根據這個SYN包計算出一個cookie值。在收到TCP ACK包時,TCP服務器在根據那個cookie值檢查這個TCP ACK包的合法性。如果合法,再分配專門的數據區進行處理未來的TCP連接。
view sourceprint?
1 [root@web~]# cat /proc/sys/net/ipv4/tcp_syncookies
2 1
===========================================
典型故障處理
如果服務器syn_recv的條數過多,可以采取的操作是:
減少server==>client重傳syn+ack的次數。
加大syn隊列長度,防止無法響應新的連接
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
當受到syn攻擊的時候,啟用syn-cookie(默認啟用,在/etc/sysctl.conf里本身就有參數配置)
view sourceprint?
1 echo 1 >/proc/sys/net/ipv4/tcp_syncookies
=================================================
四次握手
下面說tcp/ip的第四次握手,分析主動關閉和被動關閉兩種。
A:因為如果是CLIENT端主動斷掉當前連接,那么雙方關閉這個TCP連接共需要四個packet:
setup
Client ---> FIN(M) ---> Server
client發送一個FIN給server,(說它不跟你玩了),client由ESTABLISHED->FIN_WAIT1
Client <--- ACK(M+1) <--- Server
SER VER收到fin后發送ack確認(拿出兩人信物),狀態由ESTABLISHED->close_wait
client收到server的ack確認,只是改變狀態ESTABLISHED->FIN_WAIT1->FIN_WAIT2,繼續等server發送數據。
Client <-- FIN(N) <-- Server
server繼續發送FIN到client(好就不玩了吧),狀態ESTABLISHED->close_wait->LAST_ACK,等待client發送ack做最后的確認
Client --> ACK(N+1) --> Server
client收到FIN,馬上發送ack確認,狀態ESTABLISHED->FIN_WAIT1->FIN_WAIT2->TIME_WAIT[2MSL超時]->closed
server收到ack確認,狀態ESTABLISHED->close_wait->LAST_ACK->CLOSED.
client關閉連接很好想,有點要搞清楚的是,server端什么時候會發起丟掉連接的操作:
有些是應用程序控制的。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
這種規定了連接時間的,到了時間連接會斷掉。
如果沒有規定的,則按照系統keepalived定時器的設置進行,具體參數如下:
[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 連接兩端一直沒發送數據,間隔120分鐘,兩小時后開始第一次探測,間隔75秒后第二次探測,探測9次,最后放棄連接。有四種探測的情況,詳見
四種狀況其實最后一種沒什么意義,能考慮到下面三種就行了
1 client正常,每進行一次通訊,net.ipv4.tcp_keepalive_time重置一次。
2 一直到7200+75*9后也無法獲取client反饋信息,則認為client已經關閉并終止連接(連接超時)
3 client重啟, 收到探測后返回一個復位(RST)信息。server收到后終止連接(連接被對方復位)