我有一个与WildFly服务器通信的Java Swing GUI客户端。
standalone-full.xml
<jms-queue name="goReceiveFmSvrQueue">
<entry name="java:/jboss/exported/jms/goReceiveFmSvrQueue"/>
<durable>true</durable>
</jms-queue>
<jms-queue name="goSendToSvrQueue">
<entry name="java:jboss/exported/jms/goSendToSvrQueue"/>
<durable>true</durable>
</jms-queue>
我的客户端有一个Runnable MsgCenterSend类。它实例化MsgCenterSend。然后调用msgCenter.run()来启动连接。然后使用msgCenter.send()发送消息。并且msgCenter.stop()在客户端关闭时关闭它。
这有意义吗?
或者客户端是否应该在每次需要发送消息时创建连接,会话,目标和生产者?如果它这样做应该在一个单独的线程中完成?
public class MsgCenterSend implements Runnable {
private Connection connection = null;
private MessageProducer msgProducer = null;
private Session session = null;
public void run() {
Context ctx = new InitialContext(/*connection propoerties*/);
HornetQJMSConnectionFactory jmsConnectionFactory = (HornetQJMSConnectionFactory) ctx.lookup("jms/RemoteConnectionFactory");
this.connection = jmsConnectionFactory.createConnection("jmsuser", "jmsuser@123");
this.session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
Destination sendToDestination = (Destination) ctx.lookup("jms/goSendToSvrQueue");
this.msgProducer = this.session.createProducer(sendToDestination);
this.connection.start();
}
public boolean sendMsg (/*parameters*/) {
ObjectMessage message = this.session.createObjectMessage();
// set MessageObject and Properties
this.msgProducer.send(message);
}
public void stop ()
this.connection.stop();
}
}
}
客户端在退出时使用stop()。
现在我的MessageBean看起来像:
@MessageDriven(
activationConfig ={
@ActivationConfigProperty(propertyName="destinationType", propertyValue="javax.jms.Queue"),
@ActivationConfigProperty(propertyName="maxSession",propertyValue="1"),
@ActivationConfigProperty(propertyName="destination", propertyValue="jms/goSendToSvrQueue")
})
public class GoMsgBean implements MessageListener {
@ApplicationScoped
@Inject
JMSContext jmsCtx;
//This is queue client listens to. Server sends replies to it.
@Resource(name = "java:jboss/exported/jms/goReceiveFmSvrQueue")
private Queue svrSendQueue;
public GoMsgBean () {
}
@PostConstruct
public void myInit () {
System.out.println("XXXXXXXXXX Post Construct - GoMsgBean XXXXXXXXXX");
}
@PreDestroy
public void myDestroy () {
System.out.println("XXXXXXXXXX Post Destroy - logger XXXXXXXXXX");
}
public void onMessage(Message msg) {
System.out.println("XXXXXXXXXX MessageBean received a Message XXXXXXXXX");
}
}
答案 0 :(得分:1)
即使不经常我也没有看到保持连接打开的问题,除非你有严重的资源限制,消息传递协议通常很轻,只能保持打开而不用担心连接/断开/重新连接。 ActiveMQ的文档准确地说明了这一点,虽然我找不到每个连接的内存开销,但它并不是很多。还有服务器端配置可以帮助管理大量的消息,但同样,我并不担心它。
ActiveMQ的一个缺点是它不支持真正的群集,所以如果你真的要处理10个或100个成千上万的连接,那么你就会遇到问题。
最后,您需要在结束时进行性能分析,以确保应用程序与服务器一起运行。
答案 1 :(得分:0)
如果您的应用程序经常将消息发送到同一目的地,那么最好一次创建连接,会话和生产者并重新使用它们,因为创建连接,会话等操作成本很高。
如果不经常发送消息,那么最好创建所有必需的对象,发送消息并关闭对象。这样就可以在消息传递提供程序上释放资源。