php nginx mysql 網站優化方案記錄

朋友的php網站訪問很慢,叫我幫忙優化,我這裏記錄一下相關的優化信息,部分摘自網絡。

1Cpu

wKiom1M89oWBQKZTAARAfRf8Z64196.jpg

Top後看到大部分都是php-fpmmysql佔去的資源較多!

這裏隨便也鞏固一下linux top命令的知識,部分來自網絡,這個也是很有用的!

Top的第一、第二行:

Up 51days -------機器已經運行了51天了

2 users  ------- 現在機器上面有個連接用戶

Load average 0.16 0.10 0.07  ------- 分別是5分鐘、10分鐘、15分鐘平均負載

Tasks 245 total ------------現在一共245個進程

1 running   ----------有一個正在運行的進程

244 sleeping  ---------244個睡眠進程 (是不是有點多啊,具體是那些後面再具體查一下)

0 stopped  ----------- 0個被停止或者終止的進程(不明白這裏是什麼意思,是強制中斷的?)

0 zombie --------0個僵死的進程

第三行是現實cpu狀態的:

0.8%us ----------這是當前用戶進程佔去的cpu百分比

0.1%sy ---------這是當前系統進程佔去的cpu百分比

0.0%ni ---------這是nice狀態下佔去的百分比,nice是經過系統優化過的意思(這個係數越到是不是代表用戶跑的進程很垃圾啊,都要linux內核幫忙優化?又或者是在負載很大的時候系統纔會進行優化?)

98.4%id ---------idle空閒的cpu百分比(很多啊,證明cpu資源當前是足夠的啊!)

0.7%wa --------waite等待進程佔去cpu百分比(也不多啊!)

0.0%hi  --------hard interrupt 硬中斷請求

0.0%st  --------這個貌似是用到虛擬機的是纔會有的,網上有介紹是虛擬出來的cpu,在提升效率的時候往真的cpu資源偷取一定的資源,估計一般不是服務器做虛擬化的時候都用不到!

第四、五行是內存使用狀況:

Mem: 24692204k total

物理內存總量

10338168k  used

使用的物理內存總量

14354036k  free

空閒內存總量

1445008k  buffers

用作內核緩存的內存量

Swap: 1998832k total

交換區總量

3968k  used

使用的交換區總量

1994864k  free

空閒交換區總量

1188012k  cached

緩衝的交換區總量。內存中的內容被換出到交換區,而後又被換入到內存,但使用過的交換區尚未被覆蓋,該數值即爲這些內容已存在於內存中的交換區的大小。相應的內存再次被換出時可不必再對交換區寫入。

#Free

實際的程序可用內存數怎麼算呢?

free + (buffers + cached)

程序已用內存數又怎麼算呢?

used (buffers + cached)

buffer cache 的區別:

A buffer is something that has yet to be written to disk. Acache is something that has been read from the disk and stored for later use 從應用程序角度來看,buffers/cached是等於可用的,因爲buffer/cached是爲了提高文件讀寫的性能,當應用程序需在用到內存的時候,buffer/cached會很快地被回收。
所以從應用程序的角度來說,可用內存 = 系統free memory + buffers + cached.

buffers是指用來給塊設備做的緩衝大小,他只記錄文件系統的metadata以及 tracking in-flight pages.
cached是用來給文件做緩衝。
那就是說:buffers是用來存儲,目錄裏面有什麼內容,權限等等。
cached直接用來記憶我們打開的文件,如果你想知道他是不是真的生效,你可以試一下,先後執行兩次命令#man X ,你就可以明顯的感覺到第二次的開打的速度快很多。


第五行後面就是一些進程運行狀態:


列名

含義

PID

進程id

PPID

父進程id

RUSER

Real  user name

UID

進程所有者的用戶id

USER

進程所有者的用戶名

GROUP

進程所有者的組名

TTY

啓動進程的終端名。不是從終端啓動的進程則顯示爲 ?

PR

優先級

NI

nice值。負值表示高優先級,正值表示低優先級

P

最後使用的CPU,僅在多CPU環境下有意義

%CPU

上次更新到現在的CPU時間佔用百分比

TIME

進程使用的CPU時間總計,單位秒

TIME+

進程使用的CPU時間總計,單位1/100秒

%MEM

進程使用的物理內存百分比

VIRT

進程使用的虛擬內存總量,單位kb。VIRT=SWAP+RES

SWAP

進程使用的虛擬內存中,被換出的大小,單位kb。

RES

進程使用的、未被換出的物理內存大小,單位kb。RES=CODE+DATA

CODE

可執行代碼佔用的物理內存大小,單位kb

DATA

可執行代碼以外的部分(數據段+棧)佔用的物理內存大小,單位kb

SHR

共享內存大小,單位kb

nFLT

頁面錯誤次數

nDRT

最後一次寫入到現在,被修改過的頁面數。

S

進程狀態。
             D=不可中斷的睡眠狀態
             R=運行
             S=睡眠
             T=跟蹤/停止
             Z=殭屍進程

COMMAND

命令名/命令行

WCHAN

若該進程在睡眠,則顯示睡眠中的系統函數名

Flags

任務標誌,參考 sched.h

查看指定列:

默認情況下僅顯示比較重要的 PIDUSERPRNIVIRTRESSHRS%CPU%MEMTIME+COMMAND 列。
可以通過下面的快捷鍵來更改顯示內容:

5.1 f 鍵選擇顯示內容

通過 f 鍵可以選擇顯示的內容。按 f 鍵之後會顯示列的列表,按 a-z 即可顯示或隱藏對應的列,最後按回車鍵確定。

5.2 o 鍵改變顯示順序

o 鍵可以改變列的顯示順序。按小寫的 a-z 可以將相應的列向右移動,而大寫的 A-Z 可以將相應的列向左移動。最後按回車鍵確定。

5.3 F/O 鍵將進程按列排序

按大寫的 F O 鍵,然後按 a-z 可以將進程按照相應的列進行排序。而大寫的 R 鍵可以將當前的排序倒轉。

常用交互命令:

從使用角度來看,熟練的掌握這些命令比掌握選項還重要一些。這些命令都是單字母的,如果在命令行選項中使用了s選項,則可能其中一些命令會被屏蔽掉。
 Ctrl+L 擦除並且重寫屏幕。
h或者? 顯示幫助畫面,給出一些簡短的命令總結說明。
k 終止一個進程。系統將提示用戶輸入需要終止的進程PID,以及需要發送給該進程什麼樣的信號。一般的終止進程可以使用15信號;如果不能正常結束那就使用信號9強制結束該進程。默認值是信號15。在安全模式中此命令被屏蔽。
i 忽略閒置和僵死進程。這是一個開關式命令。
q 退出程序。
r 重新安排一個進程的優先級別。系統提示用戶輸入需要改變的進程PID以及需要設置的進程優先級值。輸入一個正值將使優先級降低,反之則可以使該進程擁有更高的優先權。默認值是10
S 切換到累計模式。
s 改變兩次刷新之間的延遲時間。系統將提示用戶輸入新的時間,單位爲s。如果有小數,就換算成m s。輸入0值則系統將不斷刷新,默認值是5 s。需要注意的是如果設置太小的時間,很可能會引起不斷刷新,從而根本來不及看清顯示的情況,而且系統負載也會大大增加。
f或者F 從當前顯示中添加或者刪除項目。
o或者O 改變顯示項目的順序。
l 切換顯示平均負載和啓動時間信息。
m 切換顯示內存信息。
t 切換顯示進程和CPU狀態信息。
c 切換顯示命令名稱和完整命令行。
M 根據駐留內存大小進行排序。
P 根據CPU使用百分比大小進行排序。
T 根據時間/累計時間進行排序。
   W 將當前設置寫入~/.toprc文件中。這是寫top配置文件的推薦方法。

最後的技能:top 命令小技巧:

1、輸入大寫P,則結果按CPU佔用降序排序。
2、輸入大寫M,結果按內存佔用降序排序。
3、按數字 1 則可以顯示所有CPU核心的負載情況。
4top -d 5    每隔 5 秒刷新一次,默認 1
5top -p 4360,4358    監控指定進程
6top -U johndoe    U’爲真實/有效/保存/文件系統用戶名。
7top -u 500    u’爲有效用戶標識
8top -bn 1    顯示所有進程信息,top -n 1 只顯示一屏信息,供管道調用
9top -M   #show memory summary in megabytes not kilobytes
10top -p 25097 -n 1 -b    # -b 避免輸出控制字符,管道調用出現亂碼
11top翻頁:top -bn1 | less
12、增強版的 tophtop


在檢查服務器資源情況的命令還有以下一些:

#vmstat 2 3

wKioL1M89nCA10veAAEZYekfIH8853.jpg

對上面每項的輸出解釋如下:
procs
r列表示運行和等待cpu時間片的進程數,這個值如果長期大於系統CPU的個數,說明CPU不足,需要增加CPU
b列表示在等待資源的進程數,比如正在等待I/O、或者內存交換等。
memory
swpd列表示切換到內存交換區的內存數量(以k爲單位)。如果swpd的值不爲0,或者比較大,只要siso的值長期爲0,這種情況下一般不用擔心,不會影響系統性能。
free列表示當前空閒的物理內存數量(以k爲單位)
buff列表示buffers cache的內存數量,一般對塊設備的讀寫才需要緩衝。
cache列表示page cached的內存數量,一般作爲文件系統cached,頻繁訪問的文件都會被cached,如果cache值較大,說明cached的文件數較多,如果此時IObi比較小,說明文件系統效率比較好。
swap
si列表示由磁盤調入內存,也就是內存進入內存交換區的數量。
so列表示由內存調入磁盤,也就是內存交換區進入內存的數量。
一般情況下,siso的值都爲0,如果siso的值長期不爲0,則表示系統內存不足。需要增加系統內存。
IO項顯示磁盤讀寫狀況
Bi列表示從塊設備讀入數據的總量(即讀磁盤)(每秒kb)。
Bo列表示寫入到塊設備的數據總量(即寫磁盤)(每秒kb
這裏我們設置的bi+bo參考值爲1000,如果超過1000,而且wa值較大,則表示系統磁盤IO有問題,應該考慮提高磁盤的讀寫性能。
system 顯示採集間隔內發生的中斷數
in列表示在某一時間間隔中觀測到的每秒設備中斷數。
cs列表示每秒產生的上下文切換次數。
上面這2個值越大,會看到由內核消耗的CPU時間會越多。
CPU項顯示了CPU的使用狀態,此列是我們關注的重點。
us列顯示了用戶進程消耗的CPU 時間百分比。us的值比較高時,說明用戶進程消耗的cpu時間多,但是如果長期大於50%,就需要考慮優化程序或算法。
sy列顯示了內核進程消耗的CPU時間百分比。Sy的值較高時,說明內核消耗的CPU資源很多。
根據經驗,us+sy的參考值爲80%,如果us+sy大於 80%說明可能存在CPU資源不足。
id 列顯示了CPU處在空閒狀態的時間百分比。
wa列顯示了IO等待所佔用的CPU時間百分比。wa值越高,說明IO等待越嚴重,根據經驗,wa的參考值爲20%,如果wa超過20%,說明IO等待嚴重,引起IO等待的原因可能是磁盤大量隨機讀寫造成的,也可能是磁盤或者磁盤控制器的帶寬瓶頸造成的(主要是塊操作)。
綜上所述,在對CPU的評估中,需要重點注意的是procsr列的值和CPU項中ussyid列的值。

檢查CPU性能的第二個工具是sarsar功能很強大,可以對系統的每個方面進行單獨的統計,但是使用sar命令會增加系統開銷,不過這些開銷是可以評估的,對系統的統計結果不會有很大影響。


下面是sar命令對某個系統的CPU統計輸出:
[root@webserver ~]# sar -u 3 5
Linux 2.6.9-42.ELsmp (webserver)       11/28/2008      _i686_  (8 CPU)

11:41:24 AM    CPU     %user     %nice  %system   %iowait    %steal    %idle
11:41:27 AM     all     0.88      0.00     0.29      0.00     0.00     98.83
11:41:30 AM     all     0.13      0.00     0.17      0.21     0.00     99.50
11:41:33 AM     all     0.04      0.00     0.04      0.00     0.00     99.92
11:41:36 AM     all     0.29      0.00     0.13      0.00     0.00     99.58
11:41:39 AM     all     0.38      0.00     0.17      0.04     0.00     99.41
Average:       all      0.34     0.00      0.16     0.05      0.00     99.45
對上面每項的輸出解釋如下:
%user列顯示了用戶進程消耗的CPU 時間百分比。
%nice列顯示了運行正常進程所消耗的CPU 時間百分比。
%system列顯示了系統進程消耗的CPU時間百分比。
%iowait列顯示了IO等待所佔用的CPU時間百分比
%steal列顯示了在內存相對緊張的環境下pagein強制對不同的頁面進行的steal操作
%idle列顯示了CPU處在空閒狀態的時間百分比。
這個輸出是對系統整體CPU使用狀況的統計,每項的輸出都非常直觀,並且最後一行Average是個彙總行,是上面統計信息的一個平均值。
需要注意的一點是:第一行的統計信息中包含了sar本身的統計消耗,所以%user列的值會偏高一點,不過,這不會對統計結果產生多大影響。
在一個多CPU的系統中,如果程序使用了單線程,會出現這麼一個現象,CPU的整體使用率不高,但是系統應用卻響應緩慢,這可能是由於程序使用單線程的原因,單線程只使用一個CPU,導致這個CPU佔用率爲100%,無法處理其它請求,而其它的CPU卻閒置,這就導致了整體CPU使用率不高,而應用緩慢現象的發生
針對這個問題,可以對系統的每個CPU分開查詢,統計每個CPU的使用情況:
[root@webserver ~]# sar -P 0 3 5
Linux 2.6.9-42.ELsmp (webserver)       11/29/2008      _i686_  (8 CPU)

06:29:33 PM    CPU     %user     %nice  %system   %iowait    %steal    %idle
06:29:36 PM       0     3.00      0.00     0.33      0.00     0.00     96.67
06:29:39 PM       0     0.67      0.00     0.33      0.00     0.00     99.00
06:29:42 PM       0     0.00      0.00     0.33      0.00     0.00     99.67
06:29:45 PM       0     0.67      0.00     0.33      0.00     0.00     99.00
06:29:48 PM       0     1.00      0.00     0.33      0.33      0.00    98.34
Average:         0      1.07     0.00      0.33     0.07      0.00     98.53
這個輸出是對系統的第一顆CPU的信息統計,需要注意的是,sar中對CPU的計數是從0開始的,因此,“sar -P 0 3 5”表示對系統的第一顆CPU進行信息統計,“sar -P 4 3 5”則表示對系統的第五顆CPU進行統計。依次類推。可以看出,上面的系統有八顆CPU


2、內存:

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

可以使用一下命令查使用內存最多的10個進程

ps -aux | sort -k4nr | head -n 10

或者top (然後按下M,注意大寫)

可以使用一下命令查使用CPU最多的10個進程

ps -aux | sort -k3nr | head -n 10

或者top (然後按下P,注意大寫)


mysql   11234  4.6  1.2 4509704 309872 ?      Ssl Feb08 3457:37 /usr/sbin/mysqld

www-data 31112  0.0 0.4 384968 99872 ?        S    03:10  0:03 php-fpm: pool www                                        

www-data 31082  0.0 0.3 374716 89560 ?        S    03:10  0:02 php-fpm: pool www                                        

www-data 31085  0.0 0.3 362656 77428 ?        S    03:10  0:01 php-fpm: pool www                                        

www-data 31086  0.0 0.3 364540 79100 ?        S    03:10  0:02 php-fpm: pool www                                        

www-data 31087  0.0 0.3 373984 88796 ?        S    03:10  0:03 php-fpm: pool www                                        

www-data 31089  0.0 0.3 366432 81048 ?        S    03:10  0:01 php-fpm: pool www                                        

www-data 31094  0.0 0.3 364804 79688 ?        S    03:10  0:03 php-fpm: pool www                                        

www-data 31097  0.0 0.3 370788 85620 ?        S    03:10  0:01 php-fpm: pool www                                        

www-data 31098  0.0 0.3 375548 90172 ?        S    03:10  0:03 php-fpm: pool www                                        


發現mysqlphp-fpm佔有的內存是最多的,於是就着手看看


進入mysql看看:

 Mysql>showglobal status like 'Innodb_buffer_pool_pages_data';

+-------------------------------+-------+

| Variable_name              | Value |

+-------------------------------+-------+

| Innodb_buffer_pool_pages_data | 7599  |

+-------------------------------+-------+

1 row in set (0.03 sec)

 Mysql>SHOWGLOBAL STATUS LIKE 'Innodb_buffer_pool_pages_total';

+--------------------------------+-------+

| Variable_name                  | Value |

+--------------------------------+-------+

| Innodb_buffer_pool_pages_total |8192  |

+--------------------------------+-------+

1 row in set (0.00 sec)

 Mysql>SHOWGLOBAL STATUS LIKE 'Innodb_page_size';

+------------------+-------+

| Variable_name    | Value |

+------------------+-------+

| Innodb_page_size | 16384 |

+------------------+-------+

1 row in set (0.00 sec)


'Innodb_buffer_pool_pages_data' X 100 /'Innodb_buffer_pool_pages_total'

當結果 > 95% 則增加 innodb_buffer_pool_size建議使用 ram total 75%
當結果 < 95% 則減少 innodb_buffer_pool_size
建議 'Innodb_buffer_pool_pages_data' X 'Innodb_page_size' X 1.05 /(1024*1024*1024)

貌似mysql也沒有太大的問題!

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


#free

           total       used       free    shared    buffers     cached

Mem:     24692204   21925456    2766748          0   5120908   10888396

-/+ buffers/cache:    5916152  18776052

Swap:     1998832       3972    1994860


內存佔用都90以上了,要釋放一下內存

#cat /proc/sys/vm/drop_caches

0

首先,/proc/sys/vm/drop_caches的值,默認爲0

# sync

手動執行sync命令(描述:sync 命令運行 sync 子例程。如果必須停止系統,則運行 sync 命令以確保文件系統的完整性。sync 命令將所有未寫的系統緩衝區寫到磁盤中,包含已修改的 i-node、已延遲的塊 I/O 和讀寫映射文件)

# echo 3 >/proc/sys/vm/drop_caches

# cat/proc/sys/vm/drop_caches

3

#free

           total       used       free    shared    buffers     cached

Mem:     24692204    4741228   19950976          0       9380    431832

-/+ buffers/cache:    4300016  20392188

Swap:     1998832       3972    1994860

一下子釋放了這麼多內存!


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



3io:

#iostat –d –k 1 10

參數 -d 表示,顯示設備(磁盤)使用狀態;-k某些使用block爲單位的列強制使用Kilobytes爲單位;1 10表示,數據顯示每隔1秒刷新一次,共顯示10次。

wKiom1M89rDxVqUxAALpUZT9sXc597.jpg

tps:該設備每秒的傳輸次數(Indicatethe number of transfers per second that were issued to the device.)。一次傳輸意思是一次I/O請求。多個邏輯請求可能會被合併爲一次I/O請求一次傳輸請求的大小是未知的。

kB_read/s:每秒從設備(driveexpressed)讀取的數據量;kB_wrtn/s:每秒向設備(drive expressed)寫入的數據量;kB_read:讀取的總數據量;kB_wrtn:寫入的總數量數據量;這些單位都爲Kilobytes

# iostat -d -x -k 1 10

wKioL1M89pWyI7K3AASQ_iAVvck011.jpg

rrqm/s:每秒這個設備相關的讀取請求有多少被Merge了(當系統調用需要讀取數據的時候,VFS將請求發到各個FS,如果FS發現不同的讀取請求讀取的是相同Block的數據,FS會將這個請求合併Merge);wrqm/s:每秒這個設備相關的寫入請求有多少被Merge了。

rsec/s:每秒讀取的扇區數;wsec/:每秒寫入的扇區數。r/sThe numberof read requests that were issued to the device per secondw/sThe numberof write requests that were issued to the device per second

await:每一個IO請求的處理的平均時間(單位是微秒毫秒)。這裏可以理解爲IO的響應時間,一般地系統IO響應時間應該低於5ms,如果大於10ms就比較大了。

%util:在統計時間內所有處理IO時間,除以總共統計時間。例如,如果統計間隔1秒,該設備有0.8秒在處理IO,而0.2秒閒置,那麼該設備的%util = 0.8/1 = 80%,所以該參數暗示了設備的繁忙程度。一般地,如果該參數是100%表示設備已經接近滿負荷運行了(當然如果是多磁盤,即使%util100%,因爲磁盤的併發能力,所以磁盤使用未必就到了瓶頸)。

一般iostat的用法命令如下:

iostat -d -k 1 10 #查看TPS和吞吐量信息
iostat -d -x -k 1 10 #查看設備使用率(%util)、響應時間(await
iostat -c 1 10 #查看cpu狀態


根據上面的iostat出來的數據,貌似服務器io也是沒有太大的問題!


4php+nginx的配置:

有時候搭建好的環境,在啓動的時候就無法啓動,如果沒有相關日誌記錄的話,不妨用stract命令來跟蹤一下程序的運行情況

#strace /usr/local/php/bin/php -i 2 >/tmp/php1.log ------查看php運行,並記錄在/tmp/php1.log裏面,這樣就看php1.log就知道哪裏出問題了。


phpnginx是通過php-fpm進行通信的,可以直接修改php-fpm.conf

影響PHP(5.0以上)運行效率的參數有如下:
pm = dynamic
pm.max_children = 512
pm.start_servers = 128
pm.min_spare_servers = 64
pm.max_spare_servers =256
pm.max_requests = 50000
下面一一介紹他們的作用:

pm = dynamic表示動態調整

pm.max_children = 512表示服務器最大允許運行的子進程,這個主要是爲了限制PHP運行,防止內存等資源被PHP耗光

pm.start_servers = 128表示啓動PHP的時候生成多少個子進程

pm.min_spare_servers = 64表示服務器在空閒的時候最小保持的子進程數,注意不是空閒的線程,而是在服務器空閒的時候要保持待命狀態的最小子進程數

pm.max_spare_servers =256表示服務器在空閒的時候最大保持的子進程數,注意不是空閒的線程,而是在服務器空閒的時候要保持待命狀態的最大子進程數

pm.max_requests = 50000表示每個子進程在respawning(重生也就是重啓)之前能要處理的最大請求數


對於LNMP架構
有幾個參數需要調整,且保持一直

1
nginx配置文件中:
vi /usr/local/lnmp/nginx/conf/nginx.conf
worker_connections 65535;

2
php配置文件中:
vi /usr/local/lnmp/php/etc/php-fpm.conf
rlimit_files = 65535

3
,操作系統中
vi /etc/sysctl.conf
fs.file-max = 65535
沒有這個選項這在最底部添加即可

4
,操作系統設置
ulimit -SHn 65535
echo "ulimit -SHn 65535" /etc/profile


nginx優化,我這裏引用了一下網上別人的方法,很值得借鑑

一般來說nginx配置文件中對優化比較有作用的爲以下幾項:

worker_processes 8;
nginx進程數,建議按照cpu數目來指定,一般爲它的倍數,平時設置爲2倍。

worker_cpu_affinity 00000001 0000001000000100 00001000 00010000 00100000 01000000 10000000;
爲每個進程分配cpu,上例中將8個進程分配到8cpu,當然可以寫多個,或者將一個進程分配到多個cpu。對worker_cu_affinity參數的優化參考:http://blog.haohtml.com/archives/14835

worker_rlimit_nofile 102400;
這個指令是指當一個nginx進程打開的最多文件描述符數目,理論值應該是最多打開文件數(ulimit -n)與nginx進程數相除,但是nginx分配請求並不是那麼均勻,所以最好與ulimit -n的值保持一致。

use epoll;
使用epollI/O模型,這個不用說了吧。

worker_connections 102400;
每個進程允許的最多連接數,理論上每臺nginx服務器的最大連接數爲worker_processes*worker_connections

keepalive_timeout 60;
keepalive超時時間。

client_header_buffer_size 4k;

客戶端請求頭部的緩衝區大小,這個可以根據你的系統分頁大小來設置,一般一個請求頭的大小不會超過1k,不過由於一般系統分頁都要大於1k,所以這裏設置爲分頁大小。分頁大小可以用命令getconf PAGESIZE取得。

open_file_cache max=102400 inactive=20s;
這個將爲打開文件指定緩存,默認是沒有啓用的,max指定緩存數量,建議和打開文件數一致,inactive是指經過多長時間文件沒被請求後刪除緩存。

open_file_cache_valid 30s;
這個是指多長時間檢查一次緩存的有效信息。

open_file_cache_min_uses 1;
open_file_cache指令中的inactive參數時間內文件的最少使用次數,如果超過這個數字,文件描述符一直是在緩存中打開的,如上例,如果有一個文件在inactive時間內一次沒被使用,它將被移除。

關於內核參數的優化(/etc/sysctl.conf)

net.ipv4.tcp_max_tw_buckets = 6000
timewait的數量,默認是180000

net.ipv4.ip_local_port_range =1024    65000
允許系統打開的端口範圍。

net.ipv4.tcp_tw_recycle = 1
啓用timewait快速回收。

net.ipv4.tcp_tw_reuse = 1
開啓重用。允許將TIME-WAIT sockets重新用於新的TCP連接。

net.ipv4.tcp_syncookies = 1
開啓SYN Cookies,當出現SYN等待隊列溢出時,啓用cookies來處理。

net.core.somaxconn = 262144
web應用中listen函數的backlog默認會給我們內核參數的net.core.somaxconn限制到128,而nginx定義的NGX_LISTEN_BACKLOG默認爲511,所以有必要調整這個值。

net.core.netdev_max_backlog = 262144
每個網絡接口接收數據包的速率比內核處理這些包的速率快時,允許送到隊列的數據包的最大數目。

net.ipv4.tcp_max_orphans = 262144
系統中最多有多少個TCP套接字不被關聯到任何一個用戶文件句柄上。如果超過這個數字,孤兒連接將即刻被複位並打印出警告信息。這個限制僅僅是爲了防止簡單的DoS***,不能過分依靠它或者人爲地減小這個值,更應該增加這個值(如果增加了內存之後)

net.ipv4.tcp_max_syn_backlog = 262144
記錄的那些尚未收到客戶端確認信息的連接請求的最大值。對於有128M內存的系統而言,缺省值是1024,小內存的系統則是128

net.ipv4.tcp_timestamps = 0
時間戳可以避免序列號的卷繞。一個1Gbps的鏈路肯定會遇到以前用過的序列號。時間戳能夠讓內核接受這種異常的數據包。這裏需要將其關掉。

net.ipv4.tcp_synack_retries = 1
爲了打開對端的連接,內核需要發送一個SYN並附帶一個迴應前面一個SYNACK。也就是所謂三次握手中的第二次握手。這個設置決定了內核放棄連接之前發送SYN+ACK包的數量。

net.ipv4.tcp_syn_retries = 1
在內核放棄建立連接之前發送SYN包的數量。

net.ipv4.tcp_fin_timeout = 1
如果套接字由本端要求關閉,這個參數決定了它保持在FIN-WAIT-2狀態的時間。對端可以出錯並永遠不關閉連接,甚至意外當機。缺省值是60 秒。2.2 內核的通常值是180秒,你可以按這個設置,但要記住的是,即使你的機器是一個輕載的WEB服務器,也有因爲大量的死套接字而內存溢出的風險,FIN- WAIT-2的危險性比FIN-WAIT-1要小,因爲它最多隻能吃掉1.5K內存,但是它們的生存期長些。

net.ipv4.tcp_keepalive_time = 30
keepalive起用的時候,TCP發送keepalive消息的頻度。缺省是2小時。

下面貼一個完整的內核優化設置:

引用

net.ipv4.ip_forward = 0
net.ipv4.conf.default.rp_filter = 1
net.ipv4.conf.default.accept_source_route = 0
kernel.sysrq = 0
kernel.core_uses_pid = 1
net.ipv4.tcp_syncookies = 1
kernel.msgmnb = 65536
kernel.msgmax = 65536
kernel.shmmax = 68719476736
kernel.shmall = 4294967296
net.ipv4.tcp_max_tw_buckets = 6000
net.ipv4.tcp_sack = 1
net.ipv4.tcp_window_scaling = 1
net.ipv4.tcp_rmem =4096        87380   4194304
net.ipv4.tcp_wmem =4096        16384   4194304
net.core.wmem_default = 8388608
net.core.rmem_default = 8388608
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
net.core.netdev_max_backlog = 262144
net.core.somaxconn = 262144
net.ipv4.tcp_max_orphans = 3276800
net.ipv4.tcp_max_syn_backlog = 262144
net.ipv4.tcp_timestamps = 0
net.ipv4.tcp_synack_retries = 1
net.ipv4.tcp_syn_retries = 1
net.ipv4.tcp_tw_recycle = 1
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_mem = 94500000 915000000 927000000
net.ipv4.tcp_fin_timeout = 1
net.ipv4.tcp_keepalive_time = 30
net.ipv4.ip_local_port_range = 1024    65000

下面是一個簡單的nginx配置文件:

user  www www;
worker_processes 8;
worker_cpu_affinity 00000001 00000010 00000100 00001000 00010000 0010000001000000;
error_log  /www/log/nginx_error.log  crit;
pid        /usr/local/nginx/nginx.pid;
worker_rlimit_nofile 204800;

events
{
use epoll;
worker_connections 204800;
}

http
{
include       mime.types;
default_type  application/octet-stream;

charset  utf-8;

server_names_hash_bucket_size 128;
client_header_buffer_size 2k;
large_client_header_buffers 4 4k;
client_max_body_size 8m;

sendfile on;
tcp_nopush     on;

keepalive_timeout 60;

fastcgi_cache_path/usr/local/nginx/fastcgi_cache levels=1:2
keys_zone=TEST:10m
inactive=5m;
fastcgi_connect_timeout 300;
fastcgi_send_timeout 300;
fastcgi_read_timeout 300;
fastcgi_buffer_size 64k;
fastcgi_buffers 8 64k;
fastcgi_busy_buffers_size 128k;
fastcgi_temp_file_write_size 128k;
fastcgi_cache TEST;
fastcgi_cache_valid 200 302 1h;
fastcgi_cache_valid 301 1d;
fastcgi_cache_valid any 1m;
fastcgi_cache_min_uses 1;
fastcgi_cache_use_stale error timeout invalid_header http_500;

open_file_cache max=204800 inactive=20s;
open_file_cache_min_uses 1;
open_file_cache_valid 30s;
tcp_nodelay on;

gzip on;
gzip_min_length  1k;
gzip_buffers     4 16k;
gzip_http_version 1.0;
gzip_comp_level 2;
gzip_types       text/plainapplication/x-javascript text/css application/xml;
gzip_vary on;
server
{
listen       8080;
server_name  backup.aiju.com;
index index.php index.htm;
root  /www/html/;  #這裏的位置很重要,不要寫在其它指令裏面,我曾經就調試了好久才發現這個問題的

location /status
{
stub_status on;
}

location ~ .*\.(php|php5)?$
{
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
include fcgi.conf;
}

location ~.*\.(gif|jpg|jpeg|png|bmp|swf|js|css)$
{
expires      30d;
}

log_format  access  '$remote_addr- $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" $http_x_forwarded_for';
access_log  /www/log/access.log  access;
}
}

關於FastCGI的幾個指令(http://wiki.nginx.org/NginxChsHttpFcgiModule)

fastcgi_cache_path/usr/local/nginx/fastcgi_cache levels=1:2 keys_zone=TEST:10m inactive=5m;
這個指令爲FastCGI緩存指定一個路徑,目錄結構等級,關鍵字區域存儲時間和非活動刪除時間。

fastcgi_connect_timeout 300;
指定連接到後端FastCGI的超時時間。

fastcgi_send_timeout 300;
FastCGI傳送請求的超時時間,這個值是指已經完成兩次握手後向FastCGI傳送請求的超時時間。

fastcgi_read_timeout 300;
接收FastCGI應答的超時時間,這個值是指已經完成兩次握手後接收FastCGI應答的超時時間。

fastcgi_buffer_size 64k;
指定讀取FastCGI應答第一部分需要用多大的緩衝區,一般第一部分應答不會超過1k,由於頁面大小爲4k,所以這裏設置爲4k

fastcgi_buffers 8 64k;
指定本地需要用多少和多大的緩衝區來緩衝FastCGI的應答。

fastcgi_busy_buffers_size 128k;
這個指令我也不知道是做什麼用,只知道默認值是fastcgi_buffers的兩倍。

fastcgi_temp_file_write_size 128k;
在寫入fastcgi_temp_path時將用多大的數據塊,默認值是fastcgi_buffers的兩倍。

fastcgi_cache TEST
開啓FastCGI緩存並且爲其制定一個名稱。個人感覺開啓緩存非常有用,可以有效降低CPU負載,並且防止502錯誤。

fastcgi_cache_valid 200 302 1h;
fastcgi_cache_valid 301 1d;
fastcgi_cache_valid any 1m;
爲指定的應答代碼指定緩存時間,如上例中將200302應答緩存一小時,301應答緩存1天,其他爲1分鐘。

fastcgi_cache_min_uses 1;
緩存在fastcgi_cache_path指令inactive參數值時間內的最少使用次數,如上例,如果在5分鐘內某文件1次也沒有被使用,那麼這個文件將被移除。

fastcgi_cache_use_stale error timeoutinvalid_header http_500;
不知道這個參數的作用,猜想應該是讓nginx知道哪些類型的緩存是沒用的。

以上爲nginxFastCGI相關參數,另外,FastCGI自身也有一些配置需要進行優化,如果你使用php-fpm來管理FastCGI,可以修改配置文件中的以下值:
<value name="max_children">60</value>
同時處理的併發請求數,即它將開啓最多60個子線程來處理併發連接。

<value name="rlimit_files">102400</value>
最多打開文件數。

<valuename="max_requests">204800</value>
每個進程在重置之前能夠執行的最多請求數。

下面貼幾張測試結果圖。

靜態頁面爲我在squid配置4W併發那篇文章中提到的測試文件,下圖爲同時在6臺機器運行webbench -c 30000 -t 600 http://backup.aiju.com:8080/index.html命令後的測試結果:
使用netstat過濾後的連接數:
php頁面在status中的結果(php頁面爲調用phpinfo):
php頁面在netstat過濾後的連接數:
未使用FastCGI緩存之前的服務器負載:
此時打開php頁面已經有些困難,需要進行多次刷新才能打開。上圖中cpu0負載偏低是因爲測試時將網卡中斷請求全部分配到cpu0上,並且在nginx中開啓7個進程分別制定到cpu1-7
使用FastCGI緩存之後:
此時可以很輕鬆的打開php頁面。

這個測試並沒有連接到任何數據庫,所以並沒有什麼參考價值,不過不知道上述測試是否已經到達極限,根據內存和cpu的使用情況來看似乎沒有,但是已經沒有多餘的機子來讓我運行webbench了。


導致nginx 502 bad gatewayPHP-CGI(FASTCGI)

NGINX頻爆502 BAD GATEWAY的錯誤,看了網上的教程,仍沒有徹底解決。

目前我總結的解決502 BAD GATEWAY的方式有:

1.視服務器的性能,在php-fmp.conf裏增加max_children的值,我目前用的15.

2.reload參數定時重載php-fpm。這個主要原因是php腳本執行時間過長造成的,重載php-fpm能杜絕這個問題。如何徹底解決php-cgi腳本佔用大量內存從而導致502錯誤的產生還值得進一步探討,目前該做法不失爲一種好辦法。

具體的做法是,用crontabphp-fpm平滑重啓,從而不影響PHP腳本的運行。

*/10 * * * * /usr/local/php/sbin/php-fpmreload

=================== 優化設置=========================


When you running a highload website with PHP-FPM via FastCGI, thefollowing tips may be useful to you : )

如果您高負載網站使用PHP-FPM管理FastCGI,這些技巧也許對您有用:)

1. Compile PHP’s modules as less aspossible, the simple the best (fast);

1.儘量少安裝PHP模塊,最簡單是最好(快)的

2. Increas PHP FastCGI child number to 100and even more. Sometime, 200 is OK! ( On 4GB memory server);

2.把您的PHP FastCGI子進程數調到100或以上,在4G內存的服務器上200就可以

注:我的1g測試機,開64個是最好的,建議使用壓力測試獲取最佳值

3. Using SOCKET PHP FastCGI, and put into/dev/shm on Linux;

3.使用socket連接FastCGIlinux操作系統可以放在 /dev/shm

注:在php-fpm.cnf裏設置<value name=”listen_address”>/tmp/nginx.socket</value>就可以通過socket連接FastCGI了,/dev/shm是內存文件系統,放在內存中肯定會快了.記得這時也要在nginx裏的配置裏進行修改,保持一致.

location ~ .*\.(php|php5)?$
{
#NginxFastCGI的通信方式由TCP改爲Unix SocketTCP在高併發訪問下比Unix Socket穩定,但Unix Socket速度要比TCP快。
fastcgi_pass  unix:/tmp/php-cgi.sock;
#fastcgi_pass  127.0.0.1:9000;
fastcgi_index index.php;
include fcgi.conf;
}

4. Increase Linux “max open files”, usingthe following command (must be root):

# echo ‘ulimit -HSn 65536′ >>/etc/profile
# echo ‘ulimit -HSn 65536 >> /etc/rc.local
# source /etc/profile

4.調高linux內核打開文件數量,可以使用這些命令(必須是root帳號)

echo ‘ulimit -HSn 65536′ >> /etc/profile
echo ‘ulimit -HSn 65536′ >> /etc/rc.local
source /etc/profile

注:我是修改/etc/rc.local,加入ulimit -SHn 51200

5. Increase PHP-FPM open filedescription rlimit:

# vi /path/to/php-fpm.conf
Find “<value name=”rlimit_files”>1024</value>”
Change 1024 to 4096 or higher number.
Restart PHP-FPM.

5. 增加 PHP-FPM 打開文件描述符的限制:

# vi /path/to/php-fpm.conf
找到“<value name=”rlimit_files”>1024</value>”
1024 更改爲 4096 或者更高.
重啓 PHP-FPM.


6. Using PHP code accelerator, e.g eAccelerator, XCache. And set “cache_dir” to/dev/shm on Linux.
6.使用php代碼加速器,例如 eAccelerator, XCache.linux平臺上可以把`cache_dir`指向 /dev/shm


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章