1.性能優(yōu)化概述
基于Nginx性能優(yōu)化兜叨,我們將分為如下?個(gè)??來做介紹
1.?先我們需要了解性能優(yōu)化要考慮哪些??聂沙。
2.然后我們需要了解會(huì)影響Nginx性能的?些指標(biāo)家浇。
3.最后我們需要了解優(yōu)化系統(tǒng)以及Nginx服務(wù)的哪些??赊淑。
1.1 在做性能優(yōu)化?作前爵政,我們重點(diǎn)需要考慮哪些???
1.?先需要了解我們當(dāng)前系統(tǒng)結(jié)構(gòu)和瓶頸陶缺,了解當(dāng)前使?的是什么钾挟,運(yùn)?的是什么業(yè)務(wù),都有哪些服務(wù)饱岸,了解每個(gè)服務(wù)最?能?撐多?并發(fā)等龙。?如Nginx作為靜態(tài)資源服務(wù)的并發(fā)是多少,最?瓶頸在哪?伶贰,能?持多少qps(每秒查詢率)的訪問請(qǐng)求,那我們?cè)趺吹贸鲞@組系統(tǒng)結(jié)構(gòu)瓶頸呢罐栈,?如top查看系統(tǒng)的cpu負(fù)載黍衙、內(nèi)存使?率、總的運(yùn)?進(jìn)程等荠诬,也可以通過?志去分析請(qǐng)求的情況琅翻,當(dāng)然也可以通過我們前?介紹到的stub_status模塊查看當(dāng)前的連接情況,也可以對(duì)線上低峰期的業(yè)務(wù)進(jìn)?壓?測試柑贞,去了解當(dāng)前這套系統(tǒng)能承擔(dān)多少的請(qǐng)求和并發(fā)方椎,已做好相應(yīng)的評(píng)估。這個(gè)是我們做性能優(yōu)化最先考慮的地?钧嘶。
2.其次我們需要了解業(yè)務(wù)模式棠众,我們的性能優(yōu)化其實(shí)是為業(yè)務(wù)所提供服務(wù)的,所以需要了解每個(gè)業(yè)務(wù)接?的類型,?如:電商?站中的搶購模式闸拿,平時(shí)沒什么流量空盼,但到了搶購時(shí)間流量會(huì)突增。 同時(shí)我們還需要了解系統(tǒng)結(jié)構(gòu)新荤,?如: 我們使?Nginx做的是代理揽趾、還是動(dòng)靜分離、還是后端直接服務(wù)?戶苛骨,那么這個(gè)就需要我們對(duì)每?層做好相應(yīng)的梳理篱瞎。以便更好的服務(wù)業(yè)務(wù)。
3.最后我們需要考慮性能與安全痒芝,往往注重了性能俐筋,但是忽略了安全。往往過于注重安全吼野,性能?會(huì)產(chǎn)?影響校哎。?如:我們?cè)谠O(shè)計(jì)防?墻功能時(shí),檢測過于嚴(yán)密瞳步,這樣就會(huì)給性能帶來影響闷哆。那么如果對(duì)于性能完全追求,卻不顧服務(wù)的安全单起,這個(gè)也會(huì)造成很?的隱患抱怔,所以需要評(píng)估好兩者的關(guān)系,權(quán)衡好對(duì)應(yīng)的點(diǎn)嘀倒。
了解系統(tǒng)的結(jié)構(gòu)及系統(tǒng)的瓶頸---》在流量低估時(shí)屈留,借助壓力測試工具來實(shí)現(xiàn)
了解業(yè)務(wù)模式,不同的業(yè)務(wù)類型测蘑,需求不一樣灌危,面對(duì)的場景也不一樣
考慮性能和安全,追求性能安全會(huì)弱碳胳,過于追求安全勇蝙,性能會(huì)下降
1.2 影響Nginx性能的一些指標(biāo)
1.硬件層?需要了解: 磁盤損壞、磁盤速率挨约。
1.?絡(luò)層?需要了解: 網(wǎng)絡(luò)帶寬味混、?絡(luò)是否丟包、因?yàn)檫@些都會(huì)影響http的請(qǐng)求與調(diào)?诫惭。
2.系統(tǒng)層?需要了解: 系統(tǒng)負(fù)載翁锡、系統(tǒng)內(nèi)存,以及系統(tǒng)整體的穩(wěn)定性夕土。
3.服務(wù)層?需要了解: 連接與請(qǐng)求的限速馆衔,同時(shí)還需要根據(jù)業(yè)務(wù)形態(tài)做對(duì)應(yīng)的服務(wù)設(shè)置。
4.程序?qū)?需要了解: 接?性能、處理速度哈踱、程序執(zhí)?效率荒适。
5.數(shù)據(jù)層?需要了解: 數(shù)據(jù)庫。
PS: 每個(gè)服務(wù)與服務(wù)之間都或多或少有?些關(guān)聯(lián), 我們需要將整個(gè)架構(gòu)進(jìn)?分層, 找到對(duì)應(yīng)系統(tǒng)或服務(wù)的短板, 然后進(jìn)?優(yōu)化
2.系統(tǒng)性能優(yōu)化
?件句柄, Linux?切皆?件开镣,?件句柄可以理解為就是?個(gè)索引刀诬,?件句柄會(huì)隨著我們進(jìn)程的調(diào)?頻繁增加,系統(tǒng)默認(rèn)?件句柄是有限制的邪财,不能讓?個(gè)進(jìn)程?限的調(diào)?陕壹,所以我們需要限制每個(gè)進(jìn)程和每個(gè)服務(wù)使?多?的?件句柄,?件句柄也是必須要調(diào)整的優(yōu)化參數(shù)树埠。
?件句柄的設(shè)置?式糠馆,
1.系統(tǒng)全局性修改。
2.?戶局部性修改怎憋。
3.進(jìn)程局部性修改
[root@nginx ~]# vim /etc/security/limits.conf
# 針對(duì)root?戶又碌,soft僅提醒,hard限制绊袋,nofile打開最??件數(shù)
# *代表所有?戶
* soft nofile 65535
* hard nofile 65535
root soft nofile 65535
root hard nofile 65535
#針對(duì)Nginx進(jìn)程
[root@yinwu ~]# vim /etc/nginx/nginx.conf
worker_rlimit_nofile 65535;
內(nèi)核參數(shù)優(yōu)化
[root@yinwu ~]# vim /etc/sysctl.conf
net.ipv4.ip_local_port_range = 10240 61000 #調(diào)整系統(tǒng)能使?的端?數(shù)量
net.core.somaxconn = 1024 #默認(rèn)128毕匀,連接隊(duì)列
net.ipv4.tcp_fin_timeout = 10 #time_wait的超時(shí)時(shí)間
net.ipv4.tcp_tw_reuse = 1 #重新使?time_wait的連接
net.ipv4.tcp_timestamps = 1
[root@yinwu ~]# sysctl -p #刷新
[root@yinwu ~]# netstat -an
[root@yinwu ~]# ss -s
Total: 252 (kernel 276)
TCP: 23 (estab 3, closed 11, orphaned 0, synrecv 0, timewait 1/0), ports 0
Transport Total IP IPv6
* 276 - -
RAW 0 0 0
UDP 6 5 1
TCP 12 7 5
INET 18 12 6
FRAG 0 0 0
3.代理服務(wù)優(yōu)化
通常Nginx作為代理服務(wù),負(fù)責(zé)代理?戶的請(qǐng)求癌别,那么在代理的過程中建議開啟HTTP?連接皂岔,?于減少握?次數(shù),降低服務(wù)器損耗展姐。
3.1?連接語法(應(yīng)?層?優(yōu)化)
Syntax: keepalive connections;
Default: —
Context: upstream
Syntax: keepalive_requests number; #keepalive_requests設(shè)置通過?個(gè)keepalive連
接提供的最?請(qǐng)求數(shù)躁垛。在發(fā)出最?請(qǐng)求數(shù)后,將關(guān)閉連接圾笨。
Default: keepalive_requests 100;
Context: upstream
Syntax: keepalive_timeout timeout; #keepalive_timeout超時(shí)教馆,在此期間與代理服務(wù)器的
空閑keepalive連接將保持打開狀態(tài)。
Default: keepalive_timeout 60s;
Context: upstream
3.2 配置
Nginx代理服務(wù)使??連接?式NGINX ?持 Keepalive ?連接
upstream http_backend {
server 127.0.0.1:8080;
server 127.0.0.1:8081;
keepalive 32; #Nginx到應(yīng)?服務(wù)器的連接池??最?的空閑?連接數(shù)擂达。也就是最
多有32個(gè)空閑的?連接
keepalive_requests 100; #Nginx到應(yīng)?應(yīng)?服務(wù)器的?個(gè)?連接最多可承載處理的HTTP請(qǐng)求
個(gè)數(shù)活玲,最多處理100個(gè),到100個(gè)后?動(dòng)關(guān)閉該連接谍婉,有需要Nginx會(huì)再?成新的?連接
keepalive_time 60s; #keepalive_timeout超時(shí),在60s時(shí)間內(nèi)代理服務(wù)器的空閑
keepalive連接將保持打開狀態(tài)
}
server {
...
location /http/ {
proxy_pass http://http_backend;
proxy_http_version 1.1; #這?設(shè)置了proxy代理的協(xié)議镀钓,如果沒有設(shè)置的化
默認(rèn)是1.0穗熬。只有http1.1后才增加了?連接的?持。
proxy_set_header Connection ""; #清除“connection”頭字段丁溅,是清理從 Client
過來的 http header唤蔗,因?yàn)榧词故?Client 和 NGINX 之間是短連接,NGINX 和 upstream 之間也
是可以開啟?連接的。這種情況下必須清理來? Client 請(qǐng)求中的 “Connection” header妓柜。
#proxy_params代理優(yōu)化參數(shù)[此前已講箱季,不再復(fù)述]
proxy_set_header Host $http_host;
proxy_set_header X-Forwared-For $proxy_add_x_forwarded_for;
proxy_connect_timeout 30s; # 代理連接web超時(shí)時(shí)間
proxy_read_timeout 60s; # 代理等待web響應(yīng)超時(shí)時(shí)間
proxy_send_timeout 60s; # web回傳數(shù)據(jù)?代理超時(shí)時(shí)間
proxy_buffering on; # 開啟代理緩沖區(qū),web回傳數(shù)據(jù)?緩沖區(qū),代理邊收邊傳返回
給客戶端
proxy_buffer_size 32k; # 代理接收web響應(yīng)的頭信息的緩沖區(qū)??
proxy_buffers 4 128k; # 緩沖代理接收單個(gè)?連接內(nèi)包含的web響應(yīng)的數(shù)量和??
#異常后的超時(shí)與重試機(jī)制
proxy_next_upstream error timeout http_500 http_502 http_503 http_504; #
重試upstream中的下?臺(tái)后端
proxy_next_upstream_timeout 6s; #重試次數(shù)的總時(shí)間超出了6s
proxy_next_upstream_tries 3; #重試3次(但因?yàn)橹耙呀?jīng)請(qǐng)求1次了,所以還能重試2次)棍掐,
則表示重試失敗
}
}
3.3 對(duì)于fastcgi服務(wù)器藏雏,需要設(shè)置fastcgi_keep_conn以便保持?連接
upstream fastcgi_backend {
server 127.0.0.1:9000;
keepalive 16; #Nginx到應(yīng)?服務(wù)器的連接池??最?的空閑?連接數(shù)。也就是最多有16個(gè)空
閑的?連接
}
server {
...
location /fastcgi/ {
fastcgi_pass fastcgi_backend;
fastcgi_keep_conn on; #開啟保持?連接
fastcgi_connect_timeout 600; #指定連接到后端FastCGI的超時(shí)時(shí)間
fastcgi_send_timeout 600; #向FastCGI傳送請(qǐng)求的超時(shí)時(shí)間
fastcgi_read_timeout 600; #指定接收FastCGI應(yīng)答的超時(shí)時(shí)間
fastcgi_buffer_size 64k;
fastcgi_buffers 4 64k;
fastcgi_busy_buffers_size 128k;
#異常后的超時(shí)與重試機(jī)制
fastcgi_next_upstream error timeout http_500 http_502 http_503 http_504;
#重試upstream中的下?臺(tái)后端
fastcgi_next_upstream_timeout 6s; #重試次數(shù)的總時(shí)間超出了6s
fastcgi_next_upstream_tries 3; #重試了3次(因?yàn)橹耙呀?jīng)請(qǐng)求1次了作煌,所以還能重試2 次)掘殴,則表示重試失敗.
}
}
Nginx作為代理服務(wù)總結(jié):
1.scgi和uwsgi協(xié)議沒有保持連接的概念。
2.但?論是proxy粟誓、fastcgi奏寨、uwsgi協(xié)議都有 cache 緩存的功能,開啟后可減少?站重復(fù)請(qǐng)求所帶來的壓?鹰服。
但需要注意的是:
proxy_cache的作?是緩存后端服務(wù)器的內(nèi)容病瞳,可能是任何內(nèi)容,包括靜態(tài)的和動(dòng)態(tài)悲酷,減少nginx與后端通信的次數(shù)套菜,節(jié)省了傳輸時(shí)間和后端寬帶。
fastcgi_cache的作?是緩存fastcgi?成的內(nèi)容舔涎,很多情況是php?成的動(dòng)態(tài)的內(nèi)容笼踩,少了nginx與php的通信的次數(shù),更減輕了php和數(shù)據(jù)庫(mysql)的壓?亡嫌。
4. 靜態(tài)資源優(yōu)化
Nginx作為靜態(tài)資源Web服務(wù)器嚎于,?于靜態(tài)資源處理,傳輸?常的?效
靜態(tài)資源指的是挟冠,?WEB服務(wù)器端運(yùn)?處理??成的?件
靜態(tài)資源類型 種類
瀏覽器渲染 HTML于购、CSS、JS
圖??件 JPEG知染、GIF肋僧、PNG
視頻?件 FLV、Mp4控淡、AVI
其他?件 TXT嫌吠、DOC、PDF掺炭、...
4.1 靜態(tài)資源緩存
瀏覽器緩存設(shè)置?于提??站性能辫诅,尤其是新聞?站, 圖??旦發(fā)布,改動(dòng)的可能是?常?的涧狮。所以我們希望能否?戶訪問?次后炕矮,圖?緩存在?戶的瀏覽器?時(shí)間緩存么夫。 瀏覽器是有??的緩存機(jī)制,它是基于HTTP協(xié)議緩存機(jī)制來實(shí)現(xiàn)的肤视,在HTTP協(xié)議中有很多頭信息档痪,那么實(shí)現(xiàn)瀏覽器的緩存就需要依賴特殊的頭信息來與服務(wù)器進(jìn)?特殊的驗(yàn)證,如: Expires (http/1.0) 邢滑; Cache-control (http/1.1)腐螟。Nginx靜態(tài)資源緩存參考
1.瀏覽器?緩存
2.瀏覽器有緩存
3.瀏覽器緩存過期校驗(yàn)檢查機(jī)制,說明如下:
1.瀏覽器請(qǐng)求服務(wù)器會(huì)先進(jìn)?Expires殊鞭、Cache-Control的檢查遭垛,檢查緩存是否過期,如果沒有過期則直接從緩存?件中讀取操灿。
2.如果緩存過期锯仪,?先檢查是否存在etag,如果存在則會(huì)客戶端會(huì)向web服務(wù)器請(qǐng)求if-None-Match趾盐,與etag值進(jìn)??對(duì)庶喜,由服務(wù)器決策返回200還是304。
3.如果etag不存在救鲤,則進(jìn)?last-Modified檢查久窟,客戶端會(huì)向web服務(wù)器請(qǐng)求If-Modified?Since,與last-Modified進(jìn)??對(duì)本缠,由服務(wù)器決策返回200還是304斥扛。
4.如何配置靜態(tài)資源緩存expires
#作?: 添加Cache-Control Expires頭
Syntax: expires [modified] time;
expires epoch | max | off;
Default: expires off;
Context: http, server, location, if in location
5.配置靜態(tài)資源緩存場景
server {
listen 80;
server_name static.bgx.com;
location ~ .*\.(jpg|gif|png)$ {
expires 7d;
}
}
6.如果開發(fā)代碼沒有正式上線時(shí), 希望靜態(tài)?件不被緩存
#取消js css html等靜態(tài)?件緩存
location ~ .*\.(css|js|swf|json|mp4|htm|html)$ {
add_header Cache-Control no-store;
add_header Pragma no-cache;
}
4.2 靜態(tài)資源讀取
1.?件讀取?效sendfile,如下圖
Syntax: sendfile on | off;
Default: sendfile off;
Context: http, server, location, if in location
傳統(tǒng)讀取?件?式 VS sendfile讀取?件?式
2.將多個(gè)包?次發(fā)送丹锹,?于提升?絡(luò)傳輸效率稀颁,??件推薦打開,需要開啟sendfile才?
Syntax: tcp_nopush on | off;
Default: tcp_nopush off;
Context: http, server, location
3.提??絡(luò)傳輸實(shí)時(shí)性楣黍,需要開啟keepalive
Syntax: tcp_nodelay on | off;
Default: tcp_nodelay on;
Context: http, server, location
4.3 靜態(tài)資源壓縮
Nginx將響應(yīng)報(bào)?發(fā)送?客戶端之前啟?壓縮功能匾灶,然后進(jìn)?傳輸,這能夠有效地節(jié)約帶寬租漂,并提?響應(yīng)?客戶端的速度阶女。
1.gzip傳輸壓縮,傳輸前壓縮哩治,傳輸后解壓
Syntax: gzip on | off;
Default: gzip off;
Context: http, server, location, if in location
2.gzip壓縮哪些類型的?件
Syntax: gzip_types mime-type ...;
Default: gzip_types text/html;
Context: http, server, location
3.gzip壓縮?率秃踩,加快傳輸,但壓縮本身?較耗費(fèi)服務(wù)端性能
Syntax: gzip_comp_level level;
Default: gzip_comp_level 1;
Context: http, server, location
4.gzip壓縮協(xié)議版本业筏,壓縮使?在http哪個(gè)協(xié)議, 主流選擇1.1版本
Syntax: gzip_http_version 1.0 | 1.1;
Default: gzip_http_version 1.1;
Context: http, server, location
4.靜態(tài)圖?配置壓縮案例
[root@Nginx conf.d]# mkdir -p /code/
[root@Nginx conf.d]# cat static_server.conf
server {
listen 80;
server_name static.dacs.com;
location ~* .*\.(jpg|gif|png)$ {
root /code/images;
gzip on;
gzip_http_version 1.1;
gzip_comp_level 2;
gzip_types image/jpeg image/gif image/png;
}
}
5.測試沒有開啟gzip圖?壓縮
6.啟? gzip 壓縮圖?后(由于圖?之前壓縮過, 所以壓縮?率不太明顯)
7.?件壓縮案例
[root@Nginx conf.d]# mkdir -p /code/doc
[root@Nginx conf.d]# cat static_server.conf
server {
listen 80;
server_name static.yinwuxu.com;
root /code/doc;
location ~ .*\.(txt|pdf)$ {
gzip on;
gzip_http_version 1.1;
gzip_comp_level 1;
gzip_types text/plain application/pdf;
}
}
沒有啟? gzip ?件壓縮
啟? gzip 壓縮?件
4.4 靜態(tài)資源防盜鏈
防盜鏈憔杨,指的是防?資源被其他?站惡意盜?。
基礎(chǔ)防盜鏈設(shè)置思路:
- 主要是針對(duì)客戶端請(qǐng)求過程中所攜帶的?些Header信息來驗(yàn)證請(qǐng)求的合法性驾孔,?如客戶端在請(qǐng)求的過程中都會(huì)攜帶referer信息(referer會(huì)告訴服務(wù)器我是叢哪?個(gè)??過來的)芍秆。
- 優(yōu)點(diǎn)是規(guī)則簡單,配置和使?都很?便翠勉,缺點(diǎn)是防盜鏈所依賴的Referer驗(yàn)證信息是可以偽造的妖啥,所以通過Referer信息防盜鏈并?100%可靠, 但是它能夠限制?部分的盜鏈情況对碌。
1.在盜鏈服務(wù)器上準(zhǔn)備html?件,偷取fj.xuliangwei.com?站上的圖?
[root@Nginx ~]# cat /etc/nginx/conf.d/
server {
listen 80;
server_name image.dacs.com;
location / {
root /code;
index index.html;
}
}#準(zhǔn)備?站
[root@Nginx ~]# cat /code/referer_test.html
<html>
<head>
<meta charset="utf-8">
<title>dacsedu.com</title>
</head>
<body style="background-color:red;">
<img src="http://fj.xuliangwei.com/public/tt.jpeg"/>
</body>
</html>
2.使?瀏覽器能正常訪問到偷鏈的后的圖?資源
3.在kt.xuliangwei.com服務(wù)器上開啟基于referer的防盜鏈規(guī)則
Syntax: valid_referers none | blocked | server_names | string ...;
Default: —
Context: server, location
#none: Referer來源頭部為空的情況
#blocked: Referer來源頭部不為空荆虱,這些值都不以http://或者h(yuǎn)ttps://開頭,直接填寫允許的域名
即可
#server_names: 來源頭部包含當(dāng)前的域名,可以正則匹配
#配置示例
location ~ .*\.(jpg|jpeg|gif|png)$ {
#來源域名如何合法朽们,invalid_referer這個(gè)變量被設(shè)置為0怀读,否則設(shè)置為1
valid_referers none blocked *.xuliangwei.com;
#如果invalid_referer為1則返回403
if ($invalid_referer) {
return 403;
}
}
以上配置表示: 所有來?*.xuliangwei.com都可以訪問到fj.xuliangwei.com站點(diǎn)的圖?,如果來源域名不在這個(gè)列表中骑脱,那么$invalid_referer等于1菜枷,在if語句中返回?個(gè)403給?戶, 這樣?戶便會(huì)看到?個(gè)403的??
4.使?瀏覽器驗(yàn)證會(huì)發(fā)現(xiàn)惡意的來源?站已經(jīng)?法正常盜鏈
5.如果不想直接返回403叁丧,?希望優(yōu)雅的返回?張圖?給?戶啤誊,那么可以使?rewrite跳轉(zhuǎn),如下示例返回/public/ks.jpeg圖?給?戶
location ~ .*\.(jpg||jpeg|gif|png)$ {
valid_referers none blocked *.xuliangwei.com;
if ($invalid_referer) {
rewrite ^(.*)$ /public/ks.jpeg break;
}
}
6.再次進(jìn)?盜鏈的?式訪問圖?拥娄,則不再返回403蚊锹,?是?張圖?。
7.如果希望 google稚瘾、baidu牡昆、等站點(diǎn)能夠(盜鏈)資源,那么則可以通過server_names開放
location ~* \.(gif|jpg|png|bmp)$ {
valid_referers none blocked *.xuliangwei.com server_names ~\.google\.
~\.baidu\.;
if ($invalid_referer) {
return 403;
}
}
8.當(dāng)然這種防護(hù)并不能百分百保證資源被盜鏈摊欠,因?yàn)槲覀兛梢酝ㄟ^命令修改來源的refrer信息丢烘。
4.5 靜態(tài)資源防爬?
場景?代碼示例:通過user_agent防?搜索引擎的爬取
server {
...
if ($http_user_agent ~* "YisouSpider|YoudaoBot|tt") {
return 403;
}
....
}
場景?代碼示例: 通過user_agent攔截壓測測試?具
server {
...
if ($http_user_agent ~* "Wget|ApacheBench") {
set $block_user_agent 1;
}
if ($block_user_agent = 1){
return 403;
}
...
}
測試 1.curl -A "YisouSpider1.0" -I URL 2.curl -A "ApacheBench" -I URL 3.curl -A "wget" -I URL
4.6 CPU親和配置
CPU親和(affinity)減少進(jìn)程之間不斷頻繁切換,減少性能損耗凄硼,其實(shí)現(xiàn)原理是將CPU核?和Nginx?作進(jìn)程綁定?式铅协,把每個(gè)worker進(jìn)程固定對(duì)應(yīng)的cpu上執(zhí)?,減少切換cpu的cache miss摊沉,獲得更好的性能狐史。
1.查看當(dāng)前CPU物理狀態(tài)
[root@nginx ~]# lscpu |grep "CPU(s)"
CPU(s): 24
On-line CPU(s) list: 0-23
NUMA node0 CPU(s): 0,2,4,6,8,10,12,14,16,18,20,22
NUMA node1 CPU(s): 1,3,5,7,9,11,13,15,17,19,21,23
#本次演示服務(wù)器為兩顆物理cpu,每顆物理CPU12個(gè)核?, 總共有24個(gè)核?
2.將Nginx worker進(jìn)程綁?不同的核?上说墨,官?建議與cpu的核?保持?致
# 第?種綁定組合?式
worker_processes 24;
worker_cpu_affinity 000000000001 000000000010 000000000100 000000001000
000000010000 000000100000 000001000000 000010000000 000100000000 001000000000
010000000000 10000000000;
# 第?種?式(使?較少)
worker_processes 2;
worker_cpu_affinity 101010101010 010101010101;
# 最佳?式綁定?式
worker_processes auto;
worker_cpu_affinity auto;
3.查看 nginx worker 進(jìn)程綁定?對(duì)應(yīng) cpu
ps -eo pid,args,psr|grep [n]ginx
4.設(shè)置nginx worker進(jìn)程的靜態(tài)優(yōu)先級(jí)骏全,盡可能讓nginx?直使?cpu
worker_priority number;
#默認(rèn)值是0,可以設(shè)置為-20尼斧,減少cpu上下?切換的次數(shù)
5.Nginx配置總結(jié)
1.Nginx通?的主配置?件nginx.conf姜贡,包含靜態(tài)資源優(yōu)化
[root@nginx ~]# cat nginx.conf
user www; # nginx進(jìn)程啟動(dòng)?戶
worker_processes auto; #與cpu核??致即可
worker_cpu_affinity auto; # cpu親和
error_log /var/log/nginx/error.log warn; #錯(cuò)誤?志
pid /run/nginx.pid;
worker_rlimit_nofile 35535; #每個(gè)work能打開的?件描述符,調(diào)整?1w以上,負(fù)荷較?建議
2-3w
events {
use epoll; # 使?epoll?效?絡(luò)模型
worker_connections 10240; # 限制每個(gè)worker進(jìn)程能處理多少個(gè)連接棺棵,10240x[cpu核 ?] }
http {
include mime.types;
default_type application/octet-stream;
charset utf-8; # 統(tǒng)?使?utf-8字符集
# 定義?志格式
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main; # 訪問?志
server_tokens off; # 禁?瀏覽器顯示nginx版本號(hào)
client_max_body_size 200m; # ?件上傳??限制調(diào)整
# ?件?效傳輸楼咳,靜態(tài)資源服務(wù)器建議打開
sendfile on;
tcp_nopush on;
# ?件實(shí)時(shí)傳輸熄捍,動(dòng)態(tài)資源服務(wù)建議打開,需要打開keepalived
tcp_nodelay on;
keepalive_timeout 65;
# Gzip 壓縮
gzip on;
gzip_complevel 2;
gzip_disable "MSIE [1-6]\.";
gzip_http_version 1.1;
gzip_types .....;
# 虛擬主機(jī)
include /etc/nginx/conf.d/*.conf;
}
4.?試:你對(duì)Nginx有做過哪些??的優(yōu)化,能簡單說說嗎?
- 調(diào)整cpu親和母怜、worker進(jìn)程數(shù)余耽、以及Nginx?件描述符
- 使?epool?絡(luò)模型、調(diào)整每個(gè)worker進(jìn)程的最?連接數(shù)
- 使??件?效讀取sendfile苹熏、nopush碟贾、?件實(shí)時(shí)性nodealy、keepalive
- 使?tcp?鏈接轨域、同時(shí)調(diào)整keepalive_timeout?連接超時(shí)時(shí)間
- 針對(duì)靜態(tài)資源進(jìn)?瀏覽器緩存expores袱耽、以及gzip壓縮,當(dāng)然還是建議CDN
- 隱藏當(dāng)前Nginx軟件版本號(hào)干发,避免暴露版本所帶來的攻擊 7) 使?全站https朱巨、確保?站的數(shù)據(jù)傳輸安全
- 禁?通過IP地址直接訪問?站,只允許域名訪問
- 基于refere實(shí)現(xiàn)的放盜鏈铐然,避免惡意盜鏈所帶來的流量攻擊蔬崩。?于跨域訪問(根據(jù)實(shí)際情況)
- 限制IP地址每秒連接數(shù),以及每秒請(qǐng)求數(shù)limit
- 優(yōu)雅的返回錯(cuò)誤??信息(如404搀暑、403)
- nginx proxy_cache沥阳、fastcgi_cache、uwsgi_cache緩存
- 差不多就?了自点, 重點(diǎn):優(yōu)化思路-->具體的?為事例 star桐罕。
6.PHP服務(wù)優(yōu)化
6.1 PHP配置?件
1.php程序配置管理?件/etc/php.ini,主要調(diào)整?志桂敛、?件上傳功炮、禁?危險(xiǎn)函數(shù)、關(guān)閉版本號(hào)顯示术唬、等
#實(shí)際上公司的php開發(fā)?員會(huì)在代碼中指定php錯(cuò)誤?志輸出的位置薪伏。
#;;;;;;;;;;;;;;;;;
# Error logging ; #錯(cuò)誤?志設(shè)置
#;;;;;;;;;;;;;;;;;
error_reporting = E_ALL # 記錄PHP所有錯(cuò)誤?志
log_errors = On # 開啟錯(cuò)誤?志
log_errors_max_len = 1024 #
error_log = /var/log/php_error.log # 錯(cuò)誤?志存儲(chǔ)路徑
display_error = Off # 錯(cuò)誤信息會(huì)在瀏覽器顯示,?產(chǎn)環(huán)境建議關(guān)閉
expose_php = Off # 關(guān)閉php版本信息
date.timezone = Asia/Shanghai # 調(diào)整時(shí)區(qū),默認(rèn)PRC
#;;;;;;;;;;;;;;;
# File Uploads ; #?件上傳設(shè)置
#;;;;;;;;;;;;;;;
file_uploads = On # 允許?件上傳
upload_max_filesize = 300M # 允許上傳?件的最???
post_max_size = 300M # 允許客戶端單個(gè)POST請(qǐng)求發(fā)送的最?數(shù)據(jù)
max_file_uploads = 20 # 允許同時(shí)上傳的?件的最?數(shù)量
memory_limit = 128M # 每個(gè)腳本執(zhí)?最?內(nèi)存
#php禁?危險(xiǎn)函數(shù)執(zhí)?(取決于實(shí)際情況粗仓,需要和開發(fā)溝通)
disable_functions = chown,chmod,pfsockopen,phpinfo
php危險(xiǎn)函數(shù)禁?參考列表
2.php-fpm進(jìn)程管理配置?件/etc/php-fpm.conf
#第?部分嫁怀,fpm配置
[root@nginx ~]# cat /etc/php-fpm.conf
....
;include=etc/fpm.d/*.conf
....
#第?部分,全局配置
[root@nginx ~]# cat /etc/php-fpm.d/www.conf
[global]
;pid = /var/log/php-fpm/php-fpm.pid #pid?件存放的位置
;error_log = /var/log/php-fpm.log #錯(cuò)誤?志存放的位置
;log_level = error #?志級(jí)別, alert, error, warning, notice,
debug
rlimit_files = 65535 #php-fpm進(jìn)程能夠使?的?件描述符
#第三部分借浊,進(jìn)程池定義
[www] #池名稱
user = www #進(jìn)程運(yùn)?的?戶
group = www #進(jìn)程運(yùn)?的組
;listen = /dev/shm/php-fpm.sock #監(jiān)聽在本地socket?件
listen = 127.0.0.1:9000 #監(jiān)聽在本地tcp的9000端?
;listen.allowed_clients = 127.0.0.1 #允許訪問FastCGI進(jìn)程的IP塘淑,any不限制
pm = dynamic #動(dòng)態(tài)調(diào)節(jié)php-fpm的進(jìn)程數(shù)
pm.max_children = 512 #最?啟動(dòng)的php-fpm進(jìn)程數(shù) (峰值就到512個(gè)進(jìn)程)
pm.start_servers = 32 #初始啟動(dòng)的php-fpm進(jìn)程數(shù)
pm.min_spare_servers = 32 #最少的空閑php-fpm進(jìn)程數(shù)
pm.max_spare_servers = 64 #最?的空閑php-fpm進(jìn)程數(shù)
pm.max_requests = 1500 #每?個(gè)進(jìn)程能響應(yīng)的請(qǐng)求數(shù)
pm.process_idle_timeout = 15s;
#第四部分,?志相關(guān)
php_flag[display_errors] = off
php_admin_value[error_log] = /var/log/phpfpm_error.log
php_admin_flag[log_errors] = on
#fpm慢?志
request_slowlog_timeout = 5s #php腳本執(zhí)?超過5s的?件
slowlog = /var/log/php_slow.log #記錄?該?件中
6.2 PHP監(jiān)控模塊
3.php-fpm監(jiān)控模塊蚂斤,?于監(jiān)控php-fpm狀態(tài)使?
[root@nginx ~]# vim /etc/php-fpm.d/www.conf
pm.status_path = /phpfpm_status #開啟php的狀態(tài)??
#修改nginx配置
[root@nginx conf.d]# cat /etc/nginx/conf.d/fpm.conf
server {
listen 80;
server_name php.bgx.com;
location / {
root /code;
index index.php;
}
#新增如下配置
location /phpfpm_status {
fastcgi_pass 127.0.0.1:9000;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
location ~ \.php$ {
fastcgi_pass 127.0.0.1:9000;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}
4.訪問測試phpfpm_status狀態(tài)??
[root@nginx ~]# curl http://127.0.0.1/phpfpm_status
pool: www #fpm池名稱,?多數(shù)為www
process manager: dynamic #動(dòng)態(tài)管理phpfpm進(jìn)程
start time: 05/Jul/2016 #啟動(dòng)時(shí)間存捺,如果重啟會(huì)發(fā)?變化
start since: 409 #php-fpm運(yùn)?時(shí)間
accepted conn: 22 #當(dāng)前池接受的連接數(shù)
listen queue: 0 #請(qǐng)求等待隊(duì)列,如果這個(gè)值不為0,那么需要增加FPM的進(jìn)程數(shù)量
max listen queue: 0 #請(qǐng)求等待隊(duì)列最?的數(shù)量
listen queue len: 128 #請(qǐng)求等待隊(duì)列的?度
idle processes: 4 #php-fpm空閑的進(jìn)程數(shù)量
active processes: 1 #php-fpm活躍的進(jìn)程數(shù)量
total processes: 5 #php-fpm總的進(jìn)程數(shù)量
max active processes: 2 #php-fpm最?活躍的進(jìn)程數(shù)量(FPM啟動(dòng)開始計(jì)算)
max children reached: 0 #進(jìn)程最?數(shù)量限制的次數(shù),如果數(shù)量不為0曙蒸,則說明phpfpm最?進(jìn)
程數(shù)量過?,可以適當(dāng)調(diào)整捌治。
6.3 PHP?志管理
php?志分為錯(cuò)誤?志和慢?志岗钩。
1.通過 upstream_response_time 可以監(jiān)控 Nginx 到 php 所消耗的時(shí)間
#Nginx在log_format中添加upstream_response_time
#編寫?個(gè)php代碼,然后觀察處理事件
<?php
echo "yinwuxu test ok";
sleep(1);
?>
2.php 的 error ?志說明肖油。
#編寫php代碼測試
<?php
echo "yinwuxu test ok";
echo 2/0;
?>
#注意:如果啟?display_errors = On凹嘲,會(huì)直接將錯(cuò)誤顯示??上。
3.php-fpm的慢?志构韵,php只要處理超過1s就會(huì)有記錄
slowlog = /tmp/phpslow.log
request_slowlog_timeout = 1s
#編寫php代碼測試
<?php
echo "yinwuxu test ok";
sleep(2);
?>
6.4 PHP最終配置
5.PHP-FPM配置?件 4核16G、4核32G
[root@nginx ~]# cat /etc/php-fpm.d/www.conf
[global]
pid = /var/run/php-fpm.pid
error_log = /var/log/php-fpm.log
log_level = warning
rlimit_files = 655350
events.mechanism = epoll
[www]
user = nginx
group = nginx
listen = 127.0.0.1:9000
listen.owner = www
listen.group = www
listen.mode = 0660
listen.allowed_clients = 127.0.0.1
pm = dynamic
pm.max_children = 512
pm.start_servers = 32
pm.min_spare_servers = 32
pm.max_spare_servers = 64
pm.process_idle_timeout = 15s;
pm.max_requests = 2048
pm.status_path = /phpfpm_status
#php-www模塊錯(cuò)誤?志
php_flag[display_errors] = off
php_admin_value[error_log] = /var/log/php/php-www.log
php_admin_flag[log_errors] = on
#php慢查詢?志
request_slowlog_timeout = 5s
slowlog = /var/log/php-slow.log