為什麼要效能調優?
大部分的linux發行版是為了完全相容市場中大部分電腦而設計的。這是一個相當混雜的硬體集合(硬碟,顯卡,網卡,等等)。所以Red Hat, Suse,Mandriva和其他的一些發行版廠商選擇了一些保守的設定來確保安裝成功。
簡單地說:你的發行版啟動並執行很好,但是它可以運行地更好!
比如,可能有一個具體一些特殊特性的進階硬碟,而這些特性在標準配置的情況下可能就沒被啟用。
磁碟子系統的調優
對於Linux的Ext3/4來說,幾乎在所有情況下都有所協助的一個參數是關閉檔案系統訪問時間,在/etc/fstab下看看你的檔案系統 有沒有noatime參數.atime 是最近訪問檔案的時間,每當訪問檔案時,底層檔案系統必須記錄這個時間戳記。因為系統管理員很少使用 atime,禁用它可以減少磁碟存取時間。禁用這個特性的方法是,在 /etc/fstab 的第四列中添加 noatime 選項。
網路調優
tcp串連保持管理:
如果在該參數指定時間內某條串連處於空閑狀態,則核心向遠程主機發起探測
net.ipv4.tcp_keepalive_time = 7200
核心向遠程主機發送的保活探測的時間間隔
net.ipv4.tcp_keepalive_intvl = 75
核心發送保活探測的最大次數,如果探測次數大於這個數,則斷定遠程主機不可達,則關閉該串連並釋放本地資源
一個串連7200s空閑後,核心會每隔75秒去重試,若連續9次則放棄。這樣就導致一個串連經過2h11min的時間才能被丟棄,降低該值能夠盡量減小失效串連所佔用的資源,而被新的串連所使用。
net.ipv4.tcp_keepalive_probes = 9
tcp串連管理:
表示在每個網路介面接收資料包的速率比核心處理這些包的速率快時,允許送到隊列的資料包的最大數目。
net.core.netdev_max_backlog=3000
控制每個連接埠的tcp syn的隊列長度,來自用戶端的串連請求需要排隊,直至伺服器接受,如果串連請求數大於該值,則串連請求會被丟棄,用戶端無法串連伺服器,一般伺服器要提高此值
net.ipv4.tcp_max_syn_backlog = 1024
控制核心向某個socket的ack,syn段(三向交握的第二次握手)重新發送響應的次數,降低此值可以儘早檢測到來自遠程主機的串連失敗嘗試
net.ipv4.tcp_synack_retries = 5
控制核心向已建立串連的遠程主機重新發送資料的次數,降低此值,可以儘早的檢測串連失效
net.ipv4.tcp_retries2 = 15
SYN Cookie是對TCP伺服器端的三向交握協議作一些修改,專門用來防範SYN Flood攻擊的一種手段。它的原理是,在TCP伺服器收到TCP SYN包並返回TCP SYN+ACK包時,不分配一個專門的資料區,而是根據這個SYN包計算出一個cookie值。在收到TCP ACK包時,TCP伺服器在根據那個cookie值檢查這個TCP ACK包的合法性。如果合法,再分配專門的資料區進行處理未來的TCP串連。
net.ipv4.tcp_syncookies = 1
如下的sysctl命令用於改變安全設定,但是它也可以防止網路效能的下降。這些命令被設定為預設值。
關閉如下參數可以防止駭客對伺服器IP地址的攻擊
sysctl -w net.ipv4.conf.eth0.accept_source_route=0
sysctl -w net.ipv4.conf.lo.accept_source_route=0
sysctl -w net.ipv4.conf.default.accept_source_route=0
sysctl -w net.ipv4.conf.all.accept_source_route=0
以下命令使伺服器忽略來自被列入網關的伺服器的重新導向。因重新導向可以被用來進行攻擊,所以我們只接受有信任的來源的重新導向
sysctl -w net.ipv4.conf.eth0.secure_redirects=1
sysctl -w net.ipv4.conf.lo.secure_redirects=1
sysctl -w net.ipv4.conf.default.secure_redirects=1
sysctl -w net.ipv4.conf.all.secure_redirects=1
另外,你可以配置接受或拒絕任何ICMP重新導向。ICMP重新導向是器傳輸資訊的機制。比如,當網關接收到來自所接網路主機的Internet資料報時,網關可以發送重新導向資訊到一台主機。網關檢查路由表獲得下一個網關的地址,第二個網關將資料報路由到目標網路。關閉這些重新導向得命令如下:
sysctl -w net.ipv4.conf.eth0.accept_redirects=0
sysctl -w net.ipv4.conf.lo.accept_redirects=0
sysctl -w net.ipv4.conf.default.accept_redirects=0
sysctl -w net.ipv4.conf.all.accept_redirects=0
如果這個伺服器不是一台路由器,那麼它不會發送重新導向,所以可以關閉該功能:
sysctl -w net.ipv4.conf.eth0.send_redirects=0
sysctl -w net.ipv4.conf.lo.send_redirects=0
sysctl -w net.ipv4.conf.default.send_redirects=0
sysctl -w net.ipv4.conf.all.send_redirects=0
設定管理員拒絕接受廣播風暴或者smurf 攻擊attacks:
sysctl -w net.ipv4.icmp_echo_ignore_broadcasts=1
忽略所有icmp包或者pings:
sysctl -w net.ipv4.icmp_echo_ignore_all=1
有些路由器針對廣播禎發送無效的回應,每個都產生警告並在核心產生日誌。這些回應可以被忽略:
sysctl -w net.ipv4.icmp_ignore_bogus_error_responses=1
下邊的命令用來對串連數量非常大的伺服器進行調優。
表示開啟重用。允許將TIME-WAIT sockets重新用於新的TCP串連,預設為0
net.ipv4.tcp_tw_reuse = 1
表示開啟TCP串連中TIME-WAIT sockets的快速回收,預設為0
net.ipv4.tcp_tw_recycle = 1
tcp_fin_timeout
預設值是 60
對於本端斷開的socket串連,TCP保持在FIN_WAIT_2狀態的時間。對方可能會中斷連線或一直不結束串連或不可預料的進程死亡。預設值為 60 秒。過去在2.2版本的核心中是 180 秒。您可以設定該值?但需要注意?如果您的機器為負載很重的web伺服器?您可能要冒記憶體被大量無效資料報填滿的風險?FIN-WAIT-2 sockets 的危險性低於 FIN-WAIT-1 ?因為它們最多隻吃 1.5K 的記憶體?但是它們存在時間更長。另外參考 tcp_max_orphans。
CLOSE_WAIT狀態的產生原因
如果伺服器程式APACHE處於CLOSE_WAIT狀態的話,說明通訊端是被動關閉的!
假設CLIENT端主動斷掉當前串連,那麼雙方關閉這個TCP串連共需要四個packet:
Client —> FIN —> Server
Client < --- ACK <--- Server
這時候Client端處於FIN_WAIT_2狀態;而Server 程式處於CLOSE_WAIT狀態。
Client <--- FIN <--- Server
這時Server 發送FIN給Client,Server 就置為LAST_ACK狀態。
Client ---> ACK —> Server
Client回應了ACK,那麼Server 的通訊端才會真正置為CLOSED狀態。
Server 程式處於CLOSE_WAIT狀態,而不是LAST_ACK狀態,說明還沒有發FIN給Client,那麼可能是在關閉串連之前還有許多資料要發送或者其他事要做,導致沒有發這個FIN packet。
通常來說,一個CLOSE_WAIT會維持至少2個小時的時間。如果有個流氓特地寫了個程式,給你造成一堆的CLOSE_WAIT,消耗資源,那麼通常是等不到釋放那一刻,系統就已經解決崩潰了。
改變這個值的前要經過認真的監測,避免因為死通訊端造成記憶體溢出。
sysctl -w net.ipv4.tcp_fin_timeout=30
對於所有的隊列(即系統),設定最大系統發送緩衝(wmem) 和接收緩衝(rmem)到8MB
sysctl -w net.ipv4.core.wmem_max=8388608
sysctl -w net.ipv4.core.rmem_max=8388608
使用如下命令調整tcp發送和接收緩衝。該命令設定了三個值:最小值、初始值和最大值:
sysctl -w net.ipv4.tcp_rmem="4096 87380 8388608"
sysclt -w net.ipv4.tcp.wmem="4096 87380 8388608"
第三個值必須小於或等於wmem_max和rmem_max。
當伺服器負載繁重或者是有很多用戶端都是超長延時的串連故障,可能會導致half-open串連數量的增加。這對於Web伺服器很來講很平常,尤其有很多撥號客戶時。這些half-open串連儲存在 backlog(積壓) connections 隊列中。
將這個值最少設定為4096 (預設為1024)。 即便是伺服器不接收這類串連,設定這個值還能防止受到denial-of-service (syn-flood)的攻擊
sysctl -w net.ipv4.tcp_max_syn_backlog=4096
設定ipfrag參數,尤其是NFS和Samba伺服器。這裡,我們可以設定用於重新組合IP片段的最大、最小記憶體。當ipfrag_high_thresh值被指派,片段會被丟棄直到達到ipfrag_low_thres值。
當TCP資料包傳輸發生錯誤時,開始磁碟重組。有效資料包保留在記憶體,同時損壞的資料包被轉寄。例如,設定可用記憶體範圍從256 MB到384 MB
sysctl -w net.ipv4.ipfrag_low_thresh=262144
sysctl -w net.ipv4.ipfrag_high_thresh=393216
網路安全設定
防止TCP SYN Flood 攻擊
TCP SYN Flood是一種常見,而且有效遠端(遠程)拒絕服務(Denial of Service)攻擊方式,它透過一定的操作破壞TCP三向交握建立正常串連,佔用並耗費系統資源,使得提供TCP服務的主機系統無法正常工作。由於TCP SYN Flood是透過網路底層對伺服器Server進行攻擊的,它可以在任意改變自己的網路IP地址的同時,不被網路上的其他裝置所識別,這樣就給防範網路犯罪部門追查犯罪來源造成很大的困難。
系統檢查
一般情況下,可以一些簡單步驟進行檢查,來判斷系統是否正在遭受TCP SYN Flood攻擊
1、服務端無法提供正常的TCP服務。串連請求被拒絕或逾時
2、透過 netstat -an 命令檢查系統,發現有大量的SYN_RECV串連狀態
iptables的設定
防止同步包洪水(Sync Flood)
iptables -A FORWARD -p tcp --syn -m limit --limit 1/s -j ACCEPT
也有人寫作
iptables -A INPUT -p tcp --syn -m limit --limit 1/s -j ACCEPT
–limit 1/s 限制syn並發數每秒1次,可以根據自己的需要修改
防止各種連接埠掃描
iptables -A FORWARD -p tcp --tcp-flags SYN,ACK,FIN,RST RST -m limit --limit 1/s -j ACCEPT
Ping洪水攻擊(Ping of Death)
iptables -A FORWARD -p icmp --icmp-type echo-request -m limit --limit 1/s -j ACCEPT
記憶體子系統的調優
記憶體子系統的調優不是很容易,需要不停地監測來保證記憶體的改變不會對伺服器的其他子系統造成負面影響。如果要改變虛擬記憶體參數(在/proc/sys/vm),建議每次只改變一個參數然後監測效果。
對與虛擬記憶體的調整包括以下幾個項目:
配置Linux核心如何更新dirty buffers到磁碟
磁碟緩衝區用於暫存磁碟的資料。相對於記憶體來講,磁碟緩衝區的速度很慢。因此,如果伺服器使用這類記憶體,效能會成問題。當緩衝區內的資料完全dirty,使用:
sysctl -w vm.bdflush="30 500 0 0 500 3000 60 20 0"
vm.bdflush有9個參數,但是建議只改變其中的3個:
1 nfract, 為排隊寫入磁碟前,bdflush daemon允許的緩衝區最大百分比
2 ndirty, 為bdflush即刻寫的最大緩衝區的值。如果這個值很大,bdflush需要更多的時間完成磁碟的資料更新。
7 nfract_sync, 發生同步前,緩衝區變dirty的最大百分比
配置kswapd daemon,指定Linux的記憶體頁數量
sysctl -w vm.kswapd="1024 32 64"
三個參數的描述如下:
– tries_base 相當於核心每次所的“頁”的數量的四倍。對於有很多交換資訊的系統,增加這個值可以改進效能。
– tries_min 是每次kswapd swaps出去的pages的最小數量。
– swap_cluster 是kswapd 即刻寫如的pages數量。數值小,會提高磁碟I/O的效能;數值大可能也會對請求隊列產生負面影響。
如果要對這些參數進行改動,請使用工具vmstat檢查對效能的影響。其它可以改進效能的虛擬記憶體參數為:
_ buffermem
_ freepages
_ overcommit_memory
_ page-cluster
_ pagecache
_ pagetable_cache
檔案子系統的調優
ulimit -a 用來顯示當前的各種使用者進程限制。
Linux對於每個使用者,系統限制其最大進程數。為提高效能,可以根據裝置資源情況,設定各linux 使用者的最大進程數,下面我把某linux使用者的最大進程數設為10000個:www.111Cn.net
ulimit -u 10000
對於需要做許多 socket 串連並使它們處於開啟狀態的 Java 應用程式而言,最好通過使用 ulimit -n xx 修改每個進程可開啟的檔案數,預設值是 1024。
ulimit -n 4096 將每個進程可以開啟的檔案數目加大到4096,預設為1024
其他建議設定成無限制(unlimited)的一些重要設定是:
資料區段長度:ulimit -d unlimited
最大記憶體大小:ulimit -m unlimited
堆棧大小:ulimit -s unlimited
CPU 時間:ulimit -t unlimited
虛擬記憶體:ulimit -v unlimited
暫時地,適用於通過 ulimit 命令登入 shell 會話期間。
永久地,通過將一個相應的 ulimit 語句添加到由登入 shell 讀取的檔案中,即特定於 shell 的使用者資源檔,如:
1)、解除 Linux 系統的最大進程數和最大檔案開啟數限制:
vi /etc/security/limits.conf
# 添加如下的行
* soft noproc 11000
* hard noproc 11000
* soft nofile 4100
* hard nofile 4100
說明:* 代錶針對所有使用者
noproc 是代表最大進程數
nofile 是代表最大檔案開啟數
2)、讓 SSH 接受 Login 程式的登入,方便在 ssh 用戶端查看 ulimit -a 資源限制:
a、vi /etc/ssh/sshd_config
把 UserLogin 的值改為 yes,並把 # 注釋去掉
b、重啟 sshd 服務:
/etc/init.d/sshd restart
3)、修改所有 linux 使用者的環境變數檔案:
vi /etc/profile
ulimit -u 10000
ulimit -n 4096
ulimit -d unlimited
ulimit -m unlimited
ulimit -s unlimited
ulimit -t unlimited
ulimit -v unlimited
有時候在程式裡面需要開啟多個檔案,進行分析,系統一般預設數量是1024,(用ulimit -a可以看到)對於正常使用是夠了,但是對於程式來講,就太少了。
修改2個檔案。
1.vi /etc/security/limits.conf
加上:
* soft nofile 8192
* hard nofile 20480
2./etc/pam.d/login
session required /lib/security/pam_limits.so
另外確保/etc/pam.d/system-auth檔案有下面內容
session required /lib/security/$ISA/pam_limits.so
這一行確保系統會執行這個限制。
3.一般使用者的.bash_profile
ulimit -n 1024
重新登陸ok
最佳化步驟:
修改/etc/profile檔案,加入:
ulimit -u 10240
ulimit -n 4096
ulimit -d unlimited
ulimit -m unlimited
ulimit -s unlimited
ulimit -t unlimited
ulimit -v unlimited
修改/etc/rc.d/rc.local,加入:
echo ‘999999′ > /proc/sys/fs/file-max
echo ‘999999′ > /proc/sys/fs/inode-max
(1G記憶體值修改成:65535 2G記憶體值修改成:131072 4G記憶體值修改成:262144)
修改/etc/sysctl.conf檔案,加入:
net.core.rmem_default = 8388608
net.core.rmem_max = 8388608
net.core.wmem_default = 8388608
net.core.wmem_max = 8388608
net.ipv4.tcp_timestamps = 0
net.ipv4.tcp_sack =1
net.ipv4.tcp_window_scaling = 1
net.core.netdev_max_backlog=3000
#Modify i-node
sys.fs.file-max= 65535
sys.fs.inode-max= 65535
#Set System Memory
vm.bdflush="30 500 0 0 500 3000 60 20 0"
vm.kswapd="1024 32 64"
#Disable HackAttack!
net.ipv4.conf.eth0.accept_source_route=0
net.ipv4.conf.lo.accept_source_route=0
net.ipv4.conf.default.accept_source_route=0
net.ipv4.conf.all.accept_source_route=0
net.ipv4.conf.lo.accept_redirects=0
net.ipv4.conf.all.accept_redirects=0
net.ipv4.conf.eth0.accept_redirects=0
net.ipv4.conf.default.accept_redirects=0
net.ipv4.conf.lo.secure_redirects=0
net.ipv4.conf.all.secure_redirects=0
net.ipv4.conf.eth0.secure_redirects=0
net.ipv4.conf.default.secure_redirects=0
net.ipv4.conf.eth0.send_redirects=0
net.ipv4.conf.lo.send_redirects=0
net.ipv4.conf.default.send_redirects=0
net.ipv4.conf.all.send_redirects=0
net.ipv4.tcp_syncookies=1
net.ipv4.icmp_echo_ignore_broadcasts=1
net.ipv4.icmp_ignore_bogus_error_responses=1
#Web Servers
net.ipv4.tcp_tw_reuse=1
net.ipv4.tcp_tw_recycle=1
net.ipv4.tcp_fin_timeout=30
net.ipv4.tcp_keepalive_time=1800
net.ipv4.core.wmem_max=16777216
net.ipv4.core.rmem_max=16777216
net.ipv4.tcp_rmem="4096 87380 8388608"
net.ipv4.tcp.wmem="4096 87380 8388608"
net.ipv4.tcp_max_syn_backlog=8192
防火牆安全:
iptables -A FORWARD -p tcp --syn -m limit --limit 1/s -j ACCEPT
也有人寫作
iptables -A INPUT -p tcp --syn -m limit --limit 1/s -j ACCEPT
–limit 1/s 限制syn並發數每秒1次,可以根據自己的需要修改
防止各種連接埠掃描
iptables -A FORWARD -p tcp --tcp-flags SYN,ACK,FIN,RST RST -m limit --limit 1/s -j ACCEPT
Ping洪水攻擊(Ping of Death)
iptables -A FORWARD -p icmp --icmp-type echo-request -m limit --limit 1/s -j ACCEPT
備忘說明:(相對比較激進的網路參數調整) www.111Cn.net
# Use TCP syncookies when needed
net.ipv4.tcp_syncookies = 1
# Enable TCP window scaling
net.ipv4.tcp_window_scaling = 1
# Increase TCP max buffer size
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
# Increase Linux autotuning TCP buffer limits
net.ipv4.tcp_rmem = 4096 87380 8388608
net.ipv4.tcp_wmem = 4096 65536 8388608
# Increase number of ports available
net.ipv4.ip_local_port_range = 1024 65000