一.壓縮
gzip on; 啓用 gzip 壓縮功能
gzip_min_length 1k; 不壓縮臨界值,大於1K的才壓縮
gzip_http_version; 設置對指定http協議版本進行壓縮
gzip_buffers 設置緩衝區的數量和大小,如果大小沒有設置,那麼默認是一個頁碼的大小,依賴所在系統平臺
gzip_comp_level 1~9 指定壓縮率,數值越大,壓縮率是最大的,但是消耗CPU資源多,而且慢;而小的數值是最快的,消耗資源少,但是壓縮率小。這個根據需要自己權衡
gzip_proxied 根據響應的類型,來設置是否壓縮,匹配的前提是後端服務器返回Via Header頭
gzip_types 指定需要壓縮類型
gzip_vary 該指令用於設定是否向響應數據包添加Vary:Accept-Encoding HTTP頭
gzip on;
gzip_comp_level 6; # 壓縮比例,比例越大,壓縮時間越長。默認是1
gzip_types text/xml text/plain text/css application/javascript application/x-javascript application/rss+xml; # 哪些文件可以被壓縮
gzip_disable "MSIE [1-6]\.";
測試:
用curl測試Gzip是否成功開啓(-H/–header 自定義頭信息傳遞給服務器)
curl -I -H “Accept-Encoding: gzip, deflate” “http://www.slyar.com/blog/”
二.緩存
1.nginx通過expires指令來設置瀏覽器的Header
#圖片緩存30天
location ~.*\.(jpg|png|jpeg)$
{
expires 30d;
}
#js css緩存一小時
location ~.*\.(js|css)?$
{
expires 1h;
}
2.nginx自帶的內置緩存模塊proxy_cache
proxy_temp_file_write_size 128k;
proxy_temp_path /usr/local/nginx/proxy_temp;
proxy_cache_path /usr/local/nginx/proxy_cache levels=1:2 keys_zone=content:20m inactive=1d max_size=100m;
levels設置目錄層次 keys_zone設置緩存名字和共享內存大小 inactive在指定時間內沒人訪問則被刪除 max_size最大緩存空間
location /
{
proxy_cache content; //根keys_zone後的內容對應
proxy_cache_valid 200 304 301 302 10d; //哪些狀態緩存多長時間
proxy_cache_valid any 1d; //其他的緩存多長時間
proxy_cache_key $host$uri$is_args$args; //通過key來hash,定義KEY的值
}
緩存的文件名和key爲代理URL的MD5 碼。
三.其他
worker_processes 定義了nginx對外提供web服務時的worker進程數。
worker_rlimit_nofile 102400;
更改worker進程的最大打開文件數限制,這個指令是指當一個nginx進程打開的最多文件描述符數目,理論值應該是最多打開文件數(ulimit -n)與nginx進程數(worker_processes)相除,但是nginx分配請求並不是那麼均勻,所以最好與ulimit -n的值保持一致。
Events模塊
multi_accept on 告訴nginx收到一個新連接通知後接受盡可能多的連接。
worker_connections 設置可由一個worker進程同時打開的最大連接數。如果設置了上面提到的worker_rlimit_nofile。最大客戶數也由系統的可用socket連接數限制(~ 64K),所以設置不切實際的高沒什麼好處。
use epoll; 使用epoll的I/O模型
HTTP 模塊
server_tokens 並不會讓nginx執行的速度更快,但它可以關閉在錯誤頁面中的nginx版本數字,這樣對於安全性是有好處的
sendfile 可以讓sendfile()發揮作用。sendfile()可以在磁盤和TCP socket之間互相拷貝數據(或任意兩個文件描述符)。Pre-sendfile是傳送數據之前在用戶空間申請數據緩衝區。之後用read()將數據從文件拷貝到這個緩衝區,write()將緩衝區數據寫入網絡。sendfile()是立即將數據從磁盤讀到OS緩存。因爲這種拷貝是在內核完成的,sendfile()要比組合read()和write()以及打開關閉丟棄緩衝更加有效(處理靜態文件時有效)。
tcp_nopush 告訴nginx在一個數據包裏發送所有頭文件,而不一個接一個的發送。
tcp_nodelay 告訴nginx不要緩存數據,而是一段一段的發送–當需要及時發送數據時,就應該給應用設置這個屬性,這樣發送一小塊數據信息時就不能立即得到返回值。通過設置套接字的TCP_NODELAY = on 選項來完成,這樣就禁用了Nagle 算法。
limit_conn_zone 設置用於保存各種key(比如當前連接數)的共享內存的參數。5m就是5兆字節,這個值應該被設置的足夠大以存儲(32K*5)32byte狀態或者(16K*5)64byte狀態。
limit_conn 爲給定的key設置最大連接數。這裏key是addr,我們設置的值是100,也就是說我們允許每一個IP地址最多同時打開有100個連接。
limit_conn_zone $binary_remote_addr zone=addr:5m;
limit_conn addr 100;
ngx_http_limit_conn_module 模塊
服務器流量異常,負載過大等等。對於大流量惡意的攻擊訪問,會帶來帶寬的浪費,服務器壓力,影響業務,往往考慮對同一個ip的連接數,併發數進行限制。
include /etc/nginx/mime.types;
default_type text/html;
charset UTF-8;
include 只是一個在當前文件中包含另一個文件內容的指令。這裏我們使用它來加載稍後會用到的一系列的MIME類型。
default_type 設置文件使用的默認的MIME-type。
charset 設置我們的頭文件中的默認的字符集
open_file_cache 打開緩存的同時也指定了緩存最大數目,以及緩存的時間。我們可以設置一個相對高的最大時間,這樣我們可以在它們不活動超過20秒後清除掉。
open_file_cache_valid 在open_file_cache中指定檢測正確信息的間隔時間。
open_file_cache_min_uses 定義了open_file_cache中指令參數不活動時間期間裏最小的文件數。
open_file_cache_errors 指定了當搜索一個文件時是否緩存錯誤信息,也包括再次給配置中添加文件。我們也包括了服務器模塊,這些是在不同文件中定義的。如果你的服務器模塊不在這些位置,你就得修改這一行來指定正確的位置。
open_file_cache 指令會對以下信息進行緩存:
* 打開文件描述符的文件大小和修改時間信息
* 存在的目錄信息
* 搜索文件的錯誤信息:文件不存在無權限讀取等信息
#指定一個request可接受的body大小,即請求頭裏的Content-Length. 如果請求body超過該值,nginx返回413(“Request Entity Too Large”),大文件需要適當調大
client_max_body_size 10M;
#客戶端請求頭部的緩衝區大小,這個可以根據你的系統分頁大小來設置,一般一個請求頭的大小不會超過1k
client_header_buffer_size 4k;
#指定允許爲客戶端請求頭最大分配buffer個數和大小.
large_client_header_buffers 8 128k;
四.內核優化
# vim /etc/sysctl.conf
#表示開啓重用。允許將TIME-WAIT sockets重新用於新的TCP連接,默認爲0,表示關閉
net.ipv4.tcp_tw_reuse = 1
#客戶端爲NAT網絡模式下,服務器會主動丟包,表示開啓TCP連接中TIME-WAIT sockets的快速回收,默認爲0,表示關閉
net.ipv4.tcp_tw_recycle = 1
#開啓TCP時間戳
net.ipv4.tcp_timestamps = 1
#表示如果套接字由本端要求關閉,這個參數決定了它保持在FIN-WAIT-2狀態的時間。
net.ipv4.tcp_fin_timeout = 20
# netstat -s|grep timestamp
timeout數量不大的時候,不用調整tcp_tw_recycle參數,雖然服務器端沒有使用nat,但是客戶端使用snat的情況很多,如果後發現packets rejects in established connections because of timestamp增長很快
net.ipv4.tcp_max_tw_buckets = 6000 表示系統同時保持TIME_WAIT套接字的最大數量,如果超過這個數字,TIME_WAIT套接字將立刻被清除並打印警告信息。
net.ipv4.ip_local_port_range = 1024 65000
允許系統打開的端口範圍
net.ipv4.tcp_syncookies = 1
#表示開啓SYN Cookies。當出現SYN等待隊列溢出時,啓用cookies來處理,可防範少量SYN攻擊,默認爲0,表示關閉;
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_synack_retries = 1
syn-ack握手狀態重試次數,默認5,遭受syn-flood攻擊時改爲1或2
爲了打開對端的連接,內核需要發送一個SYN 並附帶一個迴應前面一個SYN 的ACK。也就是所謂三次握手中的第二次握手。這個設置決定了內核放棄連接之前發送SYN+ACK 包的數量。
net.ipv4.tcp_syn_retries = 1
外向syn握手重試次數,默認4
在內核放棄建立連接之前發送SYN 包的數量。
net.ipv4.neigh.default.gc_stale_time=120 ARP參數,檢查一次相鄰層記錄的有效性的週期。當相鄰層記錄失效時,將在給它發送數據前,再解析一次。缺省值是60秒。
net.ipv4.conf.default.arp_ignore = 1
net.ipv4.conf.all.arp_ignore = 1
net.ipv4.conf.lo.arp_ignore = 1
arp_ignore:定義了網卡在響應外部ARP請求時候的響應級別
0:默認值,不管哪塊網卡接收到了ARP請求,只要發現本機有這個MAC都給與響應
1:總是使用最合適的網卡來響應,一個主機有多塊網卡,其中一塊網卡接收到了ARP請求,發現所請求的MAC是本機另一塊網卡的,這個時候接收到ARP請求的這塊網卡就一定不響應,只有發現請求的MAC是自己的纔給與響應。
net.ipv4.conf.default.arp_announce =2
net.ipv4.conf.all.arp_announce =2
net.ipv4.conf.lo.arp_announce = 2
定義了網卡在向外宣告自己的MAC-IP時候的限制級別
有三個值:
0:默認值,不管哪塊網卡接收到了ARP請求,只要發現本機有這個MAC都給與響應
1:儘量避免響應ARP請求中MAC不是本網卡的,一個主機有多塊網卡,其中一塊網卡接收到了ARP請求,發現所請求的MAC是本機另一塊網卡的,這個時候接收到ARP請求的這塊網卡就儘量避免響應
2:總是使用最合適的網卡來響應,一個主機有多塊網卡,其中一塊網卡接收到了ARP請求,發現所請求的MAC是本機另一塊網卡的,這個時候接收到ARP請求的這塊網卡就一定不響應,只有發現請求的MAC是自己的纔給與響應。
執行sysctl-p使修改生效
# sysctl-p
完整配置
worker_processes 1;
error_log logs/error.log;
events {
worker_connections 1024;
multi_accept on;
use epoll;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
tcp_nopush on;
server_tokens off;
keepalive_timeout 65;
gzip on;
gzip_min_length 1k;
gzip_buffers 4 16k;
gzip_http_version 1.0;
gzip_comp_level 2;
gzip_types text/plain application/x-javascript text/css application/xml;
gzip_vary on;
open_file_cache max=102400 inactive=20s;
open_file_cache_valid 30s;
open_file_cache_min_uses 2;
client_max_body_size 20m;
client_body_buffer_size 128k;
#proxy_redirect off;
#proxy_set_header Host $host;
#proxy_set_header X-Real-IP $remote_addr;
#proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
#proxy_ignore_client_abort on;
#proxy_connect_timeout 60s;
#proxy_send_timeout 60s;
#proxy_read_timeout 60s;
#proxy_buffer_size 64k;
#proxy_buffers 4 64k;
#proxy_busy_buffers_size 128k;
#proxy_intercept_errors on;
#proxy_temp_path /etc/nginx/proxy_temp;
#proxy_cache_path /etc/nginx/proxy_cache levels=1:2 keys_zone=one_cache:20m inactive=1d max_size=100m;
#proxy_ignore_headers X-Accel-Expires Expires Cache-Control Set-Cookie;
server {
listen 80;
server_name localhost;
location / {
root html;
index index.html index.htm;
}
#location ~ .*\.(html|htm|ico|jpeg|git|jpg|png|bmp|swf)$ {
# root ;
# proxy_pass http://www.demo.com:8080;
# proxy_cookie_path /demo/ /;
#
# proxy_cache one_cache;
# proxy_cache_valid 200 304 301 302 1d;
# proxy_cache_valid any 6h;
# proxy_cache_key $host$uri$is_args$args;
# add_header X-Cache '$upstream_cache_status from $host';
# expires 7d;
#}
#
#location ~ .*\.(css|js)$ {
# root ;
# proxy_pass http://www.demo.com:8080;
# proxy_cookie_path /demo/ /;
#
# proxy_cache one_cache;
# proxy_cache_valid 200 304 301 302 1d;
# proxy_cache_valid any 6h;
# proxy_cache_key $host$uri$is_args$args;
# add_header X-Cache '$upstream_cache_status from $host';
# expires 1d;
#}
#
#location ~ .*$ {
# proxy_pass http://www.demo.com:8080;
# proxy_cookie_path /demo/ /;
#}
}
}