当前位置: 首页 > news >正文

C#使用RabbitMQ-1_Docker部署并在c#中实现简单模式消息代理

介绍

RabbitMQ是一个开源的消息队列系统,实现了高级消息队列协议(AMQP)

🍀RabbitMQ起源于金融系统,现在广泛应用于各种分布式系统中。它的主要功能是在应用程序之间提供异步消息传递,实现系统间的解耦和消息的可靠传递。RabbitMQ使用Erlang语言开发,支持多种客户端语言如Python、Ruby、.NET、Java等。

此外,RabbitMQ具有以下特点:

  1. 易用性:提供了简单易用的API,使得生产者和消费者可以方便地发送和接收消息。
  2. 扩展性:可以水平扩展以处理大量的消息,支持集群部署来提高系统的吞吐量和可用性。
  3. 高可用性:通过镜像队列等机制保证消息不会因服务器故障而丢失,确保了系统的稳健运行。
  4. 多种交换模式:支持直接交换、扇形交换、主题交换和头交换等多种交换模式,满足不同的消息路由需求。
  5. 多协议支持:除了AMQP协议,还支持STOMP等其他消息协议。

在docker中部署RabbitMQ

🍀首先在dockerHub中找到RabbitMQ的镜像

rabbitmq - 官方图片 (docker.com)

🍀执行命令拉取镜像

docker pull rabbitmq

🍀镜像拉取完成之后启动镜像

docker run -d -p 5672:5672 -p 15672:15672 --name rabbitmq rabbitmq

🍀此时我们打开 http://localhost:15672/会发现无法访问,这是因为管理插件还未被激活

🍀通过docker ps -a查看部署的RabbitMQ容器id,在通过使用命令

 docker exec -it 容器id /bin/bash 

🍀进入容器内部再运行:rabbitmq-plugins enable rabbitmq_management

🍀此时就可以打开管理插件了,第一次使用 RabbitMQ 管理界面,需要使用默认的用户名和密码( guest/guest)来登录

 消息队列简单模式(直连交换机)

🍀simple模式,是RabbitMQ最简单的一种模式,如下图所示,只有一个生产者,一个消费者和一个队列

🍀生产者和消费者在发送和接受消息时,只需要指定队列名,而不需要指定发送到哪个Exchange

生产者代码

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", false, false, false, null); for (int i = 0; i < 5; i++){string message = "Hello Word ! " + i; //传递的消息内容var body = Encoding.UTF8.GetBytes(message);//此处的参数"hello" 就对应的就是上面声明的消息队列的路由键channel.BasicPublish("", "hello", null, body); //开始传递Console.WriteLine("已发送: {0}", message);}}}}
}

消费者代码(自动模式)

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", false, false, false, null);//事件的基本消费者var consumer = new EventingBasicConsumer(channel);consumer.Received += (model, ea) =>{var body = ea.Body.ToArray();var message = Encoding.UTF8.GetString(body);Console.WriteLine("已接收: {0}", message);//发送消息确认信号(手动确认)    //channel.BasicAck(ea.DeliveryTag,false);};//当 autoAck设置为true时,也就是自动确认模式,一旦消息队列将消息发送给消息消费者后,就会从内存中将这个消息删除。//当autoAck设置为false时,也就是手动模式,如果此时的有一个消费者宕机,消息队列就会将这条消息继续发送给其他的消费者,这样数据在消息消费者集群的环境下,就不会不丢失了。channel.BasicConsume("hello", true, consumer);Console.ReadKey();}}}
}

🍀在消费者代码中,要注意的是autoAck设置为true时,也就是自动确认模式的时候,要去掉手动发送确认信号代码:channel.BasicAck(ea.DeliveryTag,false);  

代码调试

🍀 在代码执行到

channel.QueueDeclare("hello", false, false, false, null);

 🍀声明一个消息队列时,在RabbitMQ的可视化界面就可以看见多了一个名称为hello的消息队列

🍀当执行完五次消息传递时,点击上图的hello消息队列,Messages:设置为5,然后点击Get Messages,就可以看到传递过来的5条消息队列了

 

🍀此时我们执行消费者代码,因为autoAck设置为true了,当消息队列将消息发送给消费者后,就会立马将消息删除,此时再点击Get Messages就会提示Queue is empty

消费者代码(手动模式)

在手动模式中,我们将原来声明的队列删除调,然后将生产者与消费者的声明队列代码中的第二个参数都改为true,意味着这个队列是持久的。在 RabbitMQ 服务器重启之后,持久的队列和它的消息都不会丢失

channel.QueueDeclare("hello", true, false, false, null);

然后添加一行代码,设置当前消费者的预取模式为只预取一条消息

channel.BasicQos(0, 1, false);

 接着是 发送消息确认信号 与 开启手动确认模式

channel.BasicAck(ea.DeliveryTag,false);
channel.BasicConsume("hello", false, consumer);

要注意的地方是,一定要在结尾处加上下方代码,否则可能会出现还没发送消息确认信号,进程就结束了,这时就会发现将接收到的helloword打印到控制台了,去RabbitMQ可视乎管理界面发现事件还未被消耗掉。

Console.ReadKey();
  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);Console.WriteLine("已接收: {0}", message);//发送消息确认信号(手动确认)    channel.BasicAck(ea.DeliveryTag,false);};//当 autoAck设置为true时,也就是自动确认模式,一旦消息队列将消息发送给消息消费者后,就会从内存中将这个消息删除。//当autoAck设置为false时,也就是手动模式,如果此时的有一个消费者宕机,消息队列就会将这条消息继续发送给其他的消费者,这样数据在消息消费者集群的环境下,就不会不丢失了。channel.BasicConsume("hello", false, consumer);Console.ReadKey();}}}

代码调试

按照上面改成手动模式后,消费者只预取一条消息,如下图0、1、2被消费掉了,此时再去RabbitMQ的可视乎管理界面点击GetMessage,只剩下3、4的消息内容了

 

相关文章:

C#使用RabbitMQ-1_Docker部署并在c#中实现简单模式消息代理

介绍 RabbitMQ是一个开源的消息队列系统&#xff0c;实现了高级消息队列协议&#xff08;AMQP&#xff09;。 &#x1f340;RabbitMQ起源于金融系统&#xff0c;现在广泛应用于各种分布式系统中。它的主要功能是在应用程序之间提供异步消息传递&#xff0c;实现系统间的解耦和…...

EasyExcel中自定义拦截器的运用

在EasyExcel中自定义拦截器不仅可以帮助我们不止步于数据的填充&#xff0c;而且可以对样式、单元格合并等带来便捷的功能。下面直接开始 我们定义一个MergeWriteHandler的类继承AbstractMergeStrategy实现CellWriteHandler public class MergeLastWriteHandler extends Abst…...

shell编程-7

shell学习第7天 sed的学习1.sed是什么2.sed有两个空间pattern hold3.sed的语法4. sed里单引号和双引号的区别:5.sed的查找方式6.sed的命令sed的标签用法sed的a命令:追加sed的i命令:根据行号插入sed的c命令:整行替换sed的r命令sed的s命令:替换sed的d命令:删除sed中的&符号 7…...

工业智能网关储能物联网应用实现能源的高效利用及远程管理

储能电力物联网是指利用物联网技术和储能技术相结合&#xff0c;实现对电力系统中各种储能设备的智能管理和优化控制。随着可再生能源的不断发展和应用&#xff0c;电力系统面临着越来越大的电力调度和储能需求而储能电力物联网的出现可以有效解决这一问题&#xff0c;提高电力…...

虹科数字化与AR部门升级为安宝特AR子公司

致关心虹科AR的朋友们&#xff1a; 感谢您一直以来对虹科数字化与AR的支持和信任&#xff0c;为了更好地满足市场需求和公司发展的需要&#xff0c;虹科数字化与AR部门现已升级为虹科旗下独立子公司&#xff0c;并正式更名为“安宝特AR”。 ”虹科数字化与AR“自成立以来&…...

服务器是什么?(四种服务器类型)

服务器 服务器定义广义: 专门给其他机器提供服务的计算机。狭义:一台高性能的计算机&#xff0c;通过网络提供外部计算机一些业务服务 个人PC内存大概8G&#xff0c;服务器内存128G起步 服务器是什么 服务器指的是 网络中能对其他机器提供某些服务的计算机系统 &#xff0c;相对…...

09-微服务Sentinel整合GateWay

一、概述 在微服务系统中&#xff0c;网关提供了微服务系统的统一入口&#xff0c;所以我们在做限流的时候&#xff0c;肯定是要在网关层面做一个流量的控制&#xff0c;Sentinel 支持对 Spring Cloud Gateway、Zuul 等主流的 API Gateway 进行限流。 1.1 总览 Sentinel 1.6.…...

python基础学习-03 安装

python3 可应用于多平台包括 Windows、Linux 和 Mac OS X。 Unix (Solaris, Linux, FreeBSD, AIX, HP/UX, SunOS, IRIX, 等等。)Win 9x/NT/2000Macintosh (Intel, PPC, 68K)OS/2DOS (多个DOS版本)PalmOSNokia 移动手机Windows CEAcorn/RISC OSBeOSAmigaVMS/OpenVMSQNXVxWorksP…...

HTML — 区块元素

HTML 通过各种标签将元素组合起来。 一. 区块元素 大多数 HTML 元素被定义为块级元素或内联元素。块级元素在浏览器显示时&#xff0c;通常会以新的行开始。例如&#xff1a;<div>、<h1>、<p>、<ul>等。 它们在使用时会独自占据一行&#xff0c;称为块…...

《PCI Express体系结构导读》随记 —— 第I篇 第3章 PCI总线的数据交换(4)

接前一篇文章&#xff1a;《PCI Express体系结构导读》随记 —— 第I篇 第3章 PCI总线的数据交换&#xff08;3&#xff09; 3.2 PCI设备的数据传递 PCI设备的数据传递使用地址译码方式&#xff0c;当一个存储器读写总线事务到达PCI总线时&#xff0c;在这条总线上的所有PCI设…...

力扣0083——删除排序链表中的重复元素

删除排序链表中的重复元素 难度&#xff1a;简单 题目描述 给定一个已排序的链表的头 head &#xff0c; 删除所有重复的元素&#xff0c;使每个元素只出现一次 。返回 已排序的链表 。 示例1 输入&#xff1a;head [1,1,2] 输出&#xff1a;[1,2]示例2 输入&#xff1a…...

MySQL数据库的一些缩写含义

DDL Data Definition Language&#xff0c;数据定义语言&#xff0c;用来定义数据库对象(数据库&#xff0c;表&#xff0c;字段) DML DML英文全称是Data Manipulation Language(数据操作语言)&#xff0c;用来对数据库中表的数据记录进 行增、删、改操作。 添加数据&#x…...

解决 ssh: connect to host github.com port 22: Connection timed out

问题 今天使用git克隆github上的代码时&#xff0c;一直报错 原以为是公钥过期了&#xff0c;就尝试修改配置公钥&#xff0c;但是尝试了几次都不行&#xff0c;最终在博客上找到了解决方案&#xff0c;在次记录一下&#xff0c;以备不时之需 解决ssh-connect-to-host-github…...

【iOS ARKit】同时开启前后摄像头BlendShapes

在上一节中已经了解了 iOS ARkit 进行BlendShapes的基本操作&#xff0c;这一小节继续实践同时开启前后摄像头进行人脸捕捉和世界追踪。 iOS设备配备了前后两个摄像头&#xff0c;在运行AR 应用时&#xff0c;需要选择使用哪个摄像头作为图像输人。最常见的AR 体验使用设备后置…...

Vue3动态插入组件

一、使用<component>is实现动态组件插入 <component>&#xff1a;一个用于渲染动态组件或元素的“元组件”。 :is : 要渲染的实际组件&#xff0c;当 is 是字符串&#xff0c;它既可以是 HTML 标签名也可以是组件的注册名。 <script> import Foo from ./F…...

介绍一下OpenCV中常用的图像处理函数

OpenCV中常用的图像处理函数有很多&#xff0c;以下是其中一些函数的介绍&#xff1a; - cvLoadImage()&#xff1a;读入图像函数。 - imshow()&#xff1a;显示图像函数。 - imwrite()&#xff1a;保存图像函数。 - Mat srcImage imread()&#xff1a;读入图像函数。 - …...

vscode vim 快捷键汇总

需满足操作&#xff1a; 上下移动按照 word 移动选中增删改查找字符/变量移动、增加、复制、删除 行选中多个相同的变量/字符屏幕移动增加多个光标快速注释 上下左右移动 CommandDescription&#x1f522; hleft (also: CTRL-H, BS, or Left key)&#x1f522; lright (also…...

npm官方注册表和淘宝镜像切换

1.切换到淘宝镜像 加快npm包的下载速度&#xff0c; //已失效 //npm config set registry https://registry.npm.taobao.org/ npm config set registry https://registry.npmmirror.com这会将npm的注册表设置为淘宝镜像 查看&#xff1a; npm config get registry如果返回的…...

LFU算法

LFU算法 Least Frequently Used&#xff08;最不频繁使用&#xff09; Leetcode有原题&#xff0c;之前手写过LRU&#xff0c;数据结构还是习惯于用java实现&#xff0c;实现是copy的评论题解。 题解注释写的很清楚 大致就是说LFUCache类维护一个存放node的map&#xff0c;同…...

JVM系列-7内存调优

&#x1f44f;作者简介&#xff1a;大家好&#xff0c;我是爱吃芝士的土豆倪&#xff0c;24届校招生Java选手&#xff0c;很高兴认识大家&#x1f4d5;系列专栏&#xff1a;Spring原理、JUC原理、Kafka原理、分布式技术原理、数据库技术、JVM原理&#x1f525;如果感觉博主的文…...

后进先出(LIFO)详解

LIFO 是 Last In, First Out 的缩写&#xff0c;中文译为后进先出。这是一种数据结构的工作原则&#xff0c;类似于一摞盘子或一叠书本&#xff1a; 最后放进去的元素最先出来 -想象往筒状容器里放盘子&#xff1a; &#xff08;1&#xff09;你放进的最后一个盘子&#xff08…...

简易版抽奖活动的设计技术方案

1.前言 本技术方案旨在设计一套完整且可靠的抽奖活动逻辑,确保抽奖活动能够公平、公正、公开地进行,同时满足高并发访问、数据安全存储与高效处理等需求,为用户提供流畅的抽奖体验,助力业务顺利开展。本方案将涵盖抽奖活动的整体架构设计、核心流程逻辑、关键功能实现以及…...

反向工程与模型迁移:打造未来商品详情API的可持续创新体系

在电商行业蓬勃发展的当下&#xff0c;商品详情API作为连接电商平台与开发者、商家及用户的关键纽带&#xff0c;其重要性日益凸显。传统商品详情API主要聚焦于商品基本信息&#xff08;如名称、价格、库存等&#xff09;的获取与展示&#xff0c;已难以满足市场对个性化、智能…...

使用分级同态加密防御梯度泄漏

抽象 联邦学习 &#xff08;FL&#xff09; 支持跨分布式客户端进行协作模型训练&#xff0c;而无需共享原始数据&#xff0c;这使其成为在互联和自动驾驶汽车 &#xff08;CAV&#xff09; 等领域保护隐私的机器学习的一种很有前途的方法。然而&#xff0c;最近的研究表明&…...

ardupilot 开发环境eclipse 中import 缺少C++

目录 文章目录 目录摘要1.修复过程摘要 本节主要解决ardupilot 开发环境eclipse 中import 缺少C++,无法导入ardupilot代码,会引起查看不方便的问题。如下图所示 1.修复过程 0.安装ubuntu 软件中自带的eclipse 1.打开eclipse—Help—install new software 2.在 Work with中…...

全志A40i android7.1 调试信息打印串口由uart0改为uart3

一&#xff0c;概述 1. 目的 将调试信息打印串口由uart0改为uart3。 2. 版本信息 Uboot版本&#xff1a;2014.07&#xff1b; Kernel版本&#xff1a;Linux-3.10&#xff1b; 二&#xff0c;Uboot 1. sys_config.fex改动 使能uart3(TX:PH00 RX:PH01)&#xff0c;并让boo…...

selenium学习实战【Python爬虫】

selenium学习实战【Python爬虫】 文章目录 selenium学习实战【Python爬虫】一、声明二、学习目标三、安装依赖3.1 安装selenium库3.2 安装浏览器驱动3.2.1 查看Edge版本3.2.2 驱动安装 四、代码讲解4.1 配置浏览器4.2 加载更多4.3 寻找内容4.4 完整代码 五、报告文件爬取5.1 提…...

力扣-35.搜索插入位置

题目描述 给定一个排序数组和一个目标值&#xff0c;在数组中找到目标值&#xff0c;并返回其索引。如果目标值不存在于数组中&#xff0c;返回它将会被按顺序插入的位置。 请必须使用时间复杂度为 O(log n) 的算法。 class Solution {public int searchInsert(int[] nums, …...

Springboot社区养老保险系统小程序

一、前言 随着我国经济迅速发展&#xff0c;人们对手机的需求越来越大&#xff0c;各种手机软件也都在被广泛应用&#xff0c;但是对于手机进行数据信息管理&#xff0c;对于手机的各种软件也是备受用户的喜爱&#xff0c;社区养老保险系统小程序被用户普遍使用&#xff0c;为方…...

AI,如何重构理解、匹配与决策?

AI 时代&#xff0c;我们如何理解消费&#xff1f; 作者&#xff5c;王彬 封面&#xff5c;Unplash 人们通过信息理解世界。 曾几何时&#xff0c;PC 与移动互联网重塑了人们的购物路径&#xff1a;信息变得唾手可得&#xff0c;商品决策变得高度依赖内容。 但 AI 时代的来…...