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()中退出而没有触发任何异常。
答案 0 :(得分:1)
我明白了。 由于我的主线程在我启动侦听器线程并且侦听器线程完美地运行(非守护程序线程)之后退出,因此它保持JVM运行。一旦监听器失去连接,程序就会退出,因为没有剩余的非守护程序线程。故障转移协议代码作为守护程序线程运行,因此JVM退出程序而不让故障转移协议代码重新连接。
所以我所做的就是添加这段代码,而不是最好的方法,但它适用于我想要做的事情。
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();
wait方法崩溃了,并没有使主线程保持活动状态。这也是一种保持程序运行而不将消息发送到队列以阻止它的方法。