Web服務器-Nginx-高并發(fā)問題
前言
Nginx應對高并發(fā)
在現(xiàn)代互聯(lián)網(wǎng)中,高并發(fā)流量是許多應用場景的常態(tài),尤其在秒殺系統(tǒng)、直播平臺,還是大型電商活動。
這些場景會帶來巨大技術挑戰(zhàn),而Nginx,是我們經(jīng)常使用的利器,應對高并發(fā)流量。
一、架構
Nginx不僅僅是一個 Web 服務器,它是 現(xiàn)代互聯(lián)網(wǎng)系統(tǒng)的流量總管,在高并發(fā)架構中扮演著至關重要的角色。
Nginx 能夠應對高并發(fā)流量,是由于底層有多項關鍵技術支撐:
事件驅(qū)動模型 + I/O 多路復用 + 異步非阻塞 I/O
1. 原生多進程架構
- 使用經(jīng)典的 Master-Worker 進程模型,這種設計是其高性能、和高可用性的基石。

- 主進程負責管理,子進程負責處理請求;

Master 進程的職責:主要負責讀取、和解析配置文件,以及,管理 Worker 進程的啟動、關閉和重啟…等等。
- 管理 Worker 進程: Master 進程負責啟動、停止和重啟 Worker 進程,確保系統(tǒng)的穩(wěn)定運行。
- 加載配置文件: 它負責讀取和解析 Nginx 的配置文件(nginx.conf),并將配置信息傳遞給 Worker 進程。
Worker 進程的職責:處理客戶端的請求,比如: HTTP 請求、TCP/UDP …連接等等等。
- 處理客戶端請求: Worker 進程是實際處理客戶端請求的進程。
- 執(zhí)行網(wǎng)絡 I/O 操作: 它負責接收和發(fā)送網(wǎng)絡數(shù)據(jù),處理 HTTP 請求和響應。
- 每個 Worker 進程都是獨立的: 這意味著它們之間互不干擾,即使某個 Worker 進程出現(xiàn)問題,也不會影響其他進程的運行。
- 通常,Worker 進程的數(shù)量會配置為與服務器的 CPU 核心數(shù)相同、或兩倍。多個 Worker 進程可以并行處理請求,充分發(fā)揮多核 CPU 的性能。
- 單線程高效處理連接:每個 Worker 進程都是單線程的,這避免了多線程上下文切換的開銷,提高了性能。
2. 事件驅(qū)動模型
與傳統(tǒng)的“一個連接一個線程/進程”模型不同,Nginx 采用事件驅(qū)動模型。
事件驅(qū)動模型,提供的高性能,是 Nginx 能夠處理百萬并發(fā)的核心。

- 1.epoll_wait 等待就緒事件(如連接/讀/寫)
- 2.就緒事件觸發(fā),執(zhí)行對應回調(diào) handler(如讀取數(shù)據(jù))
- 3.繼續(xù)監(jiān)聽下一批事件
事件驅(qū)動模型的核心是:程序不再被動地等待任務、或按照固定的流程執(zhí)行,而是主動地監(jiān)聽,并響應各種“事件”的發(fā)生。
比如:當一個事件發(fā)生時(如網(wǎng)絡數(shù)據(jù)到達、定時器觸發(fā)、用戶操作…等),程序會執(zhí)行預先注冊好的回調(diào)函數(shù)來處理它。
Nginx 并不“主動干活”,而是“事件來了才響應”,這大幅減少了空耗、與阻塞。
3. IO多路復用
事件驅(qū)動模型的底層支撐,就是操作系統(tǒng)提供的 I/O 多路復用機制。
Nginx 在 Linux 下默認使用 epoll,性能極高。

epoll 是一種 I/O 多路復用技術,它允許一個線程同時監(jiān)聽多個文件描述符(例如,網(wǎng)絡連接)。采用了“事件就緒通知”機制,當某個文件描述符上的事件就緒時(例如,數(shù)據(jù)可讀),epoll 會通知線程,線程再進行處理。內(nèi)核會主動,將其添加到 epoll 實例維護的一個就緒列表(ready list)中。
epoll 相比 select/poll,在大數(shù)量連接的情況下,性能會更好。不僅能支持百萬連接,而且是“事件通知機制”,避免無效遍歷。
所以,I/O 多路復用的價值,可以大幅提升并發(fā)能力。
4. 異步非阻塞 I/O
Nginx 的所有 I/O 操作都是 異步非阻塞的,這意味著:當線程執(zhí)行 I/O 操作時,不需要線程等待數(shù)據(jù),所有 read/write 都立刻返回。線程可以繼續(xù)執(zhí)行其他任務,當 I/O 操作完成后,通過事件通知機制進行處理。
這樣,可以確保 Nginx 的 Worker 進程,永遠不會在 I/O 操作上被掛起??梢?strong>避免線程在等待IO的時候,被阻塞,它總是忙于處理那些已經(jīng)就緒的事件。

客戶端連接 socket →注冊讀事件(非阻塞)→等數(shù)據(jù)到達
→數(shù)據(jù)到達觸發(fā)事件→回調(diào)讀取→注冊寫事件
→數(shù)據(jù)寫回→關閉或保持連接(Keepalive)
總之,異步非阻塞 I/O ,是與事件驅(qū)動模型、采用epoll的I/O 多路復用緊密結合,能夠在一個線程中同時處理多個連接,高效地處理大量的并發(fā)連接,從而提高了系統(tǒng)的并發(fā)處理能力,這是Nginx實現(xiàn)高性能的核心。
5. Nginx高并發(fā)配置實戰(zhàn)
啟用多進程并發(fā) + 高效事件模型
worker_processes auto;
worker_cpu_affinity auto;
events {
# Linux 平臺推薦使用 epoll
use epoll;
worker_connections 10240;
multi_accept on;
}
- worker_processes auto :自動設置為 CPU 核心數(shù),充分利用多核優(yōu)勢。
- use epoll :Linux 下的高性能事件驅(qū)動模型。
- worker_connections :單個 worker 支持的最大連接數(shù)(理論并發(fā) = workers × connections)。
- multi_accept on :允許 worker 一次接受多個連接,提高接入效率。
實戰(zhàn)建議:在壓力測試中逐步調(diào)整 worker_connections 以找到最佳吞吐點。
提升 TCP 連接效率(長連接+連接復用)
keepalive_timeout 65; keepalive_requests 1000; tcp_nodelay on; tcp_nopush on;
- keepalive_timeout :保持連接存活時間,減少頻繁建立/釋放的開銷。
- keepalive_requests :單連接最大請求數(shù),配合 upstream keepalive 使用。
- tcp_nodelay :加速小包傳輸,避免延遲。
- tcp_nopush :優(yōu)化響應包發(fā)送,減少數(shù)據(jù)包數(shù)量。
開啟緩存機制,減輕后端壓力
proxy_cache_path /data/nginx/cache levels=1:2 keys_zone=static_cache:50m inactive=1h max_size=2g;
server {
location /static/
{
proxy_cache static_cache;
proxy_pass http://backend_servers;
proxy_cache_valid 200 1h;
proxy_cache_use_stale error timeout updating;
}
}
- proxy_cache_path :設置緩存路徑、層級結構、大小上限;
- proxy_cache_valid :為不同狀態(tài)碼配置緩存時間;
- proxy_cache_use_stale :后端出問題時使用過期緩存兜底,提升系統(tǒng)容錯。
設置限流防護,抵御突發(fā)流量沖擊
limit_conn_zone $binary_remote_addr zone=addr_limit:10m; limit_conn addr_limit 20; limit_req_zone $binary_remote_addr zone=req_limit:10m rate=10r/s; limit_req zone=req_limit burst=20 nodelay;
- limit_conn :限制單 IP 最大連接數(shù);
- limit_req :限制請求速率(如:每秒10次),防止惡意刷接口。
場景舉例:
- 防止爬蟲惡意抓取;
- 限制高頻 API 調(diào)用;
- 緩解峰值時段突發(fā)請求。
優(yōu)化文件傳輸性能:
sendfile on; aio on; output_buffers 1 512k;
- sendfile :啟用零拷貝機制,減少磁盤 → 網(wǎng)絡的數(shù)據(jù)搬運消耗;
- aio :啟用異步文件 IO,提升大文件傳輸效率。
啟用 Gzip 壓縮減少帶寬占用
gzip on; gzip_types text/plain application/json application/javascript text/css; gzip_comp_level 5;
- 適用于靜態(tài)資源、JSON 接口響應等場景;
- 在帶寬緊張時非常有效,但注意不要壓縮已壓縮格式(如 .zip, .jpg)。
二、動靜分離
動靜分離是一種優(yōu)化應用性能、和可伸縮性的架構策略。
Nginx動靜分離,核心思想是將 Web 應用中的動態(tài)資源、和靜態(tài)資源分開部署和管理。
并通過 Web 服務器(通常是 Nginx)進行智能的請求分發(fā),如下圖所示:

1. 職責
在動靜分離架構中,Nginx 作為前置的 反向代理服務器 + 靜態(tài)資源服務器,具有如下職責:
攔截靜態(tài)資源請求,直接讀取本地文件并響應(高性能、無 I/O 等待);
轉發(fā)動態(tài)請求 到后端應用服務器(如 Tomcat、PHP-FPM、Node.js)處理業(yè)務邏輯。
通過動靜分離,我們可以將不同類型的請求交給最擅長處理它們的服務器,從而提高整體的效率和可維護性。
對于靜態(tài)資源請求,可以配置 Nginx 直接從本地文件系統(tǒng)(Nginx 服務器所在的磁盤),讀取并返回給客戶端。
也可以配置 Nginx 將請求,反向代理到專門的靜態(tài)資源服務器(例如另一臺 Nginx 服務器)、或內(nèi)容分發(fā)網(wǎng)絡 (CDN)。通常,對于大型高并發(fā)的 Web 應用,結合使用 CDN 和專門的靜態(tài)資源服務器是更優(yōu)的選擇。
對于動態(tài)資源請求,Nginx 將請求反向代理到后端的動態(tài)應用服務器集群(例如運行 PHP-FPM、Tomcat…等的服務器)。
2. 核心流程
- 收請求: Nginx 接收用戶請求;
- 分類型: Nginx 根據(jù) URI 判斷是靜態(tài)資源(如圖片、CSS、JS)還是動態(tài)請求(如 PHP 頁面)。
導向處理:
- 靜態(tài)資源,Nginx 自己處理(讀取本地文件)或轉發(fā)給專門的靜態(tài)資源服務器/CDN。
- 動態(tài)請求, Nginx 轉發(fā)給后端的應用服務器(如 Tomcat。。。等等)。
3. 配置
配置樣例
server {
listen 80;
server_name www.example.com;
# 靜態(tài)資源處理
location ~* \.(jpg|jpeg|png|gif|css|js|ico|html|woff|ttf)$ {
root /var/www/static;
expires 7d;
}
# 動態(tài)請求代理后端
location /{
proxy_pass http://127.0.0.1:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
三、限流
Nginx限流(Rate Limiting): 是指通過配置 Nginx 來,限制客戶端在一定時間內(nèi)訪問服務器的請求頻率。
Nginx 限流的核心目標:是控制客戶端請求的速率或并發(fā)連接數(shù),以保護服務器免受過載或惡意攻擊。

比如:通過Nginx限流,可以防止惡意攻擊(如DDoS攻擊)、或意外流量激增導致服務器過載。
以及,控制流量,確保服務器在承受范圍內(nèi)穩(wěn)定運行。
1. 限流原理
基于 令牌桶算法(Token Bucket) 實現(xiàn)的。
令牌桶算法是一種靈活且有效的限流算法,它允許一定程度的突發(fā)流量,同時又能平滑地限制請求速率。
工作原理,如下圖所示:

2. 流程
令牌桶算法的核心思想:是維護一個固定容量的“令牌桶”。
系統(tǒng)以恒定的速率向令牌桶中放入令牌。
每個請求到來時,都需要從令牌桶中獲取一個令牌才能被處理。
如果令牌桶中沒有足夠的令牌,則請求會被拒絕或等待。
令牌桶的容量限制了可以存儲的令牌數(shù)量,多余的令牌會被丟棄。
總結
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關文章
windows下RunHiddenConsole 啟動 nginx與php(RunHiddenConsole下載)
這篇文章主要介紹了RunHiddenConsole 啟動 nginx與php的相關資料,希望通過本文能幫助到大家,讓大家學會使用RunHiddenConsole,需要的朋友可以參考下2017-10-10
Nginx+Tomcat搭建高性能負載均衡集群的實現(xiàn)方法
這篇文章主要介紹了Nginx+Tomcat搭建高性能負載均衡集群的實現(xiàn)方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-03-03

