【问题标题】:How can I pull messages from Activemq Asynchronously如何从 Activemq 异步拉出消息
【发布时间】:2017-09-11 14:48:59
【问题描述】:

我想编写用于从Activemq 提取消息的代码。我不想一次从Activemq 提取所有消息,因为我的要求是每当我的Java 应用程序收到来自Activemq 的1 条消息时,根据消息正文,我会找到相应的HTTP Link 并转发到该链接。对于这整个逻辑,我写了 2 .java 文件名是

MessageConsumer.java

MyListener.java

MessageConsumer.java 文件仅用于建立连接。对应的代码如下。

 package PackageName;
 import java.io.IOException;
 import javax.servlet.ServletException;
 import javax.servlet.http.HttpServlet;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 import javax.jms.*;
 import org.apache.activemq.ActiveMQConnectionFactory;
 public class MessageConsumer extends HttpServlet {
@Override
protected void service(HttpServletRequest arg0, HttpServletResponse arg1)
    throws ServletException, IOException {
    try {
      //creating connectionfactory object for way
      ConnectionFactory connectionFactory=new        
      ActiveMQConnectionFactory("admin","admin","tcp://localhost:61617");
     //establishing the connection b/w this Application and Activemq
     Connection connection=connectionFactory.createConnection();
     Session session=connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
     Queue queue=session.createQueue("MessageTesing");
     javax.jms.MessageConsumer consumer=session.createConsumer(queue);
     //fetching queues from Activemq
     MessageListener listener = new MyListener();
    consumer.setMessageListener(listener);
    connection.start();
    System.out.println("Press a key to terminate");
    }
  catch (Exception e) {
    // TODO: handle exception
}
 }
}

MyListener.java 文件用于触发相应的 Applications.code 在下面

package PackageName;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.TextMessage;
public class MyListener implements MessageListener {
public void onMessage(Message msg) {
    try {
        TextMessage msg1=(TextMessage)msg;
        //just for your understanding I mention dummy code
        System.out.println(msg1.getText());
        if (msg1.getText()=="Google") {
            System.out.println("Forwarding http link to Google");
        }
        else {
            System.out.println("Forwarding http link to Facebook");
        }
    } catch (JMSException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}
}

在我的帖子中,我触发了 Google 和 Facebook 链接。但就我的要求而言,我将调用我自己的应用程序。每个应用程序需要 20 多分钟。所以我想一个接一个地提取消息。一旦之前的消息处理完成那么只有它会收到来自Activemq 的另一条消息。

但我知道我一次收到所有消息。我该如何解决这个问题。我看到了Activemq-Hellowworld 程序。我不明白。

对不起,我是Java technology 的新手。谁能帮助我。

谢谢。

【问题讨论】:

    标签: java jms activemq java-ee-6


    【解决方案1】:

    如果您使用的是MessageListener,那么您实际上是在异步接收消息(在另一个线程中)。

    您可能正在寻找同步消息接收,因此请在您的主线程中试试这个:

    final QueueReceiver queueReceiver = queueSession.createReceiver(queue);
    queueConnection.start();
    
    while (true) {
      Message message = queueReceiver.receive();
      // Process your message: insert the code from MyListener.onMessage here
    
      // Possibly add an explit message.acknowledge() here, 
      // if you want to make sure that in case of an exception no message is lost
      // (requires Session.CLIENT_ACKNOWLEDGE, when you create the queue session)
    
      // Possibly terminate program, if a certain condition/situation arises
    }
    

    没有MessageListener。

    receive() 阻塞 直到有消息可用,因此您的主线程(以及您的程序)在 receive 方法中等待。如果消息到达,它将接收并处理它。

    更新

    如果你使用

    Session session = connection.createSession(false, Session.CLIENT_ACKNOWLEDGE);
    

    那你应该打电话

    message.acknowledge()
    

    在消息被完全处理之后。

    而在Session.AUTO_ACKNOWLEDGE 的情况下,消息会立即从队列中删除(因此会丢失,如果程序在处理消息时终止)。

    【讨论】:

    • 我将您的代码集成到我的代码中,即使我收到来自Activemq 的消息,我的Activemq 控制台中的未决消息也没有减少。为什么会这样。
    • @Beryllium 因为这个任务,我完全糊涂了。
    • @user2642355 这改变了问题。我建议回滚到旧版本的问题,并发布一个主题为“如何设计......”的单独问题。在那个问题中,请描述您的应用程序的用例(没有技术内容,只是流程),以及您到目前为止所做的实现(使用 JMS 接收器的 servlet)。在 servlet 中使用 JMS 接收器的组合可能不是您想要的,所以我们需要从用例的角度来看待它。
    • 我发布了另一个问题。你能检查下面的链接。 http://stackoverflow.com/questions/18147115/how-can-i-call-externalapplication-based-on-activemq-message-using-jms
    【解决方案2】:

    您可以在MessageConsumer 对象中使用receive() 方法,而不是使用MessageListener。这样,您每次调用 receive() 方法时只会收到一条消息。

    MessageConsumer consumer = session.createConsumer(destination); 
    Message message = consumer.receive(1000);
    

    【讨论】:

      猜你喜欢
      • 2015-11-25
      • 1970-01-01
      • 2018-09-09
      • 1970-01-01
      • 1970-01-01
      • 2011-11-24
      • 2012-12-23
      • 2010-12-22
      • 1970-01-01
      相关资源
      最近更新 更多