我有一个使用 ServiceStack 构建的 Web API,它通过位于 RabbitMQ 上的 MassTransit 与 TopShelf 服务后端进行通信。大多数时候,一切正常,但有时我们开始看到大量请求开始进入错误队列的问题。
API 比较简单,只有 2 次调用。据我所知,查看日志,主要调用工作正常。然而,另一个调用是用于确定节点状态的调用,并且会导致问题。这两个调用都以相同的方式实现,使用请求/响应方法。
以下是其中一个错误的日志文件:
2012-08-25 00:01:28,544 [6] DEBUG MassTransit.Messages - SEND:rabbitmq://testapi:password@localhost:5672/test_API.Models:StatusMessage::test_API.Models.StatusMessage, Models
2012-08-25 00:01:28,575 [38] DEBUG MassTransit.Messages - SKIP:rabbitmq://testapi:password@localhost:5672/testapi_web:08cf3caf-6d81-0d5b-0050-56a800810000
2012-08-25 00:01:28,575 [38] DEBUG MassTransit.Messages - SKIP:rabbitmq://testapi:password@localhost:5672/testapi_web:08cf3caf-6d81-0d5b-0050-56a800810000
2012-08-25 00:01:28,575 [38] DEBUG MassTransit.Messages - SKIP:rabbitmq://testapi:password@localhost:5672/testapi_web:08cf3caf-6d81-0d5b-0050-56a800810000
2012-08-25 00:01:28,575 [38] DEBUG MassTransit.Messages - SKIP:rabbitmq://testapi:password@localhost:5672/testapi_web:08cf3caf-6d81-0d5b-0050-56a800810000
2012-08-25 00:01:28,575 [38] DEBUG MassTransit.Messages - SKIP:rabbitmq://testapi:password@localhost:5672/testapi_web:08cf3caf-6d81-0d5b-0050-56a800810000
2012-08-25 00:01:28,575 [38] DEBUG MassTransit.Messages - SKIP:rabbitmq://testapi:password@localhost:5672/testapi_web:08cf3caf-6d81-0d5b-0050-56a800810000
2012-08-25 00:01:28,575 [38] DEBUG MassTransit.Messages - SKIP:rabbitmq://testapi:password@localhost:5672/testapi_web:08cf3caf-6d81-0d5b-0050-56a800810000
2012-08-25 00:01:28,575 [38] DEBUG MassTransit.Messages - SKIP:rabbitmq://testapi:password@localhost:5672/testapi_web:08cf3caf-6d81-0d5b-0050-56a800810000
2012-08-25 00:01:28,575 [38] DEBUG MassTransit.Messages - SKIP:rabbitmq://testapi:password@localhost:5672/testapi_web:08cf3caf-6d81-0d5b-0050-56a800810000
2012-08-25 00:01:28,575 [38] DEBUG MassTransit.Messages - SKIP:rabbitmq://testapi:password@localhost:5672/testapi_web:08cf3caf-6d81-0d5b-0050-56a800810000
2012-08-25 00:01:28,575 [38] ERROR MassTransit.Transports.Endpoint - Message retry limit exceeded rabbitmq://testapi:password@localhost:5672/testapi_web:08cf3caf-6d81-0d5b-0050-56a800810000
2012-08-25 00:01:28,575 [38] DEBUG MassTransit.Messages - SEND:rabbitmq://testapi:password@localhost:5672/testapi_web_error:08cf3caf-6d81-0d5b-0050-56a800810000:
2012-08-25 00:01:28,575 [38] INFO MassTransit.Messages - MOVE:rabbitmq://testapi:password@localhost:5672/testapi_web:rabbitmq://testapi:password@localhost:5672/testapi_web_error:08cf3caf-6d81-0d5b-0050-56a800810000:
2012-08-25 00:01:33,888 [29] ERROR ServiceStack.ServiceInterface.ServiceBase`1 - ServiceBase<TRequest>::Service Exception
MassTransit.Exceptions.RequestTimeoutException: The request timed out: 08cf4f95-1a2b-d545-0050-56a800810000
at MassTransit.RequestResponse.RequestImpl`1.Wait() in d:\BuildAgent-03\work\8d1373c869590c5b\src\MassTransit\RequestResponse\RequestImpl.cs:line 107
at test.API.StatusService.OnGet(Status request)
at ServiceStack.ServiceInterface.RestServiceBase`1.Get(TRequest request)
我确实注意到它在抱怨超时。我们尝试了可变长度,但似乎没有帮助。查看与数据库的连接,消费者中似乎没有任何东西会真正阻止它,所以我不确定超时是由于发送时的多次失败引起的,还是仅仅是连接问题. 通常,响应会在不到一秒的时间内发生。
该请求是通过以下方式提出的:
this.DataBus.PublishRequest(new StatusMessage(request, RequestType.GET), x =>
{
x.Handle<StatusResponseMessage>(message =>
{
if (message.Exception != null)
{
Response.Message = message.Exception.Message;
}
Response.Node = message.Response.Node;
Response.Status = message.Response.Status;
});
x.SetTimeout(5.Seconds());
});
消费者是:
public void Consume(IConsumeContext<StatusMessage> context)
{
try
{
// Get status from database (not included)
context.Respond(new StatusResponseMessage(context.Message.CorrelationId, new StatusResponsePacket(context.Message.Request.Node, status, lastUpdated)));
}
catch (Exception e)
{
context.Respond(new StatusResponseMessage(context.Message.CorrelationId, e));
}
任何人都可以看到这有什么明显的错误吗?我检查了 API 和服务正在读取不同的队列(错误最终出现在 test_web_error 队列中),并检查了状态请求和响应数据包上是否设置了相关 ID 和 CorrelatedBy。如前所述,这只发生在这个调用中,而不是我们拥有的另一个调用。我也有多台服务器运行它,它似乎一次只发生在一台服务器上,但并不总是同一个服务器。