Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/entity-framework/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 在onMessage()中处理响应的最佳方法_Java_Activemq_Ibm Mq_Message Queue_Mq - Fatal编程技术网

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

Java 在onMessage()中处理响应的最佳方法,java,activemq,ibm-mq,message-queue,mq,Java,Activemq,Ibm Mq,Message Queue,Mq,我有一个独立的MQ侦听器,它侦听队列。处理onMessage()中的响应的最佳方法是什么。我不希望我的业务逻辑出现在onMessage()中。另外,我不希望onMessage()等待解析响应并存储在DB中 public abstract class MQReceiver implements MessageListener{ public void pollResults(Long counter) throws JMSException, InterruptedException {

我有一个独立的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中,您可以通过
线程
可运行

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()
中:


但是为什么不让OnMessage线程等待您完成工作呢?这几乎就是消息传递系统的用途。如果由于某些错误而无法插入数据库,则消息将回滚并且不会丢失,并且可以尝试第二次尝试。如果在其他地方卸载逻辑/数据库操作,则会丢失容错能力

无论如何,最好的方法不是从OnMessage生成线程或类似的线程,而是将消息排队到某个内部队列,由工作线程读取。如果您只是简单地启动线程,那么在处理启动时队列上的几千条消息时就会出现问题。Java为此提供了一个很好的解决方案。通过这种方式,您可以控制有多少线程应该忙于处理逻辑/数据库事务。您需要在某个地方设置一个限制,以限制您可以从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());
         }
}
final BlockingQueue internalQueue=new ArrayBlockingQueue(容量);
...
新建线程(new Runnable(){//TODO创建一个命名类,并根据需要调度尽可能多的线程。
@重写公共无效运行(){
试一试{
while(true){
字符串msg=internalQueue.take();
System.out.println(msg);
}
}捕捉(中断异常e){
System.out.println(“中断”);
}
}
}).start();
...
消息(消息消息)上的公共无效{
如果(文本消息的消息实例){
internalQueue.put(((TextMessage)message.getText());
}
}
无论如何,当您下次再考虑时,将队列保留在ActiveMQ中不是更好吗?如果过程太耗时,考虑将流程分成多个步骤,队列中的队列。

例如:

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

不幸的是,我使用的是Java 7。您能给我推荐Java 7中最好的选项吗?我尝试使用ThreadPoolTaskExecutor,我使用SpringBatch,在编写器中它调用了一个消息侦听器类。问题是底层表被另一个并行运行的spring批处理锁定,反之亦然,这会影响onMessage()。它不会发回确认。一旦您使用
ThreadPoolTaskExecutor.submit()
提交到线程池,您将获得一个
Future
。使用该
Future
进行检查,然后使用可选的
submit()
方法。使用
execute
时,将控制权完全移交给执行者
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());
         }
}