目錄
一.HTTP請求數據在服務器中的傳輸與處理詳解
1.2 套字節?
1.3 零拷貝技術?
二.I/O模型?
2.1 I/O模型簡介
2.2 常見的I/O模型及其特點
1.同步/異步
2.阻塞vs 非阻塞
3.?同步/異步與阻塞/非阻塞的關系
4.多路復用I/O模型
5.異步I/O模型
三.Nginx模塊
3.1 概述nginx
3.2 nginx配置文件?
3.2.1?Nginx的配置文件的組成部分
3.2.2 主配置文件 (nginx.conf)核心結構
3.2.3?子配置文件 (conf.d/*.conf)
3.2.4 兩者的關系
四.Nginx的安裝
4.1 yum安裝
4.2 編譯安裝
4.3 nginx開機自啟
五.Nginx相關命令
5.1 nginx常見命令
5.2?Nginx的信號
六. Nginx運維三部曲:日志分割、無縫升級與版本回滾實戰?
6.1 分割日志
6.2 升級nginx
6.2.1升級思路
6.2.2 平滑升級nginx?
6.3?回滾(退回舊版本)
一.HTTP請求數據在服務器中的傳輸與處理詳解
1.?客戶端發送數據
-
客戶端(如瀏覽器)通過HTTP請求向服務器發送數據。
-
數據被打包成TCP/IP協議的數據包,通過網絡傳輸到服務器的網卡。
2.?網卡接收數據
-
服務器的網卡接收到客戶端發送的數據包。
-
網卡通過DMA(Direct Memory Access,直接內存訪問)技術,將數據包直接寫入內核空間的內存緩沖區,而不需要CPU的干預。
3.?數據進入內核空間
-
數據包被寫入內核空間的接收緩沖區(Receive Buffer)。
-
內核的網絡協議棧(如TCP/IP協議棧)對數據包進行解析,包括:
-
檢查數據包的完整性(如校驗和)。
-
解析IP頭和TCP頭,確定數據包的目標端口和應用程序。
-
4.?數據從內核空間到用戶空間
-
內核將解析后的數據從接收緩沖區復制到用戶空間的應用程序緩沖區(Application Buffer)。
-
這個過程通常通過系統調用(如
read
或recv
)完成。
5.?應用程序處理數據
-
應用程序(如Nginx)從用戶空間的緩沖區中讀取數據。
-
應用程序根據業務邏輯處理數據,例如:
-
解析HTTP請求。
-
生成HTTP響應。
-
將響應數據寫入用戶空間的發送緩沖區。
-
6.?數據從用戶空間到內核空間
-
應用程序通過系統調用(如
write
或send
)將響應數據從用戶空間的發送緩沖區復制到內核空間的發送緩沖區(Send Buffer)。
7.?數據從內核空間到網卡
-
內核的網絡協議棧將發送緩沖區的數據打包成TCP/IP協議的數據包。
-
內核通過DMA技術將數據包從發送緩沖區直接傳輸到網卡。
8.?網卡發送數據
-
網卡將數據包發送到網絡中,傳輸回客戶端。
1.2 套字節?
套接字(Socket)是網絡編程中的一種抽象概念,用于實現不同主機之間的通信。通過套接字,應用程序可以在網絡上進行數據傳輸,支持 TCP、UDP 等多種協議。
套字節的組成:
IP 地址和端口號
- IP 地址用于標識網絡中的主機。
- 端口號用于標識主機上的具體應用程序
1.3 零拷貝技術?
從"HTTP請求數據在服務器中的傳輸與處理"的過程可以看出在傳統的 I/O 操作中,數據通常需要在用戶空間和內核空間之間多次復制,而零拷貝(Zero-Copy)旨在減少數據在內存中的復制次數,從而提高數據傳輸的效率。
零拷貝技術的工作原理
零拷貝技術通過以下方式避免數據在內存中的多次復制:
- 直接內存訪問(DMA):
- 使用 DMA 技術,數據可以直接從磁盤讀取到內核緩沖區,無需 CPU 參與。
- 內存映射(mmap):
- 將內核緩沖區映射到用戶空間,用戶程序可以直接訪問內核緩沖區,無需將數據復制到用戶空間。
- sendfile 系統調用:
- 在 Linux 中,
sendfile
?系統調用可以直接將數據從文件描述符傳輸到網絡套接字,無需經過用戶空間
- 在 Linux 中,
二.I/O模型?
2.1 I/O模型簡介
I/O模型(Input/Output Model)是計算機系統中用于處理輸入輸出操作的一種機制,它決定了程序如何與外部設備(如磁盤、網絡、鍵盤等)進行數據交互。不同的I/O模型對程序的性能、并發能力和資源消耗有重要影響。
2.2 常見的I/O模型及其特點
1.同步/異步
程序執行流程是否需要等待操作完成。
同步:程序發起一個操作后,必須等待該操作完成才能繼續執行后續代碼。
異步:程序發起一個操作后,不需要等待操作完成,可以繼續執行其他任務。操作完成后,系統會通知程序進行處理。
2.阻塞vs 非阻塞
線程是否會被掛起等待操作完成。
阻塞:當程序發起一個操作時,如果操作不能立即完成,線程會被掛起,直到操作完成。
非阻塞:當程序發起一個操作時,如果操作不能立即完成,會立即返回一個錯誤或狀態,線程可以繼續執行其他任務。
3.?同步/異步與阻塞/非阻塞的關系
-
同步阻塞:程序發起操作后,必須等待操作完成,線程會被掛起。
-
同步非阻塞:程序發起操作后,如果操作不能立即完成,會立即返回,程序需要輪詢檢查操作狀態。
-
異步阻塞:這種組合在實際中很少見,因為異步操作通常是非阻塞的。
-
異步非阻塞:程序發起操作后,不需要等待操作完成,可以繼續執行其他任務。操作完成后,系統會通知程序進行處理。
4.多路復用I/O模型
特點:單線程監控多個I/O操作:使用一個線程同時監控多個文件描述符(如Socket),當某個文件描述符就緒時,通知程序進行處理。
優點:高效處理大量并發連接,減少線程數量,節省資源。
缺點:不同操作系統的實現方式不同(如epoll
僅適用于Linux)。
常見的多路復用I/O模型有:
select
:- 支持的文件描述符數量有限(通常為1024),效率較低。
- 需要遍歷所有文件描述符來找到準備就緒的 I/O 操作,時間復雜度為O(n)。
poll
:- 解決了
select
的文件描述符數量限制,但效率仍然不高。 - 同樣需要遍歷所有文件描述符,時間復雜度為O(n)。
- 解決了
epoll
(Linux特有):- 高效支持大量文件描述符,時間復雜度為O(1)。
- 使用事件通知機制,只處理就緒的文件描述符。
5.異步I/O模型
特點:
- 完全非阻塞:
- 程序發起I/O操作后,不需要等待操作完成,可以繼續執行其他任務。
- 事件通知:
- I/O操作完成后,系統會通過回調函數或信號通知程序進行處理。
- 高效利用資源:
- 避免了線程阻塞,能夠充分利用CPU和內存資源
三.Nginx模塊
3.1 概述nginx
NGINX(發音為“engine-x”)是一個高性能的?Web服務器、反向代理服務器?和?負載均衡器。
主要功能包括:?
靜態內容服務
-
高效處理HTML、CSS、JS、圖片等靜態文件
-
支持sendfile零拷貝技術,大幅提升文件傳輸效率
動態內容處理:通過FastCGI支持PHP、Python等動態語言
負載均衡:支持HTTP、TCP/UDP負載均衡
?補充:在Nginx中,支持HTTP負載均衡和TCP/UDP負載均衡分別對應應用層(L7)和傳輸層(L4)的流量分發能力,兩者的核心區別在于協議棧層級和功能特性。?
nginx的基礎特性包括:
-
模塊化設計,較好的擴展性
-
高可靠性
-
支持熱部署:不停機更新配置文件,升級版本,更換日志文件
-
低內存消耗:10000個keep-alive連接模式下的非活動連接,僅需2.5M內存
-
event-driven, aio, mmap,sendfile
3.2 nginx配置文件?
3.2.1?Nginx的配置文件的組成部分
主配置文件:nginx.conf
子配置文件: include conf.d/*.conf
3.2.2 主配置文件 (nginx.conf)核心結構
# 全局上下文 (Main Context)
user nginx;
worker_processes auto;# 事件驅動配置 (Events Context)
events {worker_connections 1024;
}# HTTP核心配置 (HTTP Context)
http {include /etc/nginx/mime.types;default_type application/octet-stream;# 包含子配置文件include /etc/nginx/conf.d/*.conf;include /etc/nginx/sites-enabled/*;
}# 流代理配置 (Stream Context)
stream {include /etc/nginx/stream.d/*.conf;
}
3.2.3?子配置文件 (conf.d/*.conf)
子配置文件一般在主配置文件的http部分
http塊中可以包含多個子配置文件,常見的子配置文件
- HTTP 塊?是 Nginx 配置的核心部分,包含?
server
?塊、location
?塊、upstream
?塊等。 - Server 塊?定義虛擬主機,包含?
location
?塊。 - Location 塊?定義 URL 路徑的處理規則。
- Upstream 塊?定義負載均衡的后端服務器組。
- Include 指令?用于引入子配置文件,實現配置文件的模塊化。
3.2.4 兩者的關系
Nginx 的主配置文件(nginx.conf
)和子配置文件(如?conf.d/*.conf
)之間是?分層包含關系,通過模塊化設計實現配置的靈活管理。?
四.Nginx的安裝
4.1 yum安裝
1.配置好基礎倉庫后# 2. 安裝EPEL倉庫
yum install -y epel-release# 3. 安裝nginx
yum install -y nginx# 4. 啟動nginx
systemctl start nginx
4.2 編譯安裝
準備工作
#安裝依賴包
yum -y install gcc pcre-devel openssl-devel zlib-devel openssl openssl-devel
#新建nginx用戶便于管理
useradd -M -s /sbin/nologin nginx
#官網下載包
wget http://nginx.org/download/nginx-1.18.0.tar.gz
開始編譯
tar xf nginx-1.18.0.tar.gz
mkdir /apps/nginx -p
cd nginx-1.18.0/ #解壓源碼包./configure --prefix=/apps/nginx \ #配置編譯選項
--user=nginx \
--group=nginx \
--with-http_ssl_module \
--with-http_v2_module \
--with-http_realip_module \
--with-http_stub_status_module \
--with-http_gzip_static_module \
--with-pcre \
--with-stream \
--with-stream_ssl_module \
--with-stream_realip_module
#輸入完成后點擊回車鍵make -j2 && make install #編譯并安裝chown -R nginx.nginx /apps/nginx #加權限ln -s /apps/nginx/sbin/nginx /usr/sbin/ #直接啟動 不需要絕對路徑ll /apps/nginx/ #檢查該路徑下是否存在安裝的文件ls -l /apps/nginx/sbin/nginx #如果有 nginx 可執行文件,說明編譯成功。/apps/nginx/sbin/nginx -v #如果返回類似 nginx version: nginx/1.18.0,說明安裝成功。/apps/nginx/sbin/nginx #啟動 Nginxps -ef | grep nginx #如果看到 master 和 worker 進程,說明 Nginx 已運行。
??
?
4.3 nginx開機自啟
創建nginx自啟文件?
vim /usr/lib/systemd/system/nginx.service
#建立文件#修改文件內容
[Unit]
Description=nginx - high performance web server
Documentation=http://nginx.org/en/docs/
After=network-online.target remote-fs.target nss-lookup.target
Wants=network-online.target[Service]
Type=forking
PIDFile=/apps/nginx/logs/nginx.pid
#注意文件位置,如果不對 啟動不了
ExecStart=/apps/nginx/sbin/nginx
#注意啟動文件位置
ExecReload=/bin/kill -s HUP $MAINPID
ExecStop=/bin/kill -s TERM $MAINPID[Install]
WantedBy=multi-user.target
?重新加載文件,啟動
systemctl daemon-reload
#重新加載配置
systemctl enable --now nginx
#開機自啟并立即啟動 如果logs下有nginx.pid文件那會啟動失敗,只需刪除logs下的nginx.pid即可。chown -R nginx.nginx /apps/nginx
#修改權限
systemctl is-enabled nginx#如果輸出 enabled,表示 Nginx 已成功設置為開機自啟
?
補充:之后的學習中,會遇到在一臺服務器上運行多個 Nginx 實例的情況為避免 PID 沖突,所有實例都會嘗試使用同一個?pid
?文件路徑。
###如果需要修改pid文件可以執行以下操作#################
mkdir /apps/nginx/run/
#創建目錄
vim /apps/nginx/conf/nginx.conf
#修改配置文件
pid /apps/nginx/run/nginx.pid;
#找到 pid的位置修改
五.Nginx相關命令
5.1 nginx常見命令
#基本格式
nginx [選項] [參數]
選項 | 功能描述 |
---|---|
-c <配置文件> | 指定自定義的配置文件路徑。 |
-t | 測試配置文件語法是否正確。 |
-T | 測試配置文件并打印解析后的配置內容。 |
-q | 在測試配置文件時以靜默模式運行,只輸出關鍵信息。 |
-g <全局配置> | 在命令行中指定全局配置選項。 |
-e <錯誤日志文件> | 設置錯誤日志文件的路徑。 |
-s <信號> | 向 Nginx 發送信號(如?stop 、reload )。 |
-s <文件> | 啟動 Nginx 并將 master 進程的 PID 寫入指定文件。 |
-p <工作目錄> | 設置工作目錄,用于存放日志文件和臨時文件。 |
-V | 顯示 Nginx 的版本、編譯信息和配置參數。 |
-h | 顯示幫助信息,包括所有可用的命令行選項。 |
-q <文件> | 在測試配置文件時,將輸出結果寫入指定文件 |
5.2?Nginx的信號
Nginx 的信號(Signals)是用于控制 Nginx 進程行為的機制。通過向 Nginx 的 master 進程發送不同的信號,可以實現停止、重啟、重新加載配置等操作。
#基本格式
nginx -s 信號
信號 | 功能描述 | 使用方式 |
---|---|---|
stop | 立即停止 Nginx 進程。 | nginx -s stop ?或?kill -TERM <pid> |
quit | 優雅地停止 Nginx 進程。 | nginx -s quit ?或?kill -QUIT <pid> |
reload | 重新加載配置文件。 | nginx -s reload ?或?kill -HUP <pid> |
reopen | 重新打開日志文件。 | nginx -s reopen ?或?kill -USR1 <pid> |
USR2 | 熱升級 Nginx 可執行文件。 | kill -USR2 <pid> |
WINCH | 優雅地關閉舊的 worker 進程(熱升級后使用)。 | kill -WINCH <pid> |
TERM/INT | 立即停止 Nginx 進程。 | kill -TERM <pid> ?或?kill -INT <pid> |
HUP | 重新加載配置文件。 | kill -HUP <pid> |
六. Nginx運維三部曲:日志分割、無縫升級與版本回滾實戰?
6.1 分割日志
為什么需要分割日志?
-
文件過大:單個日志文件過大可能導致磁盤空間不足或日志分析工具無法處理。
-
歸檔管理:按時間或大小分割日志,便于歸檔、備份和清理。
-
性能優化:避免日志文件過大影響 Nginx 的性能。
cd /apps/nginx/logs# 1. 備份舊日志(保留原權限)
mv --backup=numbered --preserve=all access.log access.log.bak# 2. 創建新日志并設置正確權限
touch access.log
chown nginx:nginx access.log access.log.bak error.log # 同時修正所有日志權限
chmod 644 access.log access.log.bak error.log# 3. 通知 Nginx 重新打開日志
nginx -s reopen 2>/dev/null || kill -USR1 $(cat nginx.pid 2>/dev/null)# 4. 驗證結果
ls -lh access.log* error.log*
6.2 升級nginx
6.2.1升級思路
-
將舊Nginx文件換成新Nginx文件(注意備份)
-
向master進程發送USR2信號
-
master進程修改pid文件名,加后綴.oldbin
-
master進程用新Nginx文件啟動新master進程,系統中將有新舊兩個Nginx主進程共同提供Web服務
-
向舊的Nginx服務進程發送WINCH信號,使舊的Nginx worker進程平滑停止,并刪除Nginx.pid.oldbin文件
-
向舊master進程發送QUIT信號,關閉老master
-
如果發現升級有問題,可以回滾向老master發送HUP,向新master發送QUIT
6.2.2 平滑升級nginx?
?Nginx 的平滑升級是指在不停機的情況下,將 Nginx 從舊版本升級到新版本。這樣可以確保服務不中斷,用戶體驗不受影響。
從nginx1.18升級到nginx1.20
#關閉防火墻
systemctl stop firewalld
setenforce 0
#啟動服務
systemctl start nginx
#下載安裝包到src目錄
wget https://nginx.org/download/nginx-1.20.2.tar.gz -P /usr/local/src/cd /usr/local/src/;ls
?
tar xf nginx-1.20.2.tar.gz
cd nginx-1.20.2/;ls
重新編譯安裝#檢測編譯環境 加模塊
./configure --prefix=/apps/nginx --user=nginx --group=nginx --with-http_ssl_module --with-http_v2_module --with-http_realip_module --with-http_stub_status_module --with-http_gzip_static_module --with-pcre --with-stream --with-stream_ssl_module --with-stream_realip_module#不要make install
make
mv /apps/nginx/sbin/nginx /apps/nginx/sbin/nginx.bak
#將低版本的nginx主程序改名
cp /usr/local/src/nginx-1.20.2/objs/nginx /apps/nginx/sbin
#將新版本 拷入進去
/apps/nginx/sbin/nginx -t
#語法檢查
kill -USR2 `cat /apps/nginx/logs/nginx.pid`ps auxf|grep nginx
#會生成新的master進程,需要結束舊的
cat /apps/nginx/los/nginx.pid #1.20.2版本的cat /apps/nginx/los/nginx.pid.oldbin #1.18版本的kill -WINCH `cat /apps/nginx/logs/nginx.pid.oldbin`
#優雅關閉 舊版本的master processpstree -p |grep nginxcurl -I http://localhost
#檢查新版本是否實際生效,輸出中應包含 Server: nginx/1.20.2。ps -ef | grep nginx | grep -v grep #驗證舊 worker 已完全退出tail -n 20 /apps/nginx/logs/error.log
#檢查錯誤日志,確保沒有 bind() failed 或其他端口沖突錯誤。kill -QUIT `cat /apps/nginx/logs/nginx.pid.oldbin`
#如果確認新版本運行正常,可以安全關閉舊 master
6.3?回滾(退回舊版本)
回滾的本質是?重新激活舊 Master 的 Worker,并關閉新 Master。
所以必須滿足以下條件才能回滾:
-
舊 Master 進程仍在運行
-
舊 Worker 已停止(通過?
kill -WINCH
) -
未執行?
kill -QUIT 舊PID
(否則舊 Master 會退出
#喚起舊版本的主進程
kill -HUP `cat /apps/nginx/logs/nginx.pid.oldbin`#結束新版本的master進程
kill -QUIT `cat /apps/nginx/logs/nginx.pid`curl -I 127.1
#通過 curl 發送一個 HEAD 請求到本地服務器并返回響應頭信息
若舊 Master 已退出
解決方案:手動啟動舊二進制文件
# 1. 關閉新版本
kill -TERM `cat /apps/nginx/logs/nginx.pid`# 2. 啟動舊版本
cp /apps/nginx/sbin/nginx.bak /apps/nginx/sbin/nginx
/apps/nginx/sbin/nginx -t && /apps/nginx/sbin/nginx
若舊 Worker 未完全關閉?
# 強制殺死殘留 Worker
pkill -9 -f "nginx: worker process"
# 再執行標準回滾流程