WebSphere Liberty中EJB Persistent Timer高效取消技术问询
WebSphere Liberty EJB Timer 取消性能优化方案
1. 是否可通过TimerService直接获取单个定时器?
标准EJB TimerService API没有提供直接通过标识(比如你的arc)定位单个定时器的方法,但WebSphere Liberty 23.0.0.9有专有扩展API可以实现这个需求:
- 使用
com.ibm.websphere.ejbcontainer.TimerManager扩展接口,它支持通过定时器标识或自定义属性查询。你可以通过JNDI查找该服务,然后用getTimersByQuery方法传入包含arc的查询条件,直接定位目标定时器,无需遍历全部。
示例代码:
InitialContext ctx = new InitialContext(); TimerManager timerManager = (TimerManager) ctx.lookup("java:comp/websphere/TimerManager"); TimerQuery query = new TimerQuery(); query.setInfo(arc); // 若arc存储在timer的info中 // 若arc是自定义属性,改用下面的写法 // query.addProperty("arc", arc); Collection<Timer> timers = timerManager.getTimersByQuery(query); if (!timers.isEmpty()) { timers.iterator().next().cancel(); }
注意:这个扩展依赖com.ibm.websphere.appserver.api.ejbcontainer包,需要在项目中引入该API依赖。
2. 若仅能遍历所有定时器,是否有更高效的获取timer info的方式?
如果必须遍历,可从以下两个方向优化:
缓存定时器映射关系:创建定时器时,把
arc和对应的Timer实例存入全局缓存(比如ConcurrentHashMap),取消时直接从缓存取实例调用cancel。要注意在定时器到期销毁时(比如@Timeout方法执行后)移除缓存中的对应条目,避免内存泄漏。改用自定义属性存储arc:默认情况下,EJB Timer的
info会存在数据库中,每次getInfo()都会触发DB查询。你可以把arc设为定时器的自定义属性,自定义属性存在Timer元数据中,调用timer.getProperties().get("arc")无需访问数据库,性能会大幅提升。
创建定时器时设置自定义属性的示例:
TimerConfig config = new TimerConfig(); config.setInfo(originalInfo); // 保留原有info内容 Map<String, Serializable> props = new HashMap<>(); props.put("arc", arc); config.setProperties(props); timerService.createSingleActionTimer(duration, config);
取消时遍历读取属性:
for (Timer timer : timerService.getTimers()) { String timerArc = (String) timer.getProperties().get("arc"); if (arc.equals(timerArc)) { timer.cancel(); break; } }
内容的提问来源于stack exchange,提问作者Lyss P. Hacker
相关产品推荐
相关产品推荐

