【问题标题】:ActiveMQ .net client locks upActiveMQ .net 客户端锁定
【发布时间】:2011-09-29 20:41:52
【问题描述】:

我使用 Apache.NMS 和 Apcahe.NMS.ActiveMQ(1.0 版)库编写了一个 Windows 服务。该服务使用来自供应商服务器的 ActiveMQ 消息。

服务启动连接并监听消息(我处理 OnMessage 事件)

连接是事务连接,所以我在每条消息后调用 commit。

当服务启动时,一切都运行良好,并持续了一段时间。但是,它运行一段时间后,将不再消费消息。即使我重置服务。通常需要重新启动我的服务和供应商服务器(tomcat)才能让事情重新开始。供应商坚持认为他们没有任何问题。

任何一方(客户端或服务器)都不会引发异常 - 它只是“卡住”。

我应该考虑使用 Spring.Messaging.Nms 吗?

【问题讨论】:

    标签: .net activemq


    【解决方案1】:

    我发现了问题。建立连接和消息侦听器后,服务进入 Thread.Sleep(500) 循环。哑的。我重构了服务以在 OnStart 中启动所有内容并在 OnStop 中处理它。

    自从这样做以来,一切都运行良好。

    键盘和椅子之间发生经典 ID-10-T 错误。

    【讨论】:

      【解决方案2】:

      没关系,我在这里找到的:

      Transactional Message Processing with ActiveMQ and NMS

      【讨论】:

        【解决方案3】:

        我的代码有点不同。我没有在循环中轮询,而是设置了一个响应“OnMessage”事件的侦听器。我的代码类似于下面的代码。我的实际代码中有很多不相关的东西,但精神是一样的 - 希望这会有所帮助。

        factory = new Apache.NMS.ActiveMQ.ConnectionFactory("tcp://activemq:61616");
        
        connection = factory.QueueConnection(factory, "MyQueue", AcknowledgementMode.AutoAcknowledge)
        
        consumer = connection.Session.CreateConsumer(connection.Queue, "2 > 1"); //Get every msg
        
        consumer.Listener += new MessageListener(OnMessage);
        
        
        private void OnMessage(IMessage message)
        {
          //Process message here.;
        }
        

        【讨论】:

          【解决方案4】:

          我们刚刚在使用 .Net 服务与 ActiveMQ 通信时遇到了完全相同的问题,但我们的服务在仅传递大约 10-20 条消息后就锁定了。

          在使用和不使用 spring 框架的情况下都尝试过,如果不使用它会稍微好一点(除非我在想象)。

          您介意检查一下这段代码并告诉我它是否与您自己的相似吗?

          ConnectionFactory connectionFactory = new ConnectionFactory("tcp://activemq:61616");
          
          Connection connection = (Connection)connectionFactory.CreateConnection();
          connection.Start();
          
          Session session = (Session)connection.CreateSession(AcknowledgementMode.AutoAcknowledge);
          IDestination queue = session.GetQueue("test.queue");
          
          MessageConsumer consumer = (MessageConsumer)session.CreateConsumer(queue);
          
          for (int i = 0; i < 1000; i++)
          {
              IMessage msg = consumer.Receive();
              if (msg != null)
                  Console.WriteLine((msg as ITextMessage).Text);
          }
          

          【讨论】: