[TOC]
## 查找問題
### nginx timewait過多
> 在高并發短連接的TCP服務器上,當服務器處理完請求后主動正常關閉TCP連接,都會出現TIMEWAIT
> 比如取一個web頁面,1秒鐘的http短連接處理完業務,在關閉連接之后,這個業務用過的端口會停留在TIMEWAIT狀態幾分鐘,而這幾分鐘,其他HTTP請求來臨的時候是無法占用此端口的
> 當如果NGINX或者PHP-FPM 的TIMEWAIT過多,可以考慮加大連接數、以及開啟TCP重用功能
```
netstat -n|grep :80 #nginx tcp狀態
netstat -n|grep :9000 # fpm tcp狀態
netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'
```

### mysql sleep過多
> 出現的問題,同nginx一樣,采用max_connetions加大,wait_timeout改小
#### 查看TCP進程狀態
```
netstat -n|grep :3306
```
#### 查看MYSQL連接狀態
```
SHOW FULL PROCESSLIST
```
或者
```
SELECT * FROM information_schema.processlist WHERE `time`>100 ORDER BY TIME DESC
```
> 該方式可以根據條件進行查詢,更加靈活
## 1. NGINX釋放內存
> 一般linux 跑了一段時間后,buff/cache會急劇增加,導致網站無法訪問,這個時候需要寫一個腳本,每天晚上進行釋放。
> cd /home/www/
> vim clear_cache.sh
```
#!/bin/bash
sync
echo 1 > /proc/sys/vm/drop_caches
echo 2 > /proc/sys/vm/drop_caches
echo 3 > /proc/sys/vm/drop_caches
echo "清理結束"
```
> chmod 777 clear_cache.sh
> vim /etc/crontab
```
0 8 * * * root /home/www/clear_cache.sh
```
## 2. 修改worker進程數
> 一般為cpu數的1~2倍
> vim nginx.conf
```
# worker進程數這里設置的2倍
worker_processes 4;
# worker進程分配到對應的cpu方式改為auto自動化,nginx1.9之后支持auto
worker_cpu_affinity auto;
```
## 3. nginx優化配置
> A)`worker_connections`:單個worker進程最大連接數
> B) `worker_rlimit_nofile`:單個worker進程的最大打開文件數,(修改的同時系統環境下的ulimit -n 需要大于此值,不然容易報`too many open files`)
> C) `keepalive_timeout`:連接超時時間,(http1.1出了一個保持tcp連接復用,供其他的靜態資源可以復用之前打開的連接資源,盡可能設置小,建議為1分鐘,這樣不會導致TCP的長期間waiting)
> D) `limit_conn perserver`:限制當前站點最大并發數
> E) `limit_conn perip`:限制單個IP訪問最大并發數
> F) `limit_rate`:限制每個請求的流量上限(單位:KB)
> `vim /etc/security/limits.conf`,可通過`ulimit -a`查看是否生效
> 如果不是1048576 (默認1024),需進行修改
~~~
# 該方式每次重啟就會失效,記得再次設置
ulmint -n 1048576
~~~
或者
```
vim /etc/security/limits.conf
root soft nofile 1048576
root hard nofile 1048576
* soft nofile 1048576
* hard nofile 1048576
```


## 4. php-fpm優化配置
### 開啟慢日志
> slowlog:慢日志路徑
> request_slowlog_timeout:超時時間(秒)
### 進程優化
> max_children:允許創建的最大子進程數
> start_servers:起始進程數(服務啟動后初始進程數量)
> min_spare_servers:最小空閑進程數(清理空閑進程后的保留數量)
> max_spare_servers:最大空閑進程數(當空閑進程達到此值時清理)
> 本文采用的是動態進程模式,內存開支小,穩定;靜態模式對內存開銷較大,但并發能力較好,本文沒有涉及
> 每個PHP子進程需要20MB左右內存,過大的max_children會導致服務器不穩定

## 5. 系統層面進行調優
> `vim /etc/sysctl.conf`
```
net.core.somaxconn = 65535 #最大tcp監聽連接數,默認128
net.core.netdev_max_backlog = 20000 #每個網絡接口接收數據包的速率比內核處理這些包的速率快時,允許送到隊列的數據包的最大數目,默認1000
net.ipv4.tcp_max_syn_backlog = 16384 #記錄的那些尚未收到客戶端確認信息的連接請求的最大值,默認為1024
net.ipv4.tcp_max_tw_buckets = 180000 #TIME_WAIT的最大數量(盡量調大),超出的部分會被關閉掉,并且日志記錄報錯信息
net.ipv4.tcp_fin_timeout = 15 # 表示如果套接字由本端要求關閉,這個參數決定了它保持在FIN-WAIT-2狀態的時間,默認60
net.ipv4.tcp_max_orphans = 131072 #該參數用于設定系統中最多允許存在多少TCP套接字不被關聯到任何一個客戶文件句柄上,假如超過這個數字,沒有與客戶文件句柄關聯到TCP套接字將立即被復位,同時發出警告信息,這個限制只是為了簡單防治Dos攻擊,一般系統內存充足的情況下,可以增大這個參數,默認32768
net.ipv4.tcp_tw_reuse = 1 #開啟TIME-WAIT(空閑TCP)重用
net.ipv4.tcp_tw_recycle = 0 # (空閑TCP快速回收)不建議開啟,如果tcp_tw_recycle和tcp_timestamps同時開啟,服務器或者客戶機網絡處于NAT情況下,網絡會經常被斷開;
net.ipv4.tcp_syncookies = 0 #不做TCP洪水抵御
net.ipv4.tcp_timestamps?=?1 # 記錄TCP連接的最新時間戳
# 這里提一下
# 1. 要么 打開tcp_tw_recycle和tcp_timestamps選項
# 2. 要么 打開tcp_tw_reuse和tcp_timestamps選項
# 兩者選其一,我們上面的例子選擇的是第2選項,安全穩妥,不能同時都打開。
# tcp_tw_recycle 選項不適用于NAT/LB的情況,容易網絡丟失,并且在linux 4.10內核后徹底廢除了。
```
> `sysctl -p` 使其生效
> 為了以防tcp_timestamps、tcp_tw_recycle同時開啟,建議查看系統參數是否生效
~~~
cat /proc/sys/net/ipv4/tcp_timestamps
cat /proc/sys/net/ipv4/tcp_tw_recycle
cat /proc/sys/net/ipv4/tcp_tw_reuse
~~~
## 6. 進參數進行測試
> 使用ab進行測試
```
ab -c 1000 -n 1000000 http://www.test.com/test.html
```