Java Hazelcast队列停止工作,在哪里查找错误?
我将Hazelcast用作在Tomcat中运行的两个应用程序之间的非持久性队列 问题:QueueListener停止侦听其队列。这意味着,在某一点之前,以下行会定期出现在日志中,然后消失:Java Hazelcast队列停止工作,在哪里查找错误?,java,tomcat,hazelcast,Java,Tomcat,Hazelcast,我将Hazelcast用作在Tomcat中运行的两个应用程序之间的非持久性队列 问题:QueueListener停止侦听其队列。这意味着,在某一点之前,以下行会定期出现在日志中,然后消失: LOGGER.debug("No messages on {}, {}", queueName, QueueListener.this.getClass().getSimpleName()); 日志中没有错误。我有几个类扩展了QueueListener,它们都侦听不同的命名队列。其中一个刚停下来,我不知道为
LOGGER.debug("No messages on {}, {}", queueName, QueueListener.this.getClass().getSimpleName());
日志中没有错误。我有几个类扩展了QueueListener,它们都侦听不同的命名队列。其中一个刚停下来,我不知道为什么,除了一件事:它发生在处理一件物品之后。子类的handle方法记录我在日志中看到的项。然后,“在{queuename}上没有消息”日志行就消失了。执行器有两个线程。两人都停了下来,不确定是否立即停止
子类的handle方法执行Http请求并记录响应。请注意,在侦听器停止之前,响应没有出现在前两次handle
调用的日志中
子类的handle方法没有任何catch块,因此它不会接受任何异常。QueueListener中未记录任何异常
我的问题是,如何着手找出原因?去哪里找
将消息发送到此队列的应用程序与侦听此队列的应用程序在同一个Tomcat中运行。已启用多播(请参阅下面的完整HazelCast配置)。另一个Tomcat运行在同一台主机上,另一些Tomcat运行在不同的主机上,它们都连接到同一个Hazelcast实例。他们用的是同一个密码
Hazelcast版本:2.6
QueueListener.java:
package com.mi6.publishers;
import com.hazelcast.core.HazelcastInstance;
import com.hazelcast.core.IQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
public abstract class QueueListener<T> {
private static final long TIMEOUT = 10000L;
private static final Logger LOGGER = LoggerFactory.getLogger(QueueListener.class);
/**
* queue which is processed
*/
private IQueue<T> queue;
private final String queueName;
@Autowired
private HazelcastInstance instance;
private ExecutorService svc;
private final int threadCount;
private volatile boolean shutdown = false;
/**
* Constructor
*
* @param queueName
* @param threadCount
*/
public QueueListener(String queueName, int threadCount) {
this.queueName = queueName;
this.threadCount = threadCount;
}
/**
* @PostConstuct Start background threads
*/
@PostConstruct
public void init() {
LOGGER.info("Constructing hazelcast listener for {}", getClass().getSimpleName());
if (instance != null) {
queue = instance.getQueue(queueName);
svc = Executors.newFixedThreadPool(threadCount);
for (int i = 0; i < threadCount; i++) {
svc.submit(new Runnable() {
@Override
public void run() {
while (!shutdown) {
try {
T item = queue.poll(TIMEOUT, TimeUnit.MILLISECONDS);
if (item != null) {
handle(item);
} else {
LOGGER.debug("No messages on {}, {}", queueName, QueueListener.this.getClass().getSimpleName());
}
} catch (InterruptedException ex) {
// do nothing if interrupted
} catch (Exception ex) {
LOGGER.error("Error while receiving messages from queue:{}", queueName);
LOGGER.error("Error while receiving messages", ex);
}
}
}
});
}
} else {
throw new IllegalStateException("Hazelcast instance cannot be null");
}
}
/**
* call before stop
*/
@PreDestroy
public void destroy() {
shutdown = true;
if (svc != null) {
svc.shutdown();
}
}
/**
* Event handler
*
* @param item
*/
public abstract void handle(T item);
public String getQueueName() {
return queueName;
}
}
处理(T项)
做什么?@vikingsteve,好问题。子类的handle方法执行Http请求并记录响应。请注意,在侦听器停止之前,响应没有出现在前两次handle
调用的日志中。好的。我猜如果句柄
方法丢失了它的方式,那么这很可能会对hazelcast队列产生负面影响。有没有可能用no op
handle方法重写实现并测试它?实际上是有可能的。实际上,我正在重写handle方法,使其更具防御性和更详细。让我带着测试结果回来。你能试试Hazelcast 3.3吗?Hazelcast 2.6非常古老:)
@Value("${hazelcast.multicast:True}")
private Boolean hazelcastMulticast;
@Value("${hazelcast.group:groupNameNotSet}")
private String hazelcastGroup;
@Bean(destroyMethod = "shutdown")
public HazelcastInstance hazelcastInstance() {
Config cfg = new Config();
cfg.setInstanceName(hazelcastGroup);
NetworkConfig network = cfg.getNetworkConfig();
network.setPortAutoIncrement(true);
Join join = network.getJoin();
join.getMulticastConfig().setEnabled(hazelcastMulticast);
cfg.getGroupConfig().setName(hazelcastGroup);
cfg.getGroupConfig().setPassword(hazelcastGroup);
QueueConfig sms = new QueueConfig();
sms.setName("some-queue-name1");
cfg.addQueueConfig(sms);
QueueConfig flash = new QueueConfig();
flash.setName("some-queue-name2");
cfg.addQueueConfig(flash);
QueueConfig apns = new QueueConfig();
apns.setName("some-queue-name3");
cfg.addQueueConfig(apns);
QueueConfig gcm = new QueueConfig();
gcm.setName("some-queue-name4");
cfg.addQueueConfig(gcm);
return Hazelcast.newHazelcastInstance(cfg);
}