標籤:linux最佳化
1. Open File Descriptors
Linux在系統調用,大量的系統調用都依賴於檔案描述符,而檔案描述符可分配給進程的最大大小由資源限制來定義。
因此,如果檔案描述符大小不夠,或有不正常網路連接(Socket也算)、檔案IO沒有關閉並釋放出檔案描述符。也可以說是檔案控制代碼(File Operator),會導致出現Too many open files的錯誤。
該錯誤很常見,因此OP幾乎都有做最佳化。
使用如下命令可以查看系統相關的配置:
ulimit -u 查看open files設定
ulimit -a 查看所有配置
ulimit -u 65535 臨時修改open files為65535
ulimit -n 65536 使用者可以同時開啟的最大檔案數(max open files)
lsof -p pid ID 查看某進程當前開啟的檔案資源
針對所有使用者及session有效長期修改方法為:
$ sudo vim /etc/security/limits.conf
# allow all users to open 100000 files
# alternatively, replace * with an explicit username
* soft nofile 100000 #限制單個進程最大檔案控制代碼數
* hard nofile 100000
同時需要修改/etc/sysctl.conf,設定整個系統最大檔案控制代碼數,運行sysctl -p生效
# /etc/sysctl.conf
# Increase system file descriptor limit
fs.file-max = 100000
2TCP time wait間隔指定的時間長度,一個socket在等待FIN資料包從寄件者發送時強行關閉。如果TCP沒有進入CLOSED狀態,主動關閉在發送最後一個ack後,就會進入TIME_WAIT。
這在Cache軟體裡最為常見,但其它Server也存在。
net.ipv4.tcp_fin_timeout = 30 保持FIN-WAIT-2狀態時間。
net.ipv4.tcp_keepalive_time = 1200
net.ipv4.tcp_syncookies = 1
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_local_port_range = 1024 65000
# 表示用於向外串連的連接埠範圍。
# 預設情況下很小:32768到61000,改為18000到65535。
net.ipv4.tcp_max_syn_backlog = 8192 表示SYN隊列的長度,預設1024,可以容納更多等待串連的網路連接數。
net.ipv4.tcp_max_tw_buckets = 5000
# 表示系統同時保持TIME_WAIT通訊端最大數量.
# 如果超出TIME_WAIT通訊端將立刻被清除並列印警告資訊。預設為180000,改為5000。
理解伺服器tcp狀態
10
SYN_SEND 請求服務端建立串連。
SYN_RECEIVED 伺服器接收到了來自用戶端的SYN。
ESTABLISHED 用戶端接收到了服務端的SYN,會話建立完成。
LISTEN 伺服器端開始接收串連。
FIN_WAIT_1 指示活動結束。
TIMED_WAIT 用戶端在活動結束後將進入此狀態。
CLOSE_WAIT 表示被動關閉。伺服器只是從用戶端收到第一個翼片。
FIN_WAIT_2 用戶端從伺服器收到其第一個 FIN 的確認。
LAST_ACK 發送自己的FIN後進入此狀態。
CLOSED 伺服器從用戶端收到 ACK,串連已關閉。
附趙岩和我whoisd上面總結的
可以通過系統的sysctl.conf設定檔進行最佳化
1、減少處於FIN-WAIT-2串連狀態的時間,使系統可以處理更多的串連。
net.ipv4.tcp_fin_timeout = 2
如果由本端要求關閉,這個參數決定了它保持在FIN-WAIT-2狀態的時間。
對端可以出錯並永遠不關閉串連,甚至意外當機,預設值是60秒。
核心的通常值是180秒,可以按這個設定,但要記住的是,即使你的機器是一個輕載的WEB伺服器,也有因為大量的死通訊端而記憶體溢出的風險,FIN-WAIT-2的危險性比FIN-WAIT-1要小,因為它最多隻能吃掉1.5K記憶體,但是它們的生存期長些。
2、以下兩參數可解決生產情境中大量串連的Web(cache)伺服器中TIME_WAIT過多問題。
net.ipv4.tcp_tw_reuse = 1
表示開啟重用。允許將TIME-WAIT sockets重新用於新的 TCP 串連,預設為 0 表示關閉。
3、開啟TIME-WAIT重用及回收功能。
net.ipv4.tcp_tw_recycle = 1
表示開啟TCP串連中TIME-WAIT sockets的快速收回功能,預設為 0 ,表示關閉。
4、當keepalive起用的時候,TCP發送keepalive訊息的頻度,預設是2小時,改為20分鐘。
net.ipv4.tcp_keepalive_time = 600
5、允許系統開啟的連接埠範圍
net.ipv4.ip_local_port_range = 4000 65000
表示用於向外串連的連接埠範圍。預設情況下很小:32768到61000,改為4000到65000。
6、提高系統支援的最大SYN半串連數(預設1024)
net.ipv4.tcp_max_syn_backlog = 16384
表示SYN隊列的長度,預設為1024,加大隊列長度為16384,可以容納最多等待串連的網路連接數。
7、系統同時保持TIME_WAIT的最大數量
net.ipv4.tcp_max_tw_buckets = 360000
表示系統同時保持TIME_WAIT的最大數量,如果超過這個數字,TIME_WAIT將立刻被清除並列印警告資訊。預設為180000,改為 5000。
對於Apache、Nginx等伺服器,上幾行的參數可以很好地減少TIME_WAIT數量,但是對於Squid,效果卻不大。此項參數可以控制TIME_WAIT的最大數量,避免Squid伺服器被大量的TIME_WAIT拖死。
8、路由緩衝重新整理頻率,當一個路由失敗後多長時間跳到另一個路由,預設是300。
net.ipv4.route.gc_timeout = 100
9、在核心放棄建立串連之前發送SYN包的數量。
net.ipv4.tcp_syn_retries = 1
10、減少系統SYN串連重試次數(預設是5)
net.ipv4.tcp_synack_retries = 1
為了開啟對端的串連,核心需要發送一個SYN並附帶一個回應前面一個SYN的ACK。
也就是所謂三向交握中的第二次握手。這個設定決定了核心放棄串連之前發送SYN+ACK包的數量。
11、設定系統對最大跟蹤的TCP串連數的限制
net.ipv4.ip_conntrack_max = 25000000
一個完整的sysctl.conf檔案
# /etc/sysctl.conf
# Increase system file descriptor limit
fs.file-max = 100000
# Discourage Linux from swapping idle processes to disk (default = 60)
vm.swappiness = 10
# Increase ephermeral IP ports
net.ipv4.ip_local_port_range = 10000 65000
# Increase Linux autotuning TCP buffer limits
# Set max to 16MB for 1GE and 32M (33554432) or 54M (56623104) for 10GE
# Don‘t set tcp_mem itself! Let the kernel scale it based on RAM.
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
net.core.rmem_default = 16777216
net.core.wmem_default = 16777216
net.core.optmem_max = 40960
net.ipv4.tcp_rmem = 4096 87380 16777216
net.ipv4.tcp_wmem = 4096 65536 16777216
# Make room for more TIME_WAIT sockets due to more clients,
# and allow them to be reused if we run out of sockets
# Also increase the max packet backlog
net.core.netdev_max_backlog = 50000
net.ipv4.tcp_max_syn_backlog = 30000
net.ipv4.tcp_max_tw_buckets = 2000000
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_fin_timeout = 10
# Disable TCP slow start on idle connections
net.ipv4.tcp_slow_start_after_idle = 0
# If your servers talk UDP, also up these limits
net.ipv4.udp_rmem_min = 8192
net.ipv4.udp_wmem_min = 8192
# Disable source routing and redirects
net.ipv4.conf.all.send_redirects = 0
net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.all.accept_source_route = 0
# Log packets with impossible addresses for security
net.ipv4.conf.all.log_martians = 1