如何在已注册的处理程序中记录响应消息 - ServiceStack RabbitMQ
How to log the response message in a Registered Handler - ServiceStack RabbitMQ
给定这段代码:
//DirectApi
mqServer.RegisterHandler<LeadInformationInfo>(m =>
{
repository.SaveMessage(m as Message);
LeadInformationInfoResponse response = new LeadInformationInfoResponse();
try
{
var client = new JsonServiceClient(settingsFactory.GetMasterSetting("ProcessorApi:baseUri"));
response = client.Post(m.GetBody());
}
catch (WebServiceException webServiceException)
{
_log.Error("RegisterHandler<LeadInformationInfo>", webServiceException);
response = ((LeadInformationInfoResponse) webServiceException.ResponseDto);
response.CorrelationId = m.Id;
}
// Log response message here
return response;
}, 1);
我已竭尽全力确保基于原始消息 ID 属性 的 correlationId 在此消息的整个生命周期内传播,以及由此操作产生的任何子消息。如何获取响应消息的句柄,以便将其记录到处理程序中?我只能访问 ResponseDto 而不能访问消息。
此请求的原因之一是消息队列客户端无法访问数据库,只有注册了处理程序的进程才能访问。希望能更好地解释这种情况。
澄清一下,这个问题是关于在处理程序中持久化 MQ 响应消息,相关 ID 是 1 request/response 工作流中的所有消息将共享的内容。我还使用 ServiceStack ORMlite 来保留 Message 对象,因此通过 ID 查询此 table 以进行故障排除是最重要的。
谢谢,
斯蒂芬
您正在从 MQ 处理程序中调用 WebService:
var client = new JsonServiceClient(...);
response = client.Post(m.GetBody());
因此没有仅在 MQ 服务中可用的 MQ 响应。虽然 WebService 将 return 发送请求的响应,因此您可以在 MQ 请求上使用 CorrelationId,否则您可以让 Response DTO 实现类似 IHasCorrelationId
的接口并以这种方式获取它,例如:
var correlationResponse = response as IHasCorrelationId;
if (correlationResponse != null)
{
var correlationId = correlationResponse.CorrelationId;
}
创建您自己的消息实例
作为 Message<T>
class is just a POCO 如果您想创建自己的实例,您可以初始化自己的实例:
var mqResponse = new Message<Response>(response);
如果您只有运行时后期绑定类型信息,您可以创建一个:
var mqResponse = MessageFactory.Create(response);
使用RabbitMQ Message Filters
如果您只想记录传入和传出的消息,您可以使用 RabbitMQ Message Filters,例如:
var mqServer = new RabbitMqServer("localhost")
{
PublishMessageFilter = (queueName, properties, msg) => {
properties.AppId = "app:{0}".Fmt(queueName);
},
GetMessageFilter = (queueName, basicMsg) => {
var props = basicMsg.BasicProperties;
receivedMsgType = props.Type; //automatically added by RabbitMqProducer
receivedMsgApp = props.AppId;
}
};
给定这段代码:
//DirectApi
mqServer.RegisterHandler<LeadInformationInfo>(m =>
{
repository.SaveMessage(m as Message);
LeadInformationInfoResponse response = new LeadInformationInfoResponse();
try
{
var client = new JsonServiceClient(settingsFactory.GetMasterSetting("ProcessorApi:baseUri"));
response = client.Post(m.GetBody());
}
catch (WebServiceException webServiceException)
{
_log.Error("RegisterHandler<LeadInformationInfo>", webServiceException);
response = ((LeadInformationInfoResponse) webServiceException.ResponseDto);
response.CorrelationId = m.Id;
}
// Log response message here
return response;
}, 1);
我已竭尽全力确保基于原始消息 ID 属性 的 correlationId 在此消息的整个生命周期内传播,以及由此操作产生的任何子消息。如何获取响应消息的句柄,以便将其记录到处理程序中?我只能访问 ResponseDto 而不能访问消息。
此请求的原因之一是消息队列客户端无法访问数据库,只有注册了处理程序的进程才能访问。希望能更好地解释这种情况。
澄清一下,这个问题是关于在处理程序中持久化 MQ 响应消息,相关 ID 是 1 request/response 工作流中的所有消息将共享的内容。我还使用 ServiceStack ORMlite 来保留 Message 对象,因此通过 ID 查询此 table 以进行故障排除是最重要的。
谢谢, 斯蒂芬
您正在从 MQ 处理程序中调用 WebService:
var client = new JsonServiceClient(...);
response = client.Post(m.GetBody());
因此没有仅在 MQ 服务中可用的 MQ 响应。虽然 WebService 将 return 发送请求的响应,因此您可以在 MQ 请求上使用 CorrelationId,否则您可以让 Response DTO 实现类似 IHasCorrelationId
的接口并以这种方式获取它,例如:
var correlationResponse = response as IHasCorrelationId;
if (correlationResponse != null)
{
var correlationId = correlationResponse.CorrelationId;
}
创建您自己的消息实例
作为 Message<T>
class is just a POCO 如果您想创建自己的实例,您可以初始化自己的实例:
var mqResponse = new Message<Response>(response);
如果您只有运行时后期绑定类型信息,您可以创建一个:
var mqResponse = MessageFactory.Create(response);
使用RabbitMQ Message Filters
如果您只想记录传入和传出的消息,您可以使用 RabbitMQ Message Filters,例如:
var mqServer = new RabbitMqServer("localhost")
{
PublishMessageFilter = (queueName, properties, msg) => {
properties.AppId = "app:{0}".Fmt(queueName);
},
GetMessageFilter = (queueName, basicMsg) => {
var props = basicMsg.BasicProperties;
receivedMsgType = props.Type; //automatically added by RabbitMqProducer
receivedMsgApp = props.AppId;
}
};