Web Cache Server 介於 Client 跟 Web Server 之間,當使用者存取一個網址,Web Cache Server 會先向後端的 Web Server 取得資料,如果下一個 request 又存取了相同的網址,這時候就可直接由 Web Cache Server 回傳給 Client,用以減少 Web Server 的 Loading。
其他常見的開源代理伺服器有 Squid,Varnish,Nginx,HAProxy,Apache Traffic Server(ATS),其中 HAProxy 沒有 Cache 的功能,Squid 是比較老牌的 proxy server,但遇到 session 數量太高時,容易失效,已經比較少用了,然後 Varnish 取代了 Squid 的地位。
Varnish 主要功能就是 reverse proxy cache server,由於是使用記憶體作為cache,適合用來處理小文件如 css,js 及小圖片的cache。
nginx 主要功能是靜態網頁服務,若是為了提供訪問最頻繁資源的cache,可以使用 nginx-cache 模組,適合cache少量頁面資源,如果 Cache 內容過多容易造成性能瓶頸與負載過大。
所以目前看起來,有兩個伺服器可以嘗試,一個是 ngnix + cache,這個可以用在少量 cache 資源,加上可以處理靜態網頁檔案,另一個是 Apache Traffic Server (ATS),這是比較專用的 cache server,如果要建置專業的 CDN,應該要選擇使用 ATS。
Apache Traffic Server(ATS或TS)是一個高性能的、模塊化的 HTTP 代理和cache服務器。Traffic Server 最初是 Inktomi 公司的商業產品,該公司在 2003 年被 Yahoo 收購,之後 Traffic Server 一直在 Yahoo 內部使用長達 4 年,直到 2009 年 8 月 Yahoo 向 Apache 軟件基金會(ASF)貢獻了源代碼,並於 2010 年 4 月成為了 ASF 的頂級項目(Top-Level Project)。Apache Traffic Server 現在是一個開源項目,開發語言為C++。
軟件名稱 | 性能 | 功能 | 過濾規則配置 |
---|---|---|---|
Squid | 不能多核,disk cache有容量優勢,性能中等 | 多,支援ACL角色控制,也支援ICP cache 協定 | 支援外部規則文件讀取及熱加載,支援熱啟動 |
Varnish | 多核支援,memory cache,性能強 | 夠用,不支援集群,支援後端存活檢查 | 不支援外部文件讀取,需要轉譯,支援熱啟動 |
Nginx | 多核,支援代理插件,性能較強 | 多,通過plugin可以充當多種服務器 | 不支援外部文件讀取,需要轉譯,支援熱啟動 |
ATS | 多核,disk/memory cache,性能強 | 夠用,支援plugin開發,也支援ICP協議 | 支援外部規則文件讀取及熱加載,支援熱啟動,但缺乏文檔 |
HAProxy | 多核,無 cache,支援HTTP header語法操作,性能強 | 少,只專注HTTP頭部解析和轉發功能,支援ACL角色控制,支援後端存活檢查 | 支援外部規則文件讀取及熱加載,支援熱啟動,支援 sticky session 和長連接 |
nginx for CentOS 7
安裝 nginx
yum -y install nginx
# 立即啟動
systemctl start nginx
# 查看目前運作狀態
systemctl status nginx
# 查看 nginx 服務目前的啟動設定
systemctl list-unit-files | grep nginx
# 若是 disabled,可以改成開機自動啟動
systemctl enable nginx
調整 nginx 設定,先把 nginx service port 改為 6000
vi /etc/nginx/nginx.conf
listen 6000 default_server;
listen [::]:6000 default_server;
systemctl restart nginx
安裝及設定 PHP-FPM
yum -y install php php-fpm php-mysql
# 查詢 PHP-FPM 的狀態
systemctl list-unit-files | grep php-fpm
# 改成開機自動啟動
systemctl enable php-fpm
# 立即啟動
systemctl start php-fpm
# 查看目前運作狀態
systemctl status php-fpm
修改 PHP-FPM 設定
chown -R nginx.nginx /var/lib/php/session
vi /etc/php-fpm.d/www.conf
user = nginx
group = nginx
listen.owner = nginx
listen.group = nginx
listen.mode = 0660
; listen = 127.0.0.1:9000 改成
listen = /var/run/php-fpm/php-fpm.sock
systemctl restart php-fpm
修改 ulimit open file的限制
# 查閱file open 限制
ulimit -a
vi /etc/security/limits.conf
# 增加 4行
* soft nofile 65535
* hard nofile 65535
root hard nofile 65535
root soft nofile 65535
# 設定 file open數量
ulimit -n 65535
nginx proxy_cache
nginx 自 v0.7.48 開始支援了類似 Squid 的功能,他會把 url 當作 key,以 MD5 對 key 進行 hash,然後得到硬碟上對應的 hash 檔案目錄,然後將快取的內容存放到這個目錄中。目前沒有清除 cache 的功能,但可透過 ngxcachepurge 模組,清除指定 URL 的 cache。
建立 cache 目錄
mkdir -p /usr/share/nginx/cache
chown -R nginx.nginx /usr/share/nginx/cache
proxy_cache 相關的設定值
# 設定快取檔案的存放路徑 proxy_cache_path
proxy_cache_path path [levels=number] keys_zone=zone_name:zone_size [inactive=time] [max_size=size];
# path 快取檔案的存放路徑
# levels=number 快取空間有兩層 hash 目錄
# keys_zone=zone_name:zone_size zone_name是為這個快取空間命名,zone_size是記憶體快取的空間大小
# inactive=time 快取存活的時間
# max_size=size 硬碟快取空間
# example
proxy_cache_path /usr/share/nginx/cache levels=1:2 keys_zone=STATIC:50m inactive=1d max_size=20g;
# ---------------
# 設定要使用哪一個快取空間名稱 proxy_cache
proxy_cache zone_name;
# zone_name 就是剛剛在 proxy_cache_path 設定的 zone_name
# example
proxy_cache STATIC;
# ---------------
# proxy_cache_methods 設定快取哪些 HTTP method,預設為 GET/HEAD
proxy_cache_methods [GET HEAD POST]
# ---------------
# proxy_cache_min_uses 設定快取的最小使用次數,預設為 1
proxy_cache_min_uses 1;
# ---------------
# proxy_cache_valid 對不同的 reponse status code 的 URL 設定不同的快取時間
proxy_cache_valid reply_code time;
# example
proxy_cache_valid 200 302 10m;
proxy_cache_valid 301 1h;
proxy_cache_valid 404 1m;
proxy_cache_valid any 1m;
# ---------------
# proxy_cache_key 設定快取的 key 值
proxy_cache_key "$host:$server_port$uri$is_args$args"
# ---------------
# 如果後端服務器經常發生503錯誤,服務不能保證可正確取得資料,為了避免訪問錯誤,可以在cache server上做調整。如果cache過期,但訪問後端服務器又不能返回正常的內容,則使用cache的內容。
proxy_cache_use_stale error timeout invalid_header updating http_500 http_502 http_503 http_504;
如果要驗證是不是從 Cache 取得的內容,可以加上這個 header
add_header Nginx-Cache "$upstream_cache_status from cache";
當我們用瀏覽器觀看 Header 時,如果沒有 hit,會看到這樣的 header
Nginx-Cache:MISS from cache
如果有 hit,會看到這樣的 header
Nginx-Cache:HIT from cache
範例
完整的範例
http {
proxy_cache_path /usr/share/nginx/cache levels=1:2 keys_zone=STATIC:50m inactive=1d max_size=20g;
server {
location / {
proxy_pass http://127.0.0.1:8080;
proxy_set_header Host $host;
proxy_cache STATIC;
proxy_cache_valid 200 302 10m;
proxy_cache_valid 301 1h;
proxy_cache_valid 404 1m;
proxy_cache_valid any 1m;
proxy_cache_use_stale error timeout invalid_header updating
http_500 http_502 http_503 http_504;
}
}
}
紀錄最後修改好的設定檔
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;
events {
worker_connections 1024;
}
http {
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;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
include /etc/nginx/mime.types;
default_type application/octet-stream;
include /etc/nginx/conf.d/*.conf;
proxy_cache_path /usr/share/nginx/cache levels=1:2 keys_zone=STATIC:50m inactive=1d max_size=20g;
server {
listen 6000 default_server;
listen [::]:6000 default_server;
server_name _;
server_tokens off;
root /usr/share/nginx/html;
# Load configuration files for the default server block.
include /etc/nginx/default.d/*.conf;
location / {
proxy_pass http://127.0.0.1:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
location ~ .*\.(gif|jpg|png|bmp|swf|js|css|lzv|pdf|html|jsp)$ {
proxy_cache STATIC;
proxy_cache_valid 200 302 10m;
proxy_cache_valid 301 1h;
proxy_cache_valid 404 1m;
proxy_cache_valid any 1m;
#proxy_cache_use_stale error timeout invalid_header updating
# http_500 http_502 http_503 http_504;
proxy_cache_key $host$uri$is_args$args;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
#proxy_set_header X-Real-IP $Forwarded-For;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
add_header Nginx-Cache "$upstream_cache_status from cache";
proxy_pass http://127.0.0.1:8080;
}
error_page 404 /404.html;
location = /40x.html {
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
}
}
}
清除 cache
如果要清除 cache,可直接刪除 proxycachepath 目錄下所有檔案
vi clear_nginx_cache.sh
#!/bin/bash
find /usr/share/nginx/cache -type f -exec rm -f {} \;
chmod 755 clear_nginx_cache.sh
每天定時刪除超過兩天的 cache file
vi /etc/cron.daily/delete_nginx_cache.sh
#!/bin/bash
find /usr/share/nginx/cache -type f -mtime +2 -print0 | xargs -0 -r rm >/dev/null 2>&1
chmod 755 /etc/cron.daily/delete_nginx_cache.sh
處理 Nginx 產生的大量 TCP_WAIT
由於 Nginx Proxy 會產生大量 TCP_WAIT,我們需要調整 linux TCP 的參數,並調整 nginx 的設定。
# 用 netstat 查看 TCP_WAIT 數量
netstat -n | awk '/^tcp/ {++state[$NF]} END {for(key in state) print key,"\t",state[key]}'
# 用 ss 查看 TCP_WAIT 數量
ss -ant | awk 'NR>1 {++s[$1]} END {for(k in s) print k,s[k]}'
查看 /proc/sys/net/ipv4/iplocalport_range 設定檔,可得知 Linux 動態分配 Local Port 的 Range。
cat /proc/sys/net/ipv4/ip_local_port_range
32768 61000
透過修改 /etc/sysctl.conf 可調整 local service ports
vim /etc/sysctl.conf
net.ipv4.ip_local_reserved_ports = 32768-61000
sysctl -p
修改 /etc/sysctl.conf TCP 參數
vim /etc/sysctl.conf
net.ipv4.ip_local_port_range = 1024 65535
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
net.ipv4.tcp_rmem = 4096 87380 16777216
net.ipv4.tcp_wmem = 4096 65536 16777216
net.ipv4.tcp_fin_timeout = 10
net.ipv4.tcp_tw_recycle = 1
net.ipv4.tcp_timestamps = 0
net.ipv4.tcp_window_scaling = 0
net.ipv4.tcp_sack = 0
net.core.netdev_max_backlog = 30000
net.ipv4.tcp_no_metrics_save = 1
net.core.somaxconn = 65535
net.ipv4.tcp_syncookies = 0
net.ipv4.tcp_max_orphans = 262144
net.ipv4.tcp_max_syn_backlog = 262144
net.ipv4.tcp_synack_retries = 2
net.ipv4.tcp_syn_retries = 2
# sysctl.conf 重新載入設定
sysctl -p
修改 /etc/security/limits.conf
vim /etc/security/limits.conf
* soft nofile 655360
* hard nofile 655360
ulimit -n 655360
修改 /etc/nginx/nginx.conf 參數
vim /etc/nginx/nginx.conf
worker_rlimit_nofile 102400;
events {
worker_connections 1024; # 可以加到 4096
#worker_connections 768;
use epoll;
# multi_accept on;
}
upstream webserver {
server 127.0.0.1:8000 weight=10;
keepalive 16;
}
http {
#keepalive_timeout 65;
keepalive_timeout 1;
}
# 後面 proxy_pass 的地方要改成這樣
proxy_pass http://webserver;
References
varnish / squid / nginx cache 有什麼不同?
RHEL / CentOS 7 安裝 Nginx, MySQL, PHP (LEMP)
沒有留言:
張貼留言