詳解Nginx負(fù)載均衡/反向代理/日志分析
Nginx 性能優(yōu)化之三大法寶
動(dòng)靜分離
Web應(yīng)用中的資源可分為兩類(lèi):
☆ 動(dòng)態(tài)內(nèi)容
需后端程序?qū)崟r(shí)生成的數(shù)據(jù)(如PHP/Java接口返回的JSON、用戶(hù)登錄狀態(tài)頁(yè)),通常由應(yīng)用服務(wù)器(如Tomcat、Node.js)處理。
☆ 靜態(tài)內(nèi)容
無(wú)需后端計(jì)算、可直接返回的文件(如圖片、CSS/JS、字體文件),由Nginx直接高效處理。
經(jīng)典配置
server {
listen 80;
server_name example.com;
# 動(dòng)態(tài)請(qǐng)求:轉(zhuǎn)發(fā)到后端應(yīng)用服務(wù)器(如Tomcat/Node.js)
location /api/ {
proxy_pass http://backend_server:8080/; # 指向后端服務(wù)地址
proxy_set_header Host $host; # 傳遞原始請(qǐng)求頭
}
# 靜態(tài)資源:直接由Nginx從本地目錄返回
location ~* \.(jpg|jpeg|png|gif|css|js|woff|woff2|ico)$ {
root /var/www/static; # 靜態(tài)資源存放目錄
expires 30d; # 緩存30天(可選優(yōu)化)
}
# 默認(rèn)動(dòng)態(tài)請(qǐng)求(如PHP/HTML模板)
location / {
proxy_pass http://app_server:3000/; # 指向應(yīng)用服務(wù)器
}
}客戶(hù)端緩存
告知瀏覽器獲取的信息是在某個(gè)區(qū)間時(shí)間段是有效的,基本格式:
expires 30s; //表示把數(shù)據(jù)緩存30秒 expires 30m; //表示把數(shù)據(jù)緩存30分 expires 10h; //表示把數(shù)據(jù)緩存10小時(shí) expires 3d; //表示把數(shù)據(jù)緩存3天
禁止緩存配置說(shuō)明
add_header Cache-Control no-store;
案例:緩存圖片/js/css文件,緩存時(shí)間為1天
location ~* \.(jpg|jpeg|gif|png|js|css)$ {
expires 1d;
#add_header Cache-Control no-store;
}開(kāi)啟 Gzip 壓縮
壓縮文件大小變小了,傳輸更快了,目前市場(chǎng)上大部分瀏覽器是支持GZIP的。
IE6以下支持不好,會(huì)出現(xiàn)亂碼情況。
http://nginx.org/en/docs/http/ngx_http_gzip_module.html
gzip on; # 第1行:開(kāi)啟Gzip壓縮功能
gzip_min_length 1k; # 第2行:僅壓縮大于1KB的文件(小于1KB的壓縮后可能更大,不處理)
gzip_buffers 4 16k; # 第3行:壓縮時(shí)使用的緩沖區(qū)數(shù)量(4個(gè))和大小(每個(gè)16KB)
gzip_http_version 1.1; # 第4行:兼容HTTP/1.1協(xié)議(主流瀏覽器均支持)
gzip_comp_level 5; # 第5行:壓縮級(jí)別(1-10),數(shù)字越大壓縮率越高但CPU消耗越大(推薦5~6)
gzip_types text/plain
text/css
text/javascript
application/javascript
application/x-javascript
image/jpeg
image/gif
image/png
image/x-ms-bmp; # 第6行:指定要壓縮的文件類(lèi)型(優(yōu)先壓縮文本和圖片)
gzip_vary on; # 第7行:在響應(yīng)頭中添加Vary: Accept-Encoding,幫助緩存服務(wù)器區(qū)分壓縮/未壓縮版本
gzip_disable "MSIE [1-6]\."; # 第8行:禁用對(duì)IE6及以下版本的Gzip(兼容性問(wèn)題)vary 是差異,多樣化的意思。
gzip_vary 是 Nginx 配置中的一條指令,它用于控制是否在響應(yīng)頭中設(shè)置 Vary: Accept-Encoding 頭部。具體來(lái)說(shuō):
gzip_vary on;:?jiǎn)⒂脮r(shí),Nginx 會(huì)在響應(yīng)頭中加入 Vary: Accept-Encoding,表示不同的客戶(hù)端可能會(huì)根據(jù)是否支持 gzip 壓縮來(lái)收到不同的響應(yīng)內(nèi)容。這有助于緩存服務(wù)器(如 CDN)緩存壓縮和未壓縮的內(nèi)容。
gzip_vary off;:禁用時(shí),Nginx 不會(huì)在響應(yīng)頭中加入 Vary: Accept-Encoding,這意味著緩存服務(wù)器不會(huì)區(qū)分壓縮與未壓縮的內(nèi)容。這樣做通常會(huì)減少緩存的復(fù)雜性,但可能會(huì)導(dǎo)致某些情況緩存不一致。
| 指令 | 作用 | 推薦值/說(shuō)明 |
| gzip on; | 開(kāi)關(guān)Gzip功能 | 必須為 on才生效 |
| gzip_min_length 1k; | 最小壓縮文件大小 | 避免小文件壓縮后體積反而增大(默認(rèn)20B~1k,建議1k~10k) |
| gzip_buffers 4 16k; | 壓縮緩沖區(qū)配置 | 4個(gè)16KB的緩沖區(qū)(根據(jù)服務(wù)器內(nèi)存調(diào)整) |
| gzip_http_version 1.1; | 兼容的HTTP協(xié)議版本 | 現(xiàn)代瀏覽器均支持1.1 |
| gzip_comp_level 5; | 壓縮級(jí)別 | 1(最快但壓縮率低)~10(最慢但壓縮率高),推薦5~6平衡性能與效果 |
| gzip_types | 指定壓縮的文件MIME類(lèi)型 | 優(yōu)先壓縮文本(如HTML/CSS/JS)、常用圖片(如JPEG/PNG) |
| gzip_vary on; | 是否添加Vary頭 | 幫助CDN/代理服務(wù)器正確緩存壓縮與未壓縮版本 |
| gzip_disable "MSIE [1-6]\."; | 禁用低版本IE的Gzip | IE6對(duì)Gzip支持差,可能引發(fā)亂碼 |
常見(jiàn)壓縮類(lèi)型:
文本類(lèi)(.html/.css/.js)
矢量圖(.svg)
部分圖片(.png/.jpg,但已壓縮的圖片效果有限)
總結(jié)
| 優(yōu)化方向 | 核心目標(biāo) | 關(guān)鍵技術(shù) | 適用場(chǎng)景 |
| ??動(dòng)靜分離?? | 提升資源處理效率,降低后端壓力 | Nginx路由分離(動(dòng)態(tài)→后端,靜態(tài)→本地/CDN) | 所有Web應(yīng)用(尤其是高并發(fā)場(chǎng)景) |
| ??客戶(hù)端緩存?? | 減少重復(fù)傳輸,加速二次訪(fǎng)問(wèn) | expires/Cache-Control控制緩存時(shí)間 | 圖片、CSS/JS等長(zhǎng)期不變的靜態(tài)資源 |
| ??Gzip壓縮?? | 減小傳輸體積,降低帶寬消耗 | gzip模塊壓縮文本/圖片 | 文本類(lèi)資源(HTML/CSS/JS)、未高度壓縮的圖片 |
Nginx 日志分析
日志分類(lèi)
| 日志類(lèi)型 | 默認(rèn)文件名 | 核心記錄內(nèi)容 | 默認(rèn)存儲(chǔ)路徑(不同安裝方式) |
| 訪(fǎng)問(wèn)日志 | access.log | 1、$remote_addr $upstream_status $request_time等變量組合(格式可自定義) 2、查看統(tǒng)計(jì)用戶(hù)的訪(fǎng)問(wèn)信息與流量 | 源碼安裝:/usr/local/nginx/logs yum/dnf/apt 安裝:/var/log/nginx |
| 錯(cuò)誤日志 | error.log | 1、配置語(yǔ)法錯(cuò)誤、進(jìn)程異常、連接超時(shí)等信息,含行號(hào)與錯(cuò)誤碼(如[emerg] bind() failed) 2、錯(cuò)誤信息以及重寫(xiě)信息 | 同上 |
access 訪(fǎng)問(wèn)日志
cat /var/log/nginx/access.log 或者 cat /usr/local/nginx/logs/access.log
日志參數(shù)詳解
參數(shù) | 意義 |
$remote_addr | 客戶(hù)端的ip地址(代理服務(wù)器,顯示代理服務(wù)ip) |
$remote_user | 用于記錄遠(yuǎn)程客戶(hù)端的用戶(hù)名稱(chēng)(一般為“-”) |
$time_local | 用于記錄訪(fǎng)問(wèn)時(shí)間和時(shí)區(qū) |
$request | 用于記錄請(qǐng)求的url以及請(qǐng)求方法 |
$status | 響應(yīng)狀態(tài)碼,例如:200成功、404頁(yè)面找不到等 |
$body_bytes_sent | 給客戶(hù)端發(fā)送的文件主體內(nèi)容字節(jié)數(shù) |
$http_referer | 可以記錄用戶(hù)是從哪個(gè)鏈接訪(fǎng)問(wèn)過(guò)來(lái)的 |
$http_user_agent | 用戶(hù)所使用的代理(一般為瀏覽器) |
$http_xforwarded_for | 可以記錄客戶(hù)端IP,通過(guò)代理服務(wù)器來(lái)記錄客戶(hù)端的IP地址 |
設(shè)置access.log訪(fǎng)問(wèn)日志輸出格式與文件路徑:
vim /etc/nginx/nginx.conf 或者 vim /usr/local/nginx/conf/nginx.conf
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,訪(fǎng)問(wèn)站點(diǎn),查看access.log日志,可以統(tǒng)計(jì)分析用戶(hù)的流量的相關(guān)情況。
nginx -s reload
error 錯(cuò)誤日志
作用:用于Nginx排錯(cuò)
error.log,默認(rèn)記錄配置啟動(dòng)錯(cuò)誤信息和訪(fǎng)問(wèn)請(qǐng)求錯(cuò)誤信息。
cat /var/log/nginx/error.log 或者 cat /usr/local/nginx/logs/error.log
配置error_log:
vim /etc/nginx/nginx.conf 或者 vim /usr/local/nginx/conf/nginx.conf
在配置nginx.conf 的時(shí)候,有一項(xiàng)是指定錯(cuò)誤日志的,默認(rèn)情況下你不指定也沒(méi)有關(guān)系。
但有時(shí)出現(xiàn)問(wèn)題時(shí),是有必要記錄一下錯(cuò)誤日志的,方便我們排查問(wèn)題。
參考地址:https://nginx.org/en/docs/ngx_core_module.html#error_log
error_log 級(jí)別分為 debug, info, notice, warn, error, crit(從低到高)。
| 級(jí)別 | 含義 | 適用場(chǎng)景 |
| debug | 調(diào)試信息(最詳細(xì)) | 開(kāi)發(fā)/排查復(fù)雜問(wèn)題 |
| info | 一般性事件記錄 | 跟蹤運(yùn)行狀態(tài) |
| notice | 重要但非錯(cuò)誤事件 | 生產(chǎn)環(huán)境常規(guī)監(jiān)控 |
| warn | 警告事件(不影響服務(wù)) | 潛在問(wèn)題預(yù)警 |
| error | ??默認(rèn)級(jí)別??,錯(cuò)誤事件 | 服務(wù)異常排查 |
| crit | Critical,嚴(yán)重錯(cuò)誤 | 緊急問(wèn)題(如權(quán)限拒絕) |
如果配置 error,會(huì)怎么樣呢?
Nginx 只會(huì)記錄 error級(jí)別及以上(即 error和 crit)的日志,而更低級(jí)別的日志(如 warn、notice、info、debug)將被忽略。
舉例如下
cat /var/log/nginx/error.log 或者 cat /usr/local/nginx/logs/error.log
注意:
crit 記錄的日志最少,而debug記錄的日志最多。
有些模塊突破了默認(rèn)的error級(jí)別限制,也會(huì)記錄一些日志,比如進(jìn)程啟動(dòng)的一些notice通知。
小結(jié):
錯(cuò)誤日志的作用:用來(lái)查看錯(cuò)誤信息,通過(guò)提示的錯(cuò)誤信息,排除錯(cuò)誤。
GoAccess 輕量級(jí)日志分析
作用:針對(duì)Apache/Nginx訪(fǎng)問(wèn)日志進(jìn)行分析,優(yōu)點(diǎn):輕量級(jí)、開(kāi)源、帶圖形化界面!
什么是GoAccess?
GoAccess 是一款開(kāi)源的且具有交互視圖界面的 實(shí)時(shí) Web 日志分析工具,通過(guò)你的 Web 瀏覽器或者 Linux 系統(tǒng)下的 終端程序 即可訪(fǎng)問(wèn)。
能為系統(tǒng)管理員提供快速且有價(jià)值的 HTTP 統(tǒng)計(jì),并以在線(xiàn)可視化服務(wù)器的方式呈現(xiàn)。
安裝GoAccess:
安裝 GoAccess dnf install goaccess -y 如果安裝GoAccess不成功,可以先完善一下 EPEL 倉(cāng)庫(kù) 安裝 EPEL 倉(cāng)庫(kù)(Extra Packages for Enterprise Linux) dnf install epel-release -y
說(shuō)明:
EPEL 是 RedHat/CentOS 官方維護(hù)的擴(kuò)展軟件源,提供大量常用但非默認(rèn)包含的工具(如 GoAccess、htop 等)。
Nginx 默認(rèn)訪(fǎng)問(wèn)日志通常位于
/usr/local/nginx/logs/access.log(若編譯安裝時(shí)未修改路徑)
或
/var/log/nginx/access.log(若通過(guò)包管理器安裝)
本例以 Nginx 源碼編譯安裝到 /usr/local/nginx/ 為例
cd /usr/local/nginx/
注意:GoAccess分析的結(jié)果往往是一個(gè)html網(wǎng)頁(yè),如果想直接預(yù)覽,建議直接把內(nèi)容放置于Nginx訪(fǎng)問(wèn)目錄
① 離線(xiàn)分析
離線(xiàn)分析,會(huì)生成靜態(tài) HTML 報(bào)告(推薦生產(chǎn)環(huán)境)
通過(guò)以下命令對(duì)訪(fǎng)問(wèn)日志進(jìn)行分析,并將結(jié)果輸出為 HTML 文件(便于通過(guò)瀏覽器查看)
goaccess -f /usr/local/nginx/logs/access.log --log-format=COMBINED > /usr/local/nginx/html/itheimadevops/report.html
或者
goaccess -f /usr/local/nginx/logs/access.log --log-format=COMBINED > report.html
或者
goaccess -f /var/log/nginx/access.log --log-format=COMBINED > report.html
-f:指定文件
--log-format:分析的文件格式
COMBINED代表組合日志格式(XLF/ELF) Apache | Nginx
COMMON代表通用日志格式(CLF) ApacheNginx server 配置參考:
vi /usr/local/nginx/conf/nginx.conf
...
server {
# 監(jiān)聽(tīng)端口
listen 80;
# 配置域名
server_name www.itheimadevops.com;
# 配置目錄
root html/itheimadevops;
access_log logs/www.itheimadevops.com.access.log main;
error_log logs/www.itheimadevops.com.error.log;
# 配置uri匹配規(guī)則
location / {
index index.html index.htm;
}
location ~ \.(jpg|jpeg|gif|png|js|css)$ {
add_header Cache-Control no-store;
}
}
...查看 report.html
goaccess -f /var/log/nginx/access.log --log-format=COMBINED > report.html ls -hl report.html goaccess -f /usr/local/nginx/logs/access.log --log-format=COMBINED > report.html ls -hl report.html
- server1(dnf 版 Nginx)日志路徑:
/var/log/nginx/access.log - server2(源碼版 Nginx)日志路徑:
/usr/local/nginx/logs/access.log - 作用:用 goaccess 解析 Nginx 訪(fǎng)問(wèn)日志,生成可視化報(bào)表
report.html
② 實(shí)時(shí)分析
除生成靜態(tài) HTML 外,GoAccess 還支持 終端實(shí)時(shí)動(dòng)態(tài)展示(適合快速排查問(wèn)題)
goaccess /usr/local/nginx/logs/access.log \ --no-global-config \ --log-format='%h %^ %^ [%d:%t %^] "%r" %s %b "%R" "%u"' \ --date-format='%d/%b/%Y' \ --time-format='%H:%M:%S' 或者 goaccess /var/log/nginx/access.log \ --no-global-config \ --log-format='%h %^ %^ [%d:%t %^] "%r" %s %b "%R" "%u"' \ --date-format='%d/%b/%Y' \ --time-format='%H:%M:%S'
更多參考:https://www.goaccess.cc/?mod=man
Nginx 企業(yè)級(jí)日志分析實(shí)戰(zhàn)經(jīng)典案例
GoAccess 不僅能生成基礎(chǔ)的可視化報(bào)告,更能通過(guò)靈活的命令行參數(shù)與日志分析,幫助企業(yè)快速定位關(guān)鍵問(wèn)題(如高頻攻擊 IP、異常 404 請(qǐng)求、熱門(mén)業(yè)務(wù)路徑)。
本章聚焦三大典型企業(yè)級(jí)場(chǎng)景,結(jié)合實(shí)戰(zhàn)命令與結(jié)果解讀,助你掌握日志分析的“進(jìn)階用法”。
統(tǒng)計(jì)訪(fǎng)問(wèn)量最高的IP地址
在生成日志分析報(bào)告時(shí),GoAccess 默認(rèn)會(huì)統(tǒng)計(jì)并展示 “Top IPs”(訪(fǎng)問(wèn)量最高的 IP 地址列表)。
☆ 場(chǎng)景背景
企業(yè)的 Web 服務(wù)可能面臨兩類(lèi)與 IP 相關(guān)的風(fēng)險(xiǎn):
- 正常高頻訪(fǎng)問(wèn):如內(nèi)部員工頻繁調(diào)用 API、爬蟲(chóng)程序抓取公開(kāi)數(shù)據(jù)(需評(píng)估是否合理)。
- 惡意行為:如 DDoS 攻擊(大量 IP 短時(shí)間內(nèi)發(fā)起請(qǐng)求)、暴力破解(針對(duì)登錄接口的重復(fù)嘗試)、爬蟲(chóng)違規(guī)采集(超出正常頻率)。
通過(guò)統(tǒng)計(jì)訪(fǎng)問(wèn)量最高的 IP,可以快速鎖定 “誰(shuí)在頻繁訪(fǎng)問(wèn)我的服務(wù)”,進(jìn)而判斷是否需要封禁、限流或進(jìn)一步分析其行為
☆ 腳本實(shí)現(xiàn)
# 提取日志中的 IP(假設(shè)為每行第一個(gè)字段,符合 Nginx 默認(rèn)日志格式)并統(tǒng)計(jì)頻次,按次數(shù)降序排序,取前 10
awk '{print $1}' /usr/local/nginx/logs/access.log | sort | uniq -c | sort -nr | head -n 10
說(shuō)明:
awk '{print $1}':提取日志每行的第一個(gè)字段(通常是客戶(hù)端 IP,Nginx 默認(rèn)日志格式中 $1為 IP)。
sort:對(duì) IP 列表進(jìn)行排序(uniq -c要求輸入已排序)。
uniq -c:統(tǒng)計(jì)每個(gè)唯一 IP 的出現(xiàn)次數(shù)(-c表示計(jì)數(shù))。
sort -nr:按計(jì)數(shù)結(jié)果降序排序(-n數(shù)值排序,-r逆序)。
head -n 10:僅顯示前 10 條結(jié)果。統(tǒng)計(jì)404錯(cuò)誤的請(qǐng)求
☆ 場(chǎng)景背景
HTTP 404 狀態(tài)碼表示 “請(qǐng)求的資源不存在”,可能由以下原因?qū)е拢?/p>
- 用戶(hù)側(cè)問(wèn)題:用戶(hù)手動(dòng)輸入了錯(cuò)誤的 URL、點(diǎn)擊了過(guò)期的書(shū)簽或外鏈。
- 業(yè)務(wù)側(cè)問(wèn)題:前端頁(yè)面鏈接配置錯(cuò)誤(如前端代碼中的 API 地址拼寫(xiě)錯(cuò)誤)、后端服務(wù)刪除了文件但未更新前端引用、CDN 緩存了舊版本的無(wú)效鏈接。
- 攻擊行為:掃描器嘗試訪(fǎng)問(wèn)常見(jiàn)的敏感路徑(如 /admin.php、/config.json),試圖探測(cè)系統(tǒng)漏洞。
通過(guò)統(tǒng)計(jì) 404 錯(cuò)誤請(qǐng)求,可以快速定位 “哪些資源被頻繁訪(fǎng)問(wèn)但不存在”,進(jìn)而修復(fù)業(yè)務(wù)邏輯或加固安全防護(hù)。
☆ 腳本實(shí)現(xiàn)
# grep 查找關(guān)鍵狀態(tài)碼 404 grep '404' /usr/local/nginx/logs/access.log 或者 grep '404' /var/log/nginx/access.log # 提取所有狀態(tài)碼為 404 的日志行(Nginx 默認(rèn)日志格式中狀態(tài)碼是第9個(gè)字段) awk '$9 == 404' /usr/local/nginx/logs/access.log 或者 awk '$9 == 404' /var/log/nginx/access.log
如果Nginx站點(diǎn)很正常,一般來(lái)講就沒(méi)有404,可以考慮查找一下200
awk '$9 == 200' /usr/local/nginx/logs/access.log|more
進(jìn)階實(shí)現(xiàn)
# 進(jìn)階:提取 404 請(qǐng)求的路徑(第7個(gè)字段),統(tǒng)計(jì)頻次并排序
awk '$9 == 404 {print $7}' /usr/local/nginx/logs/access.log | sort | uniq -c | sort -nr | head -n 10
或者
awk '$9 == 404 {print $7}' /var/log/nginx/access.log | sort | uniq -c | sort -nr | head -n 10
或者
awk '$9 == 404' /usr/local/nginx/logs/access.log | awk '{ print $7}' | sort | uniq -c | sort -nr | head -n 10
或者
awk '$9 == 404' /var/log/nginx/access.log | awk '{ print $7}' | sort | uniq -c | sort -nr | head -n 10統(tǒng)計(jì)最熱門(mén)的URL
☆ 場(chǎng)景背景
“最熱門(mén)的 URL” 反映了用戶(hù)最常訪(fǎng)問(wèn)的頁(yè)面或接口,是企業(yè)分析 “用戶(hù)關(guān)注什么” 和 “業(yè)務(wù)重點(diǎn)在哪里” 的關(guān)鍵指標(biāo)。通過(guò)統(tǒng)計(jì)熱門(mén) URL,可以:
- 優(yōu)化資源配置:為高流量頁(yè)面分配更多服務(wù)器資源(如 CDN 加速、數(shù)據(jù)庫(kù)緩存)。
- 改進(jìn)用戶(hù)體驗(yàn):分析熱門(mén)頁(yè)面的加載速度、跳出率(需結(jié)合其他工具),針對(duì)性?xún)?yōu)化交互設(shè)計(jì)。
- 驗(yàn)證業(yè)務(wù)策略:檢查推廣活動(dòng)鏈接(如營(yíng)銷(xiāo)頁(yè) /promotion/2025)是否達(dá)到預(yù)期流量,或核心功能(如支付頁(yè) /checkout)是否易用。
☆ 腳本實(shí)現(xiàn)
# 提取日志中的請(qǐng)求路徑(第11個(gè)字段),統(tǒng)計(jì)頻次并排序,取前 10
awk '{print $11}' /usr/local/nginx/logs/access.log | sort | uniq -c | sort -nr | head -n 10
或者
awk '{print $11}' /var/log/nginx/access.log | sort | uniq -c | sort -nr | head -n 10日志輪轉(zhuǎn)
作用:利用Shell腳本對(duì)日志進(jìn)行切割,把大的訪(fǎng)問(wèn)日志切割為一個(gè)一個(gè)小日志,方便后期存儲(chǔ)以及查看分析
☆腳本實(shí)現(xiàn)
mkdir /scripts cd /scripts vim logrotate.sh ------------------分割線(xiàn)------------------- #!/bin/bash date_info=$(date +%F-%H-%M) mv /usr/local/nginx/logs/access.log /usr/local/nginx/logs/access.log.$date_info /usr/local/nginx/sbin/nginx -s reload ------------------分割線(xiàn)------------------- chmod +x /scripts/logrotate.sh
☆配置 crontab
crontab -e * * * * * /bin/bash /scripts/logrotate.sh &>/dev/null 或者 0 */6 * * * /bin/bash /scripts/logrotate.sh &>/dev/null 或者 0 * * * * /bin/bash /scripts/logrotate.sh &>/dev/null 30 2 * * * /bin/bash /scripts/logrotate.sh &>/dev/null
改進(jìn)版
mv /usr/local/nginx/logs/access.log /usr/local/nginx/logs/access.log.$(date +%F_%H-%M-%S) && /usr/local/nginx/sbin/nginx -s reopen
nginx -s reload 與 nginx -s reopen 對(duì)比表
對(duì)比項(xiàng) | reload | reopen |
主要用途 | 重新加載配置文件 | 重新打開(kāi)日志文件 |
是否創(chuàng)建新日志文件 | ? 否 | ? 是 |
是否重啟工作進(jìn)程 | ? 是(平滑重啟) | ? 否(繼續(xù)使用原進(jìn)程) |
是否重新加載配置 | ? 是 | ? 否 |
是否中斷現(xiàn)有連接 | ? 否(優(yōu)雅關(guān)閉) | ? 否 |
配置文件語(yǔ)法檢查 | ? 會(huì)進(jìn)行檢查 | ? 不會(huì)檢查 |
典型使用場(chǎng)景 | nginx.conf 配置變更后生效 | 日志切割/輪轉(zhuǎn)(配合 logrotate) |
執(zhí)行命令示例 |
|
|
工作原理簡(jiǎn)述
reload:
- 主進(jìn)程檢查新配置語(yǔ)法
- 啟動(dòng)新工作進(jìn)程(加載新配置)
- 優(yōu)雅關(guān)閉舊工作進(jìn)程
reopen:
- 主進(jìn)程通知工作進(jìn)程關(guān)閉當(dāng)前日志文件
- 工作進(jìn)程重新打開(kāi)日志文件(按配置路徑)
- 若文件不存在則自動(dòng)創(chuàng)建
總結(jié)
日志輪轉(zhuǎn)的本質(zhì)就是把一個(gè)大的日志切割為若干個(gè)小的日志,防止文件過(guò)大。
Nginx 反向代理
反向代理(Reverse Proxy)是位于 客戶(hù)端與后端服務(wù)器之間 的中間設(shè)備(或服務(wù)),客戶(hù)端直接訪(fǎng)問(wèn)代理服務(wù)器,代理服務(wù)器再將請(qǐng)求轉(zhuǎn)發(fā)給內(nèi)部的后端服務(wù)器,并將后端服務(wù)器的響應(yīng)返回給客戶(hù)端。
反向代理的好處:
- 隱藏后端架構(gòu):客戶(hù)端只與代理服務(wù)器交互,后端服務(wù)的IP、端口、部署細(xì)節(jié)(如多臺(tái)服務(wù)器集群)對(duì)客戶(hù)端不可見(jiàn)。
- 負(fù)載均衡:將客戶(hù)端請(qǐng)求分發(fā)到多臺(tái)后端服務(wù)器,提升整體處理能力(后續(xù)章節(jié)會(huì)深入講解)。
- 安全防護(hù):代理服務(wù)器可過(guò)濾惡意請(qǐng)求(如SQL注入、XSS)、限制訪(fǎng)問(wèn)IP、提供SSL加密(HTTPS終止)。
- 統(tǒng)一入口:通過(guò)一個(gè)域名/端口(如 http://example.com)訪(fǎng)問(wèn)多個(gè)后端服務(wù)(如API、靜態(tài)資源、管理后臺(tái))。
環(huán)境準(zhǔn)備
準(zhǔn)備虛擬機(jī)
角色 | IP | 主機(jī)名 | 功能 |
nginx1 | 192.168.88.101 | nginx1.itcast.cn | 代理服務(wù)器 |
nginx2 | 192.168.88.102 | nginx2.itcast.cn | 后端服務(wù)器 |
修改主機(jī)名和 hosts
hostnamectl set-hostname nginx1.itcast.cn && bash hostnamectl set-hostname nginx2.itcast.cn && bash cat >/etc/hosts<<EOF 127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4 ::1 localhost localhost.localdomain localhost6 localhost6.localdomain6 192.168.88.101 nginx1 nginx1.itcast.cn 192.168.88.102 nginx2 nginx2.itcast.cn EOF
關(guān)閉防火墻與 SELinux
iptables -F systemctl stop firewalld systemctl disable firewalld setenforce 0 sed -i '/SELINUX=enforcing/cSELINUX=disabled' /etc/selinux/config
安裝依賴(lài)包以及時(shí)間同步
# 安裝依賴(lài)包
yum install vim wget rsync net-tools epel-release -y
# 更新安裝ntp時(shí)間服務(wù)器(可選)
yum install ntpsec -y
ntpdate cn.ntp.org.cn
說(shuō)明:
ntpsec?:是 NTP (Network Time Protocol) 的一個(gè)安全增強(qiáng)分支版本,用于系統(tǒng)時(shí)間同步;
cn.ntp.org.cn:是中國(guó)國(guó)家授時(shí)中心維護(hù)的 NTP 服務(wù)器地址
# 如果Linux服務(wù)器通不了外網(wǎng),可以考慮配置一下DNS解析地址
cat >/etc/resolv.conf<<EOF
nameserver 192.168.88.2
nameserver 114.114.114.114
EOF部署實(shí)戰(zhàn)
配置后端服務(wù)器
在后端服務(wù)器nginx2上執(zhí)行
dnf安裝的nginx
[root@nginx2 ~]# dnf install nginx -y
修改nginx服務(wù)運(yùn)行端口為8080
[root@nginx2 ~]# vim /etc/nginx/nginx.conf
...
server {
listen 8080;
listen [::]:8080;
server_name _;
root /usr/share/nginx/html;
# Load configuration files for the default server block.
include /etc/nginx/default.d/*.conf;
error_page 404 /404.html;
location = /404.html {
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
}
}
...
[root@nginx2 ~]# cat /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/
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;
# Load dynamic modules. See /usr/share/doc/nginx/README.dynamic.
include /usr/share/nginx/modules/*.conf;
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;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 4096;
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;
server {
listen 8080;
listen [::]:8080;
server_name _;
root /usr/share/nginx/html;
# Load configuration files for the default server block.
include /etc/nginx/default.d/*.conf;
error_page 404 /404.html;
location = /404.html {
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
}
}
# Settings for a TLS enabled server.
#
# server {
# listen 443 ssl http2;
# listen [::]:443 ssl http2;
# 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 PROFILE=SYSTEM;
# ssl_prefer_server_ciphers on;
#
# # Load configuration files for the default server block.
# include /etc/nginx/default.d/*.conf;
#
# error_page 404 /404.html;
# location = /40x.html {
# }
#
# error_page 500 502 503 504 /50x.html;
# location = /50x.html {
# }
# }
}
[root@nginx2 ~]# cat >/usr/share/nginx/html/index.html <<EOF
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>后端Web服務(wù)器</title>
</head>
<body>
這是后端Web服務(wù)器
</body>
</html>
EOF
[root@nginx2 ~]# cat /usr/share/nginx/html/index.html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>后端Web服務(wù)器</title>
</head>
<body>
這是后端Web服務(wù)器
</body>
</html>
[root@nginx2 ~]#
檢查nginx配置文件是否正確
[root@nginx2 ~]# nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
[root@nginx2 ~]# systemctl restart nginx
[root@nginx2 ~]# systemctl status nginx
● nginx.service - The nginx HTTP and reverse proxy server
Loaded: loaded (/usr/lib/systemd/system/nginx.service; disabled; preset: disabled)
Active: active (running) since Thu 2025-12-11 11:34:51 CST; 4s ago
Process: 29371 ExecStartPre=/usr/bin/rm -f /run/nginx.pid (code=exited, status=0/SUCCESS)
Process: 29373 ExecStartPre=/usr/sbin/nginx -t (code=exited, status=0/SUCCESS)
Process: 29374 ExecStart=/usr/sbin/nginx (code=exited, status=0/SUCCESS)
Main PID: 29375 (nginx)
Tasks: 3 (limit: 22927)
Memory: 3.0M
CPU: 25ms
CGroup: /system.slice/nginx.service
├─29375 "nginx: master process /usr/sbin/nginx"
├─29376 "nginx: worker process"
└─29377 "nginx: worker process"
Dec 11 11:34:51 nginx2.itcast.cn systemd[1]: Starting The nginx HTTP and reverse proxy server...
Dec 11 11:34:51 nginx2.itcast.cn nginx[29373]: nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
Dec 11 11:34:51 nginx2.itcast.cn nginx[29373]: nginx: configuration file /etc/nginx/nginx.conf test is successful
Dec 11 11:34:51 nginx2.itcast.cn systemd[1]: Started The nginx HTTP and reverse proxy server.
[root@nginx2 ~]# systemctl enable nginx
Created symlink /etc/systemd/system/multi-user.target.wants/nginx.service → /usr/lib/systemd/system/nginx.service.
[root@nginx2 ~]# netstat -pantul|grep nginx
tcp 0 0 0.0.0.0:8080 0.0.0.0:* LISTEN 30551/nginx: master
tcp6 0 0 :::8080 :::* LISTEN 30551/nginx: master
[root@nginx2 ~]#源碼安裝的nginx
[root@nginx2 ~]# ls /usr/local/nginx/
client_body_temp fastcgi_temp logs sbin uwsgi_temp
conf html proxy_temp scgi_temp
[root@nginx2 ~]# ls /usr/local/nginx/conf/
fastcgi.conf mime.types scgi_params.default
fastcgi.conf.default mime.types.default uwsgi_params
fastcgi_params nginx.conf uwsgi_params.default
fastcgi_params.default nginx.conf.bak win-utf
koi-utf nginx.conf.default
koi-win scgi_params
[root@nginx2 ~]# vim /usr/local/nginx/conf/nginx.conf
[root@nginx2 ~]# cat /usr/local/nginx/conf/nginx.conf
worker_processes 1;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
server {
listen 8080;
server_name 192.168.88.102;
root /usr/local/nginx/html;
location / {
root html;
index index.html index.htm;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
}
[root@nginx2 ~]# nginx -t
nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful
[root@nginx2 ~]# nginx -s reload
[root@nginx2 ~]# cat >/usr/local/nginx/html/index.html <<EOF
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>后端Web服務(wù)器</title>
</head>
<body>
這是后端Web服務(wù)器
</body>
</html>
EOF
[root@nginx2 ~]# cat /usr/local/nginx/html/index.html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>后端Web服務(wù)器</title>
</head>
<body>
這是后端Web服務(wù)器
</body>
</html>
[root@nginx2 ~]# systemctl restart nginx
[root@nginx2 ~]# systemctl status nginx
● nginx.service - Nginx Web Server
Loaded: loaded (/usr/lib/systemd/system/nginx.service; enabled; preset: d>
Active: active (running) since Tue 2026-03-24 09:40:53 CST; 5s ago
Process: 4706 ExecStartPre=/usr/bin/rm -f /run/nginx.pid (code=exited, sta>
Process: 4708 ExecStart=/usr/local/nginx/sbin/nginx -c /usr/local/nginx/co>
Main PID: 4709 (nginx)
Tasks: 2 (limit: 22927)
Memory: 2.1M
CPU: 17ms
CGroup: /system.slice/nginx.service
├─4709 "nginx: master process /usr/local/nginx/sbin/nginx -c /usr>
└─4710 "nginx: worker process"
Mar 24 09:40:53 nginx2.itcast.cn systemd[1]: Starting Nginx Web Server...
Mar 24 09:40:53 nginx2.itcast.cn systemd[1]: Started Nginx Web Server.
[root@nginx2 ~]# netstat -pantul|grep nginx
tcp 0 0 0.0.0.0:8080 0.0.0.0:* LISTEN 4709/nginx: master
[root@nginx2 ~]#測(cè)試后端服務(wù)器的Web服務(wù)
[root@nginx2 ~]# curl 192.168.88.102:8080
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>后端Web服務(wù)器</title>
</head>
<body>
這是后端Web服務(wù)器
</body>
</html>
[root@nginx2 ~]#http://192.168.88.102:8080/
配置代理服務(wù)器
在前端服務(wù)器nginx1上執(zhí)行
dnf安裝的nginx
[root@nginx1 ~]# dnf install nginx -y
修改nginx1配置文件,對(duì)接nginx2
[root@nginx1 ~]# find / -name nginx.conf
/etc/nginx/nginx.conf
/usr/lib/sysusers.d/nginx.conf
[root@nginx1 ~]# vim /etc/nginx/nginx.conf
user nginx;
worker_processes auto;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
server {
listen 80;
server_name _;
# root /usr/share/nginx/html;
location / {
proxy_pass http://192.168.88.102:8080; # 關(guān)鍵!指定后端服務(wù)器的IP和端口
proxy_set_header Host $host; # 傳遞原始請(qǐng)求的Host頭(重要!)
proxy_set_header X-Real-IP $remote_addr; # 傳遞客戶(hù)端真實(shí)IP(后端可通過(guò)此頭獲?。?
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; # 傳遞完整的代理鏈路IP
}
# Load configuration files for the default server block.
include /etc/nginx/default.d/*.conf;
error_page 500 502 503 504 /50x.html;
location = /50x.html {
# root html;
}
}
}
[root@nginx1 ~]# cat /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/
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;
# Load dynamic modules. See /usr/share/doc/nginx/README.dynamic.
include /usr/share/nginx/modules/*.conf;
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;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 4096;
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;
server {
listen 80;
listen [::]:80;
server_name _;
# root /usr/share/nginx/html;
location / {
proxy_pass http://192.168.88.102:8080; # 關(guān)鍵!指定后端服務(wù)器的IP和端口
proxy_set_header Host $host; # 傳遞原始請(qǐng)求的Host頭(重要?。?
proxy_set_header X-Real-IP $remote_addr; # 傳遞客戶(hù)端真實(shí)IP(后端可通過(guò)此頭獲取)
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; # 傳遞完整的代理鏈路IP
}
# Load configuration files for the default server block.
include /etc/nginx/default.d/*.conf;
error_page 404 /404.html;
location = /404.html {
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
}
}
# Settings for a TLS enabled server.
#
# server {
# listen 443 ssl http2;
# listen [::]:443 ssl http2;
# 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 PROFILE=SYSTEM;
# ssl_prefer_server_ciphers on;
#
# # Load configuration files for the default server block.
# include /etc/nginx/default.d/*.conf;
#
# error_page 404 /404.html;
# location = /40x.html {
# }
#
# error_page 500 502 503 504 /50x.html;
# location = /50x.html {
# }
# }
}
[root@nginx1 ~]#源碼安裝的nginx
[root@nginx1 ~]# vim /usr/local/nginx/conf/nginx.conf
[root@nginx1 ~]# cat /usr/local/nginx/conf/nginx.conf
worker_processes 1;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
server {
listen 80;
server_name _;
# root /usr/local/nginx/html;
location / {
proxy_pass http://192.168.88.102:8080; # 關(guān)鍵!指定后端服務(wù)器的IP和端口
proxy_set_header Host $host; # 傳遞原始請(qǐng)求的Host頭(重要?。?
proxy_set_header X-Real-IP $remote_addr; # 傳遞客戶(hù)端真實(shí)IP(后端可通過(guò)此頭獲?。?
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; # 傳遞完整的代理鏈路IP
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
}
[root@nginx1 ~]# nginx -t
nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful
[root@nginx1 ~]# nginx -s reload
[root@nginx1 ~]#檢查Nginx配置文件并啟動(dòng)Nginx服務(wù)
[root@nginx1 ~]# nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
[root@nginx1 ~]# systemctl restart nginx
[root@nginx1 ~]# systemctl enable nginx
Created symlink /etc/systemd/system/multi-user.target.wants/nginx.service → /usr/lib/systemd/system/nginx.service.
[root@nginx1 ~]# systemctl status nginx
● nginx.service - The nginx HTTP and reverse proxy server
Loaded: loaded (/usr/lib/systemd/system/nginx.service; enabled; preset: d>
Active: active (running) since Sat 2025-12-13 12:07:24 CST; 7s ago
Main PID: 30749 (nginx)
Tasks: 3 (limit: 22926)
Memory: 3.0M
CPU: 37ms
CGroup: /system.slice/nginx.service
├─30749 "nginx: master process /usr/sbin/nginx"
├─30750 "nginx: worker process"
└─30751 "nginx: worker process"
Dec 13 12:07:24 nginx1.itcast.cn systemd[1]: Starting The nginx HTTP and rever>
Dec 13 12:07:24 nginx1.itcast.cn nginx[30747]: nginx: the configuration file />
Dec 13 12:07:24 nginx1.itcast.cn nginx[30747]: nginx: configuration file /etc/>
Dec 13 12:07:24 nginx1.itcast.cn systemd[1]: Started The nginx HTTP and revers>
# nginx -s reload # 可選驗(yàn)證測(cè)試
http://192.168.88.101/
http://192.168.88.102:8080/
Nginx代理服務(wù)器暴力broken測(cè)試
server {
listen 80;
server_name _;
location / {
return 500 "broken\n";
}
}[root@nginx1 ~]# cd /etc/nginx
[root@nginx1 nginx]# pwd
/etc/nginx
[root@nginx1 nginx]# vim nginx.conf
[root@nginx1 nginx]# cat nginx.conf
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;
include /usr/share/nginx/modules/*.conf;
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;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 4096;
include /etc/nginx/mime.types;
default_type application/octet-stream;
#include /etc/nginx/conf.d/*.conf;
server {
listen 80;
server_name _;
location / {
return 500 "broken\n";
}
#root /usr/share/nginx/html;
# location / {
# proxy_pass http://192.168.88.102:8080; # 關(guān)鍵!指定后端服務(wù)器的IP和端口
# proxy_set_header Host $host; # 傳遞原始請(qǐng)求的Host頭(重要?。?
# proxy_set_header X-Real-IP $remote_addr; # 傳遞客戶(hù)端真實(shí)IP(后端可通過(guò)此頭獲取)
# proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; # 傳遞完整的代理鏈路IP
# }
#include /etc/nginx/default.d/*.conf;
error_page 404 /404.html;
location = /404.html {
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
}
}
}
[root@nginx1 nginx]# nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
[root@nginx1 nginx]# nginx -s reload
[root@nginx1 nginx]# curl 127.0.0.1
broken
[root@nginx1 nginx]#http://192.168.88.101/
結(jié)論1:
Nginx 在沒(méi)有配置
location和root時(shí),會(huì)使用默認(rèn) root/usr/share/nginx/html提供靜態(tài)資源。
結(jié)論2:
只要定義了
location /,就會(huì)覆蓋默認(rèn)行為。
結(jié)論3:
return指令優(yōu)先級(jí)非常高,可以直接終止請(qǐng)求處理流程。
Nginx 的配置是具備兜底機(jī)制的,即使沒(méi)有顯式配置 root 和 location,也會(huì)使用默認(rèn) root 提供服務(wù)。因此在排查問(wèn)題時(shí),如果發(fā)現(xiàn)配置改了但結(jié)果沒(méi)變,要考慮是否命中了默認(rèn)行為或者其他 location。
HTTP/1.0與HTTP/1.1
HTTP/1.1 和 HTTP/1.0 是 Web 協(xié)議演進(jìn)中的兩個(gè)重要版本,主要區(qū)別如下:
主要區(qū)別對(duì)比表
| 特性 | HTTP/1.0 | HTTP/1.1 |
| 連接方式 | 默認(rèn)短連接,每個(gè)請(qǐng)求建立新TCP連接 | 默認(rèn)長(zhǎng)連接(Keep-Alive),連接可復(fù)用 |
| Host頭 | 可選,不支持虛擬主機(jī) | 必需,支持多域名共享IP |
| 緩存控制 | 簡(jiǎn)單的 Expires、Pragma | 強(qiáng)大的 Cache-Control、ETag、Last-Modified |
| 狀態(tài)碼 | 基本狀態(tài)碼 | 新增 100 Continue, 206 Partial Content 等 |
| 分塊傳輸 | 不支持 | 支持 Transfer-Encoding: chunked |
| 管道化 | 不支持 | 支持(但有限制) |
| 帶寬優(yōu)化 | 不支持范圍請(qǐng)求 | 支持 Range 和 Accept-Ranges |
| 錯(cuò)誤處理 | 簡(jiǎn)單 | 更完善的錯(cuò)誤處理和恢復(fù)機(jī)制 |
| 請(qǐng)求方法 | GET, POST, HEAD | 新增 OPTIONS, PUT, DELETE, TRACE, CONNECT |
[root@nginx1 ~]# vim /etc/nginx/nginx.conf
[root@nginx1 ~]# cat /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/
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;
# Load dynamic modules. See /usr/share/doc/nginx/README.dynamic.
include /usr/share/nginx/modules/*.conf;
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;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 4096;
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;
server {
listen 80;
listen [::]:80;
server_name _;
# root /usr/share/nginx/html;
location / {
proxy_http_version 1.1;
proxy_pass http://192.168.88.102:8080; # 關(guān)鍵!指定后端服務(wù)器的IP和端口
proxy_set_header Host $host; # 傳遞原始請(qǐng)求的Host頭(重要?。?
proxy_set_header X-Real-IP $remote_addr; # 傳遞客戶(hù)端真實(shí)IP(后端可通過(guò)此頭獲取)
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; # 傳遞完整的代理鏈路IP
proxy_set_header X-Original-Protocol $server_protocol;
}
# Load configuration files for the default server block.
include /etc/nginx/default.d/*.conf;
error_page 404 /404.html;
location = /404.html {
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
}
}
# Settings for a TLS enabled server.
#
# server {
# listen 443 ssl http2;
# listen [::]:443 ssl http2;
# 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 PROFILE=SYSTEM;
# ssl_prefer_server_ciphers on;
#
# # Load configuration files for the default server block.
# include /etc/nginx/default.d/*.conf;
#
# error_page 404 /404.html;
# location = /40x.html {
# }
#
# error_page 500 502 503 504 /50x.html;
# location = /50x.html {
# }
# }
}
[root@nginx1 ~]#
[root@nginx1 ~]# nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
[root@nginx1 ~]# nginx -s reload訪(fǎng)問(wèn)代理服務(wù)器地址
http://192.168.88.101/
總結(jié)
代理一共有兩種:(正向代理) + (反向代理)
1、正向代理用戶(hù)可以感知到,比較典型應(yīng)用(科學(xué)上網(wǎng))
2、反向代理用戶(hù)無(wú)感知,比較典型的應(yīng)用(請(qǐng)求轉(zhuǎn)發(fā),更多應(yīng)用在于負(fù)載均衡技術(shù))
Nginx 負(fù)載均衡
四層負(fù)載 vs 七層負(fù)載
① 底層實(shí)現(xiàn) => 四層負(fù)載均衡基于網(wǎng)絡(luò)層與傳輸層,也就是IP + Port(套接字 socket)實(shí)現(xiàn)請(qǐng)求轉(zhuǎn)發(fā);七層負(fù)載基于應(yīng)用層,通過(guò)URL地址請(qǐng)求轉(zhuǎn)發(fā)
② 性能不同 => 四層相當(dāng)于轉(zhuǎn)發(fā)器,效率更高;七層需要通過(guò)URL判斷才能實(shí)現(xiàn)轉(zhuǎn)發(fā),需要做額外的處理
③ 安全性不同 => 七層需要對(duì)用戶(hù)URL請(qǐng)求,判斷可以屏蔽異常請(qǐng)求,相對(duì)而言更加安全
環(huán)境準(zhǔn)備
角色 | IP | 主機(jī)名 | 功能 |
lb1 | 192.168.88.100 | lb1.itcast.cn | 負(fù)載均衡 |
web1 | 192.168.88.101 | web1.itcast.cn | Web服務(wù) |
web2 | 192.168.88.102 | web2.itcast.cn | Web服務(wù) |
修改IP、主機(jī)名和域名解析
hostnamectl set-hostname lb1.itcast.cn && bash hostnamectl set-hostname web1.itcast.cn && bash hostnamectl set-hostname web2.itcast.cn && bash cat >/etc/hosts<<EOF 127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4 ::1 localhost localhost.localdomain localhost6 localhost6.localdomain6 192.168.88.100 lb1 lb1.itcast.cn 192.168.88.101 web1 web1.itcast.cn 192.168.88.102 web2 web2.itcast.cn EOF
關(guān)閉防火墻與 SELinux
iptables -F systemctl stop firewalld systemctl disable firewalld setenforce 0 sed -i '/SELINUX=enforcing/cSELINUX=disabled' /etc/selinux/config
安裝依賴(lài)包時(shí)間同步
yum install vim wget rsync net-tools epel-release -y yum install ntpsec -y ntpdate cn.ntp.org.cn cat >/etc/resolv.conf<<EOF nameserver 192.168.88.2 nameserver 114.114.114.114 EOF
NTPsec vs Chrony
| 特性 | NTPsec | Chrony |
| 起源 | 從經(jīng)典 NTP(ntpd)分支而來(lái),由 NTPsec 團(tuán)隊(duì)維護(hù) | 獨(dú)立開(kāi)發(fā),最初為嵌入式系統(tǒng)設(shè)計(jì) |
| 設(shè)計(jì)目標(biāo) | 增強(qiáng)安全性和性能,修復(fù) ntpd 的歷史問(wèn)題 | 快速同步、低延遲,適合不穩(wěn)定網(wǎng)絡(luò)環(huán)境 |
| 社區(qū)活躍度 | 活躍,但用戶(hù)基數(shù)小于 Chrony | 廣泛采用,尤其在云環(huán)境和現(xiàn)代 Linux 發(fā)行版 |
安裝nginx
三個(gè)服務(wù)器都要按照nginx
如果網(wǎng)絡(luò)有問(wèn)題,請(qǐng)執(zhí)行以下命令
cat >/etc/resolv.conf<<EOF nameserver 192.168.88.2 nameserver 114.114.114.114 EOF
systemctl status nginx --no-pager
配置 Web1 & Web2
這節(jié)課我們聚焦 Nginx 負(fù)載均衡,關(guān)于 backend 服務(wù),用 html 簡(jiǎn)單內(nèi)容代替。
# 在LB1上執(zhí)行,統(tǒng)一 一下三臺(tái)的nginx配置文件(可選) scp /etc/nginx/nginx.conf 192.168.88.101:/etc/nginx/ scp /etc/nginx/nginx.conf 192.168.88.102:/etc/nginx/ # 在 Web1 上執(zhí)行 echo "This is Web Server1" > /usr/share/nginx/html/index.html 或者 echo "This is Web Server1" > /usr/local/nginx/html/index.html # 在 Web2 上執(zhí)行 echo "This is Web Server2" > /usr/share/nginx/html/index.html 或者 echo "This is Web Server2" > /usr/local/nginx/html/index.html
驗(yàn)證測(cè)試
curl 127.0.0.1
配置 LB1
下面的操作,都是在 LB1 上操作
第一步:查看 nginx.cnf
在 LB1 上,備份配置文件nginx.conf,然后刪除注釋與空行
第一步,備份
[root@lb1 ~]# cp /etc/nginx/nginx.conf /etc/nginx/nginx.conf.bak # 這是 dnf/yum 安裝的 Nginx
第二步,去掉注釋?zhuān)招?
[root@lb1 ~]# grep -Ev '#|^$' /etc/nginx/nginx.conf.bak > /etc/nginx/nginx.conf
第三步,簡(jiǎn)單查看配置
[root@lb1 ~]# cat /etc/nginx/nginx.conf
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;
include /usr/share/nginx/modules/*.conf;
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;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 4096;
include /etc/nginx/mime.types;
default_type application/octet-stream;
include /etc/nginx/conf.d/*.conf;
server {
listen 80;
listen [::]:80;
server_name _;
root /usr/share/nginx/html;
include /etc/nginx/default.d/*.conf;
error_page 404 /404.html;
location = /404.html {
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
}
}
}
[root@lb1 ~]#第二步:配置負(fù)載均衡
Nginx 在 http 塊中實(shí)現(xiàn)七層負(fù)載均衡,默認(rèn)使用輪詢(xún)算法;同時(shí)也支持通過(guò) stream 塊實(shí)現(xiàn)四層負(fù)載均衡
在 LB1 上操作
vim /etc/nginx/nginx.conf
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;
include /usr/share/nginx/modules/*.conf;
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;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 4096;
include /etc/nginx/mime.types;
default_type application/octet-stream;
# include /etc/nginx/conf.d/*.conf;
#################### 配置開(kāi)始 ######################
upstream my_web_service {
server 192.168.88.101:80;
server 192.168.88.102:80;
}
#################### 配置結(jié)束 ######################
server {
listen 80;
listen [::]:80;
#################### 配置開(kāi)始 ######################
server_name 192.168.88.100; # 替換為實(shí)際域名或 IP
location / {
proxy_pass http://my_web_service; # 將請(qǐng)求轉(zhuǎn)發(fā)到負(fù)載均衡組
proxy_set_header HOST $host;
}
#################### 配置結(jié)束 ######################
# server_name _;
# root /usr/share/nginx/html;
# include /etc/nginx/default.d/*.conf;
error_page 404 /404.html;
location = /404.html {
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
}
}
}第三步:重載配置,驗(yàn)證測(cè)試第三步:重載配置,驗(yàn)證測(cè)試
在 LB1 上操作
nginx -t nginx -s reload [root@lb1 ~]# curl 192.168.88.100 This is Web Server1 [root@lb1 ~]# curl 192.168.88.100 This is Web Server2 [root@lb1 ~]# curl 192.168.88.100 This is Web Server1 [root@lb1 ~]# curl 192.168.88.100 This is Web Server2
注意:如果無(wú)法訪(fǎng)問(wèn)Nginx Web服務(wù),請(qǐng)?jiān)谒蠰inux服務(wù)器上執(zhí)行以下命令!
sed -i -r 's/SELINUX=[ep].*/SELINUX=disabled/g' /etc/selinux/config setenforce 0 systemctl stop firewalld &> /dev/null systemctl disable firewalld &> /dev/null iptables -F iptables -t nat -F iptables -P INPUT ACCEPT iptables -P FORWARD ACCEPT
回到瀏覽器,多次訪(fǎng)問(wèn),會(huì)發(fā)現(xiàn)
頁(yè)面在 Web1 和 Web2 之間來(lái)回切換(這是為了方便驗(yàn)證而設(shè)計(jì)的內(nèi)容),從而驗(yàn)證負(fù)載均衡配置成功。
炫酷技能(拓展)
旋轉(zhuǎn)星空
cat >index.html<<EOF
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
<HEAD>
<TITLE> New Document </TITLE>
<META NAME="Generator" CONTENT="EditPlus">
<META NAME="Author" CONTENT="">
<META NAME="Keywords" CONTENT="">
<META NAME="Description" CONTENT="">
<style>
body {
background: #060e1b;
overflow: hidden;
}
</style>
</HEAD>
<BODY>
<canvas id="canvas"></canvas>
<script>
"use strict";
var canvas = document.getElementById('canvas'),
ctx = canvas.getContext('2d'),
w = canvas.width = window.innerWidth,
h = canvas.height = window.innerHeight,
hue = 217,
stars = [],
count = 0,
maxStars = 1400;
// Thanks @jackrugile for the performance tip! https://codepen.io/jackrugile/pen/BjBGoM
// Cache gradient
var canvas2 = document.createElement('canvas'),
ctx2 = canvas2.getContext('2d');
canvas2.width = 100;
canvas2.height = 100;
var half = canvas2.width/2,
gradient2 = ctx2.createRadialGradient(half, half, 0, half, half, half);
gradient2.addColorStop(0.025, '#fff');
gradient2.addColorStop(0.1, 'hsl(' + hue + ', 61%, 33%)');
gradient2.addColorStop(0.25, 'hsl(' + hue + ', 64%, 6%)');
gradient2.addColorStop(1, 'transparent');
ctx2.fillStyle = gradient2;
ctx2.beginPath();
ctx2.arc(half, half, half, 0, Math.PI * 2);
ctx2.fill();
// End cache
function random(min, max) {
if (arguments.length < 2) {
max = min;
min = 0;
}
if (min > max) {
var hold = max;
max = min;
min = hold;
}
return Math.floor(Math.random() * (max - min + 1)) + min;
}
function maxOrbit(x,y) {
var max = Math.max(x,y),
diameter = Math.round(Math.sqrt(max*max + max*max));
return diameter/2;
}
var Star = function() {
this.orbitRadius = random(maxOrbit(w,h));
this.radius = random(60, this.orbitRadius) / 12;
this.orbitX = w / 2;
this.orbitY = h / 2;
this.timePassed = random(0, maxStars);
this.speed = random(this.orbitRadius) / 50000;
this.alpha = random(2, 10) / 10;
count++;
stars[count] = this;
}
Star.prototype.draw = function() {
var x = Math.sin(this.timePassed) * this.orbitRadius + this.orbitX,
y = Math.cos(this.timePassed) * this.orbitRadius + this.orbitY,
twinkle = random(10);
if (twinkle === 1 && this.alpha > 0) {
this.alpha -= 0.05;
} else if (twinkle === 2 && this.alpha < 1) {
this.alpha += 0.05;
}
ctx.globalAlpha = this.alpha;
ctx.drawImage(canvas2, x - this.radius / 2, y - this.radius / 2, this.radius, this.radius);
this.timePassed += this.speed;
}
for (var i = 0; i < maxStars; i++) {
new Star();
}
function animation() {
ctx.globalCompositeOperation = 'source-over';
ctx.globalAlpha = 0.8;
ctx.fillStyle = 'hsla(' + hue + ', 64%, 6%, 1)';
ctx.fillRect(0, 0, w, h)
ctx.globalCompositeOperation = 'lighter';
for (var i = 1, l = stars.length; i < l; i++) {
stars[i].draw();
};
window.requestAnimationFrame(animation);
}
animation();
</script>
</BODY>
</HTML>
EOF
黑客數(shù)字雨
cat >index.html<<EOF
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
<HEAD>
<TITLE> New Document </TITLE>
<META NAME="Generator" CONTENT="EditPlus">
<META NAME="Author" CONTENT="">
<META NAME="Keywords" CONTENT="">
<META NAME="Description" CONTENT="">
<style>
/*Twitter @locoalien*/
/*Sitio web www.locoaliensoft.com*/
/*www.facebook.com/CulturaInformatica*/
* {margin: 0; padding: 0;}
canvas {display: block;}
body {background: black;}
</style>
</HEAD>
<BODY>
<html>
<head>
<title>Hacking locoalien Matrix console</title>
<meta charset="UTF-8">
</head>
<body>
<canvas id="locoalien"></canvas>
<script type="text/javascript">
</script>
</body>
</html>
<script>
//*--------------------------------------*
//* Desarrollado por Locoalien *
//* Twitter @locoalien *
//* Sitio web: www.locoaliensoft.com *
//*--------------------------------------*
//+++++++++++++++++++++++++++++++++++++
// El objetivo de este ejemplo es aprender a dar animacion y utilizar las propiedades
// Mas comunes de JavaScript. Veremos el poder que tiene HTML5 implementando el Canvas
// Espero les guste este ejemplo
// Para mas informacion visitar nuestra pagina de Facebook: https://www.facebook.com/CulturaInformatica
//+++++++++++++++++++++++++++++++++++++
window.onload = hacking;//Llamamos a la funcion despues de que el documento ha sido cargado completamente
function hacking(){
var c = document.getElementById("locoalien");
c.height = window.innerHeight; //innerHeight se utiliza para saber la altura de la pantalla
c.width = window.innerWidth; //innerHeight se utiliza para saber la altura de la pantalla
var letraTam=12; //Tama?o de la letras por pixel
var columnas=c.width/letraTam; //El ancho dividido por el tamano que tendra las letras
var Texto="0"; //El testo que aparecera en pantalla
Texto=Texto.split("");//La función split() permite dividir una cadena de caracteres (string) en varios bloques y crear un array con estos
var Texto2="1";
Texto2=Texto2.split("");
var letras=[];
for(var i=0; i<columnas;i++){
letras[i]=1;//Siver para saber la cantidad de letras que tendra en la pantalla
}
contexto= c.getContext('2d');//Muy importante especificar el contexto en el cual vamos a trabajar
function dibujar(){
contexto.fillStyle="rgba(0,0,0,0.05)";//Damos el color que tendra el recuadro en el que estara la animacion. en este caso sera transparente 0.05
contexto.fillRect(0,0,c.width,c.height);//Damos las dimensiones alto y ancho que tendra el cuadrado, que en este caso es de toda la pantalla
contexto.fillStyle= "#0f0";//Color de las letras
contexto.font= letraTam+"px arial";//Tama?o de la letra
for(var i=0;i<letras.length;i++){
text=Texto; //Le asigno el texto que definimos en la parte de arriba
//El ciclo for me permite darle las coordenadas correctas para posicionar el text x, y
text2=Texto2;//El texto dos que mostrara solo el 1
if(i%2==1){contexto.fillText(text,i*letraTam, letras[i]*letraTam);//Para imprimir texto disponesmos de fillText(texto,x,y)
}else{
contexto.fillText(text2,i*letraTam, letras[i]*letraTam);//Para imprimir texto disponesmos de fillText(texto,x,y)
}
if(letras[i]*letraTam > c.height && Math.random()>0.975){
letras[i]=0;
}
letras[i]++;
}
}
setInterval(dibujar,120);//velocidad a la que se ejecuta la funcion en milisegundos
}
</script>
</BODY>
</HTML>
EOF
擴(kuò)展: 解決無(wú)法顯示真實(shí)IP的問(wèn)題
我們觀察 Web1 和 Web2 的 access日志,會(huì)發(fā)現(xiàn)
# 在 Web1 和 Web2 上分別執(zhí)行 tail /var/log/nginx/access.log

為了解決 Web1/Web2 訪(fǎng)問(wèn)日志的顯示問(wèn)題(無(wú)法獲取客戶(hù)端真實(shí)的IP地址)
回到 LB1 服務(wù)器上,找到配置文件
vi /etc/nginx/nginx.conf
worker_processes 1;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
#################### 配置開(kāi)始 ######################
upstream my_web_service {
server 192.168.88.101:80;
server 192.168.88.102:80;
}
#################### 配置結(jié)束 ######################
server {
listen 80;
listen [::]:80;
#################### 配置開(kāi)始 ######################
server_name 192.168.88.100; # 替換為實(shí)際域名或 IP
location / {
proxy_pass http://my_web_service; # 將請(qǐng)求轉(zhuǎn)發(fā)到負(fù)載均衡組
proxy_set_header HOST $host;
proxy_set_header X-Real-IP $remote_addr; # 添加這兩行
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
#################### 配置結(jié)束 ######################
server_name _;
root /usr/share/nginx/html;
include /etc/nginx/default.d/*.conf;
error_page 404 /404.html;
location = /404.html {
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
}
}
}/usr/sbin/nginx -s reload
Nginx 變量:
$remote_addr:Nginx 變量,表示直接連接到當(dāng)前服務(wù)器的客戶(hù)端 IP。
X-Real-IP:記錄原始客戶(hù)端 IP,適用于單級(jí)代理場(chǎng)景。
X-Forwarded-For:記錄完整代理鏈,適用于多級(jí)代理和日志分析。
最佳實(shí)踐:兩者同時(shí)設(shè)置,兼顧簡(jiǎn)單性和可追溯性。
在Web01和Web02服務(wù)器上,打開(kāi)配置文件(默認(rèn)就是配置好的),定制日志顯示格式
在Web01和Web02服務(wù)器上
# vi /etc/nginx/nginx.conf
...
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 logs/access.log main;
...
}
在Web01和Web02服務(wù)器上,分別重啟
# /usr/sbin/nginx -s reload在 Web1 上和web2 上,都驗(yàn)證測(cè)試
tail -3 /var/log/nginx/access.log
驗(yàn)證宿主機(jī) IP
# 在宿主機(jī)(筆記本 Windows 電腦)上,執(zhí)行 ipconfig
分發(fā)請(qǐng)求關(guān)鍵字
backup關(guān)鍵字:其他的沒(méi)有backup標(biāo)識(shí)的服務(wù)器都無(wú)響應(yīng),才分發(fā)到backup服務(wù)器。
# vim conf/nginx.conf
http {
...
upstream my_web_service {
server 192.168.88.101:80 backup; # 優(yōu)先訪(fǎng)問(wèn)其他的服務(wù)器
server 192.168.88.103:80;
}
...
}down關(guān)鍵字:任何時(shí)候,請(qǐng)求都不分發(fā)給配置了down關(guān)鍵字的服務(wù)器
# vim conf/nginx.conf
http {
...
upstream my_web_service {
server 192.168.88.101:80;
server 192.168.88.103:80 down; # 下線(xiàn)了
}
...
}用的最多的還是backup,關(guān)鍵時(shí)刻起到熱備作用!
負(fù)載均衡的3種調(diào)度算法(請(qǐng)求規(guī)則)
Nginx 官方默認(rèn)3種負(fù)載均衡的算法:
① Round-Robin RR輪詢(xún)(默認(rèn)): 一次一個(gè)的來(lái)(理論上的,實(shí)際實(shí)驗(yàn)可能會(huì)有間隔)
② Weight 權(quán)重: 權(quán)重高多分發(fā)一些,服務(wù)器硬件更好的設(shè)置權(quán)重更高一些
比如,當(dāng)我們?cè)O(shè)置成 1:9,會(huì)發(fā)現(xiàn)大部分情況,都是訪(fǎng)問(wèn)的 Web2
# vim conf/nginx.conf
http {
...
upstream my_web_service {
server 192.168.88.101:80 weight=4;
server 192.168.88.103:80 weight=6;
}
...
}③ IP_HASH:代表把同一個(gè)IP來(lái)源的請(qǐng)求分到到同一個(gè)后端服務(wù)器
# vim conf/nginx.conf
http {
...
upstream my_web_service {
ip_hash; # 加上這個(gè) IP Hash 就可以
server 192.168.88.101:80;
server 192.168.88.103:80;
}
...
}小結(jié):
Round-Robin:rr輪詢(xún)算法,請(qǐng)求均分
weight:weight=8
ip_hash:淘寶、京東 => 同一個(gè)IP所有請(qǐng)求都由同一個(gè)服務(wù)器處理
Session共享解決方案(調(diào)度算法)
① http協(xié)議,http協(xié)議是一個(gè)無(wú)狀態(tài)協(xié)議,無(wú)法記錄用戶(hù)的瀏覽軌跡。
② cookie技術(shù),可以把用戶(hù)的信息記錄在瀏覽器的緩存中(緩存存在過(guò)期時(shí)間)
③ session技術(shù),可以把用戶(hù)的瀏覽軌跡保存在服務(wù)器端(默認(rèn)為/tmp目錄)
驗(yàn)證碼也是Session文件,其產(chǎn)生的驗(yàn)證碼會(huì)保存在這個(gè)文件中。
模擬負(fù)載均衡與Session共享問(wèn)題:
第一步:配置負(fù)載均衡(默認(rèn)算法使用輪詢(xún)算法)
第二步:使用賬號(hào)密碼登錄功能,登錄后臺(tái)管理界面(admin,123456)
我們發(fā)現(xiàn)了一個(gè)問(wèn)題,無(wú)論我們這么輸入這個(gè)驗(yàn)證碼,始終提示驗(yàn)證失敗,主要原因:由于使用輪詢(xún)算法,所以生成驗(yàn)證碼時(shí),相當(dāng)于一次請(qǐng)求,驗(yàn)證驗(yàn)證碼時(shí)也是一次請(qǐng)求。兩次請(qǐng)求所在的服務(wù)器不同,所以最終驗(yàn)證總是失敗。
解決辦法:想辦法讓同一個(gè)IP的請(qǐng)求,分發(fā)到同一個(gè)Web服務(wù)器。
第三步:使用IP_HASH算法,問(wèn)題解決
# vim conf/nginx.conf
http {
...
upstream my_web_service { # 加上這個(gè) IP Hash 就可以
ip_hash;
server 192.168.88.101:80;
server 192.168.88.103:80;
}
...
}注:其實(shí)Session共享的解決方案,非常多,不僅僅只有IP_HASH一種算法,還可以基于MySQL或Redis實(shí)現(xiàn)Session共享
到此這篇關(guān)于詳解Nginx負(fù)載均衡/反向代理/日志分析的文章就介紹到這了,更多相關(guān)nginx負(fù)載均衡、反向代理內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- Nginx 反向代理與負(fù)載均衡運(yùn)行小結(jié)
- Nginx實(shí)現(xiàn)負(fù)載均衡和反向代理的方法
- Nginx中反向代理+負(fù)載均衡+服務(wù)器宕機(jī)解決辦法詳解
- nginx反向代理服務(wù)器及負(fù)載均衡服務(wù)配置方法
- Nginx+Tomcat反向代理與負(fù)載均衡的實(shí)現(xiàn)
- nginx?反向代理負(fù)載均衡策略配置SSL訪(fǎng)問(wèn)匹配規(guī)則優(yōu)先級(jí)
- Nginx反向代理與負(fù)載均衡概念理解及模塊使用
- springboot整合Nginx實(shí)現(xiàn)負(fù)載均衡反向代理的方法詳解
相關(guān)文章
nginx請(qǐng)求時(shí)找路徑問(wèn)題解決
當(dāng)你安裝了nginx的時(shí)候,為nginx配置了如下的location,想要去訪(fǎng)問(wèn)路徑下面的內(nèi)容,可是總是出現(xiàn)404,找不到文件,這是什么原因呢,今天我們就來(lái)解決這個(gè)問(wèn)題,感興趣的朋友一起看看吧2023-10-10
Nginx中反向代理+負(fù)載均衡+服務(wù)器宕機(jī)解決辦法詳解
這篇文章主要介紹了Nginx中反向代理+負(fù)載均衡+服務(wù)器宕機(jī)解決辦法詳解,反向代理保證系統(tǒng)安全,不暴露服務(wù)器IP,利用nginx服務(wù)器,利用內(nèi)網(wǎng)ip進(jìn)行訪(fǎng)問(wèn),避免出現(xiàn)攻擊服務(wù)器的情況,需要的朋友可以參考下2024-01-01
HipChat上傳文件報(bào)未知錯(cuò)誤的原因分析及解決方案
HipChat的功能類(lèi)似于Campfire、Sazneo等在線(xiàn)協(xié)同工具,并且和Yammer以及Salesforce的Chatter等企業(yè)社交平臺(tái)有一定相似之處。你可以為單個(gè)項(xiàng)目或者小組搭建自有的聊天室,也可以很方便的發(fā)起一對(duì)一聊天2016-01-01
Nginx 配置前端后端服務(wù)的實(shí)現(xiàn)步驟
本文主要介紹了Nginx 配置前端后端服務(wù)的實(shí)現(xiàn)步驟,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2026-03-03
Debian系統(tǒng)下為PHP程序配置Nginx服務(wù)器的基本教程
這篇文章主要介紹了Debian系統(tǒng)下為PHP程序配置Nginx服務(wù)器的基本教程,這里使用到了FastCGI和php-fpm,需要的朋友可以參考下2015-12-12

