繁体   English   中英

处理onMessage()中响应的最佳方法

[英]Best way to handle responses in onMessage()

我有一个独立的MQ监听器,它监听队列。 在onMessage()中处理响应的最佳方法是什么。 我不希望我的业务逻辑出现在onMessage()中。 我也不希望onMessage()等待解析响应并将其存储在DB中。

public abstract class MQReceiver implements MessageListener{
    public void pollResults(Long counter) throws JMSException, InterruptedException {
        Queue rQueue = null;
        QueueSession session = null;
        QueueReceiver receiver;
        count = counter;        

        try{
            session =   connection.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
            rQueue = session.createQueue(getReceiveQueue());

            receiver = session.createReceiver(rQueue);
            receiver.setMessageListener(this);
            connection.start();
            while(count > 0){
                logger.info("Waiting......Count >> " + count);
                Thread.sleep(SLEEPTIME);    
            }

            if(count == 0){
                session.close();
                logger.info("exiting poll results");
            }

        }finally{
            if(session != null)
                session.close();
        }

      }

@Override
    public void onMessage(Message message) {
             if (message instanceof TextMessage) {
                //Parse and Apply business logic
                //Store in DB
             }
}

如果您不想等待业务逻辑和数据库交互,则可以将工作分散到另一个线程并返回。

但是请注意,如果您下班到另一个线程,则会失去对该线程的异常控制。

我认为您可以从Java 8中的CompletableFuture开始:

        YourOffworkService service;
        ....
        public void onMessage(Message msg){
           if (message instance of TextMessage) {
             CompletableFuture.runAsync(() -> { service.process(msg);});
           } 
        }

编辑

在Java 7中,您可以通过ThreadRunnable

public class YourOffworkService extends Thread {
      private Message message;

      public YourOffworkService(Message message) {
       this.message = message;
      }

      public void run() {

       // Here come the business logic / DB interaction
      }
}

然后在您的onMessage()

public void onMessage(Message msg) {
    ...bla bla...
    new YourOffworkService(msg).start();
}

但是,为什么不希望OnMessage线程等待您完成工作呢? 这几乎是消息传递系统的目的。 如果由于某些错误而无法插入数据库,则消息将回滚并且不会丢失-可以尝试再次尝试。 如果您将逻辑/数据库操作转移到其他地方,则会降低容错能力。

无论如何,最好的方法不是从OnMessage产生线程或类似线程,而是将消息排队到由工作线程读取的某些内部队列中。 如果只是简单地增加线程数量,那么在启动时,队列中的几千条消息将无法处理。 Java为此有一个不错的BlockingQueue 这样,您可以控制有多少线程在忙于执行逻辑/数据库工作。 您需要在某处设置一个限制,以限制可以从ActiveMQ读取多少条消息,然后再等待后端可以跟上。 队列是一种很好的方法。

阻塞队列示例。

final BlockingQueue<String> internalQueue = new ArrayBlockingQueue<String>(CAPACITY);

...

new Thread(new Runnable() { // TODO make a named class and schedule as many thread as needed.
        @Override public void run() {
            try {
                while (true) {
                    String msg = internalQueue.take();
                    System.out.println(msg);
                }
            } catch (InterruptedException e) {
                System.out.println("Interrupted.");
            }
        }
    }).start();

...

public void onMessage(Message message) {
         if (message instanceof TextMessage) {
              internalQueue.put(((TextMessage)message).getText());
         }
}

无论如何,当您再次考虑时,将队列保留在ActiveMQ中不是更好吗? 如果该过程太耗时,请考虑将流程分成多个步骤,并在两者之间添加队列。

例:

  • 队列 ->验证/错误检查-> 队列 ->大量逻辑-> 队列 ->大量数据库持久性->队列-> 通知

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM