java - 代理关闭后,从 ActiveMQ 队列读取的独立 java 程序不会自动重新连接

标签 java activemq

ActiveMQ 设置、服务器、属性都在 jndi.properties 文件中。

示例:

java.naming.provider.url=failover:(tcp://localhost:61616?keepAlive=true)
java.naming.factory.initial = org.apache.activemq.jndi.ActiveMQInitialContextFactory
queue.MyQueue = testUpdate

虽然我的程序如下所示:

public class MQReader{

public final String JNDI_FACTORY = "ConnectionFactory";
public final String QUEUE = "MyQueue";

private QueueConnectionFactory queueConnectionFactory;
private QueueConnection queueConnection;
private QueueSession queueSession;
private QueueReceiver queueReceiver;
private Queue queue;

public static void main(String[] args) throws Exception {

    // create a new intial context, which loads from jndi.properties file
    javax.naming.Context ctx = new javax.naming.InitialContext();
    MQReader reader = new MQReader();
    reader.init(ctx);

    try {
        reader.wait();
    } catch (InterruptedException ie) {
        ie.printStackTrace();
    }
    reader.close();
}

public void init(Context context) throws NamingException, JMSException {
    queueConnectionFactory = (QueueConnectionFactory) context.lookup(JNDI_FACTORY);
    queueConnection = queueConnectionFactory.createQueueConnection();
    queueSession = queueConnection.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
    queue = (Queue) context.lookup(QUEUE);
    queueReceiver = queueSession.createReceiver(queue);
    queueReceiver.setMessageListener(
        message ->{
            try {
                if(message != null) {
                    //do stuff like print message for testing.
                }
            } catch (JMSException jmse) {
                    System.err.println("An exception occurred: " + jmse.getMessage());
            }
        }
    );
    queueConnection.start();
}

public void close() throws JMSException {
    queueReceiver.close();
    queueSession.close();
    queueConnection.close();
}

}

我认为 jndi 中的故障转移项目应该负责我的重新连接,但事实并非如此。我运行了代理并运行了程序,它工作得很好,但是一旦我停止了代理,我的消费者程序就会退出,退出代码为 1。“进程已完成,退出代码为 1”

我不确定我在这里做错了什么。我在很多地方添加了 print out 语句,发现它在 reader.wait() 处退出,没有触发任何异常。

最佳答案

我明白了。 由于我的主线程在启动监听器线程后退出,并且监听器线程正在完美运行(非守护线程),因此它使 JVM 保持运行。一旦监听器失去连接,程序就会退出,因为没有剩余的非守护线程正在运行。故障转移协议(protocol)代码作为守护线程运行,因此 JVM 退出程序而不让故障转移协议(protocol)代码重新连接。

所以我所做的就是添加这段代码,这不是最好的方法,但它适合我想要做的事情。

 Scanner in = new Scanner(System.in);
    while(true){
        System.out.println("Please enter \"stop\" to stop the program.");
        String command = in.nextLine();
        if("stop".equalsIgnoreCase(command)){
            reader.close();
            System.exit(0);
        }
    }

而不是

try {
    reader.wait();
} catch (InterruptedException ie) {
    ie.printStackTrace();
}
reader.close();

等待方法崩溃并且没有使主线程保持 Activity 状态。这也是一种让我的程序保持运行而无需向队列发送消息来停止它的方法。

关于java - 代理关闭后,从 ActiveMQ 队列读取的独立 java 程序不会自动重新连接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37578140/

相关文章:

java - Spring批量写入ActiveMQ

java - ActiveMQ 给出 : "Could not connect to broker URL: tcp://localhost:61616" after around 10 000 messages

java - 如果在 Jetty 日志下禁用密码,JreDisabled :java. 安全意味着什么

java - Tomcat 8 是否正在读取我的 Java Rest API( war )中的 web.xml 和 context.xml 文件?

java - 如何使用jsp在选择框中根据结果集值设置所选选项

java - ActiveMQ授权

java - 以编程方式更改 TextView 对齐方式

java - Android ListView 从数据库记录实现的问题

rabbitmq - 寻找正确的 mule 组件以按 fifo 顺序解复用消息

java - 清理ActiveMQ对象