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的消息内容了

 

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

SpringBoot框架:入门指南(二)

一. RESTful API开发 1. 创建RESTful控制器 在企业级Java开发中&#xff0c;RESTful API扮演着至关重要的角色&#xff0c;为系统提供了灵活、可扩展的接口。下面将详细介绍如何创建高质量的RESTful控制器&#xff0c;充分利用Spring Boot注解。 1.1 RESTful设计原则 RESTf…

Ubuntu20.0.4下设置frpc开机自启动

目录 一、下载frp 二、解压 三、服务端部署 1.配置 2.运行 三、客户端部署 1、配置 2、后台运行 四、开机启动 1、拷贝frpc.service 2、修改配置 3、启用服务 五、ubuntu20.04使用 rc-local.service设置开机启动 1、建立开机服务添加 [Install] 段 2、授权rc-local.service 3、…

Anaconda常用命令、操作、镜像源

Anaconda常用操作 命令例子作用conda create -n 环境名 需要的库conda create -n pythonenv python3.8创建环境conda info --envsconda info --envs查看全部环境activate 环境名activate pythonenv激活环境conda deactivateconda deactivate退出环境conda remove -n 环境名 --a…

pytorch学习笔记(十一)

优化器学习 把搭建好的模型拿来训练&#xff0c;得到最优的参数。 import torch.optim import torchvision from torch import nn from torch.nn import Sequential, Conv2d, MaxPool2d, Flatten, Linear from torch.utils.data import DataLoaderdataset torchvision.datas…

uniapp安卓android离线打包本地打包整理

离线打包准备 下载Android studio 1.准备资源hbuilder 2.准备离线SDK 最新android平台SDK下载最新android平台SDK下载 3.离线打包key申请 4.直接导入HBuilder-Integrate-AS工程,直接运行simpleDemo项目即可 5.安装java 1.8 jdk-8u151-windows-x64 6.遇到这个报错报错Caus…

在游戏里开公司!基于ERNIE SDK的多智能体游戏应用

在虚拟世界有一座神奇的办公室&#xff0c;当你输入你的创业方向&#xff0c;办公室的智慧打工人们将团结合作&#xff0c;为你的项目勤劳奔走&#xff0c;并在过程中&#xff0c;把日报周报都写好&#xff0c;让你随时掌握项目进度和最终成果&#xff01;该项目基于ERNIE SDK开…

工厂方法模式-C#实现

该实例基于WPF实现&#xff0c;直接上代码&#xff0c;下面为三层架构的代码。 一 Model using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks;namespace 设计模式练习.Model.工厂方法模式 {internal class…

MSG3D论文解读

论文在stgcn与sta-lstm基础上做的。下面讲一下里面的方法&#xff1a; 1.准备工作 符号。这里是对符号进行解释。 一个人体骨骼图被记为G(v,E) 图卷积&#xff1a; 图卷积定义 考虑一种常用于处理图像的标准卷积神经网络 (CNN)。输入是像素网格。每个像素都有一个数据值向…

趣学贝叶斯统计:量化

概率理论不仅仅是一个数学概念&#xff0c;更是一种对随机性和不确定性的理解方式。通过量化我们对事件发生的信念&#xff0c;我们能够更准确地预测和解释各种现象。在本章中&#xff0c;我们将探讨事件概率与信念概率&#xff0c;为我们的理论和分析工具箱增添新的维度。 事…

Angular封装HttpClient文件下载

Angular HttpClient 文件下载 前言HttpRequest.tsdemo后端接口koa2示例功能优化实现下载进度监控 前言 使用Angular框架开发工作中&#xff0c;实现文件下载业务时&#xff0c;我们可以使用Angular自带的HttpClient。下面我们就封装一下HttpClient实现文件下载&#xff0c;当接…

前端网络请求之JavaScript XHR、Fetch、Axios

一、JavaScript XHR、Fetch AJAX&#xff1a;一种在无需重新加载整个网页的情况下&#xff0c;能够更新部分网页的技术。在后台与服务器进行少量数据交换&#xff0c;Ajax 可以使网页实现异步更新。在不重新加载整个网页的情况下&#xff0c;对网页的某部分进行更新 Fetch&…

主流电商平台:item_get-通过商品ID取商品详情,主图,sku

随着全球化的加速和互联网技术的不断发展&#xff0c;跨境电商已经成为了全球商业的重要组成部分。在这个环境下&#xff0c;如何有效地获取商品详情成为了关键的问题。本文将探讨一种基于商品ID获取商品详情的跨境电商创新方式&#xff0c;即item_get接口&#xff0c;以及其潜…

Vue3-在HTML标签、组件标签上使用v-model

本篇为Vue3学习中遇到的v-model相关的记录&#xff0c;如有问题欢迎指正 一、在标签上使用v-model v-model通常在input、select等标签上来实现数据双向绑定 <input type"text" v-model"username"> 原理&#xff1a;v-model通过给标签value赋值来实…

Windows10上使Git Bash支持rsync命令操作步骤

rsync命令是linux上常用的工具之一&#xff0c;用于远程以及本地系统中拷贝/同步文件和文件夹。 Windows Git Bash默认并不支持rsync&#xff0c;如下图所示&#xff1a; 使Git Bash支持rsync命令操作步骤&#xff1a; 1.从https://repo.msys2.org/msys/x86_64/ 下…

一、MongoDB、express的安装和基本使用

数据库【Sqlite3、MongoDB、Mysql】简介&小记 Sqlite3&#xff1a; SQLite3是一个轻量级的数据库系统&#xff0c;它被设计成嵌入式数据库。这意味着它是一个包含在应用程序中的数据库&#xff0c;而不是独立运行的系统服务。适用场景&#xff1a;如小型工具、游戏、本地…

算力总规模位列全球第二!中创:助推数据中心建设

近日&#xff0c;国新办举办新闻发布会&#xff0c;介绍2023年工业和信息化发展情况。算力、数据中心、云计算等与数字化转型、能源利用息息相关&#xff0c;被多次提及。 工业和信息化部新闻发言人、运行监测协调局局长陶青表示&#xff1a; 数字基础设施支撑有力&#xff0c;…

力扣算法-Day18

18.四数之和 给你一个由 n 个整数组成的数组 nums &#xff0c;和一个目标值 target 。请你找出并返回满足下述全部条件且不重复的四元组 [nums[a], nums[b], nums[c], nums[d]] &#xff08;若两个四元组元素一一对应&#xff0c;则认为两个四元组重复&#xff09;&#xff1…

关于数据库被勒索如何解决?

今天发现数据库被删&#xff0c;原因是勒索病毒&#xff0c;这期文章来说明下: **使用binlog日志恢复**&#xff1a; - **确认binlog状态**&#xff1a;检查MySQL服务器是否开启了binlog日志功能。如果服务器启用了binlog&#xff0c;那么在数据被篡改之前的操作都有可能被记…

golang 根据URL获取文件名

只有一个文件地址&#xff0c;但是没有文件名称&#xff0c;文件地址&#xff1a;http://XXXXXXX/getfile.aspx?fileid999 但是系统需要把文件名称也写入到数据库 可以根据 resp.Header["Content-Disposition"] 获取文件名 resp.Header["Content-Disposition&q…

继承和原型链

基于原型链的继承示例 // 继承方法 const parent { value: 2, method() { console.log(this); return this.value 1 } } console.log(parent.method());//3 不难理解 const child { __proto__: parent, } console.log(child.method());//3 this 指向child 但是属性中没有v…