簡介 一個很好的原則是調優時每次只個性一個配置。如果對配置的個性不能提高性能的話,改回預設值 優化必須要通過性能測試。不能意淫,需要前後對比,真實說明問題。 場景 1. 優化nginx。 2. 確保每次請求控制一定資源。 3. 減少訪問web容器 解決方案 nginx優化 全局優化 日誌 日誌是要讀 ...
簡介
一個很好的原則是調優時每次只個性一個配置。如果對配置的個性不能提高性能的話,改回預設值
優化必須要通過性能測試。不能意淫,需要前後對比,真實說明問題。
場景
- 優化nginx。
- 確保每次請求控制一定資源。
- 減少訪問web容器
解決方案
nginx優化
全局優化
# nginx進程數,建議按照cpu數目來指定,一般為它的倍數。
worker_processes 8;
worker_cpu_affinity 00000001 00000010 00000100 00001000 00010000 00100000 01000000 10000000;
# 這個指令是指當一個nginx進程打開的最多文件描述符數目,理論值應該是最多打開文件數(ulimit -n)與nginx進程數相除,但是nginx分配請求並不是那麼均勻,所以最好與ulimit -n的值保持一致
worker_rlimit_nofile 65535;
events {
# 使用epoll的I/O模型。
use epoll;
# 每個進程允許的最多連接數,理論上每台nginx伺服器的最大連接數為worker_processes*worker_connections
worker_connections 50000;
}
#sendfile 指令指定 nginx 是否調用 sendfile 函數(zero copy 方式)來輸出文件,對於普通應用,
#必須設為 on,如果用來進行下載等應用磁碟IO重負載應用,可設置為 off,以平衡磁碟與網路I/O處理速度,降低系統的uptime.
sendfile on;
#連接超時時間,單位時間是秒
keepalive_timeout 180;
#FastCGI相關參數是為了改善網站的性能:減少資源占用,提高訪問速度。下麵參數看字面意思都能理解。
fastcgi_connect_timeout 300;
fastcgi_send_timeout 300;
fastcgi_read_timeout 300;
fastcgi_buffer_size 64k;
fastcgi_buffers 4 64k;
fastcgi_busy_buffers_size 128k;
fastcgi_temp_file_write_size 128k;
#防止網路阻塞
tcp_nopush on;
tcp_nodelay on;
#開啟gzip壓縮
gzip on;
gzip_min_length 512;
gzip_buffers 4 16k;
gzip_http_version 1.0; #壓縮版本(預設1.1,前端如果是squid2.5請使用1.0)
gzip_comp_level 5;
#壓縮類型,預設就已經包含text/html,所以下麵就不用再寫了,寫上去也不會有問題,但是會有一個warn。
gzip_types text/plain application/json application/x-javascript text/css application/xml;
gzip_vary on;
gzip_disable "MSIE [1-6]\.";
# 這個是指多長時間檢查一次緩存的有效信息。
open_file_cache_valid 30s;
# open_file_cache指令中的inactive參數時間內文件的最少使用次數,如果超過這個數字,文件描述符一直是在緩存中打開的,如上例,如果有一個文件在inactive時間內一次沒被使用,它將被移除。
open_file_cache_min_uses 1;
# 客戶端請求頭部的緩衝區大小,這個可以根據你的系統分頁大小來設置,一般一個請求的頭部大小不會超過1k,不過由於一般系統分頁都要大於1k,所以這裡設置為分頁大小。分頁大小可以用命令getconf PAGESIZE取得
open_file_cache max=102400 inactive=20s;
日誌
日誌是要讀寫文件的,I/O消耗特別嚴重。日誌是否開啟可以根據自己具體的架構需求。
建議的是如下:
靜態資源不記錄。
# 靜態資源通過nginx來管理 location ~ .*\.(gif|jpg|jpeg|png|bmp|swf|js|css|ico)$ { # 關閉日誌 access_log off; include deny/agent.conf; if (-f $request_filename) { expires 1d; break; } }
動態資源要記,但是需要添加緩存。
access_log logs/access.log main buffer=12k;
限制資源使用
這個其實和安全非常相似。本質是限制資源使用,這樣就能讓有限的資源為更多人提供服務。
所以可以參見:web安全——代理(nginx)
減少訪問web容器
一般web容器的性能都是比較差了,所以儘量阻止訪問web容器。
動靜分離
一般的web容器的長鏈接性能都比較弱,而nginx在這方面又特別優秀。
# 動態的服務
server {
server_name sso.xxx.com;
#監聽
listen 80;
location / {
#反向代理到指定的服務
proxy_pass http://xxx-server;
#定義伺服器的預設網站根目錄位置
root /;
proxy_set_header Host $host;
#後端的Web伺服器可以通過X-Forwarded-For獲取用戶真實IP
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
client_max_body_size 100m;
}
}
# 靜態的服務
server {
server_name static.xxx.com;
location ~ .*\.(gif|jpg|jpeg|png|bmp|swf|js|css|ico)$ {
# 文件根目錄,這個目錄根據文件的位置變更即可。
root /home/static;
if (-f $request_filename) {
expires 1d;
break;
}
}
}
緩存化
把一些熱點的數據放在緩存伺服器,這樣能提升性能。
srcache_nginx+redis構建緩存系統。在web應用中通過設置http的緩存特性(最好是基於註釋或者配置,對開發者儘量是透明的,不要增加業務複雜度),來判斷是否需要緩存。
#設置key,根據功能變數名稱和uri
set $key $host$request_uri;
#來一個md5,要不然key太長。而且key特別長的時候,貌似在srache_store的時候執行不了
set_md5 $md5key $key;
#調用HttpSRCacheModule的srcache_fetch 在http進入時,執行該方法,如果取到值,則不執行代理(即不執行tomcat),直接返回
srcache_fetch GET /redis2_get $md5key;
#如果沒有設置緩存時間,則預設時間為這個
srcache_default_expire 3600s;
#調用HttpSRCacheModule的srcache_store在執行代理(即執行tomcat)後,執行該方法,而且必需為“cache-control” 不等於"no-cahce"才執行。
#srcache_expire的取值優先順序
#1、如果有cache-control;max-age=N,則取N
#2、如果沒有,有expire,則取expire
#3、如果都沒有取srcache_default_expire
srcache_store PUT /redis2_set key=$md5key&expire=$srcache_expire;
靜態化
把基本沒有變化的請求轉為靜態文件資源。直接通過文件提供服務。
實現思路見下麵的參考資料。
不過可能會有個問題,需要註意並且以後去解決
# 問題
平常訪問是沒有問題,但在高併發下,你想死的心都有。打開文件不對,一看是前面還沒寫完,另外一個用戶就訪問了,又寫,導致文件格式不對。
# 建議思路
如果最終還是要寫html,還是通過程式去實現。例如:新聞類更新時,由編輯人員點擊發佈,此時可能就寫了一個靜態的html,而不是由用戶去訪問出發寫html,避免高併發會出現的問題
需要進一步思考的地方:
緩存化
和靜態化
使用的場景。以及在nginx使用靜態化
是否合適。
驗證方法
- pagespeed.webkaka.com。驗證是否開啟gzip。
- ab|webbench,來測試介面。