• rabbitmq系列——(5 消息确认 -- 生产者 事务性消息)


      事务消息与数据库的事务类似,只是MQ的消息是要保证消息是否会全部发送成功,防止消息丢失的一种策略。
      RabbitMQ有两种策略来解决这个问题:
      1.通过AMQP的事务机制实现
      2.使用生产者确认模式实现

      本文讲事务性机制。

    1. 生产者

    using RabbitMQMsgProducer.MessageProducer;
    using Microsoft.Extensions.Configuration;
    using System;
    using System.IO;
    using RabbitMQMsgProducer.ExchangeDemo;
    using RabbitMQMsgProducer.MessageConfirm;
    
    namespace RabbitMQMsgProducer
    {
        class Program
        {
            static void Main(string[] args)
            {
                try
                {
                    {
                        // 事务性消息
                        ProducerMsgTx.Send();
                    }
                    Console.ReadLine();
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.Message);
                }
            }
        }
    }
    using RabbitMQ.Client;
    using System;
    using System.Collections.Generic;
    using System.Text;
    
    namespace RabbitMQMsgProducer.MessageConfirm
    {
        public class ProducerMsgTx
        {
            public static void Send()
            {
                ConnectionFactory factory = new ConnectionFactory();
                factory.HostName = "localhost";//服务地址
                factory.UserName = "guest";//用户名
                factory.Password = "guest";//密码 
                string queueName01 = "MsgTxQueue01";
                string queueName02 = "MsgTxQueue02";
                string exchangeName = "MsgTxExchange";
                string routingKey01 = "MsgTxKey01";
                string routingKey02 = "MsgTxKey02";
                using (var connection = factory.CreateConnection())
                {
                    //创建通道channel
                    using (var channel = connection.CreateModel())
                    {
                        Console.WriteLine("the producer is ready . GO !");
                        // 声明队列
                        channel.QueueDeclare(queue: queueName01, durable: true, exclusive: false, autoDelete: false, arguments: null);
                        channel.QueueDeclare(queue: queueName02, durable: true, exclusive: false, autoDelete: false, arguments: null);
                        //声明交换机exchang
                        channel.ExchangeDeclare(exchange: exchangeName, type: ExchangeType.Direct, durable: true, autoDelete: false, arguments: null);
                        //绑定exchange和queue
                        channel.QueueBind(queue: queueName01, exchange: exchangeName, routingKey: routingKey01);
                        channel.QueueBind(queue: queueName02, exchange: exchangeName, routingKey: routingKey02);
                        string message = "";
                        //发送消息
                        //在控制台输入消息,按enter键发送消息
                        while (true)
                        {
                            message = Console.ReadLine();
                            bool isOk = message.Equals("quit", StringComparison.CurrentCultureIgnoreCase);
                            if (isOk) { break; }
                            var body = Encoding.UTF8.GetBytes(message);
                            try
                            {
                                //开启事务机制
                                channel.TxSelect(); //事务是协议支持的
                                //发送消息
                                //同时给多个队列发送消息;要么都成功;要么都失败;
                                channel.BasicPublish(exchange: exchangeName, routingKey: routingKey01, basicProperties: null, body: body);
                                channel.BasicPublish(exchange: exchangeName, routingKey: routingKey02, basicProperties: null, body: body);
    
                                //throw new Exception();
    
                                //事务提交
                                channel.TxCommit(); //只有事务提交成功以后,才会真正的写入到队列里面去
                                Console.WriteLine($"the msg : _ {message} _ is send to broker . success .");
                            }
                            catch (Exception ex)
                            {
                                Console.WriteLine($"the msg : _ {message} _ is send to broker . fail .");
                                channel.TxRollback(); //事务回滚
                                //可能在这里还重试一下。。。
                                throw;
                            }
                        }
                        Console.Read();
                    }
                }
            }
        }
    }

    2. 执行代码,产生交换机路由和队列

     2.1 执行命令窗口,等待输入:

    发送 hello ,失败,队列中无值。

     3. 修改异常处理模拟发送消息失败:

    修改程序

     4.执行程序:

     

  • 相关阅读:
    JSP基础(一)JSP介绍,文件结构及执行过程
    使用MyEclipse开发第一个Web程序
    Activity启动模式 Tasks和Back Stack
    XML的DOM解析 Java实现 例子二
    XML 命名空间(Namespace)
    HTTP基础:URL格式、 HTTP请求、响应、消息
    Android Log相关
    Tomcat环境配置
    XML DOM解析(Java)的一个简单实例
    JSP基础(三)JSP内置对象 利用application对象做一个简单的网页计数器
  • 原文地址:https://www.cnblogs.com/Fletcher/p/14231009.html
Copyright © 2020-2023  润新知