本文記錄在 CentOS 7/8 上從源碼編譯安裝 Nginx 的完整流程,包含依賴庫編譯、核心模組配置、系統服務註冊、效能調優與反向代理實戰配置。適用於需要自定義模組、特定版本或極致效能的生產環境。
# 關閉 SELinux(或設為 permissive)
sudo setenforce 0
sudo sed -i 's/^SELINUX=enforcing/SELINUX=permissive/' /etc/selinux/config
# 安裝編譯工具鏈
sudo yum groupinstall -y "Development Tools"
sudo yum install -y wget curl unzip vim
# 建立專用用戶
sudo useradd -r -s /sbin/nologin -M nginx
sudo mkdir -p /var/cache/nginx /var/log/nginx
sudo chown nginx:nginx /var/cache/nginx /var/log/nginx
cd /usr/local/src
wget https://sourceforge.net/projects/pcre/files/pcre/8.45/pcre-8.45.tar.gz
tar -zxf pcre-8.45.tar.gz
cd pcre-8.45
./configure --prefix=/usr/local/pcre --enable-utf8 --enable-unicode-properties
make -j$(nproc) && sudo make install
cd /usr/local/src
wget https://zlib.net/current/zlib-1.3.1.tar.gz
tar -zxf zlib-1.3.1.tar.gz
cd zlib-1.3.1
./configure --prefix=/usr/local/zlib
make -j$(nproc) && sudo make install
cd /usr/local/src
wget https://www.openssl.org/source/openssl-3.0.13.tar.gz
tar -zxf openssl-3.0.13.tar.gz
cd openssl-3.0.13
./config --prefix=/usr/local/openssl shared zlib-dynamic
make -j$(nproc) && sudo make install
# 更新動態庫緩存
echo "/usr/local/openssl/lib64" | sudo tee /etc/ld.so.conf.d/openssl.conf
sudo ldconfig
cd /usr/local/src
# 穩定版
wget https://nginx.org/download/nginx-1.26.1.tar.gz
# 或主線版
# wget https://nginx.org/download/nginx-1.27.0.tar.gz
tar -zxf nginx-1.26.1.tar.gz
cd nginx-1.26.1
./configure \
--prefix=/usr/local/nginx \
--user=nginx \
--group=nginx \
--with-http_ssl_module \
--with-http_v2_module \
--with-http_realip_module \
--with-http_addition_module \
--with-http_sub_module \
--with-http_dav_module \
--with-http_flv_module \
--with-http_mp4_module \
--with-http_gunzip_module \
--with-http_gzip_static_module \
--with-http_auth_request_module \
--with-http_random_index_module \
--with-http_secure_link_module \
--with-http_degradation_module \
--with-http_slice_module \
--with-http_stub_status_module \
--with-mail \
--with-mail_ssl_module \
--with-stream \
--with-stream_ssl_module \
--with-stream_realip_module \
--with-stream_ssl_preread_module \
--with-threads \
--with-file-aio \
--with-http_v3_module \
--with-pcre=/usr/local/src/pcre-8.45 \
--with-zlib=/usr/local/src/zlib-1.3.1 \
--with-openssl=/usr/local/src/openssl-3.0.13 \
--with-openssl-opt="enable-tls1_3 enable-ec_nistp_64_gcc_128" \
--with-cc-opt="-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -m64 -mtune=generic -fPIC" \
--with-ld-opt="-Wl,-z,relro -Wl,-z,now -Wl,--as-needed -pie"
| 參數類別 | 關鍵參數 | 用途 |
|---|---|---|
| 核心路徑 | --prefix | 安裝根目錄 |
| 權限隔離 | --user/--group | 工作進程運行用戶 |
| HTTP 核心 | --with-http_ssl_module 等 | 啟用 HTTPS、HTTP/2、gzip、實時狀態等 |
| Stream 模組 | --with-stream | TCP/UDP 代理(四層負載均衡) |
| 效能優化 | --with-threads --with-file-aio | 線程池 + 異步 I/O |
| 安全強化 | --with-cc-opt/--with-ld-opt | 編譯/鏈接器安全標誌(FORTIFY、RELRO、PIE) |
| 依賴指定 | --with-pcre/zlib/openssl=路徑 | 指定源碼路徑而非系統庫,確保版本可控 |
make -j$(nproc)
sudo make install
sudo tee /etc/systemd/system/nginx.service > /dev/null <<'EOF'
[Unit]
Description=The NGINX HTTP and reverse proxy server
After=network.target remote-fs.target nss-lookup.target
[Service]
Type=forking
PIDFile=/usr/local/nginx/logs/nginx.pid
ExecStartPre=/usr/local/nginx/sbin/nginx -t
ExecStart=/usr/local/nginx/sbin/nginx
ExecReload=/usr/local/nginx/sbin/nginx -s reload
ExecStop=/bin/kill -s QUIT $MAINPID
PrivateTmp=true
LimitNOFILE=65535
LimitNPROC=65535
[Install]
WantedBy=multi-user.target
EOF
sudo systemctl daemon-reload
sudo systemctl enable --now nginx
sudo systemctl status nginx
# 常用操作
sudo systemctl reload nginx # 熱重載配置
sudo systemctl restart nginx # 完全重啟
sudo nginx -t # 測試配置語法
sudo nginx -V # 查看編譯參數
# /usr/local/nginx/conf/nginx.conf
user nginx nginx;
worker_processes auto; # 自動匹配 CPU 核心數
worker_cpu_affinity auto; # CPU 親和性綁定
worker_rlimit_nofile 65535; # 進程最大打開文件數
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
use epoll; # Linux 2.6+ 高效事件模型
worker_connections 65535; # 單進程最大連接數
multi_accept on; # 採納多個連接
accept_mutex on; # 驚群效應緩解
}
http {
include mime.types;
default_type application/octet-stream;
# 基礎優化
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
keepalive_requests 1000;
types_hash_max_size 2048;
server_names_hash_bucket_size 128;
# 壓縮優化
gzip on;
gzip_vary on;
gzip_proxied any;
gzip_comp_level 6;
gzip_min_length 1024;
gzip_buffers 16 8k;
gzip_http_version 1.1;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
gzip_disable "MSIE [1-6]\\.";
# 快取開關
open_file_cache max=10000 inactive=30s;
open_file_cache_valid 60s;
open_file_cache_min_uses 2;
open_file_cache_errors on;
# 日誌格式
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for" '
'$request_time $upstream_response_time $pipe';
access_log /var/log/nginx/access.log main buffer=32k flush=10s;
# 虛擬主機包含
include /usr/local/nginx/conf/vhosts/*.conf;
}
# /usr/local/nginx/conf/vhosts/upstream.conf
upstream backend_app {
# 輪詢(預設)
server 192.168.1.10:8080 weight=3 max_fails=2 fail_timeout=30s;
server 192.168.1.11:8080 weight=2 max_fails=2 fail_timeout=30s;
server 192.168.1.12:8080 weight=1 max_fails=2 fail_timeout=30s;
# 備援機制
server 192.168.1.13:8080 backup;
# 長連接優化
keepalive 64;
}
upstream websocket_cluster {
ip_hash; # WebSocket 需保持同一後端
server 192.168.1.20:8080;
server 192.168.1.21:8080;
}
# /usr/local/nginx/conf/vhosts/app.example.com.conf
server {
listen 80;
listen 443 ssl http2;
server_name app.example.com;
# SSL 配置
ssl_certificate /etc/ssl/certs/app.example.com.crt;
ssl_certificate_key /etc/ssl/private/app.example.com.key;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
# 安全頭
add_header X-Frame-Options SAMEORIGIN;
add_header X-Content-Type-Options nosniff;
add_header X-XSS-Protection "1; mode=block";
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
# 靜態資源快取
location ~* \.(jpg|jpeg|png|gif|ico|css|js|woff|woff2)$ {
expires 1y;
add_header Cache-Control "public, immutable";
access_log off;
root /var/www/app.example.com;
try_files $uri =404;
}
# API 反向代理
location /api/ {
proxy_pass https://backend_app;
proxy_http_version 1.1;
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_connect_timeout 30s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
proxy_buffering on;
proxy_buffer_size 64k;
proxy_buffers 8 128k;
proxy_busy_buffers_size 256k;
}
# WebSocket 支援
location /ws/ {
proxy_pass https://websocket_cluster;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_read_timeout 86400;
}
# 健康檢查端點
location = /health {
access_log off;
return 200 "healthy\n";
add_header Content-Type text/plain;
}
}
# 語法檢查
sudo nginx -t
# 熱重載
sudo nginx -s reload
# 查看進程
ps aux | grep nginx
# 壓測工具
yum install -y httpd-tools
ab -n 10000 -c 100 https://app.example.com/health
# 或使用 wrk(更現代)
git clone https://github.com/wg/wrk.git && cd wrk && make
./wrk -t4 -c200 -d30s https://app.example.com/api/health
| 現象 | 原因 | 解決 |
|---|---|---|
| 啟動失敗:port 80 occupied | Apache/httpd 佔用 | systemctl stop httpd && systemctl disable httpd |
| 權限錯誤:Permission denied | SELinux 或目錄權限 | chcon -Rt httpd_sys_content_t /var/www 或調整目錄擁有者 |
| 上游 502 Bad Gateway | 後端未啟動或端口錯誤 | 檢查 upstream server IP:Port、防火牆、後端日誌 |
| WebSocket 斷連 | 缺少 Upgrade 頭或超時設置 | 添加 proxy_set_header Upgrade/Connection、增加 proxy_read_timeout |
| 大文件上傳失敗 | client_max_body_size 過小 | client_max_body_size 100M; 在 http/server/location 層 |
從源碼編譯安裝 Nginx 雖步驟較多,但帶來版本可控、模組精簡、效能極致、安全強化的多重優勢。配合 systemd 服務化、模組化配置(include vhosts/*.conf)、完善的上游健康檢查與快取策略,可構建企業級高可用反向代理集群。建議建立標準化安裝腳本(Ansible/Shell)實現基礎設施即代碼(IaC),確保環境一致性與可復現性。