C#使用RabbitMQ-2_详解工作队列模式

简介

🍀RabbitMQ中的工作队列模式是指将任务分配给多个消费者并行处理。在工作队列模式中,生产者将任务发送到RabbitMQ交换器,然后交换器将任务路由到一个或多个队列。消费者从队列中获取任务并进行处理。处理完成后,消费者可以向RabbitMQ发送一个确认消息,表示任务已完成。

优点:

🍀工作队列模式的主要优点是能够实现负载均衡和并行处理。通过将任务分配给多个消费者,可以提高系统的处理能力和吞吐量。此外,工作队列模式还具有很好的扩展性,可以根据需要动态添加或删除消费者。

任务流程:

  1. 生产者(Producer)将任务发送到RabbitMQ交换器(Exchange)。
  2. 交换器根据路由键(Routing Key)将任务路由到一个或多个队列(Queue)。
  3. 消费者(Consumer)从队列中获取任务并进行处理。
  4. 处理完成后,消费者向RabbitMQ发送一个确认消息,表示任务已完成。

生产者代码

在这个代码中我们声明消息队列时第二个参数设置为true,表示这个队列是持久化的。接着使用while做一个循环,不断读取用户输入的消息内容,然后将其转换为字节数组后发布到"hello"队列中。

class MyClass
{
    public static void Main(string[] args)
    {
        var factory = new ConnectionFactory();
        factory.HostName = "localhost"; //RabbitMQ服务在本地运行
        factory.UserName = "guest"; //用户名
        factory.Password = "guest"; //密码

        //创建连接
        using (var connection = factory.CreateConnection())
        {
            //创建通道
            using (var channel = connection.CreateModel())
            {
                //声明一个名称为hello的消息队列
                channel.QueueDeclare("hello", true, false, false, null);

                string msg = null;
                int i = 1;
                Console.WriteLine("请输入要发送的消息内容:");
                while (!string.IsNullOrEmpty(msg = Console.ReadLine()))
                {
                    string message = $"Hello {msg} ! " + i++; //传递的消息内容
                    var body = Encoding.UTF8.GetBytes(message);
                    //此处的参数"hello" 就对应的就是上面声明的消息队列的路由键
                    channel.BasicPublish("", "hello", null, body); //开始传递
                    Console.WriteLine("已发送: {0}", message);
                }
            }
        }
    }
}

消费者代码

🍀这里最关键的一行代码就是channel.BasicQos(0, 1, false);BasicQos方法用于设置消费者的预取计数(prefetch count)。消费者从队列中获取消息的方式是通过预取计数来控制的。预取计数决定了消费者在没有发送确认信号的情况下可以同时处理多少条未确认的消息。

在Channel.BasicQos()方法中三个参数作用如下:

  1. prefetchSize:这个参数表示每次从队列中获取的消息的最大大小,单位是字节。设置为0表示没有限制。
  2. prefetchCount:这个参数表示每个消费者同时可以处理的最大未确认消息的数量。设置为1表示每个消费者只能处理一个未确认消息。
  3. global:这个布尔值表示是否将这两个参数应用于所有的消费者。如果设置为true,则这两个参数将应用于所有的消费者;如果设置为false,则这两个参数仅适用于当前的消费者。

channel.BasicQos(0, 1, false);这行代码设置了消费者的预取计数为1。这意味着消费者在没有发送确认信号的情况下,最多只会处理一条未确认的消息。

这样可以提高消费者处理消息的效率,因为消费者不需要等待其他消费者发送确认信号后再处理消息。这样可以在一定程度上提高系统的吞吐量。

class MyClass
{
    static void Main(string[] args)
    {
        //创建连接工厂
        var factory = new ConnectionFactory();
        factory.HostName = "localhost";
        factory.UserName = "guest";
        factory.Password = "guest";
        //创建连接
        using (var connection = factory.CreateConnection())
        {
            //创建通道
            using (var channel = connection.CreateModel())
            {
                //声明队列
                channel.QueueDeclare("hello", true, false, false, null);
                channel.BasicQos(0, 1, false);
                //事件的基本消费者
                var consumer = new EventingBasicConsumer(channel);
                
                consumer.Received += (model, ea) =>
                {
                    var body = ea.Body.ToArray();
                    var message = Encoding.UTF8.GetString(body);
                    
                    //这里加上睡眠时间,模拟耗时任务
                    Thread.Sleep(1000);
                    
                    Console.WriteLine("已接收: {0}", message);
                    //发送消息确认信号(手动确认)    
                    channel.BasicAck(ea.DeliveryTag,false);
                };
                
                //当 autoAck设置为true时,也就是自动确认模式,一旦消息队列将消息发送给消息消费者后,就会从内存中将这个消息删除。
                //当autoAck设置为false时,也就是手动模式,如果此时的有一个消费者宕机,消息队列就会将这条消息继续发送给其他的消费者,这样数据在消息消费者集群的环境下,就不会不丢失了。
                channel.BasicConsume("hello", false, consumer);
                Console.ReadKey();
            }
        }
    }
}

代码演示

🍀首先我们将消费者代码发布到本地文件夹中

🍀发布完成后我们找到打包好的程序集,双击两次.exe文件,运行两个消费者

 🍀接着我们运行生产者代码,在控制台随意发送6条消息。

🍀再回到我们刚刚运行的两个消费者程序,可以看到, 消息被分发给两个消费者了

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/349031.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

outlook如何群发邮件?外贸邮件群发教程?

outlook邮箱群发邮件方法?outlook怎么设置邮件群发? 如果你正在使用Outlook,那么你一定想要知道如何有效地群发邮件。Outlook作为微软办公套件的一部分,不仅功能强大,而且操作简便。下面,蜂邮EDM就来详细讲…

vscode开发FPGA(1)---TEROS_HDL插件报错

一、TerosHDL:modelsim(vlog-66)报错 Error: (vlog-66) Execution of vlib.exe failed 解决办法: 1.新建modelsim工程,并随意编译一个.v文件,将产生的work目录复制到modelsim安装路径下。 2.再将vscode设置verilog>linting>modelsim…

vue3 + jeecgBoot 获取项目IP地址

封装的useGlobSetting 函数 引入并使用 import { useGlobSetting } from //hooks/setting;const glob useGlobSetting();console.log(glob.uploadUrl) //http://192.168.105.57:7900/bs-axfd

docker的资源限制(cgroup)

前瞻 Docker 通过 Cgroup 来控制容器使用的资源配额,包括 CPU、内存、磁盘三大方面, 基本覆盖了常见的资源配额和使用量控制。 Cgroup 是 ControlGroups 的缩写,是 Linux 内核提供的一种可以限制、记录、隔离进程组所使用的物理资源(如 CPU、…

uni-app 接口封装,token过期,自动获取最新的token

一、文件路径截图 2、新建一个文件app.js let hosthttp://172.16.192.40:8083/jeecg-boot/ //本地接口 let myApi {login: ${host}wx/wxUser/login, //登录 } module.exports myApi 3、新建一个文件request.js import myApi from /utils/app.js; export const r…

【云原生】Docker的镜像创建

目录 1.基于现有镜像创建 (1)首先启动一个镜像,在容器里做修改 ​编辑(2)然后将修改后的容器提交为新的镜像,需要使用该容器的 ID 号创建新镜像 实验 2.基于本地模板创建 3&am…

uniapp上传音频文件到服务器

视频教程地址: 【uniapp录音上传组件,将录音上传到django服务器】 https://www.bilibili.com/video/BV1wi4y1p7FL/?share_sourcecopy_web&vd_sourcee66c0e33402a09ca7ae1f0ed3d5ecf7c uniapp 录制音频文件上传到django服务器保存到服务器 &#xf…

svn和git的本质区别是什么

参考: https://blog.csdn.net/feiying0canglang/article/details/126550676 上边图中,跨越了区的箭头,它中间的区数据都会同步。例如:git checkout ,它是将本地仓库数据更新到暂存区和工作区的。\ 理解 gitlab和svn都…

【深度优先搜索】【C++算法】834 树中距离之和

作者推荐 【动态规划】【map】【C算法】1289. 下降路径最小和 II 本文涉及知识点 深度优先搜索 树 图论 LeetCode834 树中距离之和 给定一个无向、连通的树。树中有 n 个标记为 0…n-1 的节点以及 n-1 条边 。 给定整数 n 和数组 edges , edges[i] [ai, bi]表…

【AIGC】Diffusers:训练扩散模型

前言 无条件图像生成是扩散模型的一种流行应用,它生成的图像看起来像用于训练的数据集中的图像。通常,通过在特定数据集上微调预训练模型来获得最佳结果。你可以在HUB找到很多这样的模型,但如果你找不到你喜欢的模型,你可以随时训…

vue常用指令(v-for)

一、v-for 指令 作用: 根据数据生成列表结构 二、代码演示 1、在li标签中获取数组元素 代码 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8" /><meta name"viewport" content"widthdevice-wid…

2024年 复习 HTML5+CSS3+移动web 笔记 之CSS遍

第一天第二天第三天 1.1 引入方式 1.2 选择器 1.3 画盒子 1.4 文字控制 1.5 综合案例 一 新闻详情 2.1 复合选择器 2.2 伪类选择器 2.3 CSS 特性 2.4 Emmet 写法 2.5 背景属性 2.6 显示模式 2.6 综合案例 一 热词 &#xff08;设计稿&#xff1f;&#xff09; 2.7 综合案例 一…

金蝶云星空-表单插件,点击事件(一)

表单插件&#xff0c;点击事件 BarItemClick、AfterBarItemClick 有时候我们在不通的场景中使用到自己的企业的逻辑思维 业务场景&#xff1a;采购订单上&#xff0c;增加一个按钮tbCeShi&#xff0c;添加下面的插件&#xff0c;弹出一个对话框&#xff1b; 添加一个按钮&am…

前端怎么监听手机键盘是否弹起

摘要&#xff1a; 开发移动端中&#xff0c;经常会遇到一些交互需要通过判断手机键盘是否被唤起来做的&#xff0c;说到判断手机键盘弹起和收起&#xff0c;应该都知道&#xff0c;安卓和ios判断手机键盘是否弹起的写法是有所不同的&#xff0c;下面讨论总结一下两端的区别以及…

前端学习生产环境、开发环境、测试环境

1、路径 定义是什么环境 NODE_ENVdevelopment 开发环境 2、.env 端口号 3、.env.development 开发环境 4、.env.production 生产环境 5、.env.test 测试环境 6、如何访问&#xff0c;通过process.env进行访问 学习中.......

SqlAlchemy使用教程(六) -- ORM 表间关系的定义与CRUD操作

SqlAlchemy使用教程(一) 原理与环境搭建SqlAlchemy使用教程(二) 入门示例及编程步骤SqlAlchemy使用教程(三) CoreAPI访问与操作数据库详解SqlAlchemy使用教程(四) MetaData 与 SQL Express Language 的使用SqlAlchemy使用教程(五) ORM API 编程入门 本章内容&#xff0c;稍微有…

SpringMVC-对静态资源的访问

1.工程中加入静态资源 在webapp下创建static文件夹&#xff0c;此文件夹专门放入静态资源 2.使项目可以处理静态资源的请求 在SpringMVC配置文件中添加以下语句 1.引入命名空间 xmlns:mvc"http://www.springframework.org/schema/mvc" xsi:schemaLocation“http…

Laravel 10.x 里如何使用ffmpeg

原理上很简单&#xff0c;就是使用命令行去调用ffmpeg&#xff0c;然后分析一下输出是不是有错误。 安装 首先安装 symfony/process&#xff0c;主要用于包装一下&#xff0c;用来代替 exec, passthru, shell_exec and system 。 composer require symfony/process composer…

75 C++对象模型探索。C++关于 虚函数表指针位置分析

如果一个类中&#xff0c;有虚函数&#xff0c;针对这个类会产生一个虚函数表。 生成这个类对象的时候&#xff0c;会有一个虚函数表指针&#xff0c;这个指针会指向这个虚函数表的开始地址。 我们本节就研究这个vptr指针。注意&#xff0c;vptr指针在 类对象中的位置。 证明…

【算法】糖果(差分约束)

题目 幼儿园里有 N 个小朋友&#xff0c;老师现在想要给这些小朋友们分配糖果&#xff0c;要求每个小朋友都要分到糖果。 但是小朋友们也有嫉妒心&#xff0c;总是会提出一些要求&#xff0c;比如小明不希望小红分到的糖果比他的多&#xff0c;于是在分配糖果的时候&#xff…