“All TCP servers should specify this socket option to allow the server to be restarted in this situation.”
最近为了提高机器利用率,将原来一台机器部署一个进程改为部署两个进程,考虑到运维的成本,就简单修改可以自动尝试新的端口,当时觉得这个只会在第二个进程启动时会出现。新版本发布没多久,通过网管系统发现异常了,到机器上一看,发现本该监听10086,10087两个端口的,结果变成了10088,10089,这尼玛肿么回事。通过监控脚本日志发现进程重启过了,按理说进程重启这端口还是不会变啊,查看运行日志发现进程重启时10086,10087都被占用了,通过netstat看到在10086上面有TIME_WAIT的链接,行家一眼就看出问题了,这尼玛不就是没设SO_REUSEADDR么,是的确实是通过设置了这个选项就搞定了。
这里顺便说下为啥端口变了就导致服务不可用,因为对外服务时是直接给的服务的指定端口,要是有一个配置中心之类的服务而不是直接暴露服务会更好些,这样就无所谓你端口变不变了,反正对外是透明的。
另外进程重启是因为在某些时刻进程负载过高导致定时器没有触发,间接导致监控脚本认为进程僵死而将其kill掉,这一点目前也修复了。
之前单进程部署时进程有时也会有重启现象,但是由于是非10086端口不可,因此在2MSL时间过后进程还是可以顺利启动的,当然之前没有防止进程僵死的监控,进程重启的概率非常小。
总结几点:
1UNP不仔细看完并实践,真不能写出健壮的网络程序
2当服务需要横向扩展时,提供一个类似配置中心的角色是必须的