什么是RabbitMQ

RabbitMQ是一个开源的AMQP实现,服务器端用Erlang语言编写。支持多种客户端,如:Python、Ruby、.NET、Java、JMS、C、PHP、ActionScript、XMPP、STOMP等,支持AJAX。用于在分布式系统中存储转发消息,在易用性、扩展性、高可用性等方面表现不俗。在中小型企业中应用比较多。

RabbitMQ整体架构

1、RabbitMQ的整体架构图

 

2、RabbitMQ的整体结构图

3、相关概念

相关概念说明

Broker:标识消息队列服务器实体.相当于安装的RabbitMQ。 Virtual Host:虚拟主机。拥有自己的队列、交换器、绑定和权限机制。相当于在一个broker中实现多租户,一个虚拟主机给一个用户使用。 Queue:消息队列,用来保存消息直到被消费者消费掉(取出消息并回复)。 Exchange:交换器,用来接收生产者发送的消息并将这些消息路由给服务器中的队列。
一般消息提供者不会直接将消息发送到指定的队列中,而是先将消息发送至交换器,交换器再将消息按照交换规则发送到指定队列。 Banding:绑定,用于消息队列和交换机之间的关联。一个绑定就是基于路由键将交换机和消息队列连接起来的路由规则,所以可以将交换器理解成一个由绑定构成的路由表。 Channel:信道,多路复用连接中的一条独立的双向数据流通道。信道是建立在真实的TCP连接内地虚拟链接,AMQP命令都是通过信道发出去的,不管是发布消息、订阅队列还是接收消息,
这些动作都是通过信道完成。因为对于操作系统来说,建立和销毁TCP都是非常昂贵的开销,所以引入了信道的概念,以复用一条TCP连接。 Connection:连接,就是与rabbitmq服务的一个socket连接。 Publisher:消息的生产者,也就是是一个向交换器发布消息的服务或者程序。 Consumer:消息的消费者,表示一个从一个消息队列中取得消息的服务或者程序。

基于.NetCore简单实现Rabbitmq

在RabbitMQ中通过Exchange分发消息时,根据类型的不同分发策略有区别。目前共四种类型:direct、fanout、topic、headers(headers匹配AMQP消息的header而不是路由键(Routing-key),此外headers交换器和direct交换器完全一致,但是性能差了很多,目前几乎用不到了)。

1、Direct

Direct是指消息发送的策略是路由键与队列名完全匹配。 它是要求队列绑定的exchange的路由键于发送消息到该exchange上的routekey完全一致,才能将消息发送到改队列中。

简单代码实现消息发送

 1        public void PublishDirectMessage(string queueName, string exchangeName, string routeKey, string message)
2 {
3
4 var factory = new ConnectionFactory()
5 {
6 HostName = _config.Host,
7 VirtualHost = _config.VirtualHost,
8 UserName = _config.UserName,
9 Password = _config.Password,
10 };
11 using (var connection = factory.CreateConnection())
12 {
13 using (var channel = connection.CreateModel())
14 {
15 //定义交换机
16 channel.ExchangeDeclare(exchangeName, ExchangeType.Direct, true, false, null);
17 //定义队列
18 channel.QueueDeclare(queueName, true, false, false, null);
19 //绑定
20 channel.QueueBind(queueName, exchangeName, routeKey, null);
21 byte[] data = Encoding.UTF8.GetBytes(message);
22 //发送消息
23 channel.BasicPublish(exchangeName, routeKey, null, data);
24 }
25 }
26 }

2、Topic

Topic是一种模糊匹配路由键的策略,它只模糊识别两个通配符:"#"和"*"。#匹配0个或多个单词,*匹配不多不少一个单词。它要求队列绑定的exchange中绑定的路由键模糊匹配发送消息的routekey,即可将消息发送到该队列中。

简单代码实现消息发送

 1        public void PublishTopicMessage(string queueName, string exchangeName, string routeKey, string message)
2 {
3
4 var factory = new ConnectionFactory()
5 {
6 HostName = _config.Host,
7 VirtualHost = _config.VirtualHost,
8 UserName = _config.UserName,
9 Password = _config.Password,
10 };
11 using (var connection = factory.CreateConnection())
12 {
13 using (var channel = connection.CreateModel())
14 {
15 channel.QueueDeclare(queueName, true, false, false, null);
16 channel.ExchangeDeclare(exchangeName, ExchangeType.Topic, true, false, null);
17 channel.QueueBind(queueName, exchangeName, routeKey, null);
18 byte[] data = Encoding.UTF8.GetBytes(message);
19 channel.BasicPublish(exchangeName, routeKey, null, data);
20 }
21 }
22 }

3、Fanout

Fanout是一种广播模式,它不需要指定路由键。凡是与改exchange绑定的队列都能收到该exchange传入的消息

简单代码实现消息发送

 1        public void PublishFanoutMessage(string queueName, string exchangeName, string message)
2 {
3
4 var factory = new ConnectionFactory()
5 {
6 HostName = _config.Host,
7 VirtualHost = _config.VirtualHost,
8 UserName = _config.UserName,
9 Password = _config.Password,
10 };
11 using (var connection = factory.CreateConnection())
12 {
13 using (var channel = connection.CreateModel())
14 {
15 channel.QueueDeclare(queueName, true, false, false, null);
16 channel.ExchangeDeclare(exchangeName, ExchangeType.Fanout, true, false, null);
17
18 byte[] data = Encoding.UTF8.GetBytes(message);
19 channel.BasicPublish(exchangeName, "", null, data);
20 }
21 }
22 }

消息消费者代码实现

 1         public void HandleMessage(string queueName)
2 {
3
4 //创建工厂--建立连接---创建channel--定义事件消费者并绑定事件--指定消费队列
5 var factory = new ConnectionFactory()
6 {
7 HostName = _config.Host,
8 VirtualHost = _config.VirtualHost,
9 UserName = _config.UserName,
10 Password = _config.Password
11 };
12 var connection = factory.CreateConnection();
13 var channel = connection.CreateModel();
14 channel.QueueDeclare(queueName,true,false,false,null);
15 // channel.BasicQos(1,1,false);
16 ///定义事件消费者
17 EventingBasicConsumer consumer = new EventingBasicConsumer(channel);
18 consumer.Received += Consumer_Received;
19 //消费
20 channel.BasicConsume(queueName, false, consumer);
21 //此处不释放channel,应该在事件处理中完成后释放,不然可能存在事件未处理完,而channel释放,导致消息没能被移除
22 //channel.Dispose();
23 //connection.Close();
24 }
25
26 private void Consumer_Received(object sender, BasicDeliverEventArgs e)
27 {
28 var message = Encoding.UTF8.GetString(e.Body.ToArray());
29 #region 业务处理
30 Console.WriteLine(message);
31 #endregion
32 EventingBasicConsumer consumer = sender as EventingBasicConsumer;
33 //string exchangeName = e.Exchange;
34 //string routeKey = e.RoutingKey;
35 //设置已经被消费
36 consumer.Model.BasicAck(e.DeliveryTag, false);
37 //释放Channel
38 consumer.Model.Dispose();
39
40 }

总结

以上简单介绍了rabbitmq的相关概念和整体结构。顺便使用代码实现了rabbitmq中的三种exchange策略(代码仅仅是简单实现,并无多大参考价值!!!)。

简单入门Rabbitmq的更多相关文章

  1. 手把手一起入门 RabbitMQ 的六大使用模式(Java 客户端)

    原文地址:手把手一起入门 RabbitMQ 的六大使用模式(Java 客户端) 为什么使用 MQ? 在这里我就不多说了,无非就是削峰.解耦和异步.这里没有很多关于 MQ 的理论和概念,只想手把手带你一 ...

  2. 用IntelliJ IDEA创建Gradle项目简单入门

    Gradle和Maven一样,是Java用得最多的构建工具之一,在Maven之前,解决jar包引用的问题真是令人抓狂,有了Maven后日子就好过起来了,而现在又有了Gradle,Maven有的功能它都 ...

  3. [原创]MYSQL的简单入门

    MYSQL简单入门: 查询库名称:show databases; information_schema mysql test 2:创建库 create database 库名 DEFAULT CHAR ...

  4. Okio 1.9简单入门

    Okio 1.9简单入门 Okio库是由square公司开发的,补充了java.io和java.nio的不足,更加方便,快速的访问.存储和处理你的数据.而OkHttp的底层也使用该库作为支持. 该库极 ...

  5. emacs最简单入门,只要10分钟

    macs最简单入门,只要10分钟  windwiny @2013    无聊的时候又看到鼓吹emacs的文章,以前也有几次想尝试,结果都是玩不到10分钟就退出删除了. 这次硬着头皮,打开几篇文章都看完 ...

  6. 【java开发系列】—— spring简单入门示例

    1 JDK安装 2 Struts2简单入门示例 前言 作为入门级的记录帖,没有过多的技术含量,简单的搭建配置框架而已.这次讲到spring,这个应该是SSH中的重量级框架,它主要包含两个内容:控制反转 ...

  7. Docker 简单入门

    Docker 简单入门 http://blog.csdn.net/samxx8/article/details/38946737

  8. Springmvc整合tiles框架简单入门示例(maven)

    Springmvc整合tiles框架简单入门示例(maven) 本教程基于Springmvc,spring mvc和maven怎么弄就不具体说了,这边就只简单说tiles框架的整合. 先贴上源码(免积 ...

  9. git简单入门

    git简单入门 标签(空格分隔): git git是作为程序员必备的技能.在这里就不去介绍版本控制和git产生的历史了. 首先看看常用的git命令: git init git add git comm ...

随机推荐

  1. Solon详解(十)- 怎么用 Solon 开发基于 undertow jsp tld 的项目?

    Solon详解系列文章: Solon详解(一)- 快速入门 Solon详解(二)- Solon的核心 Solon详解(三)- Solon的web开发 Solon详解(四)- Solon的事务传播机制 ...

  2. 093 01 Android 零基础入门 02 Java面向对象 02 Java封装 01 封装的实现 03 # 088 01 Android 零基础入门 02 Java面向对象 02 Java封装 02 static关键字 03 static关键字(下)

    093 01 Android 零基础入门 02 Java面向对象 02 Java封装 01 封装的实现 03 # 088 01 Android 零基础入门 02 Java面向对象 02 Java封装 ...

  3. 086 01 Android 零基础入门 02 Java面向对象 01 Java面向对象基础 03 面向对象基础总结 01 面向对象基础(类和对象)总结

    086 01 Android 零基础入门 02 Java面向对象 01 Java面向对象基础 03 面向对象基础总结 01 面向对象基础(类和对象)总结 本文知识点:面向对象基础(类和对象)总结 说明 ...

  4. 【漏洞复现】WinRAR目录穿越漏洞(CVE-2018-20250)复现

    前言 这漏洞出来几天了,之前没怎么关注,但是这两天发现开始有利用这个漏洞进行挖矿和病毒传播了,于是想动手复现一波. WinRAR 代码执行相关的CVE 编号如下: CVE-2018-20250,CVE ...

  5. 通用redis

    import lombok.extern.slf4j.Slf4j;import org.apache.poi.ss.formula.functions.T;import org.rcisoft.cor ...

  6. 两个多维高斯分布之间的KL散度推导

    在深度学习中,我们通常对模型进行抽样并计算与真实样本之间的损失,来估计模型分布与真实分布之间的差异.并且损失可以定义得很简单,比如二范数即可.但是对于已知参数的两个确定分布之间的差异,我们就要通过推导 ...

  7. 持续集成工具之Jenkins使用配置

    在上一篇博客中,我们主要介绍了DevOps理念以及java环境和jenkins的安装,回顾请参考https://www.cnblogs.com/qiuhom-1874/p/13805666.html: ...

  8. 多测师讲解python函数 _open_高级讲师肖sir

    open()函数 #open() 函数用于打开一个文件,创建一个 file 对象 #Python open() 函数用于打开一个文件,并返回文件对象, # 在对文件进行处理过程都需要使用到这个函数,如 ...

  9. oracle 查询当前数据库环境

    select SYS_CONTEXT('USERENV','AUTHENTICATION_TYPE')用户的认证类型 from dual;--用户的认证类型select SYS_CONTEXT('US ...

  10. Thumbnailator处理图片

    读取源图 of(String... files) of(File... files) of(InputStream... inputStreams) of(URL... urls) 输出文件 toFi ...