改完 nginx 配置,nginx -t 一跑就冒出一行红色报错,reload 不敢执行,重启更不敢,站点就这么半死不活挂着——这种场面几乎每个运维都遇到过。其实 nginx 的报错信息已经写得相当直白:哪个文件、第几行、期望什么、实际拿到什么,都在里面。下面把最常见的几类出错位置列出来,按顺序对号入座。
一、先把报错信息读明白
nginx -t 的输出有固定格式,比如 nginx: [emerg] unknown directive “proxy_passs” in /etc/nginx/conf.d/example.com.conf:14。从里面能读出三件事:错误级别 emerg 表示配置加载失败;unknown directive 说明指令名写错或位置放错了;最后的文件名加冒号数字就是出错行号。看到行号先打开对应文件的那一行,问题八成就在这一行或它的上一行。这份 nginx配置详解 的排查思路,核心就是先把报错拆成这四段来看。
# nginx -t 的典型输出,学会从里面取信息
nginx: [emerg] unknown directive "proxy_passs" in /etc/nginx/conf.d/example.com.conf:14
nginx: configuration file /etc/nginx/nginx.conf test failed
# 配置正常时会输出:
# nginx: configuration file /etc/nginx/nginx.conf test is successful
二、分号与括号不配对,占了报错的一半
现象是 unknown directive “}” 或者 unexpected end of file,看着莫名其妙,原因其实很朴素:上一行少了个分号,或者花括号多写一个、少写一个。nginx 靠分号判断一条指令结束,少了它,nginx 会把下一行当成这条指令的一部分,直到撞见 } 才发现不对。做法很简单,找到报错行往上逐行看结尾,补上分号;花括号则数一遍区块的开合是否成对。
# 错误写法:proxy_pass 这行结尾少了分号
location / {
proxy_pass http://127.0.0.1:3000
}
# 正确写法
location / {
proxy_pass http://127.0.0.1:3000;
}
三、指令放错层级
现象是 “proxy_cache_path” directive is not allowed here 或者 “server_name” directive is not allowed here。nginx 的配置是分层的:http 块放全局和缓存定义,server 块放域名和监听,location 块放具体路径规则。指令都有规定的可放层级,放错就报这条错。常见的搬运错误是把 proxy_cache_path 写进了 server 或 location,它只能待在 http 块;反过来,server_name 也不能写进 location。办法就是把它挪到正确的那一层,再跑 nginx -t 确认。
# proxy_cache_path 只能在 http 块里定义
http {
proxy_cache_path /var/cache/nginx keys_zone=page_cache:10m max_size=1g;
server {
listen 80;
server_name example.com; # server_name 属于 server 层
location / {
proxy_cache page_cache; # location 层只负责启用
}
}
}
四、引用不到的东西:upstream、证书与文件路径
现象有两类。一类是 upstream “backend” not found,说明 proxy_pass 里用了 upstream 名字,但这个名字没有定义;另一类是 open() “/etc/nginx/ssl/example.com.crt” failed (2: No such file or directory),说明证书或日志路径写错了,或者文件权限不对。前者去 http 块补上 upstream 定义;后者用 ls 核对文件到底在不在、路径大小写对不对。伪静态规则写错也常在这一步暴露,因为规则里引用的脚本文件可能根本不存在,配置本身没错,运行起来照样 404。
# 定义 upstream,名字要和 proxy_pass 里引用的一致
upstream backend {
server 127.0.0.1:3000;
keepalive 16;
}
server {
listen 443 ssl;
server_name example.com;
ssl_certificate /etc/nginx/ssl/example.com.crt;
ssl_certificate_key /etc/nginx/ssl/example.com.key;
location / { proxy_pass http://backend; }
}
反复跑 nginx -t,直到看见 syntax is ok 和 test is successful 两行,再执行 nginx -s reload。养成一个习惯:任何配置改动都先在本地起一个测试实例验证,确认通过再上生产,比在生产机上边改边试安全得多。
相关阅读:
《nginx配置详解:反向代理、缓存与伪静态的常用写法》
《网站日志怎么看?access.log 关键字段与异常识别》
《Linux服务器常用命令速查:运维高频操作一页搞定》
申请创业报道,分享创业好点子。点击此处,共同探讨创业新机遇!
