Nginx这东西,配置看着简单,但坑是真多。有时候一个配置写错了,整个站就挂了,而且报错信息还不太直观。我这些年踩过的Nginx配置坑,今天整理一下,看看你中了几个。
一、location匹配顺序搞混
这个是最常见的坑之一。Nginx的location匹配不是按配置文件里的顺序来的,而是有一套优先级规则:
1. 精确匹配(=)优先级最高
2. 前缀匹配(^~)其次
3. 正则匹配(~和~*)再其次
4. 普通前缀匹配最低
我之前就遇到过,明明写了正则location,结果请求总是被前面的普通location匹配到了。后来才明白,如果普通location匹配到了,但后面有正则location,Nginx会继续检查正则。但加了^~就不会再检查了。
建议:配置location的时候,一定要搞清楚匹配优先级,别想当然。
二、proxy_pass的斜杠问题
这个坑我踩了不止一次:
// 不带斜杠
proxy_pass http://backend;
// 带斜杠
proxy_pass http://backend/;
这两个看起来差不多,实际区别大了:
- 不带斜杠:请求/abc会转发到http://backend/abc
- 带斜杠:请求/abc会转发到http://backend/abc
等等,好像一样?不是的,关键看location怎么写:
location /api/ {
proxy_pass http://backend/; // /api/xxx -> /xxx
}
location /api/ {
proxy_pass http://backend; // /api/xxx -> /api/xxx
}
带斜杠的时候,Nginx会把location匹配到的部分替换掉。这个细微差别,搞不好就出bug。
三、root和alias分不清
这两个指令都是用来指定文件路径的,但行为不一样:
- root:完整的路径 = root + location
- alias:完整的路径 = alias(替换掉location)
举个例子:
location /static/ {
root /var/www; // 访问/static/a.js -> /var/www/static/a.js
}
location /static/ {
alias /var/www/; // 访问/static/a.js -> /var/www/a.js
}
alias后面一定要带斜杠,root带不带都行。这个搞混了,静态文件就404了。
四、忘记配置client_max_body_size
Nginx默认的请求体大小限制是1MB,上传文件超过1MB就报413错误。好多人不知道这个默认值,上传功能怎么都不好使,折腾半天才发现是Nginx的问题。
配置方法:
client_max_body_size 50m; // 根据实际需求设置
建议放在http块里全局生效,不用每个server都配一遍。
五、gzip压缩没开
这个不算bug,但影响用户体验。Nginx默认没开启gzip压缩,传输的数据量会大很多。
推荐配置:
gzip on;
gzip_min_length 1k;
gzip_comp_level 4;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml;
注意gzip_types要包含你实际使用的MIME类型,默认只压缩text/html。
六、缓存配置不完整
很多人配了缓存,但只配了一半:
// 只配了这个
expires 30d;
这个对静态文件有效,但如果要更精细的控制,还需要配proxy_cache。特别是反向代理场景,不配缓存的话,每次请求都打到后端服务器。
七、HTTPS配置不安全
配HTTPS容易,配安全的HTTPS不容易。很多教程只告诉你这样配:
ssl_protocols SSLv2 SSLv3 TLSv1;
但SSLv2和SSLv3早就不安全了!现在应该这样配:
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
还可以加上HSTS头:
add_header Strict-Transport-Security \"max-age=31536000\" always;
八、日志格式不够详细
默认的Nginx日志格式比较简单,很多关键信息没有。建议自定义一个更详细的日志格式:
log_format detailed \'$remote_addr - $remote_user [$time_local] \'
\'\"$request\" $status $body_bytes_sent \'
\'\"$http_referer\" \"$http_user_agent\" \'
\'$request_time\';
加上$request_time可以看到每个请求的处理时间,排查性能问题很有用。
九、worker_connections设太小
默认值是512,对于高并发场景远远不够。建议至少设到4096或更高:
events {
worker_connections 4096;
}
同时也要检查系统的ulimit设置,确保文件描述符限制够大。
十、配置改完不reload
这个真的很低级,但我就干过。改了配置,忘了reload,还在纳闷怎么不生效。
nginx -t // 先测试配置是否正确
nginx -s reload // 再重新加载
养成习惯,每次改完配置先test再reload。
总结
Nginx配置的坑远不止这些,但这十个是最常遇到的。建议每次写配置的时候多想想,别只顾着让功能跑通,安全和性能也要考虑。
大家还有什么Nginx踩坑经历?欢迎留言分享。
