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

时间:2014-09-09 12:39:52

标签: java tomcat hazelcast

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

问题:QueueListener停止侦听其队列。这意味着,在某个点之前,日志中会定期出现以下行,然后它会消失:

LOGGER.debug("No messages on {}, {}", queueName, QueueListener.this.getClass().getSimpleName());

日志中没有错误。我有几个扩展QueueListener的类,它们都监听一个不同的命名队列。其中一个只是停下来,我不知道为什么,除了一件事:它发生在处理一个项目后。后代类的句柄方法记录了我在日志中可以看到的项目。然后在{queuename}""没有消息记录刚刚消失。执行者有2个线程。两人都停了下来,不确定是否一下子。

后代类的handle方法执行Http请求并记录响应。请注意,在侦听器停止之前,响应未显示在前两个handle调用的日志中。

后代类的句柄方法没有任何catch块,所以它不会吞下任何异常。 QueueListener中没有记录任何异常。

我的问题,如何找到原因?在哪里寻找它?

将消息发送到此队列的应用程序在与侦听此队列的Tomcat相同的Tomcat中运行。已启用多播(请参阅完整的HazelCast配置)。还有一个运行在同一主机上的其他Tomcat和一些在不同主机上运行的其他Tomcats,它们都连接到同一个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;
    }
}

这是Hazelcast的配置方式:

@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);
}

0 个答案:

没有答案