【EAS工作流】问题记录-启用RPC异步线程池后导致偶发单据提交不进工作流原创
金蝶云社区-汪伟康
汪伟康
9人赞赏了该文章 75次浏览 未经作者许可,禁止转载编辑于2024年09月05日 14:13:16
summary-icon摘要由AI智能服务提供

文本描述了偶发付款单无法提交至工作流的问题。经分析,发现是由于RPC异步线程池未在工作线程完成时恢复工作流线程变量的初始值,导致线程复用时未触发工作流。解决方案包括修改配置文件禁用RPC异步线程池、修复异步线程池未触发监听的问题、加固凭证业务代码确保工作流服务正确开启,并完善日志打印以便于问题追踪。

  • 问题现象:偶发付款单提交不进工作流


  • 问题分析

1、worfklow.log通过搜到提交的单据id找到异常日志。

可知是该线程中工作流服务开关线程变量(ThreadLocal)中的值已经被改成false,导致不触发工作流。

image.png

2、而奇怪的是,付款单提交操作,日志中记录的是凭证提交方法中修改的工作流服务开关变量为关闭。

经业务同事再三分析确认,付款单提交方法中并没有调用凭证相关方法,因此这里陷入疑点。


3、此时我们的思路来到线程本身,我们知道业务操作的请求到EAS服务端会通过RPC线程池去调度,那么这里面存在线程复用,会不会是凭证提交的RPC线程刚好执行完成,然后被再次用来执行付款单提交方法。显然是会的。


4、于是我们分析工作流服务开关类相关代码(WfEventListenerStateManager),发现该类初始化时就会加入RPC线程池的一个监听(ThreadListener),在线程执行完成时(threadFinished(Thread thread);)会将该线程变量恢复初始值null,这样就可以保证RPC线程即便被复用也不会串线程变量。

image.png

image.png


5、那么是否是由于没有触发该监听导致的呢?

经过框架同事协助分析发现,RPC线程池当前分为同步或异步,然后RPC异步线程池没有实现线程完成时的方法,即没有在线程完成时去调用该监听类的threadFinished(Thread thread);方法,则无法将该线程变量恢复初始值null,当被该线程复用到下一个业务方法调度时就不会触发工作流校验了。

image.png


6、经核实,配置文件eas\server\profiles\server*\config\目录下的ormrpc_eas.propertie配置文件,isAsync=true 确实是启用了RPC异步线程池导致。

这里有个背景:默认EAS公有云环境该异步线程池会开启,由于很多公有云环境服务器默认有请求超时限制


  • 分析小结

问题到这里,基本破案。根因:启用RPC异步线程池之后工作流线程变量ThreadLocal没有在线程结束时恢复初始值。


  • 最终解决措施

1、该客户之前是公有云环境,后来已经改为私有云,经测试了下其实还是有超时机制。

但是为避免该类问题发生,还是建议把修改ormrpc_eas.propertie配置文件,删除isAsync=true或把true改成false 


2、对于RPC异步线程池没有实现线程完成方法触发ThreadListener 的threadFinished(Thread thread)的问题,框架同事出了私包修复。

修复后的代码如下:

image.png



3、凭证业务同事出私包加固:保证凭证业务方法调用完成之后必定会将工作流服务开启。


4、其他:工作流这块完善日志打印,将修改工作流线程变量的线程名称打印出来等等。






赞 9