前言
Nginx 是一個 Web Server, 也可以用來作為 Reverse Proxy, Load Balancer 和 HTTP cache.
這一篇文章主要紀錄如何安裝以及設定 Nginx。
安裝
1 2
| $ sudo apt-get update $ sudo apt-get install nginx
|
常用指令
1 2 3 4 5 6 7 8 9 10 11
| $ sudo nginx -t
$ sudo nginx -c <config_path>
$ sudo nginx -s stop
$ sudo nginx -s reload
|
Nginx 設定
資料夾結構
Nginx 主要的設定內容放在 /etc/nginx
,資料夾結構如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| /etc/nginx/ ├─ conf.d/ ├─ fastcgi.conf ├─ fastcgi_params ├─ koi-utf ├─ koi-win ├─ mime.types ├─ nginx.conf ├─ proxy.conf ├─ proxy_params ├─ scgi_params ├─ sites-available/ ├─ sites-enabled/ ├─ uwsgi_params └─ win-utf
|
其中:
/etc/nginx/sites-available
: 用來存放每個服務的設定檔
/etc/nginx/sites-enabled
: 用來放要啟用的服務的設定檔,在此資料夾底下建立 symbolic link 連結到 /etc/nginx/sites-available
底下的設定檔
設定檔說明
Nginx 主要的設定檔是 /etc/nginx/nginx.conf
,基本結構如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
|
events { }
http { server { location / { } } }
|
基本範例:
/etc/nginx/nginx.conf
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53
|
worker_processes 4;
events { worker_connections 1024;
use epoll; }
http { include /etc/nginx/mime.types; include /etc/nginx/proxy.conf; default_type application/octet-stream;
server_tokens off;
access_log /var/log/nginx/access.log main; error_log /var/log/nginx/error.log;
sendfile on; tcp_nopush on; tcp_nodelay on;
keepalive_timeout 65;
gzip on; gzip_vary on; gzip_disable "msie6"; gzip_min_length 1000; gzip_proxied expired no-cache no-store private auth; gzip_types text/plain text/css text/javascript application/json application/javascript application/x-javascript text/xml application/xml image/png image/x-icon image/x-jng image/svg+xml image/webp image/gif image/jpeg;
include /etc/nginx/conf.d/*.conf; include /etc/nginx/sites-enabled/*; }
|
/etc/nginx/proxy.conf
:
1 2 3 4 5 6
| proxy_http_version 1.1;
proxy_set_header Connection ""; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host $http_host;
|
載入的 Server 設定檔(/etc/nginx/sites-available/api.conf
)範例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| server { listen 80; server_name localhost; root /home/user/web;
location ~* \.(ico|jpg|jpeg|png|gif|js|css|svg)$ { access_log off; log_not_found off;
expires 1m; add_header Cache-Control "public, no-transform"; }
location / { index index.html index.htm; try_files $uri $uri/ $uri.html =404; }
location ~ /\. { access_log off; log_not_found off; deny all; } }
|
Location syntax
Location 有以下兩種語法:
location [ = | ~ | ~* | ^~ ] uri { ... }
location @name { ... }
這裡我們先以第一種語法為主,它的優先順序及說明如下:
location = /url
: Exactly matching
location ^~ /url
: The url must start with the specified pattern.
location ~ /url
或 location ~* /url
: Regex matching
~
: case sensitive matching
~*
: case insensitive matching
location /url
: The url must start with the specified pattern.
location /
: 所有 request 都會比對到此規則
以上就是 location 的基本語法,另外可以到 Nginx location match tester 去測試 location 的設定~
Proxy 設定範例
此範例是由 localhost:6000 接收到 request 後, 轉發到設定的 api server.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
| upstream api { server server.com:8000; keepalive 64; }
server { listen 6000; server_name localhost;
auth_basic "Auth"; auth_basic_user_file /path/to/password/file;
client_max_body_size 100M;
location ~* \.(ico|jpg|jpeg|png|gif|js|css|svg)$ { access_log off; log_not_found off;
expires 1m; add_header Cache-Control "public, no-transform"; }
location / { proxy_pass http://api; proxy_connect_timeout 10s; proxy_read_timeout 60s; }
location ~ /\. { access_log off; log_not_found off; deny all; } }
|
其中 upstream
block 定義了要將 request proxy 過去的 application, keepalive
是設定閒置的連線最大數量,當超過此上限時,將會關閉最近使用最少的連線,假設目前有100個閒置的連線,而我們設定 keepalive=64
,所以最近最少使用的36個連線會被關閉,這個參數要小心設定,如果設太小,會造成 Nginx 一直關閉、開啟和後端的連線,會出現大量的 TIME_WAIT 的情況。另外要讓 Nginx 可以使用 keepalive
和後端連線必須要使用 HTTP 1.1,因此需要設定 proxy_http_version 1.1
,同時也記得設定 proxy_set_header Connection ""
清理 header.
auth_basic
和 auth_basic_user_file
則是設定 Nginx 使用 HTTP authentication, auth_basic_user_file
為 password file.
client_max_body_size
設定 Body 最大長度限制,超過限制則會出現 HTTP ERROR: 413 Request Entity Too Large
的錯誤訊息。
最後使用 proxy_pass
設定轉發到 updstream api server.
Proxy as failover 設定範例
在此設定範例中,如果第一個 server fail(proxy_connect_timeout
)次數超過 max_fails
(預設為1), 第二個 server 將會用來取代 server1,持續的時間為 fail_timeout
。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| upstream api { server server1.com:8000 fail_timeout=60s max_fails=1; server server2.com:8080 backup; keepalive 256; }
server { listen 6000; server_name localhost;
location / { proxy_pass http://api; proxy_connect_timeout 10s; proxy_read_timeout 60s; } }
|
Load balancing 設定範例
Nginx 提供以下三種 load balancing 方法:
- round-robin: 會將請求輪流平均分配到每台伺服器上 (預設)
- least_conn: 將請求分配到目前連線數最少的伺服器上
- ip-hash: 利用 hash function 來決定使用者要被分配到哪個伺服器,此方法可以達到同一使用者(IP address)每次連結的伺服器是相同的
此範例是將 Nginx 作為 Load Balancer, 並設定 load balancing 方式為 least_conn
,將 request 分配至使用連線數最少的 server:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| upstream api { least_conn; server server1.com; server server2.com; server server3.com; keepalive 64; }
server { listen 6000; server_name localhost;
location / { proxy_pass http://api; proxy_connect_timeout 10s; proxy_read_timeout 60s; } }
|
另外也可以設定分配的權重(weight),weight 預設為 1,以下範例表示如果有 5 個新的請求,則會有 3 次被分配到 server1, server2 和 server3 各一次:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| upstream api { server server1.com weight=3; server server2.com; server server3.com; keepalive 64; }
server { listen 6000; server_name localhost;
location / { proxy_pass http://api; proxy_connect_timeout 10s; proxy_read_timeout 60s; } }
|
HTTPS
現在多數的服務都會使用 HTTPS,在設定 HTTPS 之前,需要先申請 SSL 憑證,可以參考: [SSL] Nginx + Let’s encrypt SSL 憑證,依照此文章設定完成後,可以在 nginx.conf
的 http block 中加上以下內容:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
|
http {
ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_prefer_server_ciphers on; ssl_ciphers ECDH+AESGCM:EDCH+AES256:ECDH+AES128:!MD5:!aNULL; ssl_session_cache shared:SSL:30m; ssl_session_tickets on; ssl_session_timeout 1h; ssl_stapling on; ssl_stapling_verify on;
}
|
參考資料