RabbitMQ C#验证消息已发送
我是RabbitMQ新手,正在尝试写入队列并验证消息是否已发送。如果失败了,我需要知道。 我做了一个假队列来看着它失败,但无论我看到什么都没有执行,当我在寻找ack时,我总是得到一个。我从来没见过基茨纳克 我甚至不确定我是不是Basicaks才是最好的选择RabbitMQ C#验证消息已发送,c#,rabbitmq,C#,Rabbitmq,我是RabbitMQ新手,正在尝试写入队列并验证消息是否已发送。如果失败了,我需要知道。 我做了一个假队列来看着它失败,但无论我看到什么都没有执行,当我在寻找ack时,我总是得到一个。我从来没见过基茨纳克 我甚至不确定我是不是Basicaks才是最好的选择 private void button1_Click(object sender, EventArgs e) { var factory = new ConnectionFactory() { HostName
private void button1_Click(object sender, EventArgs e)
{
var factory = new ConnectionFactory() { HostName = "localhost" };
using (var connection = factory.CreateConnection())
{
using (var channel = connection.CreateModel())
{
channel.QueueDeclare("task_queue", true, false, false, null);
var message = ("Helllo world");
var body = Encoding.UTF8.GetBytes(message);
channel.ConfirmSelect();
var properties = channel.CreateBasicProperties();
properties.SetPersistent(true);
properties.DeliveryMode = 2;
channel.BasicAcks += channel_BasicAcks;
channel.BasicNacks += channel_BasicNacks;
//fake queue should be task_queue
channel.BasicPublish("", "task_2queue", true, properties, body);
channel.WaitForConfirmsOrDie();
Console.WriteLine(" [x] Sent {0}", message);
}
}
}
void channel_BasicNacks(IModel model, BasicNackEventArgs args)
{
}
void channel_BasicAcks(IModel model, BasicAckEventArgs args)
{
}
你需要一个
正如您所看到的,您可以实现:
交易:
ch.txSelect(); <-- start transaction
ch.basicPublish("", QUEUE_NAME,
MessageProperties.PERSISTENT_BASIC,
"nop".getBytes());
ch.txCommit();<--commit transaction
我希望这会有所帮助。好的,您总是会收到发送邮件的确认信息,因为“每次邮件都成功传递到默认Exchange。” PS:您没有直接将消息发送到队列,Exchange收到消息后会给您确认,然后使用路由键(如果有)将消息路由到所有绑定的队列。对于那些寻找C#答案的人-以下是您需要的 类似这样的内容:(BasicAcks附加了一个事件处理程序-还有BasicAcks)
使用(var connection=FACTORY.CreateConnection())
{
var channel=connection.CreateModel();
channel.ExchangeClare(队列名称,ExchangeType.Fanout,true);
QueueDeclare(队列名称,true,false,false,null);
QueueBind(QUEUE_NAME,QUEUE_NAME,String.Empty,new Dictionary());
channel.BasicAcks+=(发送方,事件参数)=>
{
//执行确认句柄
};
channel.ConfirmSelect();
对于(var i=1;i是轻量级的更快?我确实需要最好的性能。我并不真的需要它保存到IO,而是保存在队列中。如果失败,我需要有回退代码。是的,它更快。事务非常慢,你必须等待同步磁盘操作,并且发布被锁定,直到消息被存储。顺便说一句,轻量级Publisher确认更为复杂,因为如果不想丢失消息,您应该将消息完全映射为链接。我使用了channel.ConfirmSelect();和channel.waitforconfirmsodie();并被告知使用返回事件。我可以通过这种方式看到错误。这会比ch.txSelect()更快吗/txCommit?我将每秒发送大量流量,如10k,并寻求最佳性能的建议。当然,我不会每次都打开连接,但我只做了一天:)WaitForConfirmsOrDie比txCommit快,无论如何,我建议使用WaitForConfirmsOrDie(超时),否则,如果出现问题,您可能会永远阻止发布。如果需要性能,确认发布通常不是好的选择。因此,您可以尝试在多线程中打开更多通道,并使用WaitForConfirmsOrDie(超时)我想你可以有正确的妥协。让我知道你提供的流轻量级例子不是C语言,OP正在使用的OP,你能考虑编辑这个答案并添加一个C实现吗?这是不正确的。在香草AMQP中,如果经纪人接受消息(见方法DOC)它不会回应任何东西。除非你正在使用-这是提问者需要的。
ch.setConfirmListener(new ConfirmListener() {
public void handleAck(long seqNo, boolean multiple) {
if (multiple) {
unconfirmedSet.headSet(seqNo+1).clear();
} else {
unconfirmedSet.remove(seqNo);
}
}
public void handleNack(long seqNo, boolean multiple) {
// handle the lost messages somehow
}
using (var connection = FACTORY.CreateConnection())
{
var channel = connection.CreateModel();
channel.ExchangeDeclare(QUEUE_NAME, ExchangeType.Fanout, true);
channel.QueueDeclare(QUEUE_NAME, true, false, false, null);
channel.QueueBind(QUEUE_NAME, QUEUE_NAME, String.Empty, new Dictionary<string, object>());
channel.BasicAcks += (sender, eventArgs) =>
{
//implement ack handle
};
channel.ConfirmSelect();
for (var i = 1; i <= numberOfMessages; i++)
{
var messageProperties = channel.CreateBasicProperties();
messageProperties.SetPersistent(true);
var message = String.Format("{0}\thello world", i);
var payload = Encoding.Unicode.GetBytes(message);
Console.WriteLine("Sending message: " + message);
channel.BasicPublish(QUEUE_NAME, QUEUE_NAME, messageProperties, payload);
channel.WaitForConfirmsOrDie();
}
}