问题:
高并发大压力下发现TOP平台消息会出现消息串掉,
先说一下具体的原因:
数据交互中,其中一方单独认为业务交互失败,逻辑回收而非物理关闭复用的信道,另一方在完成业务操作时将业务数据再次推送到已经被逻辑回收的通道上,会导致请求和相应错位。
代码层设计问题:
1. 信道一次业务交互中的多次消息交互缺少唯一的会话码,导致中间任何一次交互出现问题,后续的数据会错位到后续复用此信道其他请求中。
2. 底层信道的回收,异常处理,没有在信道层直接处理,而是将错误通过业务堆栈抛到最外层ajp协议解析线程管理池去做,导致不论是业务捕获异常或者是servlet,spring框架捕获异常都会出现串号。
解决方法:
1. 在协议层增加会话码,发现会话错位,关闭信道。
2. 让底层信道出现异常自己回收和关闭信道,连接池获取连接的时候判断连接是否已经无效,无效即刻移除。(不需要用抛错误堆栈的方式来实现)
后续:
TOP这边已经在考虑异步Web request请求处理的方式,后续在安全的要求下可以和nginx 做类似信道复用的web服务器+应用服务器的模式。
详细说明看下面的内容:
用两张图片说明问题。
第一张是一次请求在JK和Jboss-web之间的交互过程。
问题发生在第四步,在jboss-web向JK请求body的数据的时候可能产生超时或者其他IO异常,这时候直接会走到9这步,由于异常被捕获,连接将不会被物理关闭。
一次请求处理的调用顺序如上,按照数字顺序,当在5出现问题的时候,AjpAprProcessor没有自己物理关闭,而是依赖异常上抛的方式,返回到ajpAprProtocal来关闭AjpAprProcessor。简单来做就只需要在5就地处理,关闭连接,虽然会被放入连接池,但是只要在2这个步骤使用连接池的时候检查一下连接状态就可以丢弃这些无效的连接。