Rabbitmq MassTransit丢失消息-Rabbit MQ-当发布者和使用者终结点名称相同时,
我们遇到了这样一种情况:如果使用相同的端点名称创建发布者和使用者,MassTransit将丢失消息 注意下面的代码;如果我为使用者或发布者使用不同的端点名称(例如。“rabbitmq://localhost/mtlossPublised“对于发布者)则消息统计已发布和已使用的匹配项;如果使用相同的端点名称(如示例中所示),则使用的消息比发布的消息要少 这是预期的行为吗?或者我做错了什么,使用下面的示例代码Rabbitmq MassTransit丢失消息-Rabbit MQ-当发布者和使用者终结点名称相同时,,rabbitmq,masstransit,Rabbitmq,Masstransit,我们遇到了这样一种情况:如果使用相同的端点名称创建发布者和使用者,MassTransit将丢失消息 注意下面的代码;如果我为使用者或发布者使用不同的端点名称(例如。“rabbitmq://localhost/mtlossPublised“对于发布者)则消息统计已发布和已使用的匹配项;如果使用相同的端点名称(如示例中所示),则使用的消息比发布的消息要少 这是预期的行为吗?或者我做错了什么,使用下面的示例代码 using MassTransit; using System; using System
using MassTransit;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace MTMessageLoss
{
class Program
{
static void Main(string[] args)
{
var consumerBus = ServiceBusFactory.New(b =>
{
b.UseRabbitMq();
b.UseRabbitMqRouting();
b.ReceiveFrom("rabbitmq://localhost/mtloss");
});
var publisherBus = ServiceBusFactory.New(b =>
{
b.UseRabbitMq();
b.UseRabbitMqRouting();
b.ReceiveFrom("rabbitmq://localhost/mtloss");
});
consumerBus.SubscribeConsumer(() => new MessageConsumer());
for (int i = 0; i < 10; i++)
publisherBus.Publish(new SimpleMessage() { CorrelationId = Guid.NewGuid(), Message = string.Format("This is message {0}", i) });
Console.WriteLine("Press ENTER Key to see how many you consumed");
Console.ReadLine();
Console.WriteLine("We consumed {0} simple messages. Press Enter to terminate the applicaion.", MessageConsumer.Count);
Console.ReadLine();
consumerBus.Dispose();
publisherBus.Dispose();
}
}
public interface ISimpleMessage : CorrelatedBy<Guid>
{
string Message { get; }
}
public class SimpleMessage : ISimpleMessage
{
public Guid CorrelationId { get; set; }
public string Message { get; set; }
}
public class MessageConsumer : Consumes<ISimpleMessage>.All
{
public static int Count = 0;
public void Consume(ISimpleMessage message)
{
System.Threading.Interlocked.Increment(ref Count);
}
}
}
使用大众运输;
使用制度;
使用System.Collections.Generic;
使用System.Linq;
使用系统文本;
使用System.Threading.Tasks;
名称空间MTMessageLoss
{
班级计划
{
静态void Main(字符串[]参数)
{
var consumerBus=ServiceBusFactory.New(b=>
{
b、 UseRabbitMq();
b、 UseRabbitMqRouting();
b、 从(”rabbitmq://localhost/mtloss");
});
var publisherBus=ServiceBusFactory.New(b=>
{
b、 UseRabbitMq();
b、 UseRabbitMqRouting();
b、 从(”rabbitmq://localhost/mtloss");
});
SubscribeConsumer(()=>newmessageconsumer());
对于(int i=0;i<10;i++)
publisherBus.Publish(新的SimpleMessage(){CorrelationId=Guid.NewGuid(),Message=string.Format(“这是消息{0}”,i)});
Console.WriteLine(“按ENTER键查看您消费了多少”);
Console.ReadLine();
WriteLine(“我们使用了{0}条简单消息。按Enter键终止应用程序。”,MessageConsumer.Count);
Console.ReadLine();
consumerBus.Dispose();
publisherBus.Dispose();
}
}
公共接口ISimpleMessage:CorrelatedBy
{
字符串消息{get;}
}
公共类SimpleMessage:ISimpleMessage
{
公共Guid CorrelationId{get;set;}
公共字符串消息{get;set;}
}
公共类MessageConsumer:consumers.All
{
公共静态整数计数=0;
公共void消费(ISimpleMessage)
{
系统。螺纹。联锁。增量(参考计数);
}
}
}
所发生的事情是,在给出相同的接收器Uri时,您告诉MT在两条总线上进行负载平衡消耗,但是您只有一条总线在侦听消息
如果你让它跟踪接收到的消息,你会发现它(几乎)每秒都有一条
我已经修改了你的示例代码
We consumed 6 simple messages. Press Enter to terminate the applicaion.
Received 0
Received 3
Received 5
Received 6
Received 7
Received 8
在另一辆公交车上启动一个消费者,您将获得所有消费者
We consumed 10 simple messages. Press Enter to terminate the applicaion.
Received 0
Received 1
Received 2
Received 3
Received 4
Received 5
Received 6
Received 7
Received 8
Received 9
是的,我认为这是预期的行为。
下面是两个订户的经过调整的示例代码
using MassTransit;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace MTMessageLoss
{
class Program
{
internal static bool[] msgReceived = new bool[10];
static void Main(string[] args)
{
var consumerBus = ServiceBusFactory.New(b =>
{
b.UseRabbitMq();
b.UseRabbitMqRouting();
b.ReceiveFrom("rabbitmq://localhost/mtloss");
});
var publisherBus = ServiceBusFactory.New(b =>
{
b.UseRabbitMq();
b.UseRabbitMqRouting();
b.ReceiveFrom("rabbitmq://localhost/mtloss");
});
publisherBus.SubscribeConsumer(() => new MessageConsumer());
consumerBus.SubscribeConsumer(() => new MessageConsumer());
for (int i = 0; i < 10; i++)
consumerBus.Publish(new SimpleMessage()
{CorrelationId = Guid.NewGuid(), MsgId = i});
Console.WriteLine("Press ENTER Key to see how many you consumed");
Console.ReadLine();
Console.WriteLine("We consumed {0} simple messages. Press Enter to terminate the applicaion.",
MessageConsumer.Count);
for (int i = 0; i < 10; i++)
if (msgReceived[i])
Console.WriteLine("Received {0}", i);
Console.ReadLine();
consumerBus.Dispose();
publisherBus.Dispose();
}
}
public interface ISimpleMessage : CorrelatedBy<Guid>
{
int MsgId { get; }
}
public class SimpleMessage : ISimpleMessage
{
public Guid CorrelationId { get; set; }
public int MsgId { get; set; }
}
public class MessageConsumer : Consumes<ISimpleMessage>.All
{
public static int Count = 0;
public void Consume(ISimpleMessage message)
{
Program.msgReceived[message.MsgId] = true;
System.Threading.Interlocked.Increment(ref Count);
}
}
}
使用大众运输;
使用制度;
使用System.Collections.Generic;
使用System.Linq;
使用系统文本;
使用System.Threading.Tasks;
名称空间MTMessageLoss
{
班级计划
{
内部静态bool[]msgReceived=新bool[10];
静态void Main(字符串[]参数)
{
var consumerBus=ServiceBusFactory.New(b=>
{
b、 UseRabbitMq();
b、 UseRabbitMqRouting();
b、 从(”rabbitmq://localhost/mtloss");
});
var publisherBus=ServiceBusFactory.New(b=>
{
b、 UseRabbitMq();
b、 UseRabbitMqRouting();
b、 从(”rabbitmq://localhost/mtloss");
});
publisherBus.SubscribeConsumer(()=>newmessageconsumer());
SubscribeConsumer(()=>newmessageconsumer());
对于(int i=0;i<10;i++)
consumerBus.Publish(新SimpleMessage()
{CorrelationId=Guid.NewGuid(),MsgId=i});
Console.WriteLine(“按ENTER键查看您消费了多少”);
Console.ReadLine();
WriteLine(“我们使用了{0}条简单消息。按Enter键终止应用程序。”,
MessageConsumer.Count);
对于(int i=0;i<10;i++)
如果(msgReceived[i])
Console.WriteLine(“已收到{0}”,i);
Console.ReadLine();
consumerBus.Dispose();
publisherBus.Dispose();
}
}
公共接口ISimpleMessage:CorrelatedBy
{
int MsgId{get;}
}
公共类SimpleMessage:ISimpleMessage
{
公共Guid CorrelationId{get;set;}
public int MsgId{get;set;}
}
公共类MessageConsumer:consumers.All
{
公共静态整数计数=0;
公共void消费(ISimpleMessage)
{
Program.msgReceived[message.MsgId]=true;
系统。螺纹。联锁。增量(参考计数);
}
}
}
总之,总线的每个实例都需要自己的队列来读取。即使总线仅用于发布消息。这只是MassTransit工作方式的一个要求
-参见警告
当两个总线实例共享同一队列时,我们将行为保留为未定义。无论如何,这不是我们支持的条件。每个总线实例可以向其他总线实例发送元数据,并且需要自己的端点。这对MSMQ来说是一笔更大的交易,所以我们也许可以让这个案例在RabbitMQ上运行——但这并不是我们在这一点上花了太多心思的事情 好吧,这在一定程度上解释了这一点;但是发布者总线上的原始示例中没有订阅;所以无论如何,它们都不可能被发布者总线使用,那么为什么要进行负载平衡呢。我也不确定你的解释是否合情合理;因为那些信息都是假的