centos7之系統優化方案

優化條目:html

  • 修改ip地址、網關、主機名、DNS等
  • 關閉selinux,清空iptables
  • 添加普通用戶並進行sudo受權管理
  • 更新yum源及必要軟件安裝
  • 定時自動更新服務器時間
  • 精簡開機自啓動服務
  • 定時自動清理/ var /spool/clientmqueue/目錄垃圾文件,放置inode節點被佔滿
  • 變動默認的ssh服務端口,禁止root用戶遠程鏈接
  • 鎖定關鍵文件系統
  • 調整文件描述符大小
  • 調整字符集,使其支持中文
  • 去除系統及內核版本登陸前的屏幕顯示
  • 禁止ping
  • 歷史記錄
  • 內核參數優化
     
  • 升級具備典型漏洞的軟件版本 

一、修改ip地址、網關、主機名、DNS等java

[root@localhost ~]# vi /etc/sysconfig/network-scripts/ifcfg-eth0
DEVICE=eth0         #網卡名字
BOOTPROTO=static    #靜態IP地址獲取狀態 如:DHCP表示自動獲取IP地址
IPADDR=192.168.1.113            #IP地址
NETMASK=255.255.255.0           #子網掩碼
ONBOOT=yes#引導時是否激活
GATEWAY=192.168.1.1
[root@localhost ~]# cat /etc/sysconfig/network-scripts/ifcfg-eth0
DEVICE=eth0
BOOTPROTO=static
IPADDR=192.168.1.113
NETMASK=255.255.255.0
ONBOOT=yes
GATEWAY=192.168.1.1
[root@localhost ~]# vi /etc/sysconfig/network
HOSTNAME=c64     #修改主機名,重啓生效
GATEWAY=192.168.1.1    #修改默認網關,若是上面eth0裏面不配置網關的話,默認就使用這裏的網關了。
[root@localhost ~]# cat /etc/sysconfig/network
HOSTNAME=c64
GATEWAY=192.168.1.1
咱們也能夠用  hostnamec64  來臨時修改主機名,從新登陸生效
修改DNS
[root@localhost ~]# vi /etc/resolv.conf   #修改DNS信息
nameserver 114.114.114.114
nameserver 8.8.8.8
[root@localhost ~]# cat /etc/resolv.conf  #查看修改後的DNS信息
nameserver 114.114.114.114
nameserver 8.8.8.8
[root@localhost ~]# service network restart   #重啓網卡,生效
重啓網卡,也能夠用下面的命令
[root@localhost ~]# /etc/init.d/network restart

 

二、關閉selinux,清空iptablesnode

關閉selinux防火牆
默認雲服務器都是關着的
cat /etc/selinux/config 
setenforce 0 設置不啓動
getenforce   查看

清空iptableslinux

# iptables –F     #清理防火牆規則
# iptables –L     #查看防火牆規則
Chain INPUT (policy ACCEPT)
target     prot opt source               destination
Chain FORWARD (policy ACCEPT)
target     prot opt source               destination
Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination
#/etc/init.d/iptables save   #保存防火牆配置信息

針對centos7防火牆配置nginx

修改防火牆
CentOS切換爲iptables防火牆
firewall-cmd --state 查看防火牆狀態

切換到iptables首先應該關掉默認的firewalld,而後安裝iptables服務。
1、關閉firewall:
systemctl stop firewalld.service 
systemctl disable firewalld.service #禁止firewall開機啓動

2、安裝iptables防火牆
yum install iptables-services #安裝
service iptables save

3、編輯iptables防火牆配置
vi /etc/sysconfig/iptables #編輯防火牆配置文件
下邊是一個完整的配置文件:
在你運行完save中間插入下面的規則
-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
-A INPUT -p icmp -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -m state --state NEW -m tcp -p tcp --dport 22 -j ACCEPT
-A INPUT -m state --state NEW -m tcp -p tcp --dport 80 -j ACCEPT
-A INPUT -m state --state NEW -m tcp -p tcp --dport 3306 -j ACCEPT
-A INPUT -j REJECT --reject-with icmp-host-prohibited
-A FORWARD -j REJECT --reject-with icmp-host-prohibited
:wq! #保存退出

systemctl start iptables.service  #開啓
systemctl enable iptables.service #設置防火牆開機啓動

附贈防火牆腳本,前提你已經切換至iptablesweb

#!/bin/bash

IPT=`which iptables`
$IPT -F
$IPT -X
$IPT -P INPUT DROP
$IPT -P FORWARD ACCEPT 
$IPT -P OUTPUT ACCEPT
$IPT -N syn-flood
##本地迴環 內網容許任何
$IPT -A INPUT -i lo -j ACCEPT
$IPT -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
$IPT -A INPUT -m state --state NEW -s 10.0.0.0/8 -j ACCEPT
# ssh 端口開放 任何IP
$IPT -A INPUT -m state --state NEW -p tcp --dport 22 -j ACCEPT
# 根據需求填寫相應的端口
$IPT -A INPUT -p tcp -m multiport --dports 80,8087,89 -j ACCEPT
# zabbix監控地址
$IPT -A INPUT -p tcp -s zabbix.ip -m state --state NEW -m tcp --dport 10050 -j ACCEPT
# ICMP 規則控制
$IPT -A INPUT -p icmp -m limit --limit 100/sec --limit-burst 100 -j ACCEPT
$IPT -A INPUT -p icmp -m limit --limit 1/s --limit-burst 10 -j ACCEPT
# DOS防禦
$IPT -A INPUT -p tcp -m tcp --tcp-flags FIN,SYN,RST,ACK SYN -j syn-flood
$IPT -A INPUT -j REJECT --reject-with icmp-host-prohibited
$IPT -A syn-flood -p tcp -m limit --limit 3/sec --limit-burst 6 -j RETURN
$IPT -A syn-flood -j REJECT --reject-with icmp-port-unreachable
fwiptables.sh

 

三、添加普通用戶並運行sudo受權管理apache

可參考http://www.javashuo.com/article/p-ymrxsonm-br.html編程

 

四、更新yum源及必要軟件安裝 ubuntu

yum源文件
yum update   更新源文件
yum clean all  清除緩存
yum makecache 創建yum緩存 CentOS
-Base.repo 網絡源文件 推薦使用阿里雲 若是發生問題極可能是域名解析問題 vim /etc/resolv.conf nameserver 8.8.8.8
阿里
nameserver 100.100.2.138
nameserver 100.100.2.136
options timeout:2 attempts:3 rotate single-request-reopen

接下來就要安裝幾個必要的軟件了vim

yum install lrzsz ntpdate sysstat net-tools -y
lrzsz 是上傳下載的軟件
sysstat 是用來檢測系統性能及效率的工具
net-tools 沒有ifconfig命令時候須要安裝工具

 

五、定時自動更新服務器時間

默認雲服務器有同步的時間服務器
修改時間 date
硬件時間 hwclock --show
同步公有時間服務器,可搭配任務計劃,阿里雲的時間服務器ntp.aliyun.com
yum -y install ntp
ntpdate asia.pool.ntp.org
time.nist.gov
time.nuri.net
ntpdate asia.pool.ntp.org 或者 ntp.aliyun.com
注意;若是出現ntpdate[24325]: the NTP socket is in use, exiting,須要systemctl stop ntpd.service中止,而後同步,以後再啓動,阿里雲服務器默認同步阿里雲時間服務器

時間設置

輸出當前時間
date +"%Y-%m-%d %H:%M:%S" # 2018-06-08 14:05:08
輸出指定時間
-d<字符串>:顯示字符串所指的日期與時間。字符串先後必須加上雙引號;
date -d "1 day ago" +"%Y-%m-%d"   2018-06-07  ago是昨天
date -d "1 day" +"%Y-%m-%d"       2018-06-09  不加參數是明天
如下使用數字表示先後多少天的加減
date +%Y%m%d #顯示前天年月日 
date -d "+1 day" +%F   #顯示前一天的日期  %F就是%Y-%m-%d
date -d "-1 day" +%F   #顯示後一天的日期   
date -d "-1 month" +F  #顯示上一月的日期 
date -d "+1 month" +F  #顯示下一月的日期 
date -d "-1 year" +F   #顯示前一年的日期 
date -d "+1 year" +F   #顯示下一年的日期
設置時間
-s<字符串>:根據字符串來設置日期與時間。字符串先後必須加上雙引號; 
date -s 01:01:01 #設置具體時間,不會對日期作更改 
date -s "01:01:01 2012-05-23" #這樣能夠設置所有時間 
date -s "01:01:01 20120523"   #這樣能夠設置所有時間 
date -s "2012-05-23 01:01:01" #這樣能夠設置所有時間 
date -s "20120523 01:01:01"   #這樣能夠設置所有時間

附贈當前任務的執行時間腳本

#!/bin/bash 
start=$(date +%s)   # 1528437613
nmap man.linuxde.net &> /dev/null 
end=$(date +%s) 
difference=$(( end - start )) 
echo $difference seconds.

時區設置

修改時區                                                                                
1)使用tzselect設置時區
2)複製相應的時區文件,替換系統默認時區
  cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
3)將當前時間寫入BIOS永久生效(避免重啓後失效)
  hwclock
4)centos /etc/sysconfig/clock
  ubuntu /etc/timezone

任務計劃使用

cat /var/spool/cron/root 可直接修改配置文件,注意重啓/reload
crontab -e crontab -l -u root #查看root用戶 基本格式 : *  *  *  *  *  command 分 時 日 月 周 命令 第1列表示分鐘1~59 每分鐘用*或者 */1表示 第2列表示小時1~23(0表示0點) 第3列表示日期1~31 第4列表示月份1~12 第5列標識號星期0~6(0表示星期天) 第6列要運行的命令 每個月一、10、22日的4 : 45重啓apache 45 4 1,10,22 * * /usr/local/etc/rc.d/lighttpd restart 天天18 : 00至23 : 00之間每隔30分鐘重啓apache 0,30 18-23 * * * /usr/local/etc/rc.d/lighttpd restart 每個月的4號與每週一到週三的11點重啓apache 0 11 4 * mon-wed /usr/local/etc/rc.d/lighttpd restart 晚上11點到早上7點之間,每隔一小時重啓apache * 23-7/1 * * * /usr/local/etc/rc.d/lighttpd restart

 

六、精簡開機自啓動服務

修改啓動服務
systemctl 是管制服務的主要工具,它整合了chkconfig 與 service功能於一體。
systemctl is-enabled iptables.service   #查詢防火牆是否開機啓動
systemctl restart sshd #有可能不須要加service
systemctl is-enabled servicename.service #查詢服務是否開機啓動
systemctl enable *.service #開機運行服務
systemctl disable *.service #取消開機運行
systemctl start *.service #啓動服務
systemctl stop *.service #中止服務
systemctl restart *.service #重啓服務
systemctl reload *.service #從新加載服務配置文件
systemctl status *.service #查詢服務運行狀態
systemctl --failed #顯示啓動失敗的服務
  

七、定時自動清理 cat /var/spool/postfix/maildrop/目錄垃圾文件,放置inode節點被佔滿

 centos7默認安裝了postfix郵件服務,所以郵件位置 /var/spool/postfix/maildrop/會存在垃圾文件,若是長時間不清理,會致使inode數量不夠用,從而沒法存放文件

mkdir /server/scripts -p
vi /server/scripts/spool_clean.sh
#!/bin/sh
find/var/spool/clientmqueue/-typef -mtime +30|xargsrm-f

而後將其加入到crontab定時任務中

echo '*/30 * * * * /bin/sh /server/scripts/spool_clean.sh >/dev/null 2>&1' >> /var/spool/cron/root

 

八、變動默認的ssh服務端口,禁止root用戶遠程鏈接

可參考http://www.javashuo.com/article/p-ymrxsonm-br.html

咱們默認不會禁止root登陸,端口酌情處理

 

九、鎖定關鍵文件系統

加鎖,不可修改加鎖文件
[root@jokerpro ~]# chattr +i /etc/passwd
[root@jokerpro ~]# lsattr /etc/passwd
----i--------e-- /etc/passwd
去鎖,能夠修改文件
[root@jokerpro ~]# chattr -i /etc/passwd 
[root@jokerpro ~]# lsattr /etc/passwd   
-------------e-- /etc/passwd

使用chattr命令後,爲了安全咱們須要將其更名

mv /usr/bin/chattr /usr/bin/任意名稱

 

十、調整文件描述符大小

  文件描述符是由無符號整數表示的句柄,進程使用它來標識打開的文件。文件描述符與包括相關信息(文件的打開模式,文件的位置類型,文件的出始類型等)的文件對象相關聯,這些信息被稱做文件的上下文。文件描述符的有效範圍是0到OPEN_MAX。
  對於內核而言,全部打開的文件都是經過文件描述符引用的,當打開一個現有文件或建立一個新文件時,內核向進程返回一個文件描述符。當讀或寫一個文件時,使用open或create返回的文件描述符標識該文件,並將其做爲參數傳遞給read或write。

可經過ulimit -a查看當前設置

# ulimit -a
core file size          (blocks, -c) 0
data seg size           (kbytes, -d) unlimited scheduling priority (-e) 0 file size (blocks, -f) unlimited pending signals (-i) 3895 max locked memory (kbytes, -l) 64 max memory size (kbytes, -m) unlimited open files (-n) 65535 # 文件描述符 pipe size (512 bytes, -p) 8 POSIX message queues (bytes, -q) 819200 real-time priority (-r) 0 stack size (kbytes, -s) 8192 # 堆棧文件 cpu time (seconds, -t) unlimited max user processes (-u) 3895 virtual memory (kbytes, -v) unlimited file locks (-x) unlimited

 

文件描述符

查看linux服務器文件描述符設置的狀況
ulimit -n 1024 默認打開的文件描述符就是1024 對於高併發業務來說,默認值確定不夠 cat /etc/security/limits.conf 65535是最大支持的文件描述符 root soft nofile 65535 root hard nofile 65535 可使用下面一行來替代上面 * - nofile 65535 重啓便可

配置完成後,從新登陸便可查看。

提示:也能夠把ulimit -SHn 65535命令臨時生效,或者加入到/etc/rc.local,而後每次重啓生效

# cat >>/etc/rc.local<<EOF
# open files
ulimit -HSn 65535
# stack size
ulimit -s 65535
EOF

 

十一、調整字符集,使其支持中文

修改字符編碼,默認是LANG=en_US.UTF-8
修改該文件以前,能夠先查看已經安裝的語言包:
locale -a  可經過grep過濾查看是否有中文語言包
若是沒有語言包
yum install kde-l10n-Chinese  
yum reinstall glibc-common  
安裝完成後經過vi命令編輯配置文件
vim /etc/locale.conf
LANG="zh_CN.UTF-8"
source /etc/locale.conf 

 

十二、去除系統及內核版本登陸前的屏幕顯示

# cat /etc/redhat-release 
CentOS Linux release 7.4.1708 (Core) 
# cat /etc/issue
\S
Kernel \r on an \m

 

1三、禁止linux系統被ping

# 開啓禁止ping
echo "net.ipv4.icmp_echo_ignore_all=1" 1>> /etc/sysctl.conf sysctl -p
# 關閉禁止ping
首先要刪除 /etc/sysctl.conf 裏面net.ipv4.icmp_echo_ignore_all = 1
以後執行以下命令
echo 0 1> /proc/sys/net/ipv4/icmp_echo_ignore_all
# 後續就能夠經過更改 cat  /proc/sys/net/ipv4/icmp_echo_ignore_all文件
0 關閉 1 開啓

 

1四、歷史記錄

# 如下都是臨時生效,默認1000不須要更改
# 設置的是閒置帳號的超時時間
export TMOUT=10 10秒後提示超時時間
# 設置終端history顯示條數
export HISTSIZE=5 只顯示最近5條信息
# 上面的終端顯示對應的是 cat ~/.bash_history 
export HISTFILESIZE=5 該文件只保存5條信息
# 清空歷史記錄
history -c
# 指定條數刪除
history -d 歷史記錄條屬

 

1五、內核參數優化

說明:本優化適合apache,nginx,squid多種等web應用,特殊的業務也可能須要略做調整。

[root@jokerpro ~]# vi /etc/sysctl.conf
# 表示套接字由本端要求關閉,這個參數決定了它保持在FIN-wAIT-2狀態的時間,默認值是60秒,建議調整爲2,該參數對應系統路徑爲:/proc/sys/net/ipv4/tcp_fin_timeout 60
net.ipv4.tcp_fin_timeout = 2

# 表示開啓重用,容許TIME-wAIT sockets從新用於新的TCP連接,默認值爲0,表示關閉,該參數對應系統路徑爲:/proc/sys/net/ipv4/tcp_tw_reuse 0
net.ipv4.tcp_tw_reuse = 1
# 表示開啓TCP連接中TIME_WAIT sockets的快速回收,該參數對應系統路徑爲:/proc/sys/net/ipv4/tcp_tw_recycle,默認爲0 表示關閉,不建議開啓,由於nat網絡問題
net.ipv4.tcp_tw_recycle = 0
# reuse和recycle這倆個參數是爲防止生產環境下web,squid等業務服務器time_wait網絡狀態數量過多設置的
注意:
tcp TIME_WAIT
進入主題前必須作鋪墊啊,講講TIME_WAIT.由於TCP鏈接是雙向的,因此在關閉鏈接的時候,兩個方向各自都須要關閉。先發FIN包的一方執行的是主動關閉;後發FIN包的一方執行的是被動關閉。主動關閉的一方會進入TIME_WAIT狀態,而且在此狀態停留兩倍的MSL(最大報文存活時間,通常Linux內核設置30秒)時長。

爲何主動方要傻乎乎等2MSL呢?不等,行不行?

TCP目的是可靠傳輸,主動關閉的一方發出FIN,被動方回覆ACK,接着被動方發送FIN,主動方收到被動關閉的一方發出的FIN包後,迴應ACK包,同時進入TIME_WAIT狀態,可是由於網絡緣由,主動關閉的一方發送的這個ACK包極可能延遲,從而觸發被動鏈接一方重傳FIN包。極端狀況下,這一去(ACK去被動方)一回(重傳FIN回來),就是兩倍的MSL時長。

若是主動關閉的一方跳過TIME_WAIT直接進入CLOSED,或者在TIME_WAIT停留的時長不足兩倍的MSL,那麼當被動關閉的一方早先發出的FIN延遲包到達或者重傳FIN包到達後,就可能出現相似下面的問題:

主動方舊的TCP鏈接已經不存在了,主動方只能返回RST包
主動方新的TCP鏈接被創建起來了,延遲包可能干擾新的鏈接
因此, TIME_WAIT必須等,2MSL不能少

減小TIME_WAIT
TIME_WAIT期間,資源不會釋放,如今都追求高性能高併發,快速釋放資源是躲不掉的.對於客戶端由於有端口65535問題,TIME_WAIT過多直接影響處理能力. 對於服務器,無故口數量限制的問題,Linux優化也很給力,每一個處於TIME_WAIT 狀態下鏈接內存消耗不多, 並且也能經過tcp_max_tw_buckets = ${你要的閾值} 配置最大上限,可是對於短鏈接爲主的web服務器,幾十萬的鏈接,基數很大,耗得內存也不小哦.快速釋放老是好的

tcp_tw_recycle:回收TIME_WAIT鏈接
對客戶端和服務器同時起做用,開啓後在 3.5*RTO 內回收,RTO 200ms~ 120s 具體時間視網絡情況。RTO(Retransmission TimeOut)重傳超時時間.內網情況比tcp_tw_reuse 稍快,公網尤爲移動網絡大多要比tcp_tw_reuse 慢,優勢就是可以回收服務端的TIME_WAIT數量

可是,有個小坑:當多個客戶端經過NAT方式聯網並與服務端交互時,服務端看到的是同一個IP,也就是說對服務端而言這些客戶端實際上等同於一個,惋惜因爲這些客戶端的時間戳可能存在差別,因而乎從服務端的視角看,即可能出現時間戳錯亂的現象,進而直接致使時間戳小的數據包被丟棄。客戶端處於NAT很常見,基本公司家庭網絡都走NAT.

tcp_tw_reuse:複用TIME_WAIT鏈接 只對客戶端起做用,1秒後才能複用,當建立新鏈接的時候,若是可能的話會考慮複用相應的TIME_WAIT鏈接。一般認爲tcp_tw_reuse比tcp_tw_recycle安全一些,這是由於一來TIME_WAIT建立時間必須超過一秒纔可能會被複用;二來只有鏈接的時間戳是遞增的時候纔會被複用。

客戶端請求服務器,服務器響應後主動關閉鏈接,TIME_WAIT存在於服務器,服務器是被鏈接者,沒有複用一說,因此只對客戶端起做用.若是是客戶端主動關閉,TIME_WAIT存在於客戶端,這個時候再次鏈接服務器,能夠複用以前TIME_WAIT留下的半廢品.

tcp_timestamps:以上兩點,必須在客戶端和服務端timestamps 開啓時才管用(默認開啓) 須要根據timestamp的遞增性來區分是否新鏈接
總結
客戶端tcp_tw_reuse複用鏈接管用, tcp_tw_recycle有用,可是客戶端主要不是接受鏈接,用處不大
服務器tcp_tw_recycle回收鏈接管用,tcp_tw_reuse複用無效.爲了減小TIME_WAIT留在服務器,能夠在服務器開啓KeepAlive,儘可能不讓服務器主動關閉,而是客戶端主動關閉,減小TIME_WAIT產生.
reuse/recycle
 
 

# 表示開啓SYN Cookies功能,當出現SYN等待隊列溢出時,啓用Cookies來處理,可防範少許SYN攻擊,該參數對應系統路徑爲:/proc/sys/net/ipv4/tcp_syscookies,默認爲1,表示開啓
net.ipv4.tcp_syncookies = 1

# 表示當keepalive啓用時,TCP發送keepalive消息的頻度,默認是2小時,建議更改成10分鐘,該參數對應系統路徑爲:/proc/sys/net/ipv4/tcp_keepalive_time,默認爲7200秒
net.ipv4.tcp_keepalive_time =600

# 該選項用來設定容許系統打開的端口範圍,即用於向外連接的端口範圍,該參數對應系統路徑爲:/proc/sys/net/ipv4/ip_local_port_range 默認,32768 60999
net.ipv4.ip_local_port_range = 32768   60999

# 表示SYN隊列的長度,默認爲1024,建議加大隊列的長度,爲8182或更多,這樣能夠容納更多等待連接的網絡鏈接數,該參數爲服務器端用於記錄那些還沒有收到客戶端確認信息的連接請求的最大值,
該參數對應系統路徑爲:/proc/sys/net/ipv4/tcp_max_syn_backlog
net.ipv4.tcp_max_syn_backlog = 1024
# 該選項默認值是128,這個參數用於調節系統同時發起的TCP鏈接數,在高併發的請求中,默認的值可能會致使連接超時或重傳,所以,須要結合併發請求數來調節此值,
該參數對應系統路徑爲:/proc/sys/net/ipv4/somaxconn 128 # 默認沒有這個配置,須要本身生成
net.core.somaxconn = 1024
注意:
socket接收的全部鏈接都是存放在隊列類型的數據結構中,關鍵問題是這種隊列有兩個,並且其長度都是能夠設置的。
 
分別是下面兩個內核參數:
 
/proc/sys/net/ipv4/tcp_max_syn_backlog
 
/proc/sys/net/core/somaxconn
 
其中:
 
tcp_max_syn_backlog是指定所能接受SYN同步包的最大客戶端數量,即半鏈接上限;
 
somaxconn是指服務端所能accept即處理數據的最大客戶端數量,即完成鏈接上限。
 
對於沒有調優的新裝的centOS6.5系統,這兩個參數的值都是128。
 
 
這麼描述雖然精確,可是沒有必定基礎,不熟練網絡編程的人理解起來很費勁。
 
打個簡單的比方:
 
某某發佈公告要邀請四海以內若干客人到場參加酒席。客人蔘加酒席分爲兩個步驟:
 
1、到大廳;
 
2、找到座位(吃東西,好比糖果、飯菜、酒等)。
 
tcp_max_syn_backlog用於指定酒席現場面積容許容納多少人進來;
 
somaxconn用於指定有多少個座位。
 
顯然tcp_max_syn_backlog>=somaxconn。
 
若是要前來的客人數量超過tcp_max_syn_backlog,那麼多出來的人雖然會跟主任見面握手,可是要在門外等候;
 
若是到大廳的客人數量大於somaxconn,那麼多出來的客人就會沒有位置坐(必須坐下才能吃東西),只能等待有人吃完有空位了才能吃東西。
 
那麼問題來了:
 
somaxconn是內核裏的參數,listen函數有個參數backlog,若是在listen方法裏面指定該參數大於somaxconn的值,從新編譯並啓動程序,服務端所能接收的完整的鏈接數上限是backlog呢仍是somaxconn?
 
答案很簡單,listen方法指定的backlog是在用戶態指定的,內核態的參數優先級高於用戶態的參數,因此即便在listen方法裏面指定backlog是一個大於somaxconn的值,socket在內核態運行時還會檢查一次somaxconn,若是鏈接數超過somaxconn就會等待。
 
就至關於主人指定了能有多少座位沒用,客人到了現場,準備入座時,還要看酒店的客戶經理判斷能有多少個座位。
 
 
 
結論:
 
在沒有調優的centOS7.4版本的服務器上,因爲受到系統級別的限制,在該服務器上運行的服務端程序,在同一時間,最大隻能接受128個客戶端發起持久鏈接,而且只能處理128個客戶端的數據通訊
tcp_max_syn_backlog/somaxconn
 
# 表示系統同時保持TIME_WAIT套接字的最大數量,若是超過這個數值,TIME_WAIT套接字將馬上被清除並打印警告信息,默認爲5000,對於Aapache,Nginx等服務器來講能夠將其調低一點,
如改成5000-30000,不用業務的服務器也能夠給大一點,好比LVS,Squid,該參數對應系統路徑爲:/proc/sys/net/ipv4/tcp_max_tw_buckets net.ipv4.tcp_max_tw_buckets = 5000

# 表示內核放棄創建連接以前發送SYN包的數量,該參數對應系統路徑爲:/proc/sys/net/ipv4/tcp_syn_retries,默認是6
net.ipv4.tcp_syn_retries = 1
# 參數的值決定了內核放棄連接以前發送SYN+ACK包的數量,該參數對應系統路徑爲:/proc/sys/net/ipv4/tcp_synack_retries,默認是2
net.ipv4.tcp_synack_retries = 1


# 表示當每一個網絡接口接收數據包的速率比內核處理這些包的速率快時,容許發送到隊列的數據包最大數,該參數對應系統路徑爲:/proc/sys/net/ipv4/netdev_max_backlog,默認值爲1000
net.core.netdev_max_backlog = 1000  # 默認沒有這個配置,須要本身生成

# 用於設定系統中最多有多少個TCP套接字不被關聯到任何一個用戶文件句柄上,若是超過這個數值,孤立連接將當即被複位並打印出警號信息,這個限制只是爲了防止簡單的DoS攻擊,不能過度依靠這個限制甚至
人爲減少這個值,更多的狀況是增長這個值,默認是4096,建議該值修改成2000,該參數對應系統路徑爲:/proc/sys/net/ipv4/tcp_max_orphans net.ipv4.tcp_max_orphans = 2000

# 如下參數是對iptables防火牆的優化,防火牆不開會有提示,能夠忽略不理。
net.ipv4.ip_conntrack_max = 25000000
net.ipv4.netfilter.ip_conntrack_max = 25000000
net.ipv4.netfilter.ip_conntrack_tcp_timeout_established = 180
net.ipv4.netfilter.ip_conntrack_tcp_timeout_time_wait = 120
net.ipv4.netfilter.ip_conntrack_tcp_timeout_close_wait = 60
net.ipv4.netfilter.ip_conntrack_tcp_timeout_fin_wait = 120
注意:
不少TIME_WAIT鏈接致使Cannot assign requested address的解決辦法



客戶端connect服務器,執行必定時間後,接口返回-99的錯誤

查看錯誤信息 OS error code  99:  Cannot assign requested address

猜測端口被用光的緣由,網絡搜索獲得一個解釋:客戶端頻繁的連服務器,因爲每次鏈接都在很短的時間內結束,致使不少的TIME_WAIT,以致於用光了可用的端口號,因此新的鏈接沒辦法綁定端口,即「Cannot assign requested address」

經過netstat,的確看到不少TIME_WAIT狀態的鏈接

由於是調用API,因此沒法對鏈接進行opt設置,只能經過設置系統配置得以解決

解決辦法:

執行命令修改以下2個內核參數   
sysctl -w net.ipv4.tcp_timestamps=1  開啓對於TCP時間戳的支持,若該項設置爲0,則下面一項設置不起做用

sysctl -w net.ipv4.tcp_tw_recycle=1  表示開啓TCP鏈接中TIME-WAIT sockets的快速回收



常常檢查apache的鏈接數,會發現不少無用的time_wait鏈接。有人說這是正常的,是由於一個請求中途中斷形成的;還有人說微軟的IE鏈接時產生的Time_wait會比用Firefox鏈接時多。我的認爲有必定的Time_wait是正常的,若是超過了鏈接數的比例就不是很正常,因此仍是找來方法解決一下。

先檢查一下time wait的值:
[root@aaa1 ~]#sysctl -a | grep time | grep wait
net.ipv4.netfilter.ip_conntrack_tcp_timeout_time_wait = 120
net.ipv4.netfilter.ip_conntrack_tcp_timeout_close_wait = 60
net.ipv4.netfilter.ip_conntrack_tcp_timeout_fin_wait = 120

這裏解決問題的關鍵是如何可以重複利用time_wait的值,檢查net.ipv4.tcp_tw當前值:
[root@aaa1 ~]# sysctl -a|grep net.ipv4.tcp_tw
net.ipv4.tcp_tw_reuse = 0
net.ipv4.tcp_tw_recycle = 0
增長或修改net.ipv4.tcp_tw值,將當前的值更改成1分鐘(reuse是表示是否容許從新應用處於TIME-WAIT狀態的socket用於新的TCP鏈接; recycle是加速TIME-WAIT sockets回收):
[root@aaa1 ~]# vi /etc/sysctl.conf
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_tw_recycle = 1
使內核參數生效:
[root@aaa1 ~]# sysctl -p
用netstat再觀察時會發現已經恢復正常。

結合DDOS和TIME_WAIT過多,建議增長以下參數設置:
# Use TCP syncookies when needed
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_synack_retries=3
net.ipv4.tcp_syn_retries=3
net.ipv4.tcp_max_syn_backlog=2048
# 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 16777216
net.ipv4.tcp_wmem = 4096 65536 16777216
# Increase number of ports available
net.ipv4.tcp_fin_timeout = 30
net.ipv4.tcp_keepalive_time = 300
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_tw_recycle = 1
net.ipv4.ip_local_port_range = 5000 65000


附:查看當前的鏈接數情況
netstat -nat|awk '{print awk $NF}'|sort|uniq -c|sort -n
1 established
1 State
2 LAST_ACK
4 CLOSING
4 FIN_WAIT2
9 LISTEN
17 FIN_WAIT1
18 SYN_RECV
27 ESTABLISHED
811 TIME_WAIT
上面的命令能夠幫助分析哪一種tcp狀態數量異常。其中的SYN_RECV表示正在等待處理的請求數;ESTABLISHED表示正常數據傳輸狀態;TIME_WAIT表示處理完畢,等待超時結束的請求數。

附:查看IP鏈接數情況
netstat -nat|grep ":80"|awk '{print $5}' |awk -F: '{print $1}' | sort| uniq -c|sort -n
發現異常的,能夠封了這個IP



===============



TCP/IP TIME_WAIT狀態原理


TIME_WAIT狀態原理

----------------------------

通訊雙方創建TCP鏈接後,主動關閉鏈接的一方就會進入TIME_WAIT狀態。

客戶端主動關閉鏈接時,會發送最後一個ack後,而後會進入TIME_WAIT狀態,再停留2個MSL時間(後有MSL的解釋),進入CLOSED狀態。

下圖是以客戶端主動關閉鏈接爲例,說明這一過程的。



 

 

 

TIME_WAIT狀態存在的理由

----------------------------

TCP/IP協議就是這樣設計的,是不可避免的。主要有兩個緣由:

1)可靠地實現TCP全雙工鏈接的終止

TCP協議在關閉鏈接的四次握手過程當中,最終的ACK是由主動關閉鏈接的一端(後面統稱A端)發出的,若是這個ACK丟失,對方(後面統稱B端)將重發出最終的FIN,所以A端必須維護狀態信息(TIME_WAIT)容許它重發最終的ACK。若是A端不維持TIME_WAIT狀態,而是處於CLOSED 狀態,那麼A端將響應RST分節,B端收到後將此分節解釋成一個錯誤(在java中會拋出connection reset的SocketException)。

於是,要實現TCP全雙工鏈接的正常終止,必須處理終止過程當中四個分節任何一個分節的丟失狀況,主動關閉鏈接的A端必須維持TIME_WAIT狀態 。

 

2)容許老的重複分節在網絡中消逝 

TCP分節可能因爲路由器異常而「迷途」,在迷途期間,TCP發送端可能因確認超時而重發這個分節,迷途的分節在路由器修復後也會被送到最終目的地,這個遲到的迷途分節到達時可能會引發問題。在關閉「前一個鏈接」以後,立刻又從新創建起一個相同的IP和端口之間的「新鏈接」,「前一個鏈接」的迷途重複分組在「前一個鏈接」終止後到達,而被「新鏈接」收到了。爲了不這個狀況,TCP協議不容許處於TIME_WAIT狀態的鏈接啓動一個新的可用鏈接,由於TIME_WAIT狀態持續2MSL,就能夠保證當成功創建一個新TCP鏈接的時候,來自舊鏈接重複分組已經在網絡中消逝。

 

 

 

 

MSL時間

----------------------------

MSL就是maximum segment lifetime(最大分節生命期),這是一個IP數據包能在互聯網上生存的最長時間,超過這個時間IP數據包將在網絡中消失 。MSL在RFC 1122上建議是2分鐘,而源自berkeley的TCP實現傳統上使用30秒。

 

TIME_WAIT狀態維持時間

----------------------------

TIME_WAIT狀態維持時間是兩個MSL時間長度,也就是在1-4分鐘。Windows操做系統就是4分鐘。

 

 

 

 

用於統計當前各類狀態的鏈接的數量的命令

---------------------------

#netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'

 

返回結果以下:

LAST_ACK 14

SYN_RECV 348

ESTABLISHED 70

FIN_WAIT1 229

FIN_WAIT2 30

CLOSING 33

TIME_WAIT 18122

 

對上述結果的解釋:

CLOSED:無鏈接是活動的或正在進行

LISTEN:服務器在等待進入呼叫

SYN_RECV:一個鏈接請求已經到達,等待確認

SYN_SENT:應用已經開始,打開一個鏈接

ESTABLISHED:正常數據傳輸狀態

FIN_WAIT1:應用說它已經完成

FIN_WAIT2:另外一邊已贊成釋放

ITMED_WAIT:等待全部分組死掉

CLOSING:兩邊同時嘗試關閉

TIME_WAIT:另外一邊已初始化一個釋放

LAST_ACK:等待全部分組死掉

 

 

進一步論述這個問題:

===============================

 

 

--------------客戶端主動關閉鏈接-----------------------

注意一個問題,進入TIME_WAIT狀態的通常狀況下是客戶端。

大多數服務器端通常執行被動關閉,服務器不會進入TIME_WAIT狀態。

當在服務器端關閉某個服務再從新啓動時,服務器是會進入TIME_WAIT狀態的。

舉例:

1.客戶端鏈接服務器的80服務,這時客戶端會啓用一個本地的端口訪問服務器的80,訪問完成後關閉此鏈接,馬上再次訪問服務器的

80,這時客戶端會啓用另外一個本地的端口,而不是剛纔使用的那個本地端口。緣由就是剛纔的那個鏈接還處於TIME_WAIT狀態。

2.客戶端鏈接服務器的80服務,這時服務器關閉80端口,當即再次重啓80端口的服務,這時可能不會成功啓動,緣由也是服務器的連

接還處於TIME_WAIT狀態。

 

服務端提供服務時,通常監聽一個端口就夠了。例如Apach監聽80端口。

客戶端則是使用一個本地的空閒端口(大於1024),與服務端的Apache的80端口創建鏈接。

當通訊時使用短鏈接,並由客戶端主動關閉鏈接時,主動關閉鏈接的客戶端會產生TIME_WAIT狀態的鏈接,一個TIME_WAIT狀態的鏈接就佔用了一個本地端口。這樣在TIME_WAIT狀態結束以前,本地最多就能承受6萬個TIME_WAIT狀態的鏈接,就無故口可用了。

客戶端與服務端進行短鏈接的TCP通訊,若是在同一臺機器上進行壓力測試模擬上萬的客戶請求,而且循環與服務端進行短鏈接通訊,那麼這臺機器將產生4000個左右的TIME_WAIT socket,後續的短鏈接就會產生address already in use : connect的異常。

 

關閉的時候使用RST的方式,不進入 TIME_WAIT狀態,是否可行?

 

--------------服務端主動關閉鏈接------------------------------

服務端提供在服務時,通常監聽一個端口就夠了。例如Apach監聽80端口。

客戶端則是使用一個本地的空閒端口(大於1024),與服務端的Apache的80端口創建鏈接。

當通訊時使用短鏈接,並由服務端主動關閉鏈接時,主動關閉鏈接的服務端會產生TIME_WAIT狀態的鏈接。

因爲都鏈接到服務端80端口,服務端的TIME_WAIT狀態的鏈接會有不少個。

假如server一秒鐘處理1000個請求,那麼就會積壓240秒*1000=24萬個TIME_WAIT的記錄,服務有能力維護這24萬個記錄。

 

大多數服務器端通常執行被動關閉,服務器不會進入TIME_WAIT狀態。

服務端爲了解決這個TIME_WAIT問題,可選擇的方式有三種:

     保證由客戶端主動發起關閉(即作爲B端)

     關閉的時候使用RST的方式

     對處於TIME_WAIT狀態的TCP容許重用

 

通常Apache的配置是:

Timeout 30  

KeepAlive On   #表示服務器端不會主動關閉連接  

MaxKeepAliveRequests 100  

KeepAliveTimeout 180  

表示:Apache不會主動關閉連接,

兩種狀況下Apache會主動關閉鏈接:

一、Apache收到了http協議頭中有客戶端要求Apache關閉鏈接信息,如setRequestHeader("Connection", "close");  

2、鏈接保持時間達到了180秒的超時時間,將關閉。

 

若是配置以下:

KeepAlive Off   #表示服務器端會響應完數據後主動關閉連接  
TIME_WAIT
# 使配置文件生效
[root@jokerpro ~]# sysctl –p 

提示:

因爲CentOS7.X系統中的模塊名不是ip_conntrack,而是nf_conntrack,因此在/etc/sysctl.conf優化時,須要把net.ipv4.netfilter.ip_conntrack_max 這種老的參數,改爲net.netfilter.nf_conntrack_max這樣才能夠。

即對防火牆的優化,在5.8上是

net.ipv4.ip_conntrack_max = 25000000
net.ipv4.netfilter.ip_conntrack_max = 25000000
net.ipv4.netfilter.ip_conntrack_tcp_timeout_established = 180
net.ipv4.netfilter.ip_conntrack_tcp_timeout_time_wait = 120
net.ipv4.netfilter.ip_conntrack_tcp_timeout_close_wait = 60
net.ipv4.netfilter.ip_conntrack_tcp_timeout_fin_wait = 120

對於 ip_conntrack_max 計算方法

-容許的最大跟蹤鏈接條目,在這篇文檔中咱們叫做CONNTRACK_MAX 
 
CONNTRACK_MAX = RAMSIZE (in bytes) / 16384 / (x / 32) 
這裏x是指針的bit數,(例如,32或者64bit)

內存爲8G
CONNTRACK_MAX = 8*1024*1024*1024 / 16384 / (64 / 32) 
CONNTRACK_MAX

 

在7.4上是

net.nf_conntrack_max = 25000000
net.netfilter.nf_conntrack_max = 25000000
net.netfilter.nf_conntrack_tcp_timeout_established = 180
net.netfilter.nf_conntrack_tcp_timeout_time_wait = 120
net.netfilter.nf_conntrack_tcp_timeout_close_wait = 60
net.netfilter.nf_conntrack_tcp_timeout_fin_wait = 120

另外,在此優化過程當中可能會有報錯:

一、5.8版本上

error: "net.ipv4.ip_conntrack_max"is an unknown key
error: "net.ipv4.netfilter.ip_conntrack_max"is an unknown key
error: "net.ipv4.netfilter.ip_conntrack_tcp_timeout_established"is an unknown key
error: "net.ipv4.netfilter.ip_conntrack_tcp_timeout_time_wait"is an unknown key
error: "net.ipv4.netfilter.ip_conntrack_tcp_timeout_close_wait"is an unknown key
error: "net.ipv4.netfilter.ip_conntrack_tcp_timeout_fin_wait"is an unknown key

這個錯誤多是你的防火牆沒有開啓或者自動處理可載入的模塊ip_conntrack沒有自動載入,解決辦法有二,一是開啓防火牆,二是自動處理開載入的模塊ip_conntrack

modprobe ip_conntrack
echo "modprobe ip_conntrack">> /etc/rc.local

二、6.4版本上

error: "net.nf_conntrack_max"isan unknown key
error: "net.netfilter.nf_conntrack_max"isan unknown key
error: "net.netfilter.nf_conntrack_tcp_timeout_established"isan unknown key
error: "net.netfilter.nf_conntrack_tcp_timeout_time_wait"isan unknown key
error: "net.netfilter.nf_conntrack_tcp_timeout_close_wait"isan unknown key
error: "net.netfilter.nf_conntrack_tcp_timeout_fin_wait"isan unknown key

這個錯誤多是你的防火牆沒有開啓或者自動處理可載入的模塊ip_conntrack沒有自動載入,解決辦法有二,一是開啓防火牆,二是自動處理開載入的模塊ip_conntrack

modprobe nf_conntrack
echo "modprobe nf_conntrack">> /etc/rc.local

三、6.4版本上

error: "net.bridge.bridge-nf-call-ip6tables"isan unknown key
error: "net.bridge.bridge-nf-call-iptables"isan unknown key
error: "net.bridge.bridge-nf-call-arptables"isan unknown key

這個錯誤是因爲自動處理可載入的模塊bridge沒有自動載入,解決辦法是自動處理開載入的模塊ip_conntrack

modprobe bridge
echo "modprobe bridge">> /etc/rc.local
相關文章
相關標籤/搜索