gpt4 book ai didi

c# - 消息队列服务重启后服务收不到消息

转载 作者:太空狗 更新时间:2023-10-29 17:51:01 24 4
gpt4 key购买 nike

我们有一个服务从 n 个消息队列接收消息。但是,如果重新启动消息队列服务,即使消息队列服务已成功重新启动,消息检索服务也会停止接收消息。

我试图专门捕获在消息检索服务中抛出的 MessageQueueException 并再次调用队列的 BeginReceive 方法。但是,在消息队列服务重启的 2 秒左右,我得到了大约 1875 个异常实例,然后当我们的 StartListening 方法中抛出另一个 MessageQueueException 时服务停止运行。

有没有一种优雅的方法可以从消息队列服务重启中恢复?

    private void OnReceiveCompleted(object sender, ReceiveCompletedEventArgs e)
{
MessageQueue queue = (MessageQueue)sender;

try
{
Message message = queue.EndReceive(e.AsyncResult);

this.StartListening(queue);

if (this.MessageReceived != null)
this.MessageReceived(this, new MessageReceivedEventArgs(message));
}
catch (MessageQueueException)
{
LogUtility.LogError(String.Format(CultureInfo.InvariantCulture, StringResource.LogMessage_QueueManager_MessageQueueException, queue.MachineName, queue.QueueName, queue.Path));
this.StartListening(queue);
}
}

public void StartListening(MessageQueue queue)
{
queue.BeginReceive();
}

我需要处理由此导致的无限循环问题并稍微清理一下,但你明白了。

当 MessageQueueException 发生时,调用 RecoverQueue 方法。

    private void RecoverQueue(MessageQueue queue)
{
string queuePath = queue.Path;
bool queueRecovered = false;

while (!queueRecovered)
{
try
{
this.StopListening(queue);
queue.Close();
queue.Dispose();

Thread.Sleep(2000);

MessageQueue newQueue = this.CreateQueue(queuePath);

newQueue.ReceiveCompleted += new ReceiveCompletedEventHandler(this.OnReceiveCompleted);

this.StartListening(newQueue);

LogUtility.LogInformation(String.Format(CultureInfo.InvariantCulture, "Message queue {0} recovered successfully.", newQueue.QueueName));

queueRecovered = true;
}
catch (Exception ex)
{
LogUtility.LogError(String.Format(CultureInfo.InvariantCulture, "The following error occurred while trying to recover queue: {0} error: {1}", queue.QueueName, ex.Message));
}
}
}

public void StopListening(MessageQueue queue)
{
queue.ReceiveCompleted -= new ReceiveCompletedEventHandler(this.OnReceiveCompleted);
}

最佳答案

收到服务重启导致的异常后,您必须释放旧的 MessageQueue,即取消绑定(bind)您的 ReceiveCompleted 事件,处理 MessageQueue 等。然后创建一个新的 MessageQueue 实例,并在新的 MessageQueue 实例上再次连接到 ReceiveCompleted 事件。

或者,您可以使用轮询方法在特定时间间隔创建一个新实例,调用 MessageQueue.Receive(TimeSpan),将等待传入消息或直到超时发生。在这种情况下,您处理消息并销毁 MessageQueue 实例并再次开始迭代。

通过每次重新创建 MessageQueue,您可以确保内置恢复。此外,由于底层队列的内部缓存,创建 MessageQueue 的开销很小。

伪代码...

while (!notDone)// or use a timer or periodic task of some sort...
{
try
{
using (MessageQueue queue = new MessageQueue(queuePath))
{
Message message = queue.Receive(TimeSpan.FromMilliseconds(500));

// process message
}
}
catch (MessageQueueException ex)
{
// handle exceptions
}
}

关于c# - 消息队列服务重启后服务收不到消息,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10336630/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com