标签:ejb cluster timer cluster 集群
最近Customer Site报了一个错误,在Weblogic Cluster HA测试过程中,发生了Traffic集群中有一个节点在重启过程中仍然有请求数据送到该节点的问题。研究了相关的代码,发现了一个非常有趣又普遍的问题。
由于Traffic分发系统没有部署在Weblogic集群中,又需要分发到Weblogic集群中的Traffic节点,系统中使用了自己的load balancing机制。
代码中负责traffic分发的loadbalancer从Cluster当中部署的ClusterWebApp应用去拿Cluster中当前活着的trafficList。
而ClusterWebApp中Serverlet的getTrafficList是一个Web Serivce接口,从集群中部署的Stateless EJB获取trafficList并通过JSON返回给loadbalancer。如下图所示:
ClusterEJB中getTrafficList的实现,由于每次都从Weblogic读取traffic信息耗时比较长,所以在ClusterEJB中引入了缓存。
当ClusterWebApp调用ClusterEJB的getTrafficList方法时,返回的是ClusterEJB缓存的running traffic list。
这个缓存是通过Cluster EJB Timer来更新,每次timeout去Weblogic获取最新的traffic server list.
系统HA出错的日志显示是因为ClusterWebApp返回的trafficList偶尔会包含已经shutdown的节点。那么第一时间点就怀疑缓存失效。
查看ClusterEJB中timer的实现,使用的是Cluster EJB Timer,在weblogic部署描述符中指明了:<wls:timer-implementation>Clustered</wls:timer-implementation>
Cluster EJB Timer是用来处理聚群范围内的全局任务,比如定时生成报表,发送邮件等任务,这些任务不需要同时在多个集群节点同时执行,很显然本例中ClusterEJB的缓存
在于集群中部署了ClusterEJB的每一个节点,期望行为是Timer可以在每个节点同时执行更新缓存状态。而使用Cluster EJB Timer只能保证每次超时会在某一个节点上运行(取决
于集群的默认load balance算法或者部署描述符中指定的算法),这样集群中很多节点就会很长时间没有更新缓存从而出现了缓存失效的情况。
把Cluster EJB Timer改成Local就可以修复这个问题。
这是当初从非集群环境迁移到集群环境的时候直接使用了集群EJB Timer来代替普通Java Timer,没有仔细研究使用场景导致的错误。Timer或者类似的任务在集群部署的时候都要小心到底是Local的还是集群的。
Cluster EJB Timer 参考(英文)
weblogic-ejb-jar.xml Deployment Descriptor Reference
小心陷阱: 迁移应用到Cluster遇到的Timer问题,布布扣,bubuko.com
标签:ejb cluster timer cluster 集群
原文地址:http://blog.csdn.net/cloud_ll/article/details/38404719