這是一系列免費的知識,有圖文版和視訊版,你現在看到的是圖文版。
NGINX 系列課分為三篇,基礎篇、進階篇和企業實踐篇,你現在正在閱讀的是基礎篇。
視訊版釋出在我自己的社群,喜歡看視訊的朋友可前往社群,微信掃碼登入或微信授權登入後即可播放。
寫在前面
基礎篇學習目的:瞭解 NGINX,並能夠自己動手操作,能獨立完成負載均衡配置,並繫結域名,實現通過域名訪問後端服務。
NGINX系列課課學習目的:瞭解 NGINX、能夠自己獨立完成負載均衡配置、能夠自己搭建高可用的企業級生產環境、對 NGINX 進行監控。
聽過視訊課的朋友已經能夠獨立完成負載均衡配置了,還提交了作業
我們這半年,將會輸出非常多公開課,有圖文版、有視訊版。重要的是,這些都是免費的!!! 來了就能聽。課程清單如下
其中綠色標註的是已經發布的內容,紅色的是正在準備素材的內容。
NGINX 基礎篇圖文版
好的,正題來了,開始吧。
如果平時接觸後端或者伺服器比較少的朋友可能會問,NGINX 是什麼?
關於它是什麼,我們可以引用 NGINX 官網和百度百科中的介紹,NGINX 是一款高效能的 HTTP 伺服器,同時也是一款反向代理伺服器(NGINX 官網原文稱為 reverse proxy server
)。除了支援 HTTP 協議外,還支援郵件協議、TCP/UDP 等。
它能夠做什麼?
在我看來,它其實是一款閘道器。作用 1 請求轉發,作用 2 限流,作用 3 鑑權,作用 4 負載均衡。上面提到的反向代理 reverse proxy server
,可以歸類到請求轉發。
正向代理,反向代理???
太多道理我們就不講了,可以閱讀其他平臺上關於這個問題的解讀 https://zhuanlan.zhihu.com/p/...
這裡我們簡單總結一下,正向代理代理的物件是客戶端,反向代理代理的物件是服務端。
做爬蟲的朋友們,平時你們用的 IP 代理就是正向代理,爬蟲程式通過代理,將請求轉發給後端。而我們提到的 NGINX 反向代理則是將客戶端的請求轉發到後端。從上面講到的文章裡借幾張圖
用 NGINX 的公司多嗎?
大部分公司都有用到 NGINX,大至 Google Meta(Facebook) Amazon Alibaba Tencent HUAWEI,小至全世界 70%+ (我猜的,實際比這更多)的網際網路企業,社群使用的也是 NGINX
安裝 NGINX
安裝基於 Ubuntu20.04,雲伺服器。基礎篇先通過快速安裝,讓我們可以操作起來,學一些基礎,後續進階篇會有編譯安裝。
開啟 Terminal,執行 sudo apt install nginx -y
,等待命令執行即完成安裝。安裝完成後它會自行啟動,大家訪問自己伺服器的地址即可,例如我的伺服器 IP 是 101.42.137.185
,那我訪問的是 http://101.42.137.185
如果頁面顯示的是 Welcome to nginx
字樣,說明服務正常。如果沒有,請檢查安裝時 Terminal 輸出的錯誤資訊,或者檢查自己的防火牆、安全組策略等(如果不懂,或者怎麼操作也不對,可以通過社群之前釋出的 Linux 雲伺服器公開課學習)
NGINX 基本工作原理和模組關係簡述
NGINX 有一個主程式和多個工作程式。主程式用於維護自身運轉,例如讀取配置、解析配置、維護工作程式、重新載入配置等等;工作程式才是具體響應請求的程式。
工作程式數可在配置檔案中調整。
NGINX 由模組組成,這些模組受配置檔案中的配置操控,也就是說配置檔案決定了 NGINX 的工作方式。
這裡還是引用其他文章,就不自己一一寫明瞭。NGINX 原理和架構可以參考 https://zhuanlan.zhihu.com/p/...,實際上在初期我們需要關注的只有一個地方,也就是模組那部分,隨便看看做個大體瞭解即可,不必深入。
NGINX 的訊號
訊號,這裡指的是控制訊號。訊號是控制 NGINX 工作狀態的模組,訊號語法格式為
nginx -s signal
常用的訊號有
stop 快速關停
quit 正常關停
reload 重新載入配置
reopen 重新開啟日誌檔案
NGINX 的正確關停,是 nginx -s quit
它可以讓 NGINX 處理完已經開始的工作後再退出。
NGINX 配置說明
基於之前的社群公開課,我們可以在正式講 NGINX 配置前先看看它的應用程式管理配置。通過 status 命令找到 NGINX 的 Server 配置檔案
> systemctl status nginx
檢視 NGINX 的 Server 配置
[Unit]
Description=A high performance web server and a reverse proxy server
Documentation=man:nginx(8)
After=network.target
[Service]
Type=forking
PIDFile=/run/nginx.pid
ExecStartPre=/usr/sbin/nginx -t -q -g 'daemon on; master_process on;'
ExecStart=/usr/sbin/nginx -g 'daemon on; master_process on;'
ExecReload=/usr/sbin/nginx -g 'daemon on; master_process on;' -s reload
ExecStop=-/sbin/start-stop-daemon --quiet --stop --retry QUIT/5 --pidfile /run/nginx.pid
TimeoutStopSec=5
KillMode=mixed
[Install]
WantedBy=multi-user.target
看到 ExecStart
選項,可以確定 NGINX 安裝在 /usr/sbin/nginx
,這個配置檔案與我們之前的公開課 Linux 雲伺服器公開課講到的知識遙相呼應,這裡提一下。
查詢預設的主配置檔案
配置檔案部分正式開始
NGINX 有主配置檔案和輔助配置檔案,主配置檔案預設名稱為 nginx.conf
,預設存放在 /etc/nginx/nginx.conf
。輔助配置檔案的路徑受主配置檔案控制,具體路徑通過主配置檔案設定,輔助配置的檔名稱和路徑都可更改,檔名通常以 conf
結尾。
安裝完成後如果你不知道主配置檔案在哪,可以通過預設路徑查詢,或者通過 find
命令搜尋。
> sudo find / -name nginx.conf
/etc/nginx/nginx.conf
主配置檔案基本結構和作用。使用 cat /etc/nginx/nginx.conf
可列出檔案內容。如果你不懂,那麼可以通過社群之前釋出的的公開課 Linux 雲伺服器公開課學習具體的 Linux 檔案檢視指令。
user www-data; # 使用者
worker_processes auto; 工作程式數
pid /run/nginx.pid; # 程式檔案
include /etc/nginx/modules-enabled/*.conf; # 外掛模組配置
events {
worker_connections 768; # 允許同時連線的連線數
# multi_accept on;
}
http {
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3; # Dropping SSLv3, ref: POODLE
ssl_prefer_server_ciphers on;
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
include /etc/nginx/conf.d/*.conf; # 輔助配置檔案路徑
include /etc/nginx/sites-enabled/*;
}
# 示例
#mail {
...
#}
這裡列出的配置檔案我做了適當的調整,刪除了被註釋的內容,保留了有效內容。重要項的含義都用中文以註釋的形式標記在上面了。
看到配置,你肯定有點懵,這都是些啥啊。接下來我們來學習 NGINX 配置檔案的基礎語法。
NGINX 配置檔案基礎語法
NGINX 配置檔案中的配置項成為指令,指令分為簡單指令和塊指令。簡單的指令由指令名稱和引數組成,以空格進行分隔並以英文分號結尾,例如
worker_processes auto;
其中 worker_processes
是指令,這個指令的作用是設定工作程式數。auto
代表程式數的數量,可以是數字也可以是 auto
(根據 CPU 數量按固定數學公式計算,一般是 CPU+1)。
塊指令語法格式與簡單指令相似,單以花括號包裹更多的簡單指令,例如
http {
server {
...
}
}
上下文/語境
上下文有些地方也稱語境,如果塊指令內包含其他指令,則這個塊指令稱為上下文。常見的上下文例如
events
http
server
location
有一個隱藏的上下文指令,main。它不需要顯示宣告,所有指令的最外層就是 main 的範圍。main 作為其他上下文的參考,例如 events 和 http 必須在 main 範圍中;server 必須在 http 中;location 必須在 server 中;以上限定是固定的,不可以隨意放置,否則無法執行 NGINX 程式,但能夠在日誌裡看到錯誤提示資訊。
講了這麼多,你一定乏了,拿我們來動手吧!
使用 NGINX 為後端程式配置代理
一個簡單的 WEB 服務,例如下面這個 flask 應用
from flask import Flask
from flask_restful import Resource, Api
app = Flask(__name__)
api = Api(app)
class HelloWorld(Resource):
def get(self):
app.logger.info("receive a request, and response '穿甲兵技術社群'")
return {'message': '穿甲兵技術社群', "address": "https://chuanjiabing.com"}
api.add_resource(HelloWorld, '/')
if __name__ == '__main__':
app.run(debug=True, host="127.0.0.1", port=6789)
將內容寫入到伺服器上的某個檔案,例如 /home/ubuntu/ke.py
。
啟動前記得安裝相關的 Python 庫 pip3 install flask-restful
在 Ubuntu 20.04 上預設帶有新版 Python,環境什麼的不用擔心。執行這個 Web 後端服務 python3 /home/ubuntu/ke.py
完成後端的啟動後,我們來配置 NGINX
通過前面檢視主配置檔案可知,輔助配置檔案的目錄為 /etc/nginx/conf.d
,那麼現在我們在輔助配置檔案目錄新增配置檔案
> sudo vim /etc/nginx/conf.d/ke.conf
server {
listen 8000;
server_name localhost;
location / {
proxy_pass http://localhost:6789;
}
}
檢查配置檔案是否正確
> sudo nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
重新載入配置
> sudo nginx -s reload
瀏覽器訪問 http://ip:port
例如我的伺服器 http://101.42.137.185:8000/
就可以看到後端的輸出了
NGINX 日誌檔案
預設分為正常日誌和內部錯誤日誌,日誌路徑可在主配置檔案中設定
/var/log/nginx/access.log
/var/log/nginx/error.log
檢視正常日誌
> cat /var/log/nginx/access.log
117.183.211.177 - - [19/Nov/2021:20:18:46 +0800] "GET / HTTP/1.1" 200 107 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.71 Safari/537.36"
117.183.211.177 - - [19/Nov/2021:20:18:48 +0800] "GET /favicon.ico HTTP/1.1" 404 209 "http://101.42.137.185:8000/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.71 Safari/537.36"
官方文件-日誌格式 http://nginx.org/en/docs/http...
預設的日誌格式
log_format compression '$remote_addr - $remote_user [$time_local] '
'"$request" $status $bytes_sent '
'"$http_referer" "$http_user_agent" "$gzip_ratio"';
可在主配置檔案中自行配置,具體配置項參考官方文件。
使用 NGINX 為前端程式配置代理
一個簡單的 HTML 文件
> vim /home/ubuntu/index.html
<html><meta charset="utf-8"/><body><title>穿甲兵技術社群</title><div><p>穿甲兵技術社群<p><a>https://chuanjiabing.com</a></div><body></html>
無論是大型前端專案還是中小型前端專案,一般來講都需要編譯為 HTML 文件,然後使用類似 NGINX 這樣的應用提供可訪問的服務。
注意:一些 Vue/React 的服務有可能會做服務端渲染部署,但大部分還是編譯為 HTML。這裡的簡單示例和那些前端工程專案在配置上並沒有什麼區別。作為示例,不用糾結,學習 NGINX 才是要緊的。
> sudo vim /etc/nginx/conf.d/page.conf
server {
listen 1235;
server_name localhost;
charset utf-8;
location / {
root /home/ubuntu/;
index index.html index.htm;
}
}
基於 NGINX 實現負載均衡
想象一下場景,例如現在你伺服器上的後端服務主要是用於格式化時間,有很多爬蟲程式需要呼叫它,而且還需要確保服務穩定可用。
場景延伸:假設你逆向了一個 JS 演算法,現在所有爬蟲都需要在發出請求前呼叫這個演算法生成 sign 值,帶著值去請求。如果你把 JS 程式碼放在 Python/Golang 這類程式碼裡做本地呼叫執行,那麼你改動演算法時需要改動/重新部署所有爬蟲程式,但做成 WEB 服務,只需要改動/重啟這個 WEB 服務就可以了。
現在 1 個後端服務的情況下有 2 個明顯缺點:
1、服務效能不夠,請求太多會導致程式卡頓,響應速度慢,影響整體效率;
2、服務整體不穩定,一旦程式退出或者伺服器當機,那服務將不可訪問;
使用負載均衡的好處
1、啟動多個後端服務,配置負載均衡,讓請求按需(例如輪流)轉發到它門那裡進行處理,那麼就能夠承擔更多的工作需求;
2、一個 NGINX 負載多個後端服務,當一個服務或者幾個服務出現程式退出的情況,還有其他服務在工作;
NGINX 只需要引入 proxy_pass
指令和對應的 upstream
上下文即可實現負載均衡。一個簡單的負載均衡配置例如
⚠️ 實驗前,請先啟動多個後端程式。可以將剛才的 Flask 程式碼複製到另一個檔案(例如 /home/ubuntu/main.py
,但記得需要改動裡面的埠號,建議改為跟教程一樣的 6799),如果你想在網頁上看到負載的效果,可以在響應內容處用 6789/6799 來區分具體是那個後端程式。
# /etc/nginx/conf.d/ke.conf 內容改為
upstream backend{
server localhost:6789;
server localhost:6799;
}
server {
listen 8000;
server_name localhost;
location / {
proxy_pass http://backend;
}
}
儲存後重新載入配置即可
> sudo nginx -s reload
多次訪問 http://101.42.137.185:8000/
,可以看到頁面上顯示的內容是 6789 和 6799 這兩個後端服務交替返回資訊,這說明負載均衡配置成功。
域名解析與配置實踐
開啟雲服務商控制檯(後續以騰訊云為例,因為教程錄製時使用的是騰訊雲輕量級伺服器),其他雲服務商介面有差異,請大家見機行事。
在搜尋框處搜尋域名解析(騰訊的的是 DNSPOD)
進入找到要解析的域名(這裡的前提是你自己已經買了域名,做好備案。如果沒有,那看我操作也可以),點選解析
點選新增記錄
在主機記錄處輸入子域名名稱(例如 ke
)、在記錄值處輸入伺服器 IP 地址後選擇儲存即可,其他選項預設。
完成雲伺服器控制檯的設定後,還不可以通過域名訪問到我們伺服器上的應用
前往伺服器改動 NGINX 輔助配置檔案,更改埠、繫結域名
> sudo vim/etc/nginx/conf.d/ke.conf
# 改動 server 上下文中的 listen 和 server_name
listen 80;
server_name ke.chuanjiabing.com;
記得過載配置
> sudo nginx -s reload
然後就可以通過域名 http://ke.chuanjiabing.com/
訪問服務了
課後作業:在社群課程帖子下曬出後端程式的 NGINX 負載均衡配置截圖,3 張。一張是配置截圖;另外兩張是瀏覽器訪問時負載配置生效的截圖。
後續進階篇和企業實踐篇的課程大綱如下,後續課程的學習目的:能夠在工作中很好的應用 NGINX,完成企業級生產環境部署和監控告警
NGINX 進階篇
NGINX 負載均衡策略理論
編譯安裝 NGINX
基於 NGINX 實現許可權驗證
基於 NGINX 實現訪問限流
基於 NGINX 的簡單反爬蟲
基於 NGINX 實現不停機更新
NGINX 企業級實踐篇
NGINX 的 HTTPS 配置實踐
NGINX 外掛安裝
NGINX 資料監控實戰
NGINX 生產環境高可用部署實踐