Nginx常見用法總結(面試必備)

  • 2019 年 10 月 7 日
  • 筆記

Nginx在日常開發過程中主要作為靜態資源服務器(http服務器)和反向代理服務器。

Nginx常用變量

  • $host: 請求的主機頭
if ($host = 'bbs.gitlib.com') {  	rewrite ^/$ http://bbs.bliwan.com permanent;  }
  • $remote_addr: 客戶端IP地址
  • $remote_port: 客戶端端口號
  • $remote_user: 已經經過Auth Basic Module驗證的用戶名
  • $http_referer: 請求引用地址
  • $http_user_agent: 客戶端代理信息(UA)
  • $http_x_forwarded_for: 相當於網絡訪問路徑
  • $body_bytes_sent: 頁面傳送的位元組數
  • $time_local: 服務器時間
  • $request: 客戶端請求
  • $request_uri: 請求的URI,帶參數, 不包含主機名
  • $request_filename: 請求的文件路徑
  • $request_method: 請求的方法,如GET、POST
  • $args: 客戶端請求中的參數
  • $query_string: 等同於$args, 客戶端請求的參數
  • $nginx_version: 當前nginx版本
  • $status: 服務器響應狀態碼
  • $server_addr: 服務器地址
  • $server_port: 請求到達的服務器端口號
  • $server_protocol: 請求的協議版本
  • $content_type: HTTP請求信息里的Content-Type字段
  • $content_length: HTTP請求信息里的Content-Length字段
  • $uri: 請求中的當前URI(不帶請求參數,參數位於$args)
  • $document_root: 當前請求在root指令中指定的值
  • $document_uri: 與$uri相同

定義日誌格式示例:

log_format access '$remote_addr - $remote_user [$time_local] "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent" $http_x_forwarded_for';  輸入格式:  14.18.29.118 - - [24/Jun/2017:20:53:09 +0800] "GET /index.html HTTP/1.1" 200 23 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36" -

Nginx設置重定向

return形式

# 301永久重定向,302臨時重定向  return 301 https://example.com$request_uri;    # return 返回形式  return code;  return code URL;  return URL;

rewrite形式

rewrite ^/$ http://bbs.gitlib.com permanent;

rewrite flag說明:

  • last: 停止處理後續rewrite指令集,然後對當前重寫的新URI在rewrite指令集上重新查找
  • break: 停止處理後續rewrite指令集,並不在重新查找,但是當前location內剩餘非rewrite語句和location外的非rewrite語句可以執行
  • redirect: 如果replacement不是以http:// 或https://開始,返回302臨時重定向
  • permant: 返回301永久重定向

Nginx條件判斷

if判斷

if ($http_user_agent ~ (125LA|WinHttpRequest|360Spider)) {  	return 444;  }    if ($http_referer ~* "filter=author&orderby=dateline") {  	return 444;  }    if ($host = 'bbs.gitlib.com') {  	rewrite ^/$ http://bbs1.gitlib.com permanent;  }

比較符說明:

  • 使用=、!= 比較的一個變量和字符串,true/false
  • 使用~、~*與正則表達式匹配的變量,如果這個正則表達式中包含右花括號}或者分號;則必須給整個正則表達式加引號
  • 使用-f、!-f 檢查一個文件是否存在
  • 使用-d、!-d 檢查一個目錄是否存在
  • 使用-e、!-e 檢查一個文件、目錄、符號鏈接是否存在
  • 使用-x、!-x 檢查一個文件是否可執行

set設置變量

if ( $host ~* (.*).yzz.cn) {  	set $domain $1;  }  root /www/website/www/gitlib/$domain/;    # set語法  set variable value;

Nginx反向代理

proxy_pass

proxy_pass將請求傳遞給HTTP服務器  proxy_buffering: on; # 設置是否開啟Proxy Buffer,默認為on  proxy_pass http://upload.gitlib.com; # 設置被代理服務器的地址  proxy_connect_timeout 600;# 設置Nginx服務器與後端被代理服務器嘗試建立連接的超時時間,默認為60s  proxy_read_timeout 600; # 設置Nginx服務器向後端被代理服務器發出read請求後,等待響應的超時時間,默認為60s  proxy_send_timeout 600; # 設置Nginx服務器向後端被代理服務器發出write請求後,等待響應的超時時間,默認為60s  proxy_buffer_size 8k; # 設置Nginx服務器從被代理服務器獲取的第一段數據buffer大小,一般和proxy_buffers設置的buffer大小一致,或者更小, 默認為4k或者8k  proxy_buffers 4 32k; # 設置Proxy Buffer的個數和每個Buffer的大小  proxy_busy_buffers_size 64k; # 設置處在Busy狀態的Buffer總大小上限,默認為8K或者16K  proxy_temp_file_write_size 64k; #  proxy_next_upstream error timeout invalid_header http_500 http_503 http_404; # upstream設置被代理服務器集群時,設置組內服務器出現哪些異常時,可以依次輪詢到下一個組內服務器處理  proxy_redirect off; # 修改響應頭Location值,off表示直接返回proxy_pass後的值,默認為default(客戶端請求的URI),

fastcgi_pass

fastcgi_pass將請求傳遞給FastCGI服務器

fastcgi_connect_timeout 3000;  fastcgi_send_timeout 3000;  fastcgi_read_timeout 3000;  fastcgi_buffer_size 200k;  fastcgi_buffers 8 200k;  fastcgi_busy_buffers_size 200k;  fastcgi_max_temp_file_size:1024M; # 設置臨時文件大小,默認為1024M  fastcgi_temp_file_write_size 200k;# 配置同時寫入臨時文件的數據量的大小,合理的配置可以避免磁盤IO負載過高,導致系統性能下降,默認為8KB或16KB  fastcgi_temp_path /dev/shm; # 配置磁盤上的一個文件路徑,用於臨時存放代理服務器的大體積響應數據,如果proxy buffer 被裝滿後,響應數據仍然沒有被Nginx服務器完全接收,響應數據就被會臨時存放在該文件中

uwsgi_pass

uwsgi_pass將請求傳遞給uwsgi服務器(如python服務)

scgi_pass

scgi_pass將請求傳遞給SCGI服務器

memcached_pass

memcached_pass將請求傳遞給memcached服務器

Nginx負載均衡

Nginx通過proxy_pass和upstream指令實現負載均衡,Nginx原生支持的負載均衡算法有如下幾種:

輪詢

每個請求按時間順序逐一分配到不同的應用服務器,如果應用服務器down掉,自動剔除,剩下的繼續輪詢

權重

通過配置權重,指定輪詢幾率,權重和訪問比率成正比,用於應用服務器性能不均的情況

ip_hash

每個請求按訪問ip的hash結果分配,這樣每個訪客固定訪問一個應用服務器,可以解決session共享的問題。

least_conn

最小連接數

示例:

upstream php {  	server 127.0.0.1:9000 max_fails=3 fail_timeout=30s;  	server 192.168.1.16 backup;  	server 192.168.1.17 down;  }    upstream php {  	server 192.168.10.2 weight=1;  	server 192.168.10.3 weight=2;  }    upstream php {  	ip_hash;  	server 192.168.10.16;  	server 192.168.10.17;  }

Nginx緩存

Proxy Cache

Nginx通過proxy_cache來實現緩存。Buffer和Cache都是用於提供IO吞吐小路的,但是概念不同。Buffer(緩衝)主要用於傳輸效率不同步或者優先級不相同的設備之間傳輸數據,一般通過對一方數據進行臨時存放,再統一發送的辦法傳遞給另一方,以降低進程之間的等待時間,保證速度較快的進程不發生間斷,臨時存放的數據一旦傳送給另一方,這些數據本身也就沒有用處了;Cache(緩存)主要用於將硬盤上已有的數據在內存中建立緩存數據,提高數據的訪問效率,對於過期不用的緩存可以隨時銷毀。

Proxy Cache機制依賴於Proxy Buffer機制,只有在Proxy Buffer機制開啟的情況下Proxy Cache的配置才會發揮作用。

相關配置參數說明:

  • proxy_cache: zone | off; # 默認為off,即關閉proxy_cache功能,zone為用於存放緩存的內存區域名稱
  • proxy_cache_path: path [levels=levels] keys_zone=name:size [inactive=time] [max_size=size];
  • path設置緩存數據存放的路徑;
  • levels設置目錄層級,如levels=1:2,表示有兩級子目錄,第一個目錄名取md5值的倒數第一個值,第二個目錄名取md5值的第2和3個值。
  • keys_zone設置內存zone的名字和大小,如keys_zone=my_zone:10m
  • inactive設置緩存多長時間就失效,當硬盤上的緩存數據在該時間段內沒有被訪問過,就會失效了,該數據就會被刪除,默認為10s。
  • max_size設置硬盤中最多可以緩存多少數據,當到達該數值時,nginx會刪除最少訪問的數據

示例

proxy_cache_path /data/nginx_cache/ levels=1:2 keys_zone=my_zone:10m inactive=300s max_size=5g;  location / {  	proxy_cache my_zone;  	proxy_pass http://192.168.10.110: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;  }

Expires

 location ~ .*.(jpg|jpeg|gif|png|ico|swf)?$  {  	expires 1d; #設置過期時間  }

Nginx實現Gzip壓縮

通過gzip相關指令可以配置Gzip壓縮,對響應數據進行在線實時壓縮。

相關配置參數說明:

  • gzip: on; # 開啟或關閉gzip功能,默認為off
  • gzip_buffers: 16 8K; # 配置Gzip壓縮文件時使用的緩存空間大小,默認number*size=128K
  • gzip_comp_level: 9; # 壓縮級別,壓縮程度越高,壓縮效率最低,最費時間
  • gzip_min_length:# 配置最小壓縮的數據大小,如果響應頁面的大小大於該值,才開啟Gzip功能(一些小文件會導致壓縮後的大小比源文件還大),默認為20,建議設置為1k(1024)
  • gzip_http_version:1.0; # 配置只有高於指定版本的HTTP協議才能開啟Gzip,默認為1.1, 目前絕大多數瀏覽器都支持Gzip自解壓,一般採用默認值即可
  • gzip_proxied:any; # 設置是否對被代理服務器返回的數據進行壓縮,默認為off
  • gzip_vary: on; # 開啟壓縮標記,開啟後在響應頭部添加 Vary: Accept-Encoding,默認為off
  • gzip_types:text/plain application/x-javascript text/css application/xml text/javascript; # 對指定類型的文檔進行Gzip壓縮
  • gzip_static:on; # 對於存在服務器上.gz作為後綴的文件,且客戶端瀏覽器支持gzip壓縮,就直接返回壓縮後的數據

示例:

gzip on;  gzip_static on;  gzip_comp_level 9;  gzip_min_length 1k;  gzip_buffers 4 8k;  gzip_http_version 1.0;  gzip_vary on;  gzip_proxied any;  gzip_types text/plain application/x-javascript text/css application/xml text/javascript;

Nginx常見配置參數

  • server_names_hash_max_size 1024;
  • server_names_hash_bucket_size 512;
  • client_header_buffer_size 32k; # 客戶端請求頭部的緩衝區大
  • large_client_header_buffers 4 32k;
  • client_max_body_size 10m;#設置最大的允許客戶端請求主體的大小(上傳文件大小限制), 默認為1m
  • client_body_buffer_size 128k;
  • keepalive_timeout 60; #客戶端連接超時時間,單位是秒, 默認是75秒
  • sendfile on; # 開啟高效傳輸模式,默認為off
  • tcp_nopush on;
  • tcp_nodelay on;
  • ssi on; # 開啟ssi支持,默認為false
  • ssi_silent_errors on; # 設置為on表示在處理ssi文件時不輸出錯誤信息,默認為false
  • ssi_types text/html; # 默認支持html ,如果需要支持shtml(服務器執行腳本),需要設置為ssi_types text/shtml
  • server_tokens off; # 關閉nginx版本號的顯示,默認為on

Nginx優化相關參數

  • worker_processes 2; # 配置生成的worker process數量,一般為cpu核數
  • worker_rlimit_nofile 65536; # 一個nginx進程打開的最多文件描述符數目,一般設置為與系統設定的值相同(ulimit -n)
  • worker_cpu_affinity 01 10;# 為每個進程分配CPU的工作內核
  • use epoll; # 事務模型
events {   use epoll; # 事務模型   worker_connections 20000; # 一個nginx進程的連接數,nginx服務器允許的同事連接的客戶端最大數量Client = worker_processes * worker_connections/2;  }

Nginx常見用法

依據UA屏蔽爬蟲

if ($http_user_agent ~* "qihoobot|Baiduspider|Googlebot|Googlebot-Mobile|Googlebot-Image|Mediapartners-Google|Adsbot-Google|Feedfetcher-Google|Yahoo! Slurp|Yahoo! Slurp China|YoudaoBot|Sosospider|Sogou  spider|Sogou web spider|MSNBot|ia_archiver|Tomato Bot") {  	return 403;  }

屏蔽IP訪問

allow 133.27.182.82;  allow 113.106.18.0/24;  allow 121.201.104.0/24;  deny all;

使用Auth權限訪問

auth_basic "bbs-auth";  auth_basic_user_file /usr/local/nginx/conf/bbsauthpwd;

限制帶寬

# 用戶下載達到 500k 後,便控制其速度在 50k 以內  location /download/ {  	limit_rate_after 500k;  	limit_rate 50k;  }

限制連接

# 定義了一個名為「down」,10M大小,以連接IP為key的連接數據存儲空間  limit_conn_zone $binary_remote_addr zone=down:10m;    # 讀取名為`down`連接數據存儲空間的數據,限制每個key(上面是以ip作為IP) 最大同時連接數為4  location ~ .*.(rar|zip|apk)?$ {  	limit_conn down 4;  	limit_rate 150k;  }    limit_conn_log_level notice: 指定當觸發limit的時候日誌打印級別

限制請求

# 定義一個名為」one」, 10M大小,每秒1個請求的請求數據存儲空間  limit_req_zone $binary_remote_addr zone=one:10m rate=10r/s;    # 引用名為「one」的存儲空間,burst為等待請求數量數,當等待請求數量超過50個時,則拋出503錯誤,nodelay 針對的是 burst 參數,burst=50 nodelay 表示這50個請求立馬處理,不能延遲,相當於特事特辦。不過,即使這20個突發請求立馬處理結束,後續來了請求也不會立馬處理。burst=50 相當於緩存隊列中佔了50個坑,即使請求被處理了,這20個位置這隻能按 100ms一個來釋放  limit_req zone=one burst=50 nodelay;  limit_req_log_level notice: 指定當觸發limit的時候日誌打印級別

實時顯示Nginx運行狀況

在安裝nginx是編譯http_stub_status_module即可,使用參數為–with-http_stub_status_module

location /ngx_status {  	stub_status on;  	access_log on;  }

設置錯誤頁面

error_page 404 /404.html

Nginx 常見錯誤碼

  • 301 永久重定向
  • 302 臨時重定向
  • 403 禁止訪問
  • 404 文件不存在
  • 413 文件上傳超過限制
  • 500 服務器錯誤
  • 502 後台服務器無響應
  • 504 Nginx超時,請求過多,工作進程不足