0

我有一个与 WildFly 服务器通信的 Java Swing GUI 客户端。

独立-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");
  }
}
4

2 回答 2

1

即使很少看到保持连接打开的问题,除非您有严重的资源限制,否则消息传递协议通常足够轻量级,可以保持打开状态而不必担心连接/断开/重新连接。ActiveMQ 的文档就是这么说的,虽然我找不到每个连接的内存开销,但它并不多。还有服务器端配置可以帮助管理大量消息,但同样,我并不担心。

ActiveMQ 的一个缺点是它不支持真正的集群,所以如果你真的要处理 10 或 100 的数千个连接,那么你就会遇到问题。

最后,您需要对自己的终端进行性能分析,以确保应用程序与服务器一起运行。

于 2016-02-18T02:01:21.797 回答
0

如果您的应用程序经常向同一个目的地发送消息,那么最好创建一次连接、会话和生产者并重新使用它们,因为创建连接、会话等是昂贵的操作。

如果消息不经常发送,那么最好创建所有需要的对象,发送消息并关闭对象。这样就可以在消息传递提供程序上释放资源。

于 2016-02-15T09:51:40.277 回答