title: “理解Nginx”
url: “https://wsk1103.github.io/”
tags:
- 架構
- Nginx
1. Nginx 是什麼
Nginx官網說明
nginx [engine x] is an HTTP and reverse proxy server, a mail proxy server, and a generic TCP/UDP proxy server, originally written by Igor Sysoev.
nginx [engine x]是HTTP和反向代理服務器,郵件代理服務器和通用TCP / UDP代理服務器,最初由Igor Sysoev編寫。
2. 安裝
基於centOS7 安裝
直接一鍵安裝
yum -y install nginx
ps:可能出現的問題
沒有可用軟件包 nginx。
錯誤:無須任何處理
這個時候是因爲 nginx 在 yum 裏面是沒有的,需要使用到 epel源 ,也就是安裝 epel-release 。
yum install epel-release
安裝成功後再安裝 nginx
3.啓動Nginx
[root@wsk1103 nginx]# systemctl start nginx
默認端口爲 80 ,打開瀏覽器,訪問 localhost,出現 NGINX 頁面表示啓動成功
關於 nginx 命令
systemctl enable nginx 開機啓動nginx服務
systemctl disable nginx 禁止開機啓動nginx服務
systemctl is-enable nginx 查詢是否開機啓動nginx服務
systemctl start nginx 啓動nginx服務
systemctl stop nginx 停止nginx服務
systemctl reload nginx 重新加載nginx服務
systemctl restart nginx 重啓nginx服務
systemctl status nginx 查看nginx服務狀態
或者 將 systemctl 替換成 service
service nginx start 啓動nginx服務
service nginx stop 停止nginx服務
4. 文件說明
安裝完成後,配置文件 nginx.conf 位於 /etc/nginx/nginx.conf
[root@wsk1103 yum.repos.d]# cd /etc/nginx/
[root@wsk1103 nginx]# ls
conf.d koi-utf scgi_params
default.d koi-win scgi_params.default
fastcgi.conf mime.types uwsgi_params
fastcgi.conf.default mime.types.default uwsgi_params.default
fastcgi_params nginx.conf win-utf
fastcgi_params.default nginx.conf.default
1. nginx.conf,nginx.conf.default
主要的配置文件
2. conf.d,default.d
空的文件夾
3. fastcgi.conf, fastcgi.conf.default,fastcgi_params,fastcgi_params.default
fastcgi例子
Nginx 配置Fastcgi解析時會調用fastcgi_params配置文件來傳遞服務器變量,這樣CGI中可以獲取到這些變量的值。
這允許我們使單個的FCGI配置儘可能的簡單。我們可以根據實際的路徑替換 SCRIPT_FILENAME 和 DOCUMENT_ROOT 裏面的 document_root 變量是硬編碼的,可能無法隨着我們的安裝(通常會報“找不到腳本”的錯誤)。如果要使用NGINX +虛擬主機+ PHP,我們應該省略 SCRIPT_NAME 變量,以便 PHP 選擇正確的 DOCUMENT_ROOT
4. koi-utf,koi-win,win-utf
這三個文件都是與編碼轉換映射文件,用於在輸出內容到客戶端時,將一種編碼轉換到另一種編碼。
5. uwsgi_params,scgi_params
與 fastcgi_params 一樣,傳遞哪些服務器變量,只有前綴不一樣,以 uwsgi_param 開始而非 fastcgi_param 。
6. mime.types,mime.types.default
文件擴展名與文件類型映射表,Nginx 根據映射關係,設置http請求響應頭的Content-Type值。當在映射表找不到時,使用nginx.conf中default-type指定的默認值。
默認配置中的指定的default-type爲application/octet-stream。
include /etc/nginx/mime.types;
default_type application/octet-stream;
訪問日誌路徑 和 錯誤日誌路徑
[root@wsk1103 wsk]# cd /var/log/nginx/
裏面有日誌 access.log(接收日誌) 和 error.log(錯誤處理日誌)
5. 正向代理和反向代理
5.1. 反向代理
指服務器以代理服務器的形式,將接受到的網絡請求轉發到內部的其他服務器上,並從該內部服務器將響應結果返回給網絡請求,這個時候請求者只知道代理服務器的IP地址,而不知道真正的服務器地址,防止真正的服務器受到不必要的攻擊。
反向代理的好處
- 保護真正的後臺服務器,使黑客不知道真正的服務器的IP地址。
- 通過緩存靜態資源,加速Web請求。
- 實現負載均衡。
5.2. 正向代理
正向代理服務器,一個位於客戶端和後臺服務器之間的服務器,爲了從後臺服務器取得內容,客戶端向代理髮送一個請求並指定目標(後臺服務器),然後代理向後臺服務器轉交請求並將獲得的內容返回給客戶端。
6. Nginx 配置文件
配置文件目錄
[root@wsk1103 ~]# vi /etc/nginx/nginx.conf
文件說明
# For more information on configuration, see:
# * Official English Documentation: http://nginx.org/en/docs/
# * Official Russian Documentation: http://nginx.org/ru/docs/
#定義 nginx 運行的用戶和用戶組
user nginx;
#nginx 進程數,建議設置爲等於 CPU 總核心數。
#worker_processes auto這個是不建議的,最好是設置成固定數值
worker_processes auto;
#nginx 默認沒有開啓利用多核 CPU, 通過增加 worker_cpu_affinity 配置參數來充分利用多核 CPU 以下是 8 核的配置參數
#這個配置用於將 worker process 與指定 CPU 核綁定,降低由於多 CPU 核切換造成的寄存器等重建帶來的性能損耗。
worker_cpu_affinity 00000001 00000010 00000100 00001000 00010000 00100000 01000000 10000000;
#所有錯誤輸出的日誌位置
error_log /var/log/nginx/error.log;
#進程文件
pid /run/nginx.pid;
# Load dynamic modules. See /usr/share/doc/nginx/README.dynamic.
#nginx啓動時會優先加載這個目錄下的所有 .conf 文件
#該目錄裏面的文件 mod-http-image-filter.conf mod-http-perl.conf mod-http-xslt-filter.conf mod-mail.conf mod-stream.conf
include /usr/share/nginx/modules/*.conf;
events {
#單個後臺 worker process 進程的最大併發鏈接數
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 指令指定 nginx 是否調用 sendfile 函數來輸出文件,對於普通應用設爲 on,如果用來進行下載等應用磁盤 IO 重負載應用,可設置爲 off,以平衡磁盤與網絡 I/O 處理速度,降低系統的負載。注意:如果圖片顯示不正常把這個改成 off。
sendfile on;
#防止網絡阻塞
tcp_nopush on;
#防止網絡阻塞
tcp_nodelay on;
#開啓目錄列表訪問,適合下載服務器,默認關閉。
autoindex on;
##連接客戶端超時時間各種參數設置##
#單位是秒,客戶端連接時時間,超時之後服務器端自動關閉該連接 如果 nginx 守護進程在這個等待的時間裏,一直沒有收到瀏覽發過來 http 請求,則關閉這個 http 連接
keepalive_timeout 65;
#客戶端請求頭的超時時間
client_header_timeout 10;
#客戶端請求主體超時時間
client_body_timeout 10;
#關閉不響應的客戶端連接。這將會釋放那個客戶端所佔有的內存空間
reset_timedout_connection on;
#客戶端響應超時時間,在兩次客戶端讀取操作之間。如果在這段時間內,客戶端沒有讀取任何數據,nginx 就會關閉連接
send_timeout 10;
#FastCGI 相關參數是爲了改善網站的性能:減少資源佔用,提高訪問速度。
#Nginx 的 buffer 機制,對於來自 FastCGI Server 的 Response,Nginx 將其緩衝到內存中,然後依次發送到客戶端瀏覽器。緩衝區的大小由 fastcgi_buffers 和 fastcgi_buffer_size 兩個值控制。
#連接超時
fastcgi_connect_timeout 300;
#發生超時
fastcgi_send_timeout 300;
#讀取超時
fastcgi_read_timeout 300;
#緩存區大小
fastcgi_buffer_size 8k;
#控制 nginx 最多創建 4 個大小爲 8K 的緩衝區
fastcgi_buffers 4 8k;
##默認值是fastcgi_buffer的2倍
fastcgi_busy_buffers_size 16k;
#寫入緩存文件使用多大的數據塊,默認值是fastcgi_buffer的2倍
fastcgi_temp_file_write_size 16k;
#影響散列表的衝突率。types_hash_max_size越大,就會消耗更多的內存,但散列key的衝突率會降低,檢索速度就更快。types_hash_max_size越小,消耗的內存就越小,但散列key的衝突率可能上升。
types_hash_max_size 2048;
#服務器名字的 hash 表大小
server_names_hash_bucket_size 128;
#上傳文件大小限制
client_header_buffer_size 1k;
#設定請求緩,一般來說默認就夠了。發生414 (Request-URI Too Large) 錯誤時請增大這兩個參數。
large_client_header_buffers 4 8k;
#客戶端上傳的body的最大值。超過最大值就會發生413(Request Entity Too Large)錯誤。默認爲1m,最好改大一點。
client_max_body_size 8m;
#對傳輸文件壓縮-gzip 模塊設置
#開啓 gzip 壓縮輸出
gzip on;
#最小壓縮文件大小
gzip_min_length 1k;
#壓縮緩衝區
gzip_buffers 4 16k;
#壓縮版本
gzip_http_version 1.1;
#壓縮等級,gzip 壓縮比,1 爲最小,處理最快;9 爲壓縮比最大,處理最慢,傳輸速度最快,也最消耗 CPU;
gzip_comp_level 2;
#壓縮類型,默認就已經包含 application/xml; text/html
gzip_types text/plain application/x-javascript text/css
gzip_vary on;
#文件擴展名與文件類型映射表
include /etc/nginx/mime.types;
default_type application/octet-stream;
# Load modular configuration files from the /etc/nginx/conf.d directory.
# See http://nginx.org/en/docs/ngx_core_module.html#include
# for more information.
include /etc/nginx/conf.d/*.conf;
upstream wsk1103.github.io {
#upstream 的負載均衡,weight 是權重,可以根據機器配置定義權重。weigth 參數表示權值,權值越高被分配到的機率越大。
#另外還有 ip_hash 輪訓
server 192.168.134.2 weight=1;
server 192.168.134.3 weight=2;
server 192.168.134.4 weight=3;
}
#虛擬主機的配置
server {
#監聽端口,默認服務
listen *:80 | *:8000; # 監聽所有的 80 和 8000 端口
#域名可以有多個,用空格隔開
server_name wsk1103.github.io wsk1103.github.com;
#server_name .wsk1103.com www.wsk1103. wsk1103.*; # 使用通配符
#server_name ~^w{3}.wsk1103.com$; # 使用正則
#配置中,可以用正則的地方,都以~開頭
# 當匹配到多個時,處理優先級
# 1. 準確匹配到 server_name
# 2. 通配符在開始時匹配到 server_name
# 3. 通配符在結尾時匹配到 server_name
# 4. 正則表達式匹配 server_name
# 5. 順序加載
index index.html index.htm index.php;
root /usr/share/nginx/html;
# 訪問 localhost 時,重定向到 https://wsk1103.github.io
rewrite ".*" https://wsk1103.github.io;
# Load configuration files for the default server block.
include /etc/nginx/default.d/*.conf;
# location 的4種匹配模式,匹配優先級 ‘ = > 其他 ’
# 1. = :用於標準 uri前,要求請求字符串與其嚴格匹配,成功則立即處理
# 2. ^~ :用於標準 uri前,並要求一旦匹配到,立即處理,不再去匹配其他的正則 uri
# 3. ~ :用於正則 uri前,表示 uri 包含正則表達式,並區分大小寫
# 4. ~* :用於正則 uri前, 表示 uri 包含正則表達式,不區分大小寫
location ~ .*.(php|java)?$ {
fastcgi_pass 127.0.0.1:8081;
fastcgi_index index.php;
include fastcgi.conf;
}
#緩存時間設置
location ~ .*.(gif|jpg|jpeg|png|bmp|swf|js|css)$ {
expires 10d;
#d表示天,h表示小時
}
#服務器收到請求後,首先要在服務端指定的目錄中尋找請求資源
location /image/ {
# 將訪問 /image/ 下的文件指向 系統定義的目錄 /home/wsk/image/ 中
root /home/wsk/;
autoindex on;
}
#對 "/" 啓用反向代理
location / {
#代理到本地的8081端口
proxy_pass http://127.0.0.1:8081;
proxy_redirect off;
proxy_set_header X-Real-IP $remote_addr;
#使後端服務器可以通過 X-Forwarded-For 獲取用戶真實 IP
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
#以下是一些反向代理的配置,可選。
proxy_set_header Host $host;
client_max_body_size 10m; #允許客戶端請求的最大單文件字節數
client_body_buffer_size 128k; #緩衝區緩衝用戶端請求的最大字節數,
##代理設置 以下設置是 nginx 和後端服務器之間通訊的設置##
proxy_connect_timeout 90; #代理連接超時
proxy_send_timeout 90; #代理髮送超時
proxy_read_timeout 90; #代理接收超時
proxy_buffering on; #該指令開啓從後端被代理服務器的響應內容緩衝 此參數開啓後 proxy_buffers 和 proxy_busy_buffers_size 參數纔會起作用
proxy_buffer_size 4k; #設置代理服務器(nginx)保存用戶頭信息的緩衝區大小
proxy_buffers 4 32k; #設置4個緩衝區,大小限制爲 32k
proxy_busy_buffers_size 64k; #高負荷下緩衝大小,默認爲 proxy_buffers 的2倍
proxy_max_temp_file_size 2048m; #默認 1024m, 該指令用於設置當網頁內容大於 proxy_buffers 時,臨時文件大小的最大值。如果文件大於這個值,它將從 upstream 服務器同步地傳遞請求,而不是緩衝到磁盤
proxy_temp_file_write_size 512k; 這是當被代理服務器的響應過大時 nginx 一次性寫入臨時文件的數據量。
proxy_temp_path /var/tmp/nginx/proxy_temp; ##定義緩衝存儲目錄,之前必須要先手動創建此目錄
proxy_headers_hash_max_size 51200;
proxy_headers_hash_bucket_size 6400;
}
# 404時顯示的頁面
error_page 404 /404.html;
location = /40x.html {
}
# 50*時顯示的頁面
error_page 500 502 503 504 /50x.html;
location = /50x.html {
}
#本地動靜分離反向代理配置
#所有 jsp 的頁面均交由 tomcat 處理
location ~ .(jsp|jspx|do)?$ {
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_pass http://127.0.0.1:8080;
}
#設定查看 nginx 狀態的地址
location /nginxStatus {
stub_status on;
access_log on;
auth_basic "nginxStatus";
auth_basic_user_file conf/htpasswd;
#htpasswd 文件的內容可以用 apache 提供的 htpasswd 工具來產生。
}
}
# 設置HTTPS
# Settings for a TLS enabled server.
#
# server {
# listen 443 ssl http2 default_server;
# listen [::]:443 ssl http2 default_server;
# server_name _;
# root /usr/share/nginx/html;
#
# ssl_certificate "/etc/pki/nginx/server.crt";
# ssl_certificate_key "/etc/pki/nginx/private/server.key";
# ssl_session_cache shared:SSL:1m;
# ssl_session_timeout 10m;
# ssl_ciphers HIGH:!aNULL:!MD5;
# ssl_prefer_server_ciphers on;
#
# # Load configuration files for the default server block.
# include /etc/nginx/default.d/*.conf;
#
# # 將 http 強制轉換成 https
# if ($scheme = 'http') {
# rewrite ^(.*)$ https://$host$uri;
# }
# location / {
# }
#
# error_page 404 /404.html;
# location = /40x.html {
# }
#
# error_page 500 502 503 504 /50x.html;
# location = /50x.html {
# }
# }
}
7. Nginx的Master-Worker模式
Nginx 採用的是工作模式是 多進程&多路IO複用模型(與Netty相似)。
流程說明:
- 當 Nginx 啓動後,會啓動一個 master 進程和多個相互獨立的 worker 進程。
- 當接收都請求時, master 最先接收到信息,然後再分配給 worker ,每一個 worker 都有機會來處理這次請求。
- master 進程持續監控着 worker 的運行狀態,當 worker 異常退出時,重新啓動一個新的 worker 。
PS:進程 worker 的數量一般會設置成CUP核數。如果設置過多,會導致 worker 競爭CUP,從而帶來了不必要的上下文切換(這個和java的多線程類似)。使用多進程模式,不僅能提高併發率,而且進程之間相互獨立,一個 worker 進程掛了不會影響到其他 worker 進程。
設置 worker 的數量
在 nginx.conf 裏面配置
#nginx 進程數,建議設置爲等於 CPU 總核心數。
worker_processes 8;
8. Nginx實現熱部署
通過修改配置文件 nginx.conf 後,不需要停止 Nginx,也不需要中斷請求,就能讓配置文件生效
[root@wsk1103 ~]# nginx -s reload # 重新加載
[root@wsk1103 ~]# nginx -t # 檢查配置
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
因爲 Nginx 是使用 master-worker 的模式,在修改配置文件 nginx.conf 後,會重新生成新的 worker 進程,並且用新的配置處理請求,而舊的 worker 進程,則是等把原來的請求處理完畢後,會自動 kill 。
9. Nginx在高併發下的高效處理
Nginx 採用了 Linux 的 epoll 模型, epoll 模型是基於事件驅動機制,它可以監控多個事件是否準備完畢,如果準備完成,那麼放入 epoll 隊列中,這個過程是異步的。 worker 只需要從 epoll 隊列循環處理即可。
Nginx 與 多進程模式 Apache 的比較
- 事件驅動適合於I/O密集型服務,多進程或線程適合於CPU密集型服務
- Nginx 是事件驅動,更主要是作爲反向代理,而不是服務器使用。
- Nginx 只需要少量進程配合事件驅動,不需要像 Apache 多進程模型跑幾百個進程。
- Nginx 處理靜態文件效果顯著,因爲讀寫文件和網絡通信都是 I/O 操作。
10. Keepalived + Nginx 實現高可用
- 請求不是直接打到 Nginx 上,而是先通過 Keepalived (虛擬IP,VIP)
- Keepalived 應該能監控 Nginx 的生命狀態