C# .NET AMQP消息传递模式问题
我使用RabbitMQ创建了一个小类,它在主题交换上实现了发布/订阅消息传递模式。在此发布/订阅之上,我有以下方法和属性:C# .NET AMQP消息传递模式问题,c#,events,rabbitmq,messaging,eai,C#,Events,Rabbitmq,Messaging,Eai,我使用RabbitMQ创建了一个小类,它在主题交换上实现了发布/订阅消息传递模式。在此发布/订阅之上,我有以下方法和属性: void Send(Message,Subject)-将消息发布到目标主题,供任何订阅者处理 MessageReceivedEvent-订阅此消息传递实例上收到的消息事件(消息传递实例在创建时绑定到所需的订阅主题) SendWaitReply(消息,主题)-发送消息并阻止,直到收到相关id与已发送消息id(或超时)匹配的回复消息。这本质上是发布/订阅模式之上的请求/回复或R
- 对于侦听事件,当侦听器在单个线程中运行时,通过事件订阅服务器同步处理消息。这会在处理大量消息时(即,在使用web api事件的后端进程中)导致一些严重的性能问题。我正在考虑传入回调函数,而不是订阅事件,然后使用Task或Threadpool并行调度回调集合。线程安全现在显然是调用方关心的问题。我不确定这是不是一个正确的方法
- 对于SendWaitReply事件,我构建了一个看似黑客的解决方案,它从消息侦听器循环获取所有入站消息,如果它们包含非空的关联guid,则将它们放在ConcurrentDictionary中。然后,在SendWaitReply方法中,我轮询ConcurrentDictionary以查找包含与所发送消息的Id匹配的密钥的消息(或在特定时间段后超时)。如果有更快/更好的方法,我真的很想调查一下。也许有一种方法可以向所有当前被阻止的SendWaitReply方法发出信号,表明新消息可用,并且它们都应该检查自己的ID,而不是连续轮询
- 主题交换。服务A=>一些命令=>主题交换。服务B
- Topic\u-Exchange.Service\u-B=>some\u-command\u-reply=>Topic\u-Exchange.Service\u-A
从体系结构级别后退—我仍然存在消息侦听器循环的问题。我试过EventingBasicConsumer,但仍然看到一个区块。我的类的工作方式是调用方订阅类实例提供的委托。消息循环触发该委托上的事件,然后这些订阅者处理该消息。似乎我需要一种不同的方式将消息事件处理程序传递到实例中,这样它们就不会全部位于一个强制执行同步处理的委托后面。很难说为什么代码在没有示例的情况下会阻塞,但为了防止在使用时阻塞,您应该使用EventBasicConsumer
var consumer = new EventingBasicConsumer;
consumer.Received += (s, delivery) => { /* do stuff here */ };
channel.BasicConsume(queue, false, consumer);
一个警告是,如果您使用的是autoAck=false(正如我所做的),那么您需要确保在执行channel.BasicAck时锁定通道,否则您可能会遇到.NET库中的并发问题
对于SendWaitReply,如果您只使用RabbitMQ客户机库中包含的SimpleRpcClient,您的运气可能会更好:
var props = channel.CreateBasicProperties();
// Set your properties
var client = new RabbitMQ.Client.MessagePatterns.SimpleRpcClient(channel, exchange, ExchangeType.Direct, routingKey);
IBasicProperties replyProps;
byte[] response = client.Call(props, body, out replyProps);
SimpleRpcClient将处理创建临时队列、关联ID等,而不是构建自己的队列。如果你发现你想做一些更高级的事情,这也是一个很好的参考