背景介绍

工作流缓存

工作流缓存是存在于EAS实例内部的JVM缓存,同时通过UDP组播(端口:38928)实现了各实例之间缓存同步,下图是工作流缓存的简要工作机制:

Untitled

问题表现

测试数据显示一些问题是因为工作流缓存不一致导致的。

重现过程:

  1. 通过设置客户端的set-url.bat分别登陆到主干环境的server2,server3。

  2. 在工作流监控中选择一条 正在运行的流程数 据复制出 流程实例ID。

  3. 在查询分析器执行以下逻辑:

    1. 在server2,server3上分别加载该流程,查看该流程的状态
    2. 在server2把状态更新为已完成,closed.complete
    3. 在server2清除当前的流程缓存(默认会通知server3)
    4. 在server3上重新查看该流程的状态
    SELECT * FROM T_wfr_procinst where fprocinstid='0df33aa8-1f1a-4650-bcb0-dcdc17fe33bcWFPCINST'--open.running
    UPDATE T_wfr_procinst SET fstate='open.running'   WHERE  FPROCINSTID ='0df33aa8-1f1a-4650-bcb0-dcdc17fe33bcWFPCINST'
    UPDATE T_wfr_procinst SET fstate='closed.completed'   WHERE  FPROCINSTID ='0df33aa8-1f1a-4650-bcb0-dcdc17fe33bcWFPCINST'
    com.kingdee.bos.workflow.enactment.WfEngine.getEngine(ctx).getProcessInst("0df33aa8-1f1a-4650-bcb0-dcdc17fe33bcWFPCINST").getProcessMeta().getState()
    
    com.kingdee.bos.workflow.enactment.WfEngine.getEngine(ctx).getCacheManager().processInstExpired("6896ba3b-f004-4534-ad7e-7b921c62791cWFPCINST");
    
  4. 通过第3步发现在server3上流程状态依然为运行中,证明缓存通知机制失效

分析过程

1,**udp不可靠,消息丢失?**聚焦在“udp”部分,查看udp 组播代码,发现未指定网卡,根据网上的资料来看,如果服务器存在多网卡的情况 会存在绑定到一个不可用的网卡 导致udp包发不出去。代码中加入下面这行,发现问题依然存在:

Untitled

2,转换思路,连上服务器查看“网络配置”,一开始也没思路,在网上查资料发现可以通过Linux自带的 ncat命令来监控tcp/udp,通过一番学习之后,使用如下命令来监听组播端口38928的入站信息:

>ncat -ul -p 38928

在客户端发送“缓存清除”命令之后,服务器上果然监听到入站信息,证明组播端口是通的,但是没办法证明组播成员之间是互通的???(存疑)

Untitled

3,使用arthas监控关键逻辑,来观察实例是否收到缓存清除命令