2019独角兽企业重金招聘Python工程师标准>>>

RabbitMQ原理与相关操作(一)

小编是菜鸟一枚,最近想试试MQ相关的技术,所以自己看了下RabbitMQ官网,试着写下自己的理解与操作的过程。

刚开始的第一篇,原理只介绍 生产者、消费者、队列,至于其他的内容,会在后续中陆续补齐。

引入MQ话题

什么时候会用到MQ

可能很多人有疑惑:MQ到底是什么?哪些场景下要使用MQ?
前段时间安装了RabbitMQ,现在就记录下自己的学习心得吧。
首先看段程序:

class Program{static void Main(string[] args){new Thread(Write).Start();new Thread(Write).Start();new Thread(Write).Start();new Thread(Write).Start();}public static void WriteLog(int i){using (FileStream f = new FileStream(@"d:\\test.txt", FileMode.Append)){using (StreamWriter sw = new StreamWriter(f, Encoding.Default)){sw.Write(i);}}}public static void Write(){for (int i = 0; i < 10000; i++){WriteLog(i);}}}

View Code

仅仅从代码上看,没有觉得任何问题对吧?编译也是通过的,但是执行时,出现一个问题:

当然,这仅仅是一个小的案例,类似这种多线程写文件造成的问题, 就应该使用MQ了。

MQ的使用场景大概包括解耦,提高峰值处理能力,送达和排序保证,缓冲等。

MQ概述

消息队列技术是分布式应用间交换信息的一种技术。

消息队列可驻留在内存或磁盘上,队列存储消息直到它们被应用程序读走。

通过消息队列,应用程序可独立地执行--它们不需要知道彼此的位置、或在继续执行前不需要等待接收程序接收此消息。

MQ主要作用是接受和转发消息。你可以想想在生活中的一种场景:当你把信件的投进邮筒,邮递员肯定最终会将信件送给收件人。我们可以把MQ比作 邮局和邮递员。

MQ和邮局的主要区别是,它不处理消息,但是,它会接受数据、存储消息数据、转发消息。

RabbitMQ术语

生产者

消息发送者,在MQ中被称为生产者(producer),一个发送消息的应用也被叫做生产者,用P表示

消费者:

生产者“生产”出消息后,最终由谁消费呢?等待接受消息的应用程序,我们称之为消费者(Consuming ),用C表示

队列:

消息只能存储在队列(queue )中。尽管消息在rabbitMQ和应用程序间流通,但是队列却是存在于RabbitMQ内部。

一个队列不受任何限制,它可以存储你想要存储的消息量,它本质上是一个无限的缓冲区。

多个生产者可以向同一个队列发送消息,多个消费者可以尝试从同一个消息队列中接收数据。

一个队列像下面这样(上面是它的队列名称)

注意:

生产者、消费者、中间件不必在一台机器上,实际应用中也是绝大多数不在一起的。我们可以用一张图表示RabbitMQ的构造:

注:此图片摘自于百度百科RabbitMQ。

使用RabbitMQ解决多线程写入文件问题

分析

多线程写入,产生消息的也就是一个程序(一个生产者P),消费消息的也是一个消息,它的模型应该是:

编写代码

引入RabbitMQ client DLL

程序包管理控制台命令:

PM> Install-Package RabbitMQ.Client

生产者

首先,创建一个 connection 通过socket连接 去和服务器连接起来(需要传目的服务器的IP、用户名、密码等)。

接着 创建一个 channel ,这是大部分的要做的事情所在。

要发送消息,我们必须声明一个队列,,然后我们可以向队列发布消息。

执行一次BasicPublish方法,推送一个消息。

class Program{static void Main(string[] args){new Thread(Write).Start();new Thread(Write).Start();new Thread(Write).Start();}public static void Write(){var factory = new ConnectionFactory() { HostName = "localhost", UserName = "eric", Password = "123456", };using (var connection = factory.CreateConnection())using (var channel = connection.CreateModel()){channel.QueueDeclare(queue: "writeLog", durable: false, exclusive: false, autoDelete: false, arguments: null);for (int i = 0; i < 8000; i++){string message = i.ToString();var body = Encoding.UTF8.GetBytes(message);channel.BasicPublish(exchange: "", routingKey: "writeLog", basicProperties: null, body: body);Console.WriteLine("Program Sent {0}", message);}}}}

View Code

声明的队列,在服务器中如果不存在了,会自动创建。而消息的内容是字节数组,在使用时,注意编码问题。

消费者

当队列里有消息时,消费者要随时能够从队列里获取消息,所以我需要一直运行它,让它监听消息。

就像我们打篮球进行传球,需要事先确认要传给的那个队友位置一样,生产者要发送消息,一定要事先知道消费消息的程序的对列是哪个。所以,在运行生产者程序前,需要先启动消费者程序。

由此,声明对列,就应该在消费者程序中完成。

class Program{public static void Main(){var factory = new ConnectionFactory() { HostName = "localhost", UserName = "eric", Password = "123456", VirtualHost ="/"};using (var connection = factory.CreateConnection())using (var channel = connection.CreateModel()){channel.QueueDeclare(queue: "writeLog",durable: false,exclusive: false,autoDelete: false,arguments: null);var consumer = new EventingBasicConsumer(channel);consumer.Received += (model, ea) =>{var body = ea.Body;var message = Encoding.UTF8.GetString(body);ExcuateWriteFile(message);Console.WriteLine(" Receiver Received {0}", message);};channel.BasicConsume(queue: "writeLog",noAck: true,consumer: consumer);Console.WriteLine(" Press [enter] to exit.");Console.ReadLine();}}public static void ExcuateWriteFile(string i){using (FileStream fs = new FileStream(@"d:\\test.txt", FileMode.Append)){using (StreamWriter sw = new StreamWriter(fs, Encoding.Unicode)){sw.Write(i);}}}}

View Code

执行程序

先执行 消费者程序,让它一直保持监听。

错误解决

执行时VS报错:

“RabbitMQ.Client.Exceptions.BrokerUnreachableException”类型的未经处理的异常在 RabbitMQ.Client.dll 中发生 其他信息: None of the specified endpoints were reachable。

进入查看详细的内部异常:

innerEception:{"The AMQP operation was interrupted: AMQP close-reason, initiated by Peer, code=530, text=\"NOT_ALLOWED - access to vhost '/' refused for user 'eric'\", classId=10, methodId=40, cause="}

此时,我们打开在http://localhost:15672/#/users 可以看到eric 下 的Can access virtual hosts 为 NoAccess

解决办法:

rabbitmqctl控制台输入

rabbitmqctl set_permissions -p / userName "." "." ".*"

再次执行时,可以看到:

然后运行 生产者程序。

我们先开着 Receive ,当生产者运行时

消费者的自动触发执行 :

直到所有的 指定的 queue 里面的消息完全消费完为止。(此时消费者程序仍然在监听中)

对于需要安装和设置用户的同学,请参考 windows下 安装 rabbitMQ 及操作常用命令

本文参考:

rabbitMq外文网站

百度百科

转载于:https://my.oschina.net/morpheusWB/blog/1529641

[RabbitMQ]RabbitMQ原理与相关操作(一)相关推荐

  1. rabbitmq 持久化_RabbitMQ原理与相关操作(三)消息持久化

    现在聊一下RabbitMQ消息持久化: 问题及方案描述 1.当有多个消费者同时收取消息,且每个消费者在接收消息的同时,还要处理其它的事情,且会消耗很长的时间.在此过程中可能会出现一些意外,比如消息接收 ...

  2. 深入了解RabbitMQ工作原理及简单使用

    深入了解RabbitMQ工作原理及简单使用 RabbitMQ系列文章 RabbitMQ在Ubuntu上的环境搭建 深入了解RabbitMQ工作原理及简单使用 RabbitMQ交换器Exchange介绍 ...

  3. 消息队列+RabbitMq工作原理

    目录 1.消息队列 2.应用场景 2.1 异步处理 2.2 应用解耦 2.3流量削锋 2.4 日志处理 3.RabbitMQ介绍 4.RabbitMQ工作原理 1.消息队列 消息即是信息的载体 消息队 ...

  4. [RabbitMQ]工作原理_原理名词解释

    RabbitMQ 核心部分 各个名词介绍 RabbitMQ工作原理 Broker: 接收和分发消息的应用,RabbitMQ Server 就是 Message Broker Virtual host: ...

  5. 深入解读RabbitMQ工作原理及简单使用

    深入解读RabbitMQ工作原理及简单使用 RabbitMQ系列目录 RabbitMQ在Ubuntu上的环境搭建 深入解读RabbitMQ工作原理及简单使用 Rabbit的几种工作模式介绍与实践 Ra ...

  6. 关于Linux中的apt-get的相关操作及原理

    关于Linux中的apt-get的相关操作及原理 Linux下的apt-get指令与相关文件夹 apt-get是linux下的一种简便的安装和更新软件的方法,在装软件的时候常用的命令就是 sudo a ...

  7. RabbitMQ 架构原理

    1.RabbitMQ 架构原理 由于 RabbitMQ 实现了 AMQP 协议,所以 RabbitMQ 的工作模型也是基于 AMQP 的.理解这张图片至关重要. 1.1 Broker 中介 我们要使用 ...

  8. [RabbitMQ]RabbitMQ深入理解(一)进阶/管理/配置

    2019独角兽企业重金招聘Python工程师标准>>> 本文源于朱忠华的<RabbitMQ实战指南> RabbitMQ简介 消息队列中间件有两种传递模式:点对点 和 发布 ...

  9. RabbitMQ#RabbitMQ+Haproxy消息队列集群和代理部署

    文章目录 一.消息队列/中间件 1.RabbitMQ本质上起到的作用就是削峰填谷 2.MQ简介(RabbitMQ比Kafka) 3.MQ消息队列的分类 二.RabbitMQ介绍(端口15672) 1. ...

最新文章

  1. 【Live555】live555源码详解(七):GenericMediaServer、RTSPServer、RTSPClient
  2. 如何团队协作,代码托管?Git使用教程:最详细、最浅显、一文读懂Git常用操作!...
  3. TextInputLayout
  4. java build.gradle 详解_java – Gradle构建失败[无法解析配置的所有依赖项’:compile’.]...
  5. 当当架构部张亮:从码农到大牛,技术与心境的双重提升
  6. 图的存储结构matlab,matlab存储 一幅图像的的函数为( )
  7. 学完Java后找工作难吗?需要满足什么条件?
  8. 管理11gRAC基本命令 (转载) 很详细
  9. excel如何找到高频词_拟录取后:应届生和往届生档案哪里找;重灾院校区;高频词背诵表...
  10. JavaScript数组sort()方法小结
  11. C#网络编程概述 三
  12. NLP预训练家族 | 自成一派的GPT!
  13. C++ 构造函数抛出异常注意事项
  14. vue 启动只显示error_Vue-声明式渲染
  15. FR JavaScript 调用存储执行并输出影响行数
  16. jspx格式手机打开,jspx来自埃及的java web快速开发框架
  17. 谈谈IT行业的各种证书
  18. 服务器08系统操作日志在哪看,怎么查看服务器操作系统日志
  19. USB摄像头驱动分析
  20. kafka 中如何保证数据消息不丢失

热门文章

  1. 一个方框,文字在边框上
  2. asp.net 中Gridview 使用总结
  3. GridView:根据单元格的值给单元格着色
  4. 利用JBPM4.4的AssignmentHandler实现用户角色整合另一种构思
  5. 基于按annotation的hibernate主键生成策略
  6. spring+hibernate的配置
  7. hdu3715 二分+2sat+建图
  8. 【Windows 逆向】使用 Cheat Engine 工具进行指针扫描挖掘关键数据内存真实地址 ( 指针扫描 )
  9. 【OkHttp】OkHttp 源码分析 ( 网络框架封装 | OkHttp 4 迁移 | OkHttp 建造者模式 )
  10. 【Flutter】Flutter 手势交互 ( 点击事件处理 | 点击 onTap | 双击 | 长按 onLongPress | 点击取消 | 按下 onTapDown | 抬起 onTapUp )