在現代 Web 架構中,選擇合適的 HTTP 伺服器是建構高效能系統的基礎。NGINX 自 2004 年誕生以來,憑藉其事件驅動的非同步架構與卓越的效能表現,逐漸成為全球最受歡迎的 Web 伺服器之一。相較於傳統的 Apache HTTP Server 採用每個連線一個執行緒或行程的模型,NGINX 使用非阻塞的事件驅動機制,能以極低的記憶體消耗處理數以萬計的並發連線。

在台灣的網路產業環境中,從新創公司到大型企業,從電商平台到內容服務,NGINX 的應用無處不在。其靈活的配置機制不僅支援靜態內容服務,更能作為反向代理與負載平衡器,在微服務架構中扮演 API 閘道的角色。隨著行動網路與雲端運算的普及,系統面臨的並發壓力與可用性要求持續攀升,深入理解 NGINX 的工作原理與最佳實務成為系統管理者與開發者的必備技能。

本文將從實務角度出發,探討 NGINX 在各種應用場景中的配置方法與優化策略。我們將深入剖析與 PHP-FPM、Python uWSGI 的整合機制,說明 SSL/TLS 安全通訊的建立方式,展示反向代理與負載平衡的實作技巧,並提供完整的故障診斷方法。透過實際案例與配置範例,讀者將能掌握建構高效能、高可用性 Web 服務的完整技術棧。

NGINX 架構原理與核心特性

NGINX 的高效能來自其獨特的架構設計。傳統的 Web 伺服器如 Apache 在處理請求時,通常為每個連線建立一個新的執行緒或行程。這種模型在低並發情況下運作良好,但當連線數量增加時,大量的執行緒或行程會消耗可觀的系統資源,包含記憶體與 CPU 時間片。更嚴重的是,頻繁的上下文切換會顯著降低系統效能。

NGINX 採用的事件驅動架構徹底改變了這種模式。它使用單一的主行程負責讀取配置與管理工作行程,而工作行程則採用非阻塞的事件循環機制處理實際的請求。每個工作行程能同時處理數以千計的連線,當某個連線暫時無法處理時,例如等待後端回應,工作行程不會閒置等待,而是立即切換到處理其他連線。這種設計讓 NGINX 能以極少的行程數量處理大量並發連線。

@startuml
!define PLANTUML_FORMAT svg
!theme _none_

skinparam dpi auto
skinparam shadowing false
skinparam linetype ortho
skinparam roundcorner 5
skinparam defaultFontName "Microsoft JhengHei UI"
skinparam defaultFontSize 16
skinparam minClassWidth 100

package "NGINX 架構" {
  component "主行程\n(Master Process)" as master
  component "工作行程 1\n(Worker Process)" as worker1
  component "工作行程 2\n(Worker Process)" as worker2
  component "工作行程 N\n(Worker Process)" as workerN
  component "快取管理行程\n(Cache Manager)" as cache
  
  cloud "客戶端連線池" {
    actor "客戶端 1" as client1
    actor "客戶端 2" as client2
    actor "客戶端 N" as clientN
  }
  
  database "共享記憶體\n(Shared Memory)" as shm
}

master --> worker1 : 管理
master --> worker2 : 管理
master --> workerN : 管理
master --> cache : 管理

client1 --> worker1 : 非阻塞連線
client2 --> worker1 : 非阻塞連線
clientN --> worker2 : 非阻塞連線

worker1 --> shm : 共享資料
worker2 --> shm : 共享資料
workerN --> shm : 共享資料
cache --> shm : 快取管理

note right of master
  負責讀取配置
  管理工作行程
  處理信號
end note

note bottom of worker1
  事件驅動模型
  非阻塞 I/O
  處理數千連線
end note

@enduml

NGINX 的配置檔案採用層次化的區塊結構,主要分為幾個上下文層級。http 區塊包含所有 HTTP 相關的配置,server 區塊定義虛擬主機,location 區塊則用於匹配特定的 URI 模式。這種結構化的設計讓配置既清晰又靈活,能夠精確控制不同請求的處理方式。

在配置中,指令的繼承與覆蓋規則需要特別注意。子區塊會繼承父區塊的設定,但可以覆蓋特定的指令。例如,在 http 區塊中設定的 gzip 壓縮會應用到所有虛擬主機,但某個 server 區塊可以選擇停用壓縮。這種機制提供了全域預設值與個別客製化的平衡。

PHP-FPM 整合與動態內容處理

PHP 是 Web 開發中最廣泛使用的伺服器端腳本語言之一。NGINX 本身並不內建 PHP 解析能力,需要透過 FastCGI 協定與外部的 PHP 處理器通訊。PHP-FPM 是 PHP 官方提供的 FastCGI 實作,專為與 NGINX 等 Web 伺服器整合而設計。它採用獨立的行程池管理模型,能夠有效處理 PHP 請求並提供良好的穩定性與效能。

PHP-FPM 的行程管理模式是其核心特性之一。它支援三種管理模式,分別是 static、dynamic 與 ondemand。static 模式會固定啟動指定數量的工作行程,適合流量穩定的環境。dynamic 模式會根據負載動態調整行程數量,在最小與最大值之間浮動。ondemand 模式則在有請求時才啟動行程,適合資源受限的環境。選擇合適的模式需要考慮系統資源與流量特性。

# NGINX 主配置檔案片段
http {
    # 全域設定
    include       mime.types;
    default_type  application/octet-stream;
    
    # 日誌格式定義
    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;
    error_log  /var/log/nginx/error.log warn;
    
    # 效能優化設定
    sendfile        on;
    tcp_nopush      on;
    tcp_nodelay     on;
    keepalive_timeout  65;
    types_hash_max_size 2048;
    
    # Gzip 壓縮
    gzip on;
    gzip_vary on;
    gzip_proxied any;
    gzip_comp_level 6;
    gzip_types text/plain text/css text/xml text/javascript 
               application/json application/javascript application/xml+rss;
    
    # PHP 處理的虛擬主機配置
    server {
        listen 80;
        listen [::]:80;
        server_name example.com www.example.com;
        
        root /var/www/html;
        index index.php index.html index.htm;
        
        # 字元編碼
        charset utf-8;
        
        # 存取日誌
        access_log /var/log/nginx/example.com.access.log main;
        error_log  /var/log/nginx/example.com.error.log;
        
        # 靜態檔案快取設定
        location ~* \.(jpg|jpeg|png|gif|ico|css|js|svg|woff|woff2|ttf|eot)$ {
            expires 1y;
            add_header Cache-Control "public, immutable";
            access_log off;
        }
        
        # 預設路由
        location / {
            try_files $uri $uri/ /index.php?$query_string;
        }
        
        # PHP 處理配置
        location ~ \.php$ {
            # 安全檢查,防止路徑遍歷攻擊
            try_files $uri =404;
            
            # FastCGI 基本設定
            fastcgi_split_path_info ^(.+\.php)(/.+)$;
            
            # 透過 Unix socket 連接 PHP-FPM
            fastcgi_pass unix:/var/run/php/php8.2-fpm.sock;
            
            # 或使用 TCP 連接(適合分離部署)
            # fastcgi_pass 127.0.0.1:9000;
            
            fastcgi_index index.php;
            
            # FastCGI 參數設定
            include fastcgi_params;
            fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
            fastcgi_param PATH_INFO $fastcgi_path_info;
            
            # 效能與安全優化
            fastcgi_buffer_size 128k;
            fastcgi_buffers 256 16k;
            fastcgi_busy_buffers_size 256k;
            fastcgi_temp_file_write_size 256k;
            fastcgi_read_timeout 300;
            
            # 隱藏 PHP 版本資訊
            fastcgi_hide_header X-Powered-By;
        }
        
        # 拒絕存取隱藏檔案
        location ~ /\. {
            deny all;
            access_log off;
            log_not_found off;
        }
        
        # 禁止存取備份檔案
        location ~ ~$ {
            deny all;
            access_log off;
            log_not_found off;
        }
    }
}

在 PHP-FPM 端的配置同樣重要。行程池配置檔案通常位於 /etc/php/8.2/fpm/pool.d/www.conf,其中包含了行程管理、資源限制與安全設定等關鍵參數。

; PHP-FPM 行程池配置
[www]

; 行程池執行的使用者與群組
user = www-data
group = www-data

; 監聽方式(Unix socket 效能較佳)
listen = /var/run/php/php8.2-fpm.sock

; Socket 權限設定
listen.owner = www-data
listen.group = www-data
listen.mode = 0660

; 行程管理模式
pm = dynamic

; 行程數量設定
pm.max_children = 50
pm.start_servers = 5
pm.min_spare_servers = 5
pm.max_spare_servers = 35

; 單一行程最大請求數(防止記憶體洩漏)
pm.max_requests = 500

; 行程閒置超時
pm.process_idle_timeout = 10s

; 慢查詢日誌
slowlog = /var/log/php8.2-fpm-slow.log
request_slowlog_timeout = 5s

; PHP 環境變數
env[HOSTNAME] = $HOSTNAME
env[PATH] = /usr/local/bin:/usr/bin:/bin
env[TMP] = /tmp
env[TMPDIR] = /tmp
env[TEMP] = /tmp

; PHP.ini 覆蓋設定
php_admin_value[error_log] = /var/log/php8.2-fpm-error.log
php_admin_flag[log_errors] = on
php_value[session.save_handler] = files
php_value[session.save_path] = /var/lib/php/sessions

調整 PHP-FPM 的行程數量需要根據系統資源與流量模式。一個簡單的估算方法是測量單個 PHP 行程的平均記憶體使用量,然後根據可用記憶體計算最大行程數。例如,如果每個行程平均使用 50MB 記憶體,而伺服器有 4GB 可用記憶體分配給 PHP-FPM,那麼理論上可以支援 80 個行程。實際配置時應該保留一定的緩衝空間,避免系統記憶體耗盡。

Python 應用整合與 uWSGI 部署

Python 在 Web 開發領域同樣佔有重要地位,從傳統的 Django 與 Flask 框架到現代的 FastAPI,都需要適當的應用伺服器來處理請求。uWSGI 是一個功能豐富的應用伺服器,支援多種協定與程式語言,特別適合在生產環境中部署 Python 應用程式。

uWSGI 的架構包含主行程與工作行程。主行程負責管理工作行程的生命週期,處理重載與監控等任務。工作行程則實際處理請求,可以是單執行緒或多執行緒模式。對於 I/O 密集型的應用,多行程模式通常提供更好的效能。對於 CPU 密集型的任務,則需要注意 Python 的全域直譯器鎖可能造成的限制。

@startuml
!define DISABLE_LINK
!define PLANTUML_FORMAT svg
!theme _none_

skinparam dpi auto
skinparam shadowing false
skinparam linetype ortho
skinparam roundcorner 5
skinparam defaultFontName "Microsoft JhengHei UI"
skinparam defaultFontSize 16
skinparam minClassWidth 100

participant "客戶端" as client
participant "NGINX" as nginx
participant "uWSGI Master" as uwsgi_master
participant "uWSGI Worker 1" as worker1
participant "uWSGI Worker 2" as worker2
participant "Python 應用" as app
database "資料庫" as db

client -> nginx : HTTP 請求
nginx -> nginx : 路由匹配

alt 靜態檔案
  nginx --> client : 直接回傳
else 動態請求
  nginx -> uwsgi_master : uwsgi 協定
  uwsgi_master -> worker1 : 分配請求
  worker1 -> app : 載入 WSGI 應用
  app -> db : 查詢資料
  db --> app : 回傳結果
  app --> worker1 : 處理完成
  worker1 --> uwsgi_master : 回應資料
  uwsgi_master --> nginx : uwsgi 回應
  nginx --> client : HTTP 回應
end

note right of nginx
  反向代理角色
  處理靜態內容
  SSL 終止
end note

note right of worker1
  多行程並發
  應用程式隔離
  自動重啟機制
end note

@enduml

在實際部署時,推薦使用 systemd 管理 uWSGI 服務,這提供了自動重啟、日誌管理與資源控制等便利功能。

# uWSGI 配置檔案 /etc/uwsgi/apps-available/myapp.ini
[uwsgi]

# 應用程式設定
chdir = /var/www/myapp
module = myapp.wsgi:application
home = /var/www/myapp/venv

# 行程管理
master = true
processes = 4
threads = 2
enable-threads = true

# Socket 設定
socket = /run/uwsgi/myapp.sock
chmod-socket = 666
vacuum = true

# 效能優化
max-requests = 5000
max-worker-lifetime = 3600
reload-on-rss = 512
worker-reload-mercy = 60

# 日誌設定
logto = /var/log/uwsgi/myapp.log
log-date = true
log-maxsize = 50000000

# 監控與統計
stats = /run/uwsgi/myapp-stats.sock
memory-report = true

# 應用程式重載
touch-reload = /var/www/myapp/reload.trigger
py-autoreload = 1

# 錯誤處理
die-on-term = true
catch-exceptions = true

# 環境變數
env = DJANGO_SETTINGS_MODULE=myapp.settings
env = ENVIRONMENT=production

對應的 NGINX 配置需要正確設定 uwsgi_pass 指令,並包含必要的 uwsgi 參數。

server {
    listen 80;
    server_name myapp.example.com;
    
    # 應用程式根目錄
    root /var/www/myapp;
    
    # 客戶端最大請求大小
    client_max_body_size 75M;
    
    # 靜態檔案處理
    location /static/ {
        alias /var/www/myapp/static/;
        expires 30d;
        add_header Cache-Control "public, immutable";
    }
    
    location /media/ {
        alias /var/www/myapp/media/;
        expires 7d;
        add_header Cache-Control "public";
    }
    
    # 動態請求轉發到 uWSGI
    location / {
        include uwsgi_params;
        uwsgi_pass unix:/run/uwsgi/myapp.sock;
        
        # 超時設定
        uwsgi_read_timeout 300;
        uwsgi_send_timeout 300;
        
        # 緩衝設定
        uwsgi_buffering on;
        uwsgi_buffer_size 8k;
        uwsgi_buffers 8 8k;
        
        # 請求標頭傳遞
        uwsgi_param HTTP_X_FORWARDED_PROTO $scheme;
        uwsgi_param HTTP_X_REAL_IP $remote_addr;
    }
    
    # 健康檢查端點
    location /health/ {
        include uwsgi_params;
        uwsgi_pass unix:/run/uwsgi/myapp.sock;
        access_log off;
    }
}

systemd 服務單元檔案提供了服務管理的標準化方式。

# /etc/systemd/system/uwsgi-myapp.service
[Unit]
Description=uWSGI instance for myapp
After=network.target

[Service]
User=www-data
Group=www-data
WorkingDirectory=/var/www/myapp
Environment="PATH=/var/www/myapp/venv/bin"

ExecStart=/usr/local/bin/uwsgi --ini /etc/uwsgi/apps-available/myapp.ini
ExecReload=/bin/kill -HUP $MAINPID
KillSignal=SIGQUIT
Restart=on-failure
RestartSec=5s

# 資源限制
LimitNOFILE=65535
LimitNPROC=4096

# 安全強化
NoNewPrivileges=true
PrivateTmp=true

[Install]
WantedBy=multi-user.target

SSL/TLS 安全通訊配置

在現代 Web 環境中,HTTPS 已從選項變成必須。無論是保護使用者隱私、防止中間人攻擊,或是滿足搜尋引擎與瀏覽器的要求,SSL/TLS 加密都是不可或缺的。NGINX 提供了完整的 SSL/TLS 支援,能夠高效地處理加密連線。

Let’s Encrypt 免費憑證服務的出現大幅降低了 HTTPS 部署的門檻。透過 Certbot 工具,可以自動化憑證的申請、安裝與更新流程。在生產環境中,建議使用自動化腳本定期檢查憑證有效期並進行更新。

# SSL/TLS 安全配置最佳實務
server {
    listen 80;
    listen [::]:80;
    server_name example.com www.example.com;
    
    # HTTP 到 HTTPS 永久重定向
    return 301 https://$server_name$request_uri;
}

server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    server_name example.com www.example.com;
    
    # SSL 憑證路徑
    ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
    ssl_trusted_certificate /etc/letsencrypt/live/example.com/chain.pem;
    
    # SSL 協定與加密套件
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384';
    ssl_prefer_server_ciphers off;
    
    # SSL 會話快取
    ssl_session_cache shared:SSL:10m;
    ssl_session_timeout 1d;
    ssl_session_tickets off;
    
    # OCSP Stapling
    ssl_stapling on;
    ssl_stapling_verify on;
    resolver 8.8.8.8 8.8.4.4 valid=300s;
    resolver_timeout 5s;
    
    # 安全標頭
    add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;
    add_header X-Frame-Options "SAMEORIGIN" always;
    add_header X-Content-Type-Options "nosniff" always;
    add_header X-XSS-Protection "1; mode=block" always;
    add_header Referrer-Policy "no-referrer-when-downgrade" always;
    
    # Content Security Policy
    add_header Content-Security-Policy "default-src 'self' https:; script-src 'self' 'unsafe-inline' 'unsafe-eval' https:; style-src 'self' 'unsafe-inline' https:;" always;
    
    root /var/www/html;
    index index.html;
    
    location / {
        try_files $uri $uri/ =404;
    }
}

憑證的自動更新可以透過 cron 任務實現。

# 自動更新 Let's Encrypt 憑證腳本
#!/bin/bash

# 更新憑證
certbot renew --quiet --no-self-upgrade

# 如果憑證有更新,重載 NGINX
if [ $? -eq 0 ]; then
    nginx -t && systemctl reload nginx
fi

# 記錄執行時間
echo "憑證更新檢查完成: $(date)" >> /var/log/certbot-renewal.log

將此腳本加入 crontab,設定每天執行兩次檢查。

# /etc/cron.d/certbot-renewal
0 0,12 * * * root /usr/local/bin/certbot-renewal.sh

反向代理與負載平衡實務

NGINX 作為反向代理能在客戶端與後端伺服器之間提供額外的抽象層。這不僅能隱藏後端架構細節,提升安全性,還能實現負載分散、SSL 終止、快取加速等多種功能。在微服務架構中,NGINX 常被部署為 API 閘道,統一處理外部請求並路由到不同的內部服務。

負載平衡策略的選擇會影響系統的效能與可靠性。NGINX 支援多種負載平衡演算法,包含輪詢、最少連線、IP 雜湊與權重分配等。輪詢是最簡單的策略,依序將請求分配給後端伺服器。最少連線策略會優先選擇當前連線數最少的伺服器,適合請求處理時間差異較大的情境。IP 雜湊則確保來自相同客戶端的請求總是路由到同一台後端伺服器,適合需要會話親和性的應用。

# 負載平衡與健康檢查配置
upstream backend_servers {
    # 負載平衡策略
    least_conn;
    
    # 後端伺服器定義
    server backend1.example.com:8080 weight=3 max_fails=3 fail_timeout=30s;
    server backend2.example.com:8080 weight=2 max_fails=3 fail_timeout=30s;
    server backend3.example.com:8080 weight=1 max_fails=3 fail_timeout=30s;
    
    # 備用伺服器(所有主伺服器失敗時使用)
    server backup.example.com:8080 backup;
    
    # 連線保持
    keepalive 32;
    keepalive_timeout 60s;
    keepalive_requests 100;
}

server {
    listen 80;
    server_name api.example.com;
    
    # 請求限流
    limit_req_zone $binary_remote_addr zone=api_limit:10m rate=10r/s;
    limit_req zone=api_limit burst=20 nodelay;
    
    # 連線限制
    limit_conn_zone $binary_remote_addr zone=conn_limit:10m;
    limit_conn conn_limit 10;
    
    location / {
        # 反向代理設定
        proxy_pass http://backend_servers;
        
        # 標頭傳遞
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Request-ID $request_id;
        
        # 超時設定
        proxy_connect_timeout 60s;
        proxy_send_timeout 60s;
        proxy_read_timeout 60s;
        
        # 緩衝設定
        proxy_buffering on;
        proxy_buffer_size 4k;
        proxy_buffers 8 4k;
        proxy_busy_buffers_size 8k;
        
        # 錯誤處理
        proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504;
        proxy_next_upstream_tries 2;
        proxy_next_upstream_timeout 10s;
        
        # 保持連線
        proxy_http_version 1.1;
        proxy_set_header Connection "";
    }
    
    # 健康檢查端點
    location /health {
        access_log off;
        return 200 "healthy\n";
        add_header Content-Type text/plain;
    }
    
    # 監控端點
    location /nginx_status {
        stub_status;
        access_log off;
        allow 127.0.0.1;
        deny all;
    }
}

在生產環境中,監控後端伺服器的健康狀態至關重要。雖然開源版 NGINX 不支援主動健康檢查,但可以透過被動健康檢查實現基本的故障偵測。當後端伺服器回應錯誤達到指定次數時,NGINX 會將其標記為不可用,並在一段時間後重新嘗試。

@startuml
!define PLANTUML_FORMAT svg
!theme _none_

skinparam dpi auto
skinparam shadowing false
skinparam linetype ortho
skinparam roundcorner 5
skinparam defaultFontName "Microsoft JhengHei UI"
skinparam defaultFontSize 16
skinparam minClassWidth 100

package "負載平衡架構" {
  actor "客戶端" as client
  component "NGINX\n負載平衡器" as lb
  
  package "後端伺服器群" {
    component "伺服器 1\n(權重 3)" as server1
    component "伺服器 2\n(權重 2)" as server2
    component "伺服器 3\n(權重 1)" as server3
    component "備用伺服器" as backup
  }
  
  database "共享快取" as cache
  database "會話儲存" as session
}

client --> lb : HTTP/HTTPS 請求

lb --> server1 : 最少連線\n負載分散
lb --> server2 : 最少連線\n負載分散
lb --> server3 : 最少連線\n負載分散
lb ..> backup : 故障轉移

server1 --> cache : 快取存取
server2 --> cache : 快取存取
server3 --> cache : 快取存取

server1 --> session : 會話資料
server2 --> session : 會話資料
server3 --> session : 會話資料

note right of lb
  健康檢查
  連線保持
  請求限流
  SSL 終止
end note

note bottom of "後端伺服器群"
  水平擴展
  故障隔離
  權重分配
  自動恢復
end note

@enduml

故障診斷與效能優化

在生產環境運行 NGINX 時,不可避免地會遇到各種問題。系統化的故障診斷方法能幫助快速定位並解決問題。NGINX 的日誌是診斷的第一道線索,存取日誌記錄了所有請求的詳細資訊,錯誤日誌則包含了系統警告與錯誤訊息。

配置測試是避免錯誤配置導致服務中斷的重要步驟。NGINX 提供了 -t 選項來驗證配置檔案的語法正確性。在每次修改配置後,都應該先執行測試,確認無誤後再重載或重啟服務。

# 配置測試腳本
#!/bin/bash

echo "正在測試 NGINX 配置..."

# 檢查配置語法
nginx -t

if [ $? -eq 0 ]; then
    echo "配置測試通過"
    echo "正在重載 NGINX..."
    systemctl reload nginx
    
    if [ $? -eq 0 ]; then
        echo "NGINX 重載成功"
    else
        echo "NGINX 重載失敗,請檢查日誌"
        exit 1
    fi
else
    echo "配置測試失敗,請修正錯誤"
    exit 1
fi

效能監控提供了系統運作狀態的可見性。除了 NGINX 內建的 stub_status 模組,還可以整合更進階的監控工具如 Prometheus 與 Grafana。

# 啟用 stub_status 監控
server {
    listen 127.0.0.1:8080;
    server_name localhost;
    
    location /nginx_status {
        stub_status;
        access_log off;
    }
    
    location /metrics {
        # Prometheus exporter 端點
        proxy_pass http://127.0.0.1:9113/metrics;
    }
}

常見的效能瓶頸包含檔案描述符限制、工作行程數量不足、緩衝區配置不當等。調整這些參數需要根據實際負載進行測試。

# 效能優化配置
user nginx;
worker_processes auto;
worker_rlimit_nofile 65535;

events {
    worker_connections 4096;
    use epoll;
    multi_accept on;
}

http {
    # 檔案快取
    open_file_cache max=200000 inactive=20s;
    open_file_cache_valid 30s;
    open_file_cache_min_uses 2;
    open_file_cache_errors on;
    
    # TCP 優化
    sendfile on;
    tcp_nopush on;
    tcp_nodelay on;
    
    # 連線保持
    keepalive_timeout 65;
    keepalive_requests 100;
    
    # 客戶端緩衝
    client_body_buffer_size 128k;
    client_max_body_size 10m;
    client_header_buffer_size 1k;
    large_client_header_buffers 4 4k;
    
    # 輸出緩衝
    output_buffers 1 32k;
    postpone_output 1460;
}

WordPress 生產環境部署實戰

WordPress 作為全球最受歡迎的內容管理系統,其部署配置具有代表性。一個安全且高效能的 WordPress 環境需要整合 NGINX、PHP-FPM、MySQL 與快取機制等多個元件。

# WordPress 完整生產環境配置
server {
    listen 80;
    listen [::]:80;
    server_name example.com www.example.com;
    return 301 https://$server_name$request_uri;
}

server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    server_name example.com www.example.com;
    
    root /var/www/wordpress;
    index index.php;
    
    # SSL 配置(參考前述 SSL 章節)
    ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
    
    # 安全標頭
    add_header X-Frame-Options "SAMEORIGIN" always;
    add_header X-Content-Type-Options "nosniff" always;
    
    # 上傳限制
    client_max_body_size 64M;
    
    # WordPress 固定連結支援
    location / {
        try_files $uri $uri/ /index.php?$args;
    }
    
    # PHP 處理
    location ~ \.php$ {
        try_files $uri =404;
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_pass unix:/var/run/php/php8.2-fpm.sock;
        fastcgi_index index.php;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        
        # WordPress 特定設定
        fastcgi_intercept_errors off;
        fastcgi_buffer_size 16k;
        fastcgi_buffers 4 16k;
        fastcgi_connect_timeout 300;
        fastcgi_send_timeout 300;
        fastcgi_read_timeout 300;
    }
    
    # 靜態資源快取
    location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ {
        expires 1y;
        add_header Cache-Control "public, immutable";
        access_log off;
    }
    
    # WordPress 上傳目錄
    location ~* /wp-content/uploads/.*\.php$ {
        deny all;
    }
    
    # 禁止存取敏感檔案
    location ~ /\.(ht|git|svn|env) {
        deny all;
    }
    
    location = /xmlrpc.php {
        deny all;
        access_log off;
    }
    
    location = /wp-config.php {
        deny all;
    }
    
    # WordPress 管理後台限流
    location ~* ^/wp-(admin|login\.php) {
        limit_req zone=wp_admin burst=5 nodelay;
        try_files $uri $uri/ /index.php?$args;
    }
}

# 管理後台限流區域定義
limit_req_zone $binary_remote_addr zone=wp_admin:10m rate=1r/s;

完整的 WordPress 環境還需要優化資料庫與啟用物件快取。使用 Redis 或 Memcached 作為物件快取能顯著提升效能。

# Redis 物件快取安裝腳本
#!/bin/bash

# 安裝 Redis
apt-get update
apt-get install -y redis-server php-redis

# 配置 Redis
sed -i 's/bind 127.0.0.1/bind 127.0.0.1/' /etc/redis/redis.conf
sed -i 's/# maxmemory <bytes>/maxmemory 256mb/' /etc/redis/redis.conf
sed -i 's/# maxmemory-policy noeviction/maxmemory-policy allkeys-lru/' /etc/redis/redis.conf

# 重啟服務
systemctl restart redis-server
systemctl restart php8.2-fpm

echo "Redis 物件快取安裝完成"

總結

NGINX 在現代 Web 架構中的重要性不言而喻。從簡單的靜態內容服務到複雜的微服務閘道,NGINX 都能提供高效且可靠的解決方案。本文探討了從基礎配置到進階應用的完整技術棧,涵蓋 PHP-FPM 與 Python 整合、SSL/TLS 安全通訊、反向代理與負載平衡等核心主題。

在台灣的產業環境中,隨著雲原生架構與容器化技術的普及,NGINX 的應用場景持續擴展。在 Kubernetes 環境中,NGINX Ingress Controller 提供了靈活的流量管理能力。作為服務網格的資料平面,NGINX 也在微服務通訊中發揮重要作用。

展望未來,HTTP/3 與 QUIC 協定的標準化將帶來新的效能提升機會。WebAssembly 在邊緣運算的應用也為 NGINX 開啟了新的可能性。持續學習與實踐,掌握 NGINX 的最新發展與最佳實務,將有助於建構更加高效、安全與可靠的 Web 服務。