服务总线如何在服务器重启后重新连接(非天蓝色)

时间:2016-10-18 09:11:51

标签: c# windows-services servicebus

我在Premise上使用Service Bus 1.1,我正在构建一个WindowsService,它应该只是在另一台机器上运行的特定队列上侦听。

连接到SB的WindowsService代码如下:

MessagingFactory _receiverFactory = MessagingFactory.CreateFromConnectionString(sbConnectionString);
MessageReceiver _messageReceiver = _receiverFactory.CreateMessageReceiver(listeningQueue);

BrokeredMessage brokeredMessage = _messageReceiver.Receive(TimeSpan.FromSeconds(60));

在重新启动服务器之前一切正常:我注意到如果WindowsService在服务总线的所有服务都可用之前启动,我的应用程序将永远不会连接,直到我手动重启WindowsService。

实际上,如果在构建MessagingFactory时SB没有完全运行,接收指令将始终失败,即使SB服务第二次回来......

我试图拦截异常(MessagingCommunicationException)并重建MessagingFactory,但根本不起作用,重新连接的唯一方法是重启WindowsService。

有什么建议吗?

1 个答案:

答案 0 :(得分:0)

  1. 设置高可用性(“HA”)服务场。
  2. https://blogs.technet.microsoft.com/meamcs/2013/12/08/recommended-practices-service-bus-for-windows-server/

    http://www.planetgeek.ch/2014/12/10/service-bus-for-windows-server-high-availability/

    但即使你做了或不做#1“HA”,你也应该做#2。

    1. 使用“Polly”捕获并自动重试特定的例外

      using System;
      using System.Collections.Generic;
      using System.Linq;
      using System.Threading;
      
      using Microsoft.ServiceBus;
      using Microsoft.ServiceBus.Messaging;
      
      using Polly;
      
      private static void KeepReadingTheQueue(QueueClient qc)
      {
          int retries = 0;
          int eventualFailures = 0;
      
          Policy pol = Policy.Handle<System.OperationCanceledException>(ex => null != ex)
              .Or<UnauthorizedAccessException>(ex => null != ex)
              .Or<Microsoft.ServiceBus.Messaging.MessagingCommunicationException>()
              .Or<Microsoft.ServiceBus.Messaging.MessageLockLostException>()
              .WaitAndRetryForever(
              sleepDurationProvider: attempt => TimeSpan.FromMilliseconds(500), // Wait 500ms between each try.
              onRetry: (exception, calculatedWaitDuration, context) => // Capture some info for logging!
              {
      
                  ReportDuplicatesOrMissing("Policy.OnRetry", batchNumbers);
      
                  // This is your new exception handler! 
                  // Tell the user what they've won!
                  Console.WriteLine("Log, then retry: " + exception.Message, ConsoleColor.Yellow);
                  retries++;
              });
      
          int i = 0;
      
          int receiveBatchSize = 1; /* i have this in a custom settings class, hard coded here */
      
          while (true)
          {
              i++;
      
              ReportDuplicatesOrMissing("while.true", batchNumbers);
      
              try
              {
                  // Retry the following call according to the policy - 15 times.
                  pol.Execute(() =>
                  {
                      IEnumerable<BrokeredMessage> messages = null;
                      if (receiveBatchSize <= 1)
                      {
                          // Receive the message from the queue
                          BrokeredMessage receivedMessage = qc.Receive();
                          List<BrokeredMessage> listMsgs = new List<BrokeredMessage>();
                          listMsgs.Add(receivedMessage);
                          messages = listMsgs as IEnumerable<BrokeredMessage>;
                      }
                      else
                      {
                          messages = qc.ReceiveBatch(receiveBatchSize);
                          int count = messages.Count();
                          if (count > 0)
                          {
                              Console.WriteLine("ReceiveBatch.Count='{0}'", count);
                          }
                      }
      
                      foreach (BrokeredMessage receivedMessage in messages)
                      {
                          if (receivedMessage != null)
                          {
                              MyPayLoadObject concreteMsgObject = receivedMessage.GetBody<MyPayLoadObject>();
                              receivedMessage.Complete();
                              Console.WriteLine(@"Message received: {0}", concreteMsgObject);
                          }
                          else
                          {
                              Console.WriteLine(@"No new messages in the queue");
                              Thread.Sleep(1000);
                          }
      
                          Thread.Sleep(100);
                      }
      
                  });
              }
              catch (Exception e)
              {
                  Console.WriteLine("Request " + i + " eventually failed with: " + e.Message, ConsoleColor.Red);
                  eventualFailures++;
              }
          }
      }
      
    2. packages.config

      <?xml version="1.0" encoding="utf-8"?>
      <packages>
        <package id="Microsoft.WindowsAzure.ConfigurationManager" version="2.0.1.0" targetFramework="net45" />
        <package id="Polly" version="4.3.0" targetFramework="net45" />
        <package id="WindowsAzure.ServiceBus" version="2.1.4.0" targetFramework="net45" />
      </packages>
      
相关问题