1.前言
平台是基于传统主从架构开发,leader负责所有实例的写操作,follower负责执行leader下发的命令,leader follower之间采用akka进行通信,将下发的命令&执行结果通过kryo序列化后进行交互
2.问题描述
在平台用户日益增多,任务量不断增长的情况下,偶然一次有用户反馈,任务长时间处于中间状态不变更(启动中,停止中),持续时间十分钟+
3.排查过程
业务角度:
- 查看集群资源使用情况,检查资源是否不足从而导致任务提交pending,【pass】
- 查看任务提交日志是否有异常,导致任务在不断重试提交,【pass】
平台角度:
- 定位任务提交节点,查看当前节点身份(Leader/Follower),查看任务执行轨迹日志,任务从启动到任务提交过程没有异常日志,最终也看到任务成功在集群running 【pass】
- 检查主从通信,判断是follower没上报结果还是leader收到结果后未成功处理,经过定位问题为后者,具体异常为KryoException,Leader在收到Follower上报结果进行反序列化时出现异常
定位到时kryo框架序列化是问题时,开始围绕kryo排查问题点,定位到异常栈为:Buffer underflow.,查看kryo相关文档了解到,在出现该异常的情况可能有如下四种:
- 1.output未flush或者close
- 2.返回byteArray方式不对,应该用stream而不是output
- 3.不能在多线程环境中执行
- 4.序列化和反序列时字段发生变更,或者byte[]不完整
检查业务代码,对比上述可能异常情况点,前3中情况,程序中已做相应处理,重点关注第四种情况,在查看kryo文档发现,在用kryo做序列化时,需要将序列化涉及到的对象注册到kryo并指定一个ID,用于序列化对象和ID之间的映射,这么做的原因是因为在反序列化时kryo