Java Hazelcast队列停止工作,在哪里查找错误?

Java Hazelcast队列停止工作,在哪里查找错误?,java,tomcat,hazelcast,Java,Tomcat,Hazelcast,我将Hazelcast用作在Tomcat中运行的两个应用程序之间的非持久性队列 问题:QueueListener停止侦听其队列。这意味着,在某一点之前,以下行会定期出现在日志中,然后消失: LOGGER.debug("No messages on {}, {}", queueName, QueueListener.this.getClass().getSimpleName()); 日志中没有错误。我有几个类扩展了QueueListener,它们都侦听不同的命名队列。其中一个刚停下来,我不知道为

我将Hazelcast用作在Tomcat中运行的两个应用程序之间的非持久性队列

问题: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);
}