问题已经解决,分享一下,免得被坑。
目前问题的出现依赖于守护进程(watcher)的部分功能,口述一下
1 watcher会通过内网心跳来了解自己负责的这几个服务器程序是否存活,
2 每个Scene独占一个进程,不存在2个Scene挤在一个进程中,也就是,一个进程中有一个NetInner fiber和一个逻辑 fiber
3 通过粗暴的叉掉服务器框框的办法模拟“服务器宕机”,这样死掉的服务器是来不及 progress.WaitForExit的,也就是说,Watcher和已死服务器之间的Session是没有办法通过操作系统层面(Socket层面)的Error来断开的。
由于服务器之间用的是Udp socket,因此也不会有超时机制(也不应该有)来让这个Socket断开。
并且,从Session到Channel,冲突Id都是已死服务器的StartSceneConfig.Id!! 因此,这个Session从Channel开始就已经漏了,连Channel都不会感觉到下边Socket已经换了,上边的Session,再上边的NetInner,再再上边的ProcessOuterSender,更不会知道。
所以Watcher还一直守着个“僵尸Session”来监听,自然不会有任何消息,毕竟Socket都换了。
发现问题三小时,解决问题五分钟:watcher一旦发现程序状态是HasExitd的,直接组播给所有存活服务器,要求他们的NetInner手动Dispose掉这个已死服务的Id所对应的Session,然后再走启动流程就可以了。
我不确定有没有更好的做法,而且也不觉得这是个Bug,有更好的姿势请不吝赐教