nginx使用踩坑记录
本文档仅记录在试用过程中遇到的问题及注意事项,将根据使用经验不断完善。
使用nginx
支持websocket (ws://)
-
环境
操作系统:windows Server 2016/windows 10
nginx版本:nginx 1.15.7
tomcat + websocket + java
-
nginx配置支持websocket协议
location{
...
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
...
}
404问题
nginx关于websocket的配置:
server {
listen 9999;
server_name test2.com.cn;
location /ws {
proxy_http_version 1.1;
proxy_pass http://abc.def.ghi.123:9999/ws;
proxy_set_header Origin "";
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_connect_timeout 60s;
proxy_read_timeout 120s;
proxy_send_timeout 120s;
}
}
问题描述
开发环境没问题,可正常连接websocket服务并接收消息。
测试环境(无nginx代理),通过域名、公网ip访问也都没有问题。
生产环境(通过nginx代理),出现问题:
配置好nginx后,在控制台输入nginx -t检查配置文件无问题,nginx -s reload刷新nginx配置。
客户端(浏览器)通过域名访问项目时(websocket请求链接为ws://abc.def.ghi.123:9999/ws),浏览器console报错404
问题排查
排查:
-
配置问题(各种百度后,都是加proxy_http_version 1.1、及两个 upgrade将协议升级成websocket协议的配置就可以),排查后不是nginx配置的问题
-
协议问题,有资料说需要ssl协议证书,不过这是针对wss方式的,项目中使用实现的websocket的方式为ws,所以也不是这个问题。
-
客户端请求地址路径错误问题
-
最开始一看到报错就先怀疑的路径问题,查了nginx日志发现代理过去了,又去应用服务器查看tomcat的日志,发现tomcat返回了404;
websocket第一次握手时是http协议,仍然会请求tomcat,握手后才会告诉服务端“我是websocket”进而将协议升级为upgrade/websocket协议。
-
使用websocket在线测试工具,例如:http://www.websocket-test.com/,发现也访问不到ws://abc.def.ghi.123:9999/ws,于是想着线下模拟场景排查一下。
-
在线下模拟配置相似环境(windows10+nginx1.15.7+tomcat9),发现路径没问题,可以访问到。
-
也就是在线下模拟的时候,发现了一个问题,执行 nginx -s reload,nginx配置并没有立即生效,为了验证,又重新改了一下配置文件并reload刷新,新加的nginx配置仍未生效,查看系统进程,发现nginx起了十几个进程,这下忽然就看到了希望。
把nginx停掉,然后把系统进程里的nginx进程全部杀掉,再次启动一个nginx,发现新增配置生效。
-
去线上把nginx停掉,重新启动,发现websocket可正常访问了。
-
小结
windows版本的nginx 1.15.7更新配置后执行nginx -s reload,有时候会重新启动一个进程但是并不结束之前正在运行的进程,因此新修改的nginx配置也没有生效,所以我目前若更改完配置文件后都会先nginx -s stop停止nginx,然后再start nginx,这样配置文件是生效的。
支持websocket (wss://)
需要在nginx中配置ssl安全证书。
此项还没有深入了解,项目中目前没有使用到,闲余会继续尝试,补充本文档。
nginx代理配置
根据“ 域名:端口号 ”代理到不同/相同服务ip的不同端口
#映射到web服务(80端口)
server {
listen 80;
server_name test1.com.cn;
location / {
proxy_pass http://abc.def.ghi.123;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
#映射到跟web服务在同一服务器的websocket服务(9999端口)
server {
listen 9999;
server_name test2.com.cn;
location /ws {
proxy_http_version 1.1;
proxy_pass http://abc.def.ghi.123:9999/ws;
proxy_set_header Host $host:$server_port;
proxy_set_header Origin "";
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_connect_timeout 60s;
proxy_read_timeout 120s;
proxy_send_timeout 120s;
}
}