服务公告

服务公告 > 综合新闻 > Nginx-星耀云

Nginx-星耀云

发布时间:2026-04-27 13:09

一、前言

搞过的人都知道,最烦的是Nginx配完了访问502、用着用着进程挂了、日志里一堆诡异错误根本不知道从哪查。新手上来就是server块复制粘贴,资深点的配置了一大堆但线上跑着跑着就出幺蛾子。本文不废话,直接给你一套能上生产环境的Nginx实战配置模板,从基础安装到高可用调优,手把手跑通。

二、操作步骤

第1步:确认系统环境并安装Nginx

CentOS/RHEL 执行:

sudo yum install -y epel-release sudo yum install -y nginx nginx -v

预期输出(CentOS/RHEL):

nginx version: nginx/1.20.1 built with OpenSSL 1.0.2k-fips 26 Jan 2017 TLS SNI support enabled

Ubuntu 执行:

sudo apt-get update sudo apt-get install -y nginx nginx -v

预期输出(Ubuntu):

nginx version: nginx/1.18.0 (Ubuntu) built with OpenSSL 1.1.1f 31 Mar 2020

第2步:查看默认配置结构

CentOS/RHEL 执行:

ls -la /etc/nginx/ cat /etc/nginx/nginx.conf

预期输出(CentOS/RHEL):

total drwxr-xr-x 2 root root 4096 Dec 1 10:00 nginx.conf drwxr-xr-x 3.15 root 6 Nov 9 2020 nginx.conf.default conf.d/ default.d/ mime.types mime.types.default modules-enabled/ modules-available/ nginx.conf nginx.conf.default scgi_params scgi_params.default uwsgi_params uwsgi_params.default win-utf

Ubuntu 执行:

ls -la /etc/nginx/ cat /etc/nginx/nginx.conf

预期输出(Ubuntu):

conf.d/ fastcgi.conf fastcgi.conf.default fastcgi_params fastcgi_params.default koi-utf koi-win mime.types mime.types.default nginx.conf nginx.conf.default scgi_params scgi_params.default sites-available/ sites-enabled/ uwsgi_params uwsgi_params.default win-utf

第3步:创建站点配置文件

执行命令:

sudo mkdir -p /var/www/example.com/html sudo chown -R www-data:www-data /var/www/example.com echo '<html><body><h1>Nginx实战配置成功</h1></body></html>' | sudo tee /var/www/example.com/html/index.html

预期输出:

<html><body><h1>Nginx实战配置成功</h1></body></html>

创建站点配置文件:

sudo tee /etc/nginx/sites-available/example.com.conf <<'EOF' server { listen 80; server_name example.com www.example.com; root /var/www/example.com/html; index index.html index.htm; access_log /var/log/nginx/example.com_access.log; error_log /var/log/nginx/example.com_error.log; location / { try_files $uri $uri/ =404; } location /health { access_log off; return 200 "healthy\n"; add_header Content-Type text/plain; } } EOF

预期输出:

server { listen 80; server_name example.com www.example.com; root /var/www/example.com/html; index index.html index.htm; access_log /var/log/nginx/example.com_access.log; error_log /var/log/nginx/example.com_error.log; location / { try_files $uri $uri/ =404; } location /health { access_log off; return 200 "healthy\n"; add_header Content-Type text/plain; } } EOF

启用站点(创建软链接):

CentOS/RHEL 执行:

sudo ln -s /etc/nginx/sites-available/example.com.conf /etc/nginx/conf.d/example.com.conf sudo nginx -t

Ubuntu 执行:

sudo ln -s /etc/nginx/sites-available/example.com.conf /etc/nginx/sites-enabled/example.com.conf sudo nginx -t

预期输出(两者相同):

nginx: the configuration file /etc/nginx/nginx.conf syntax is ok nginx: configuration file /etc/nginx/nginx.conf test is successful

第4步:配置SSL反向代理到后端应用

生成自签名证书(生产环境请用Let's Encrypt):

sudo mkdir -p /etc/nginx/ssl sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/nginx/ssl/example.com.key -out /etc/nginx/ssl/example.com.crt -subj "/C=CN/ST=Beijing/L=Beijing/O=MyCompany/CN=example.com"

预期输出:

Generating a RSA private key .............................+++++ .......................................+++++ writing new private key to '/etc/nginx/ssl/example.com.key' -----

创建反向代理配置:

sudo tee /etc/nginx/sites-available/api-proxy.conf <<'EOF' upstream backend { server 127.0.0.1:8080 max_fails=3 fail_timeout=30s; server 127.0.0.1:8081 backup; keepalive 32; } server { listen 443 ssl http2; server_name api.example.com; ssl_certificate /etc/nginx/ssl/example.com.crt; ssl_certificate_key /etc/nginx/ssl/example.com.key; ssl_protocols TLSv1.2 TLSv1.3; ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256; ssl_prefer_server_ciphers on; ssl_session_cache shared:SSL:10m; ssl_session_timeout 1d; client_max_body_size 50M; proxy_read_timeout 300s; proxy_connect_timeout 75s; proxy_send_timeout 300s; location / { proxy_pass http://backend; proxy_http_version 1.1; proxy_set_header Connection ""; 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-Forwarded-Host $host; proxy_set_header X-Forwarded-Port $server_port; proxy_buffering off; proxy_request_buffering off; } location /metrics { proxy_pass http://127.0.0.1:9090/metrics; proxy_set_header Host $host; } } server { listen 80; server_name api.example.com; return 301 https://$server_name$request_uri; } EOF

预期输出:

server { listen 443 ssl http2; server_name api.example.com; ... }

⚠️ 警告:启用新配置前务必执行测试!

sudo ln -s /etc/nginx/sites-available/api-proxy.conf /etc/nginx/sites-enabled/api-proxy.conf sudo nginx -t && echo "配置语法正确"

预期输出:

nginx: the configuration file /etc/nginx/nginx.conf syntax is ok nginx: configuration file /etc/nginx/nginx.conf test is successful 配置语法正确

第5步:配置负载均衡(upstream)

创建负载均衡配置:

sudo tee /etc/nginx/sites-available/loadbalancer.conf <<'EOF' upstream web_cluster { least_conn; server 10.0.1.10:8000 weight=5 max_fails=2 fail_timeout=10s; server 10.0.1.11:8000 weight=3 max_fails=2 fail_timeout=10s; server 10.0.1.12:8000 weight=2 max_fails=3 fail_timeout=30s; server 127.0.0.1:8000 backup; } server { listen 80; server_name lb.example.com; location / { proxy_pass http://web_cluster; 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_next_upstream error timeout http_502 http_503 http_504; proxy_next_upstream_tries 3; proxy_next_upstream_timeout 10s; } location /status { proxy_pass http://web_cluster; access_log off; } } EOF sudo ln -sf /etc/nginx/sites-available/loadbalancer.conf /etc/nginx/sites-enabled/loadbalancer.conf sudo nginx -t

预期输出:

nginx: the configuration file /etc/nginx/nginx.conf syntax is ok nginx: configuration file /etc/nginx/nginx.conf test is successful

第6步:配置限流防止滥用

创建限流配置:

sudo tee /etc/nginx/sites-available/rate-limit.conf <<'EOF' limit_req_zone $binary_remote_addr zone=api_limit:10m rate=100r/s; limit_req_zone $binary_remote_addr zone=login_limit:10m rate=5r/m; limit_conn_zone $binary_remote_addr zone=conn_limit:10m; server { listen 80; server_name limit.example.com; root /var/www/limit.example.com/html; location /api/ { limit_req zone=api_limit burst=200 nodelay; proxy_pass http://backend; proxy_set_header Host $host; } location /auth/login { limit_req zone=login_limit burst=10 nodelay; limit_conn conn_limit 5; proxy_pass http://backend; limit_req_status 429; limit_conn_status 429; } error_page 429 = @rate_limit_exceeded; location @rate_limit_exceeded { return 429 '{"error":"rate_limit_exceeded","retry_after":60}'; add_header Content-Type application/json; } } EOF sudo ln -sf /etc/nginx/sites-available/rate-limit.conf /etc/nginx/sites-enabled/rate-limit.conf sudo nginx -t

预期输出:

nginx: the configuration file /etc/nginx/nginx.conf syntax is ok nginx: configuration file /etc/nginx/nginx.conf test is successful

第7步:配置日志轮转与性能调优

创建日志轮转配置:

sudo tee /etc/logrotate.d/nginx <<'EOF' /var/log/nginx/*.log { daily missingok rotate 30 compress delaycompress notifempty create 0640 www-data adm sharedscripts postrotate [ -f /var/run/nginx.pid ] && kill -USR1 `cat /var/run/nginx.pid` endscript } EOF cat /etc/logrotate.d/nginx

预期输出:

/var/log/nginx/*.log { daily missingok rotate 30 compress delaycompress notifempty create 0640 www-data adm sharedscripts postrotate [ -f /var/run/nginx.pid ] && kill -USR1 `cat /var/run/nginx.pid` endscript }

调优系统内核参数(添加到 /etc/sysctl.conf):

sudo tee -a /etc/sysctl.conf <<'EOF' net.core.somaxconn = 65535 net.core.netdev_max_backlog = 65535 net.ipv4.tcp_max_syn_backlog = 65535 net.ipv4.ip_local_port_range = 1024 65535 net.ipv4.tcp_tw_reuse = 1 net.ipv4.tcp_fin_timeout = 15 fs.file-max = 1000000 EOF sudo sysctl -p

预期输出:

net.core.somaxconn = 65535 net.core.netdev_max_backlog = 65535 net.ipv4.tcp_max_syn_backlog = 65535 net.ipv4.ip_local_port_range = 1024 65535 net.ipv4.tcp_tw_reuse = 1 net.ipv4.tcp_fin_timeout = 15 fs.file-max = 1000000

第8步:平滑reload验证所有配置

执行reload:

sudo nginx -s reload sleep 1 sudo nginx -v && ps aux | grep nginx | grep -v grep

预期输出:

nginx version: nginx/1.20.1 root 12345 0.0 0.2 12345 4567 ? Ss 10:00 0:00 nginx: master process /usr/sbin/nginx -c /etc/nginx/nginx.conf www-data 12346 0.0 0.1 12356 2345 ? S 10:00 0:00 nginx: worker process www-data 12347 0.0 0.1 12356 2346 ? S 10:00 0:00 nginx: worker process www-data 12348 0.0 0.1 12356 2347 ? S 10:00 0:00 nginx: worker process www-data 12349 0.0 0.1 12356 2348 ? S 10:00 0:00 nginx: worker process

检查所有站点配置加载情况:

sudo nginx -T 2>&1 | grep -E "server_name|listen" | head -30

预期输出:

listen 80; server_name example.com www.example.com; listen 443 ssl http2; server_name api.example.com; listen 80; server_name api.example.com; listen 80; server_name lb.example.com; listen 80; server_name limit.example.com;

三、常见问题FAQ

Q1:配置reload了但完全不生效,curl返回的还是旧内容?

老手回答:先确认你改的不是include进来的文件里的错误路径,其次检查proxy_cache有没有缓存。直接curl -I 看一下响应头里的Cache-Control和X-Cache-Status。另外还有个坑——如果你在server块里用了set $var "xxx",但这个变量在location里没被引用,Nginx会把它优化掉根本不执行。排查命令:nginx -T | grep -A5 'location /your_path'。

Q2:upstream后端明明是通的,但Nginx报502 Bad Gateway?

老手回答:别上来就怀疑Nginx配置,大概率是后端应用的问题。用curl直连后端地址看能不能返回,再看后端日志。常见坑:后端监听的端口绑定了127.0.0.1但你的proxy_pass写的公网IP、后端进程OOM被OOM Killer干掉了、后端用的是Unix Socket但权限不对。调试命令:netstat -tlnp | grep 8080 看端口监听状态,tail -f /var/log/nginx/error.log 看实时错误日志。

Q3:CPU占用率飙到100%,Nginx worker进程全卡住?

老手回答:十有八九是惊群问题或者没开worker_connections导致的。更恶心的是upstream keepalive没配对——Nginx侧设置了keepalive但后端没开启长连接,每次请求都要走三次握手。另一个常见场景是regex location匹配了带参数的请求,正则回溯导致CPU 100%。先执行top -H -p $(pgrep -d',' nginx)看看是哪个worker占用高,然后用strace -p pid -f -T看看卡在哪。

Q4:同一个IP访问量正常但带宽打满了,怀疑被恶意爬虫?

老手回答:先用awstats或者goaccess分析access日志,确认是哪个URL消耗带宽。如果是大文件下载类站点,配置下proxy_cache_range,不然每次请求都透传到后端。很可能是CSS/JS/图片没做压缩或没开启gzip,或者被人镜像了你的站点。配置gzip_static可以减少压缩CPU消耗。恶意爬虫的话,limit_req和limit_conn先怼上去,然后分析日志把异常IP加入iptables的recent模块黑名单。

Q5:HTTPS配置了但Chrome还是显示不安全?

老手回答:检查证书链是否完整——用openssl s_client -connect yourdomain.com:443 -showcerts看看返回的证书链有没有中间证书。另外检查SNI是否启用,很多CDN或者负载均衡器会改掉SNI头导致证书匹配失败。还有个老坑:mixed content,页面里引用了http://的资源,浏览器会降级显示不安全。用curl -k可以绕过证书验证,但线上别用-k参数排查。

四、总结

核心要点:

  • 生产环境必须分离配置:站点配置放sites-available/sites-enabled或conf.d/,不要全塞nginx.conf
  • reload前必须nginx -t验证语法,配置错了不会回滚,只会让你半夜爬起来
  • 反向代理必须设置X-Forwarded-*系列请求头,不然后端拿不到真实客户端IP
  • upstream的backup参数只用于故障转移,不是负载分担,权重weight才是分担
  • 限流配置要分场景:API接口用r/s,后台登录用r/m,防止暴力破解
  • 所有配置修改完成后立即检查ps aux | grep nginx确认进程存活

延伸阅读:

最后说一句:Nginx配置这东西,文档看一百遍不如线上踩一个坑。记住生产环境改配置前先备份nginx.conf,改完后立刻reload并检查进程状态,别等到用户投诉了才发现。

上一篇: DNS-星耀云

下一篇: Varnish 自动化-星耀云