我有多个MDB(以及大量的mdb实例)作为消息的消费者。我必须在这些Beans中收集某些统计信息,并将它们每X(当前30)秒发送到JMS目的地。
可以在bean本身中执行此操作吗?
例如:bean收集数据localy,并有一个使用@Scheduled注释的writeStatistic()方法。
是否可以集中统计统计信息?
中央bean从所有bean实例收集所有统计数据并发送它。如果可以的话,怎么办呢?
我通过编写一个看起来像这样的单例会话bean来解决我的任务:
@Singleton
@Startup
@ConcurrencyManagement(ConcurrencyManagementType.BEAN)
@Asynchronous
public class StatisticsCollector {
private ConcurrentMap<Integer, ConcurrentMap<String, AtomicInteger>> statistics = new ConcurrentHashMap<Integer, ConcurrentMap<String, AtomicInteger>>();
public void trackDatum(int projectId, String property, int increment) {
LOG.debug("Tracking datum: project: " + projectId + ", property: " + property + ", increment: " + increment);
// get statistics for project
ConcurrentMap<String, AtomicInteger> productstats;
if (!statistics.containsKey(projectId)) {
synchronized (statistics) {
if (!statistics.containsKey(projectId)) {
productstats = new ConcurrentHashMap<String, AtomicInteger>();
statistics.put(projectId, productstats);
} else {
productstats = statistics.get(projectId);
}
}
} else {
productstats = statistics.get(projectId);
}
// get current counter for property
AtomicInteger value;
if (!productstats.containsKey(property)) {
synchronized (productstats) {
if (!productstats.containsKey(property)) {
value = new AtomicInteger();
productstats.put(property, value);
} else {
value = productstats.get(property);
}
}
} else {
value = productstats.get(property);
}
// increment
value.addAndGet(increment);
}
@Schedule(minute = "*", hour = "*", second = "*/30", persistent = false)
public void sendStatistics() {
// send statistics to remote consumer via JMS
}
}
我自己进行了并发管理,因为我希望尽可能多地从bean中获得性能。
答案 0 :(得分:2)
可以在bean本身中执行此操作吗?
我想你的意思是:
@MessageDriven(...)
public MDBean implements MessageListener {
private Statistic statisticForThisBean;
// ...
@Timeout
public void sendStatisticForThisBean() {
// ...
}
}
肯定不是选项。无法保证@Timeout
- 带注释的方法将针对所有>>的bean实例运行,更不用说每30秒运行一次了。 timeout方法在MDB的一个空闲实例上运行,容器选择它。
是否可以集中统计数据?
就个人而言,我这样做:让所有MDB(所有实例)在处理逻辑结束时将部分统计信息发送到队列。我会写一个单独的组件:
“组件”可以是计时器任务,也可以是单独的独立应用程序。
另一种可能的解决方案可能是单个有状态bean,MDB将依次调用以更新统计信息。但是,以下限制适用: