nginx端口占用案例分享
2016-11-20 13:43 whitejava 阅读(1809) 评论(0) 编辑 收藏 举报这里分享一个案例,问题的原因是反向代理使用不当。
现象
首先描述一下问题的现象。当时的问题是应用启动失败,日志里面报错显示端口占用。我们的应用都是通过脚本发布的,之前发布过多次都没有出现过问题。那么同样的脚本、同样的机器,这次怎么就发布失败了呢?
报错信息如下:
OSError: [Errno 48] Address already in use
问题排查
这个报错是很常见的,以为是发布的过程中上一个应用没有正常关闭。然后熟练的打开终端,连接到服务器,通过netstat -ant|grep LISTEN命令检查这个端口被谁占用了。这条命令的输出如下:
tcp 0 0 0.0.0.0:53130 0.0.0.0:* LISTEN
tcp 0 0 0.0.0.0:39308 0.0.0.0:* LISTEN
tcp 0 0 0.0.0.0:111 0.0.0.0:* LISTEN
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN
tcp 0 0 0.0.0.0:46429 0.0.0.0:* LISTEN
tcp 0 0 0.0.0.0:2049 0.0.0.0:* LISTEN
tcp 0 0 0.0.0.0:51329 0.0.0.0:* LISTEN
tcp6 0 0 0.0.0.0:2280 :::* LISTEN
我们的服务使用8080端口。于是熟练的在输出的内容里寻找8080。可是并没有找到!
看来这次情况跟以往不太一样了。怎么会这样呢?既然没有端口占用,为什么应用会起不来?于是我再次尝试启动应用,还是报了相同的错误。
转机
既然这样,那么我直接搜索8080试试,于是输入了下面的命令:
netstat -ant | grep 8080
很快,得到了下面的结果:
tcp 0 0 192.168.6.55:59580 192.168.6.55:8080 TIME_WAIT
居然出现了TIME_WAIT。在我的三观里TIME_WAIT只会出现在断开连接的时候啊,监听端口是不会出现TIME_WAIT的。这是要打破三观的节奏吗?
真相
真相只有一个。我让运维借用sudo权限看看这个连接是哪个进程的。最后发现这个端口是被nginx占用的。原来,nginx接收了很多请求,进行代理的时候发起tcp连接,这时会占用一个未被使用的随机端口。而后端应用和nginx部署在同一台机器,由于请求过多,nginx发起了大量连接,每个连接都是短连接,占用了大量的随机端口,并且需要经过30秒的TIME_WAIT状态才能释放占用。碰巧把后端应用的8080端口也占用了,导致应用无法启动。
结论
不要把nginx和后端应用部署在同一台机器。会有一定几率导致后端应用的端口被占用。