大家好,我是民工哥。
無論是運維、開發、測試,Nginx技術棧的學習總是必不可少的,只是不同的崗位掌握的深度與廣度不同而已。所以,民工哥利用週末休息時間,將往期推送的Nginx文章給大家重新整理出來,整理出成體系的Nginx知識體系,供大家學習與參考。
碼字不易,如有幫助,請點在看與轉發朋友圈支援一波,感謝!!!!
Nginx 簡介
Nginx 是開源
、高效能
、高可靠
的 Web
和反向代理伺服器
,而且支援熱部署,幾乎可以做到 7 * 24 小時不間斷執行,即使執行幾個月也不需要重新啟動,還能在不間斷服務的情況下對軟體版本進行熱更新。效能是 Nginx 最重要的考量,其佔用記憶體少、併發能力強、能支援高達 5w 個併發連線數,最重要的是, Nginx 是免費的並可以商業化,配置使用也比較簡單。
官方網站:http://www.nginx.org
Nginx 特點
Web伺服器
高效能的WEB伺服器軟體,與Apache相比,它支援更多的併發連線且佔用伺服器資源少,效率高
反向代理或負載均衡伺服器
作為負載均衡伺服器,它可以作為HTTP SERVER或DB等服務的代理伺服器,類似Haproxy代理軟體的功能,Nginx的代理功能相對簡單,效率也不及Haproxy,同時它也是一個優秀的郵件代理服務軟體
快取伺服器
Nginx還可以作快取伺服器,類似於專業的快取軟體功能
Nginx 優缺點
Nginx 優點
- 高併發:能支援1-2萬甚至更多的併發連線(靜態小檔案)
- 記憶體消耗少
- 可以做HTTP反向代理——負載均衡的功能
- 內建對叢集節點伺服器的健康性查功能,不過功能相對較弱
- 通過cache外掛可以實現快取軟體能夠實現的功能
Nginx 的缺點
Nginx 僅能支援http、https和Email協議,這樣就在適用範圍上面小些,這個是它的缺點
對後端伺服器的健康檢查,只支援通過埠來檢測,不支援通過 url來檢測。不支援 Session 的直接保持,但能通過 ip_hash 來解決
Nginx 應用場景
Nginx 的最重要的幾個使用場景:
- 靜態資源服務,通過本地檔案系統提供服務;
- 反向代理服務,延伸出包括快取、負載均衡等;
- API 服務, OpenResty ;
對於前端來說 Node.js 並不陌生, Nginx 和 Node.js 的很多理念類似, HTTP 伺服器、事件驅動、非同步非阻塞等,且 Nginx 的大部分功能使用 Node.js 也可以實現,但 Nginx 和 Node.js 並不衝突,都有自己擅長的領域。Nginx 擅長於底層伺服器端資源的處理(靜態資源處理轉發、反向代理,負載均衡等), Node.js 更擅長上層具體業務邏輯的處理,兩者可以完美組合。
用一張圖表示:
Nginx 到底可以做什麼?看完這篇你就懂了!
更多關於Nginx常用場景應用配置可參考:
Apache VS Nginx
Apache和Nginx都屬於Web伺服器,兩者都實現了HTTP 1.1協議。無論是選擇哪個,都是根據應用場景來決定的,所以些檔案僅從應用場景出發,來對比兩者之間的各自特點。要讓正確的工具,做出正確的事。
功能對比
Nginx和Apache一樣,都是HTTP伺服器軟體,在功能實現上都採用模組化結構設計,都支援通用的語言介面,如PHP、Perl、Python等,同時還支援正向和反向代理、虛擬主機、URL重寫、壓縮傳輸、SSL加密傳輸等。
- 在功能實現上,Apache的所有模組都支援動、靜態編譯,而Nginx模組都是靜態編譯的,
- 對FastCGI的支援,Apache對Fcgi的支援不好,而Nginx對Fcgi的支援非常好;
- 在處理連線方式上,Nginx支援epoll,而Apache卻不支援;
- 在空間使用上,Nginx安裝包僅僅只有幾百K,和Nginx比起來Apache絕對是龐然大物。
Nginx相對apache的優點
- 輕量級,同樣起web 服務,比apache 佔用更少的記憶體及資源
- 靜態處理,Nginx 靜態處理效能比 Apache 高 3倍以上
- 抗併發,nginx 處理請求是非同步非阻塞的,而apache則是阻塞型的,在高併發下nginx 能保持低資源低消耗高效能。在- - Apache+PHP(prefork)模式下,如果PHP處理慢或者前端壓力很大的情況下,很容易出現Apache程式數飆升,從而拒絕服務的現象。
- 高度模組化的設計,編寫模組相對簡單
- 社群活躍,各種高效能模組出品迅速啊
apache相對nginx的優點
- rewrite,比nginx 的rewrite 強大
- 模組超多,基本想到的都可以找到
- 少bug,nginx的bug相對較多
- 超穩定
- Apache對PHP支援比較簡單,Nginx需要配合其他後端用
更多更詳細的比較說明請參考:Apache VS Nginx,你選對了嗎?
Nginx 安裝
本文以CentOS 7.x 系統為例,使用 yum 安裝 Nginx。
yum install nginx -y
安裝完成後,通過 rpm -ql nginx 命令檢視 Nginx 的安裝資訊。
# Nginx配置檔案
/etc/nginx/nginx.conf # nginx 主配置檔案
/etc/nginx/nginx.conf.default
# 可執行程式檔案
/usr/bin/nginx-upgrade
/usr/sbin/nginx
# nginx庫檔案
/usr/lib/systemd/system/nginx.service # 用於配置系統守護程式
/usr/lib64/nginx/modules # Nginx模組目錄
# 幫助文件
/usr/share/doc/nginx-1.16.1
/usr/share/doc/nginx-1.16.1/CHANGES
/usr/share/doc/nginx-1.16.1/README
/usr/share/doc/nginx-1.16.1/README.dynamic
/usr/share/doc/nginx-1.16.1/UPGRADE-NOTES-1.6-to-1.10
# 靜態資源目錄
/usr/share/nginx/html/404.html
/usr/share/nginx/html/50x.html
/usr/share/nginx/html/index.html
# 存放Nginx日誌檔案
/var/log/nginx
主要關注的資料夾有兩個:
- /etc/nginx/conf.d/是子配置項存放處,/etc/nginx/nginx.conf 主配置檔案會預設把這個資料夾中所有子配置項都引入;
- /usr/share/nginx/html/靜態檔案都放在這個資料夾,也可以根據你自己的習慣放在其他地方;
Nginx 常用命令
systemctl 系統命令:
# 開機配置
systemctl enable nginx # 開機自動啟動
systemctl disable nginx # 關閉開機自動啟動
# 啟動Nginx
systemctl start nginx # 啟動Nginx成功後,可以直接訪問主機IP,此時會展示Nginx預設頁面
# 停止Nginx
systemctl stop nginx
# 重啟Nginx
systemctl restart nginx
# 重新載入Nginx
systemctl reload nginx
# 檢視 Nginx 執行狀態
systemctl status nginx
# 檢視Nginx程式
ps -ef | grep nginx
# 殺死Nginx程式
kill -9 pid # 根據上面檢視到的Nginx程式號,殺死Nginx程式,-9 表示強制結束程式
Nginx 應用程式命令:
nginx -s reload # 向主程式傳送訊號,重新載入配置檔案,熱重啟
nginx -s reopen # 重啟
Nginxnginx -s stop # 快速關閉
nginx -s quit # 等待工作程式處理完成後關閉
nginx -T # 檢視當前 Nginx 最終的配置
nginx -t # 檢查配置是否有問題
Nginx 配置檔案
Nginx 的配置檔案結構如下:
# main段配置資訊
user nginx; # 執行使用者,預設即是nginx,可以不進行設定
worker_processes auto; # Nginx 程式數,一般設定為和 CPU 核數一樣
error_log /var/log/nginx/error.log warn; # Nginx 的錯誤日誌存放目錄
pid /var/run/nginx.pid; # Nginx 服務啟動時的 pid 存放位置
# events段配置資訊
events {
use epoll; # 使用epoll的I/O模型(如果你不知道Nginx該使用哪種輪詢方法,會自動選擇一個最適合你作業系統的)
worker_connections 1024; # 每個程式允許最大併發數
}
# http段配置資訊
# 配置使用最頻繁的部分,代理、快取、日誌定義等絕大多數功能和第三方模組的配置都在這裡設定
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; # Nginx訪問日誌存放位置
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; # 載入子配置項
# server段配置資訊
server {
listen 80; # 配置監聽的埠
server_name localhost; # 配置的域名
# location段配置資訊
location / {
root /usr/share/nginx/html; # 網站根目錄
index index.html index.htm; # 預設首頁檔案
deny 172.168.22.11; # 禁止訪問的ip地址,可以為all
allow 172.168.33.44;# 允許訪問的ip地址,可以為all
}
error_page 500 502 503 504 /50x.html; # 預設50x對應的訪問頁面
error_page 400 404 error.html; # 同上
}
}
- main 全域性配置,對全域性生效;
- events 配置影響 Nginx 伺服器與使用者的網路連線;
- http 配置代理,快取,日誌定義等絕大多數功能和第三方模組的配置;
- server 配置虛擬主機的相關引數,一個 http 塊中可以有多個 server 塊;
- location 用於配置匹配的 uri ;
- upstream 配置後端伺服器具體地址,負載均衡配置不可或缺的部分;
更多關於Nginx配置檔案的介紹可以參考下列文章:
如果你平時配置Nginx比較頻繁,我推薦你使用這個神器:強大!Nginx 配置線上一鍵生成“神器”
Nginx常用的內建變數
Nginx 的程式模型
Nginx 伺服器,正常執行過程中:
- 多程式:一個 Master 程式、多個 Worker 程式
- Master 程式:管理 Worker 程式
- 對外介面:接收外部的操作(訊號)
- 對內轉發:根據外部的操作的不同,通過訊號管理 Worker
- 監控:監控 worker 程式的執行狀態,worker 程式異常終止後,自動重啟 worker 程式
- Worker 程式:所有 Worker 程式都是平等的
- 實際處理:網路請求,由 Worker 程式處理;
- Worker 程式數量:在 nginx.conf 中配置,一般設定為核心數,充分利用 CPU 資源,同時,避免程式數量過多,避免程式競爭 CPU 資源,增加上下文切換的損耗。
為什麼Nginx功能如此強大,可以參考:
Nginx優化配置
其實核心內容主要是通過修改 Nginx 配置檔案來進行調優的!
在我們的日常工作學習中,我們會該如何去優化自己的Nginx伺服器?遇到以下問題我們該如何處理呢?
- 如何自定義返回給客戶端的404錯誤頁面
- 如何檢視伺服器狀態資訊
- 如何優化Nginx併發量
- .......
這些問題都可以參考這篇文章的解決方案:Nginx 高效能優化配置實戰總結
Nginx 是如何實現併發的?為什麼 Nginx 不使用多執行緒?Nginx常見的優化手段有哪些?502錯誤可能原因有哪些?這種面試問題你肯定是經常被問到。
對於Nginx伺服器的安全,在日常使用中也是非常重要的,這裡給大家分享一點實踐經驗:如何構建高效安全的Nginx Web伺服器
最後給大家分享2個基於HTTPS優化案例:
Nginx 日誌相關
介紹完了安裝、配置、優化這些常用的場景之後,日誌這塊也是非常重要的,大家都知道日常排錯,日誌起著舉足輕重的作用。
Nginx日誌主要分為兩種:access_log(訪問日誌)和error_log(錯誤日誌)。通過訪問日誌我們可以得到使用者的IP地址、瀏覽器的資訊,請求的處理時間等資訊。錯誤日誌記錄了訪問出錯的資訊,可以幫助我們定位錯誤的原因。
error_log /var/log/nginx/error.log warn;
#配置錯誤日誌的級別及儲存目錄
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;
#配置訪問日誌儲存目錄
}
關於Nginx日誌的配置實踐看這篇:Nginx 日誌配置實踐!超詳細
由於nginx功能強大,效能突出,越來越多的web應用採用nginx作為http和反向代理的web伺服器。而nginx的訪問日誌不管是做使用者行為分析還是安全分析都是非常重要的資料來源之一。如何有效便捷的採集nginx的日誌進行有效的分析成為大家關注的問題。
通過幾個例項來介紹如何通過filebeat、logstash、rsyslog採集nginx的訪問日誌和錯誤日誌,我也可以:利用ELK分析Nginx日誌。
Nginx版本升級
這裡我們來聊一聊,在企業實際生產環境中經常遇到的一個情況,如何升級Nginx到新的版本和如何回滾至舊版本。
版本升級其實就是針對二進位制檔案的升級,過程如下:
[root@nginx ~]# /usr/local/nginx-1.12.2/sbin/nginx -v
nginx version: nginx/1.12.2
[root@nginx ~]# cd /usr/local/nginx-1.12.2/sbin/
[root@nginx sbin]# mv nginx nginx-1.12.2
#首先備份原來的舊版本nginx二進位制檔案
[root@nginx sbin]# cp /usr/local/nginx-1.14.2/sbin/nginx ./
#拷貝新版本的二進位制檔案到當前目錄
注:其實升級新版本,最重要的就是平滑升級,讓前端使用者無感知(也就是不中斷服務,這個其實不難,生產中多臺依次灰度升級)。
對於升級來說,最難的不是升級,而是回滾,因為在實際生產環境回滾的機率是存在,比如:新版本由於某些未知bug導致與現有應用不相容、或出現執行不穩定的情況等等。
所以,對於我們來說,故障回滾是重點。這裡給大家推薦我總結的:1分鐘搞定 Nginx 版本的平滑升級與回滾
Nginx 反向代理與負載均衡
反向代理簡介
反向代理(Reverse Proxy)方式是指以代理伺服器來接受internet上的連線請求,然後將請求轉發給內部網路上的伺服器,並將從伺服器上得到的結果返回給internet上請求連線的客戶端,此時代理伺服器對外就表現為一個反向代理伺服器。反向代理是為服務端服務的,反向代理可以幫助伺服器接收來自客戶端的請求,幫助伺服器做請求轉發,負載均衡等。
反向代理對服務端是透明的,對我們是非透明的,即我們並不知道自己訪問的是代理伺服器,而伺服器知道反向代理在為他服務。
配置例項
http {
.............
upstream product_server{
127.0.0.1:8081;
}
upstream admin_server{
127.0.0.1:8082;
}
upstream test_server{
127.0.0.1:8083;
}
server {
#預設指向product的server
location / {
proxy_pass http://product_server;
}
location /product/{
proxy_pass http://product_server;
}
location /admin/ {
proxy_pass http://admin_server;
}
location /test/ {
proxy_pass http://test_server;
}
}
}
如果你對Nginx 配置中location 的規則不太熟悉,推薦你看看這篇文章:Nginx 實踐:location 路徑匹配。nginx 每個location都是一個匹配目錄,nginx的策略是:訪問請求來時,會對訪問地址進行解析,從上到下逐個匹配,匹配上就執行對應location大括號中的策略,並根據策略對請求作出相應。
所以,有時候就因為在配置時,少些了一個字元“/”,就造成訪問不通報錯,這種問題是非常覺的故障原因之一,正所謂:Nginx配置中一個不起眼字元"/"的巨大作用,失之毫厘謬以千里,這篇文章詳細進了相關的說明與舉例驗證。
反向代理的優勢:
- 隱藏真實伺服器;
- 負載均衡便於橫向擴充後端動態服務;
- 動靜分離,提升系統健壯性;
Nginx 負載均衡
nginx能實現負載均衡,什麼是負載均衡呢?就是說應用部署在不同的伺服器上,但是通過統一的域名進入,nginx則對請求進行分發,將請求分發到不同的伺服器上去處理,這樣就可以有效的減輕了單臺伺服器的壓力。
配置例項
upstream server_pools {
server 192.168.1.11:8880 weight=5;
server 192.168.1.12:9990 weight=1;
server 192.168.1.13:8989 weight=6;
#weigth參數列示權值,權值越高被分配到的機率越大
}
server {
listen 80;
server_name mingongge.com;
location / {
proxy_pass http://server_pools;
}
}
Nginx 實現負載均衡的策略
- 輪詢策略:預設情況下采用的策略,將所有客戶端請求輪詢分配給服務端。這種策略是可以正常工作的,但是如果其中某一臺伺服器壓力太大,出現延遲,會影響所有分配在這臺伺服器下的使用者。
- 最小連線數策略:將請求優先分配給壓力較小的伺服器,它可以平衡每個佇列的長度,並避免向壓力大的伺服器新增更多的請求。
- 最快響應時間策略:優先分配給響應時間最短的伺服器。
- 客戶端 ip 繫結策略:來自同一個 ip 的請求永遠只分配一臺伺服器,有效解決了動態網頁存在的 session 共享問題。
想要高可用?搞定負載均衡架構是關鍵,
關於負載均衡和反向代理的區別可以參考:一文詳解負載均衡和反向代理的真實區別,關於 nginx 反向代理和負載均衡策略 實戰案例。
Nginx 動靜分離
Nginx動靜分離是讓動態網站裡的動態網頁根據一定規則把不變的資源和經常變的資源區分開來,動靜資源做好了拆分以後,我們就可以根據靜態資源的特點將其做快取操作,這就是網站靜態化處理的核心思路。推薦:CentOS 7.3:LAMP 動靜分離部署可以瞭解一下Apache的配置,然後再回過頭理解Nginx的動靜分離可更直觀。
server {
listen 80;
server_name mingongge.com;
location /static {
root /wwww/web/web_static_site;
}
}
也可以使用下面的方法
location /image {
alias /web/nginx/static/image/;
}
注意:使用alias末尾一定要新增/,並且它只能位於location中
使用前後端分離後,可以很大程度提升靜態資源的訪問速度,即使動態服務不可用,靜態資源的訪問也不會受到影響。
小試牛刀!Nginx 搭建靜態資源伺服器,這篇文章是給大家介紹整個搭建過程,非常詳細。
Nginx 高階功能
除了負載均衡,Nginx還可以做很多,限流、快取、黑白名單等
重定向配置
location / {
return 404; #直接返回狀態碼
}
location / {
return 404 "pages not found"; #返回狀態碼 + 一段文字
}
location / {
return 302 /blog ; #返回狀態碼 + 重定向地址
}
location / {
return https://www.mingongge.com ; #返回重定向地址
}
示例如下
server {
listen 80;
server_name www.mingongge.com;
return 301 http://mingongge.com$request_uri;
}
server {
listen 80;
server_name www.mingongge.com;
location /cn-url {
return 301 http://mingongge.com.cn;
}
}
server{
listen 80;
server_name mingongge.com; # 要在本地hosts檔案進行配置
root html;
location /search {
rewrite ^/(.*) https://www.mingongge.com redirect;
}
location /images {
rewrite /images/(.*) /pics/$1;
}
location /pics {
rewrite /pics/(.*) /photos/$1;
}
location /photos {
}
}
流量拷貝
需求:將生產環境的流量拷貝到預上線環境或測試環境,這樣做有很多好處,比如:
- 可以驗證功能是否正常,以及服務的效能;
- 用真實有效的流量請求去驗證,又不用造資料,不影響線上正常訪問;
- 這跟灰度釋出還不太一樣,映象流量不會影響真實流量;
- 可以用來排查線上問題;
- 重構,假如服務做了重構,這也是一種測試方式;
為了實現流量拷貝,Nginx提供了ngx_http_mirror_module模組,這就是 Nginx 又一牛X的功能!流量拷貝
限流
Nginx按請求速率限速模組使用的是漏桶演算法,即能夠強行保證請求的實時處理速度不會超過設定的閾值。
Nginx官方版本限制IP的連線和併發分別有兩個模組:
- limit_req_zone 用來限制單位時間內的請求數,即速率限制,採用的漏桶演算法 "leaky bucket"。
- limit_req_conn 用來限制同一時間連線數,即併發限制。
葵花寶典!一文搞定 Nginx 限流配置
快取
Nginx 快取作為效能優化的一個重要手段,可以極大減輕後端伺服器的負載。下面我們將介紹 Nginx 快取配置的相關指令以及 http 快取機制,以及 Nginx 快取實踐案例分析。
可參考:Nginx 快取機制詳解!
灰度釋出
執行過程:
- 當使用者請求到達前端代理服務Nginx,內嵌的lua模組解析Nginx配置檔案中的lua指令碼程式碼;
- Lua變數獲得客戶端IP地址,去查詢memcached快取內是否有該鍵值,如果有返回值執行@client_test,否則執行@client。
- Location @client_test把請求轉發給部署了new版程式碼的伺服器,location @client把請求轉發給部署了normal版程式碼的伺服器,伺服器返回結果。整個過程完成。
下面是安裝配置過程詳細過程:基於 Nginx+lua+Memcache 實現灰度釋出
這裡還給大家推薦一篇文章:基於 Nginx 實現灰度釋出與 AB 測試
封殺惡意訪問
看了 nginx 的訪問日誌,發現每天有好多國外的 IP 地址來訪問我的網站,並且訪問的內容基本上都是惡意的。因此我決定禁止國外 IP 來訪問我的網站
想要實現這個功能有很多方法,下面我就來介紹基於 NGINX 的 ngx_http_geoip2 模組 來禁止國外 IP 訪問網站。詳細的解決方案配置如:通過 Nginx 來實現封殺惡意訪問
Nginx+keepalived 實現高可用
Keepalived軟體起初是專為LVS負載均衡軟體設計的,用來管理並監控LVS叢集系統中各個服務節點的狀態,後來又加入了可以實現高可用的VRRP (Virtual Router Redundancy Protocol ,虛擬路由器冗餘協議)功能。因此,Keepalived除了能夠管理LVS軟體外,還可以作為其他服務(例如:Nginx、Haproxy、MySQL等)的高可用解決方案軟體。keepalived高可用叢集服務
安裝及配置過程請參考:Nginx+keepalived 實現高可用,防盜鏈及動靜分離配置,寫得太好了!
Nginx 終極指南
介紹用來提高Nginx伺服器的安全性,穩定性和效能的12種操作。
- 保持Nginx的及時升級
- 去掉不用的Nginx模組
- 禁用server_tokens項
- 禁止非法的HTTP User Agents
- 禁掉不需要的 HTTP 方法
- 設定緩衝區容量上限
- 限制最大連線數
- 設定日誌監控
- 阻止圖片外鏈
- 禁止 SSL 並且只開啟 TLS
- 證照加密(HTTPS)
- 重定向HTTP請求到HTTPS
以上12個具體的配置過程可參考:提高Nginx伺服器硬度的12個技巧
Nginx 監控
監控Web伺服器對於檢視網站上發生的情況至關重要。關注最多的便是日誌變動,檢視實時日誌檔案變動大家第一反應應該是'tail -f /path/to/log'命令吧,但是如果每個網站的訪問日誌都是使用這種方式檢視也是相當崩潰的,今天小編就跟大家分享一個強大的Nginx日誌監控工具。
一個小工具幫你搞定實時監控Nginx伺服器
日常生產環境搭建了Nginx叢集后,就需要繼續深入研究的就是日常Nginx監控。Nginx如何監控?相信百度就可以找到:nginx-status
通過Nginx-status,實時獲取到Nginx監控資料後,如何和現有監控系統整合?一個很好的解決方案:Nginx+Telegraf+Influxdb+Grafana
即通過Telegraf監控外掛定時收集Nginx的監控狀態,儲存到時序資料庫Influxdb中,然後通過Grafana展現即可。
這是我發現的又一款管理神器,可以實現配置管理,和效能監控。具體的安裝與配置過程,在這篇文章:又一款 Nginx 管理視覺化神器!配置、監控一條龍 中介紹過了。
Nginx 知識體系動態更新地址
關於Nginx 知識體系動態更新地址,大家可以持續關注民工哥技術之路公眾號,然後查閱 Nginx 技術專欄 可以實時檢視更新的文章,無論是學習、還是查漏補缺都是非常實用的技術手冊。