• net core 使用 rabbitmq


    windows环境安装:
    https://www.cnblogs.com/ericli-ericli/p/5902270.html
    .NET Core 使用RabbitMQ
    https://www.cnblogs.com/stulzq/p/7551819.html

    安装

    "C:Program FilesRabbitMQ Server abbitmq_server-3.7.9sbin abbitmq-plugins.bat" enable rabbitmq_management

    net stop RabbitMQ && net start RabbitMQ

    创建用户,密码,绑定角色

    查看已有用户及用户的角色:
    rabbitmqctl.bat list_users

    新增一个用户:
    rabbitmqctl.bat add_user username password
    示例:
    rabbitmqctl.bat add_user tangsansan 123456

    rabbitmqctl.bat set_user_tags username administrator

    示例:
    rabbitmqctl.bat set_user_tags tangsansan administrator

    基本用法

    引入:RabbitMQ.Client

    消费者

               //创建连接工厂
                var factory = new ConnectionFactory()
                {
                    UserName = "tangsansan",//用户名
                    Password = "123456",//密码
                    HostName = "localhost"//rabbitmq ip
                };
    
                //创建连接
                var connection = factory.CreateConnection();
                //创建通道
                var channel = connection.CreateModel();
                //定义一个队列
                channel.QueueDeclare("hello", false, false, false, null);
                Console.WriteLine("
    RabbitMQ连接成功,请输入消息,输入exit退出!");
    
                string input;
                do
                {
                    input = Console.ReadLine();
    
                    var sendBytes = Encoding.UTF8.GetBytes(input);
                    //发布消息
                    channel.BasicPublish("", "hello", null, sendBytes);
    
                } while (input.Trim().ToLower() != "exit");
    
                channel.Close();
                connection.Close();
    

    生产者

     //创建连接工厂
                var factory = new ConnectionFactory()
                {
                    UserName = "tangsansan",//用户名
                    Password = "123456",//密码
                    HostName = "localhost"//rabbitmq ip
                };
    
                //创建连接
                var connection = factory.CreateConnection();
                //创建通道
                var channel = connection.CreateModel();
                //定义一个队列
                channel.QueueDeclare("hello", false, false, false, null);
                Console.WriteLine("
    RabbitMQ连接成功,请输入消息,输入exit退出!");
    
                string input;
                do
                {
                    input = Console.ReadLine();
    
                    var sendBytes = Encoding.UTF8.GetBytes(input);
                    //发布消息
                    channel.BasicPublish("", "hello", null, sendBytes);
    
                } while (input.Trim().ToLower() != "exit");
    
                channel.Close();
                connection.Close();
    

    启动了一个生产者,两个消费者,可以看见两个消费者都能收到消息,消息投递到哪个消费者是由RabbitMQ决定的。

    RabbitMQ消费失败的处理

    RabbitMQ采用消息应答机制,即消费者收到一个消息之后,需要发送一个应答,然后RabbitMQ才会将这个消息从队列中删除,如果消费者在消费过程中出现异常,断开连接切没有发送应答,那么RabbitMQ会将这个消息重新投递

    //接收到消息事件
    consumer.Received += (ch, ea) =>
    {
        var message = Encoding.UTF8.GetString(ea.Body);
    
        Console.WriteLine($"收到消息: {message}");
    
        Console.WriteLine($"收到该消息[{ea.DeliveryTag}] 延迟10s发送回执");
        Thread.Sleep(10000);
        //确认该消息已被消费
        channel.BasicAck(ea.DeliveryTag, false);
        Console.WriteLine($"已发送回执[{ea.DeliveryTag}]");
    };
    

    使用RabbitMQ的Exchange

    前面我们可以看到生产者将消息投递到Queue中,实际上这在RabbitMQ中这种事情永远都不会发生。实际的情况是,生产者将消息发送到Exchange(交换器),由Exchange将消息路由到一个或多个Queue中(或者丢弃)
    生产者将消息发送到Exchange(交换器),由Exchange将消息路由到一个或多个Queue中(或者丢弃)

    Direct Exchange

                string exchangeName = "TestChange";
                string queueName = "hello";
                string routeKey = "helloRouteKey";
    
                //创建连接工厂
                var factory = new ConnectionFactory()
                {
                    UserName = "tangsansan",//用户名
                    Password = "123456",//密码
                    HostName = "localhost"//rabbitmq ip
                };
    
                //创建连接
                var connection = factory.CreateConnection();
                //创建通道
                var channel = connection.CreateModel();
    
                //定义一个Direct类型交换机
                channel.ExchangeDeclare(exchangeName, ExchangeType.Direct, false, false, null);
    
                //定义一个队列
                channel.QueueDeclare(queueName, false, false, false, null);
    
                //将队列绑定到交换机
                channel.QueueBind(queueName, exchangeName, routeKey, null);
    
               Console.WriteLine($"
    RabbitMQ连接成功,Exchange:{exchangeName},Queue:{queueName},Route:{routeKey},
    
    请输入消息,输入exit退出!");
    
                string input;
                do
                {
                    input = Console.ReadLine();
    
                    var sendBytes = Encoding.UTF8.GetBytes(input);
                    //发布消息
                    channel.BasicPublish(exchangeName, routeKey, null, sendBytes);
    
                } while (input.Trim().ToLower() != "exit");
    
                channel.Close();
                connection.Close();
    

    Fanout Exchange


    所有发送到Fanout Exchange的消息都会被转发到与该Exchange 绑定(Binding)的所有Queue上。

    Fanout Exchange 不需要处理RouteKey 。只需要简单的将队列绑定到exchange 上。这样发送到exchange的消息都会被转发到与该交换机绑定的所有队列上。类似子网广播,每台子网内的主机都获得了一份复制的消息。

    所以,Fanout Exchange 转发消息是最快的。

    static void Main(string[] args)
            {
                string exchangeName = "TestFanoutChange";
                string queueName1 = "hello1";
                string queueName2 = "hello";
                string routeKey = "";
    
                //创建连接工厂
                ConnectionFactory factory = new ConnectionFactory
                {
                    UserName = "tangsansan",//用户名
                    Password = "123456",//密码
                    HostName = "localhost"//rabbitmq ip
                };
    
                //创建连接
                var connection = factory.CreateConnection();
                //创建通道
                var channel = connection.CreateModel();
    
                //定义一个Direct类型交换机
                channel.ExchangeDeclare(exchangeName, ExchangeType.Fanout, false, false, null);
    
                //定义队列1
                channel.QueueDeclare(queueName1, false, false, false, null);
                //定义队列2
                channel.QueueDeclare(queueName2, false, false, false, null);
    
                //将队列绑定到交换机
                channel.QueueBind(queueName1, exchangeName, routeKey, null);
                channel.QueueBind(queueName2, exchangeName, routeKey, null);
    
                //生成两个队列的消费者
                ConsumerGenerator(queueName1);
                ConsumerGenerator(queueName2);
    
    
                Console.WriteLine($"
    RabbitMQ连接成功,
    
    请输入消息,输入exit退出!");
    
                string input;
                do
                {
                    input = Console.ReadLine();
    
                    var sendBytes = Encoding.UTF8.GetBytes(input);
                    //发布消息
                    channel.BasicPublish(exchangeName, routeKey, null, sendBytes);
    
                } while (input.Trim().ToLower() != "exit");
                channel.Close();
                connection.Close();
            }
    
            /// <summary>
            /// 根据队列名称生成消费者
            /// </summary>
            /// <param name="queueName"></param>
            static void ConsumerGenerator(string queueName)
            {
                //创建连接工厂
                ConnectionFactory factory = new ConnectionFactory
                {
                    UserName = "tangsansan",//用户名
                    Password = "123456",//密码
                    HostName = "localhost"//rabbitmq ip
                };
    
                //创建连接
                var connection = factory.CreateConnection();
                //创建通道
                var channel = connection.CreateModel();
    
                //事件基本消费者
                EventingBasicConsumer consumer = new EventingBasicConsumer(channel);
    
                //接收到消息事件
                consumer.Received += (ch, ea) =>
                {
                    var message = Encoding.UTF8.GetString(ea.Body);
    
                    Console.WriteLine($"Queue:{queueName}收到消息: {message}");
                    //确认该消息已被消费
                    channel.BasicAck(ea.DeliveryTag, false);
                };
                //启动消费者 设置为手动应答消息
                channel.BasicConsume(queueName, false, consumer);
                Console.WriteLine($"Queue:{queueName},消费者已启动");
            }
    

    Topic Exchange


    所有发送到Topic Exchange的消息被转发到能和Topic匹配的Queue上,

    Exchange 将路由进行模糊匹配。可以使用通配符进行模糊匹配,符号“#”匹配一个或多个词,符号“”匹配不多不少一个词。因此“XiaoChen.#”能够匹配到“XiaoChen.pets.cat”,但是“XiaoChen.” 只会匹配到“XiaoChen.money”。

    所以,Topic Exchange 使用非常灵活。

          static void Main(string[] args)
            {
                string exchangeName = "TestTopicChange";
                string queueName = "hello";
                string routeKey = "TestRouteKey.*";
    
                //创建连接工厂
                ConnectionFactory factory = new ConnectionFactory
                {
                    UserName = "tangsansan",//用户名
                    Password = "123456",//密码
                    HostName = "localhost"//rabbitmq ip
                };
    
                //创建连接
                var connection = factory.CreateConnection();
                //创建通道
                var channel = connection.CreateModel();
    
                //定义一个Direct类型交换机
                channel.ExchangeDeclare(exchangeName, ExchangeType.Topic, false, false, null);
    
                //定义队列1
                channel.QueueDeclare(queueName, false, false, false, null);
    
                //将队列绑定到交换机
                channel.QueueBind(queueName, exchangeName, routeKey, null);
    
    
    
                Console.WriteLine($"
    RabbitMQ连接成功,
    
    请输入消息,输入exit退出!");
    
                string input;
                do
                {
                    input = Console.ReadLine();
    
                    var sendBytes = Encoding.UTF8.GetBytes(input);
                    //发布消息
                    channel.BasicPublish(exchangeName, "TestRouteKey.one", null, sendBytes);
    
                } while (input.Trim().ToLower() != "exit");
                channel.Close();
                connection.Close();
            }
    

    问题:

    None of the specified endpoints were reachable

    这个异常在创建连接时抛出(CreateConnection()),原因一般是ConnectionFactory参数设置不对,比如HostName、UserName、Password
    未设置VirtualHost的权限
    设置方法:RabbitmqWeb管理网站-->Admin

  • 相关阅读:
    安装GitLab出现ruby_block[supervise_redis_sleep] action run
    docker tag根据镜像id做标签,用于应用的回滚
    Jenkenis报错:该jenkins实例似乎已离线
    kubernetes-批量删除Evicted Pods
    阿里云k8s构建镜像时设置版本号用于版本回滚
    Java虚拟机6:内存溢出和内存泄露、并行和并发、Minor GC和Full GC、Client模式和Server模式的区别
    Java虚拟机5:Java垃圾回收(GC)机制详解
    Java虚拟机4:内存溢出
    Java虚拟机3:常用JVM命令参数
    Java虚拟机2:Java内存区域及对象
  • 原文地址:https://www.cnblogs.com/tangge/p/10078996.html
Copyright © 2020-2023  润新知