一、RabbitMQ 概念详解和应用
消息队列和同步请求的区别
无论RabbitMQ还是Kafka,本质上都是提供了基于message或事件驱动异步处理业务的能力,相比于http和rpc的直接调用,它有着不可替代的优势:
1. 解耦,解耦的一个最常见做法就是在服务之间新增一层,使原来直接依赖的A,B service 松耦合,这在微服务架构中尤为重要。
2. 流量控制:通过消息队列意味着我们可以监控时间段内的需要处理的业务量,对于明显超出服务承受能力的请求,我们可以延迟处理或者拒绝处理,保证服务的稳定性与可用性。
3. 负载均衡:可以通过消息代理实现下游服务的负载均衡,有利于保证服务的高可用性;
消息队列协议介绍 AMQP
协议: AMQP,即Advanced Message Queuing Protocol,一个提供统一消息服务的应用层标准高级消息队列协议,是应用层协议的一个开放标准,为面向消息的中间件设计。
RabbitMQ模型:
1、Server:又称 broker,接受客户端连接,实现 AMQP 实体服务。
2、Connection:连接和具体 broker 网络连接。
3、Channel:网络信道,几乎所有操作都在 channel 中进行,channel 是消息读写的通道。客户端可以建立多个 channel,每个 channel 表示一个会话任务。
4、message:消息,服务器和应用程序之间传递的数据,由 properties 和 body 组成。properties 可以对消息进行修饰,比如消息的优先级,延迟等高级特性;body 是消息实体内容。
5、Virtual host:虚拟主机,用于逻辑隔离,最上层消息的路由。一个 Virtual host 可以若干个 Exchange 和 Queue,同一个 Virtual host 不能有同名的 Exchange 或 Queue。
6、Exchange:交换机,接受消息,根据路由键转发消息到绑定的队列上。
7、Binding:Exchange 和 Queue 之间的虚拟连接,binding 中可以包括 routing key。
8、Routing key:一个路由规则,虚拟机根据他来确定如何路由 一条消息。
9、Queue:消息队列,用来存放消息的队列。
Exchange 各种类型
交换机的类型,direct、topic、fanout、headers;
1、Direct Exchange,所有发送到 Direct Exchange 的消息被转发到 RouteKey 中指定的 Queue, Direct Exchange 可以使用默认的默认的 Exchange (default Exchange),默认的 Exchange 会绑定所有的队列,所以 Direct 可以直接使用 Queue 名(作为routing key )绑定。或者消费者和生产者的 routing key 完全匹配。
2、Toptic Exchange,是指发送到 Topic Exchange 的消息被转发到所有关心的 Routing key 中指定 topic 的 Queue 上。Exchange 将 routing key 和某 Topic 进行模糊匹配,此时队列需要绑定一个 Topic。所谓模糊匹配就是可以使用通配符,“#”可以匹配一个或多个词,“*”只匹配一个词。比如“log.#”可以匹配“log.info.test”, "log.*"就只能匹配 log.error。
3、Fanout Exchange:不处理路由键,只需简单的将队列绑定到交换机上。发送到该交换机上的消息都会被发送到与该交换机绑定的队列上。Fanout 转发是最快的。
总而言之:Direct change是严格意义上的匹配,routing key 与 binding key 完全一样; Fanout Exchange 是完全不关心你的routing key,向所有绑定的queue 全部发送;这是两个极端,那么Toptic Exchange 就相对Direct change宽松一些,它的消息投递取决于模糊匹配的结果。
最后介绍headers模式:
4. Headers Exchange:
headers类型的Exchange不依赖于routing key与binding key的匹配规则来路由消息,而是根据发送的消息内容中的headers属性进行匹配。
在绑定Queue与Exchange时指定一组键值对;当消息发送到Exchange时,RabbitMQ会取到该消息的headers(也是一个键值对的形式),对比其中的键值对是否完全匹配Queue与Exchange绑定时指定的键值对;如果完全匹配则消息会路由到该Queue,否则不会路由到该Queue。
通过图来表示:

RabbitMQ 单机安装与使用
windows 系统下,安装教程传送门(https://www.cnblogs.com/saryli/p/9729591.html)
linux 系统下,安装教程传送门(https://www.linuxprobe.com/install-rabbitmq-on-centos-7.html)
(会在后面的系列介绍高可用集群的搭建)
这里以dotnet 为例,示例如何使用 rabbitmq。
Producer End:
public class MessageQueueService
{
private IConnection _connection;
private IModel _channel;
private const string TicketExchangeName = "tickets";
public MessageQueueService()
{
var factory = new ConnectionFactory() { HostName = "localhost" };
_connection = factory.CreateConnection();
_channel = GetChannel();
_channel.ExchangeDeclare(TicketExchangeName, ExchangeType.Fanout, false, false);
} public void SendTicketMessage(Ticket message, string optType)
{ var messageBytes = ObjectToByteArray(message);
_channel.BasicPublish(TicketExchangeName, optType, false, null, messageBytes);
}
}
Consumer End:
public class TicketConsumerService : IHostedService
{
private IConnection _connection;
private IModel _channel;
private const string TicketExchangeName = "tickets";
private string queueName = "";
public TicketConsumerService()
{
var factory = new ConnectionFactory() { HostName = "localhost" };
_connection = factory.CreateConnection();
_channel = _connection.CreateModel();
_channel.ExchangeDeclare(TicketExchangeName, ExchangeType.Fanout, false, false);
} Task IHostedService.StartAsync(CancellationToken cancellationToken)
{
queueName = _channel.QueueDeclare().QueueName;
_channel.QueueBind(queueName, TicketExchangeName, "buy");
var consumer = new EventingBasicConsumer(_channel);
consumer.Received += (model, ea) =>
{
Ticket message = (Ticket)ByteArrayToObject(ea.Body.ToArray());
var routingKey = ea.RoutingKey;
Console.WriteLine(" [x] Received '{0}':'{1}'",
routingKey, message.Boarding);
};
_channel.BasicConsume(queue: queueName, autoAck: true, consumer: consumer);
return Task.CompletedTask;
} Task IHostedService.StopAsync(CancellationToken cancellationToken)
{
_connection.Dispose();
_channel.Dispose(); return Task.CompletedTask;
} private Object ByteArrayToObject(byte[] arrBytes)
{
MemoryStream memStream = new MemoryStream();
BinaryFormatter binForm = new BinaryFormatter();
memStream.Write(arrBytes, 0, arrBytes.Length);
memStream.Seek(0, SeekOrigin.Begin);
Object obj = (Object)binForm.Deserialize(memStream); return obj;
}
}
这篇主要介绍了一些Message Queue的概念及如何在web 开发过程中使用。下一篇会介绍RabbitMQ的一些进阶特性和使用场景。
--------------------------------------------
欢迎大家留言讨论,指出错误和不当之处!
一、RabbitMQ 概念详解和应用的更多相关文章
- .NET 云原生架构师训练营(模块二 基础巩固 RabbitMQ Masstransit 详解)--学习笔记
2.6.7 RabbitMQ -- Masstransit 详解 Consumer 消费者 Producer 生产者 Request-Response 请求-响应 Consumer 消费者 在 Mas ...
- JWT基础概念详解
JWT基础概念详解 JWT介绍 之前我们文章讲过分布式session如何存储,其中就讲到过Token.JWT.首先,我们来回顾一下使用Token进行身份认证. 客户端发送登录请求到服务器 服务器在用户 ...
- RabbitMQ Exchange详解以及Spring中Topic实战
前言 AMQP,即Advanced Message Queuing Protocol,高级消息队列协议,是应用层协议的一个开放标准,为面向消息的中间件设计.消息中间件主要用于组件之间的解耦. 业务需求 ...
- java入门---对象和类&概念详解&实例
Java作为一种面向对象语言.支持以下基本概念: 多态 继承 封装 抽象 类 对象 实例 方法 重载 这篇文章,我们主要来看下: 对象:对象是类的一个实例(对象不是找个女朋友),有状态 ...
- Android屏幕密度(Density)和分辨率概念详解
移动设备有大有小,那么如何适应不同屏幕呢,这给我们编程人员造成了很多困惑.我也是突然想到这些问题,然后去网上搜搜相关东西,整理如下. 首先,对下面这些长度单位必须了解. Android中的长度单位 ...
- Storm 学习之路(二)—— Storm核心概念详解
一.Storm核心概念 1.1 Topologies(拓扑) 一个完整的Storm流处理程序被称为Storm topology(拓扑).它是一个是由Spouts 和Bolts通过Stream连接起来的 ...
- Storm 系列(二)—— Storm 核心概念详解
一.Storm核心概念 1.1 Topologies(拓扑) 一个完整的 Storm 流处理程序被称为 Storm topology(拓扑).它是一个是由 Spouts 和 Bolts 通过 Stre ...
- 图像处理术语解释:灰度、色相、饱和度、亮度、明度、阿尔法通道、HSL、HSV、RGBA、ARGB和PRGBA以及Premultiplied Alpha(Alpha预乘)等基础概念详解
☞ ░ 前往老猿Python博文目录 ░ 一.引言 由于老猿以前没接触过图像处理,在阅读moviepy代码时,对类的有些处理方法代码看不懂是什么含义,为此花了4天时间查阅了大量资料,并加以自己的理解和 ...
- 1-Hyperledger Fabric概念详解
目录 一.Hyperledger Fabric概述 二.基本术语 1.共享账本ledger 2.通道Channel 3.组织Org 4.智能合约Chaincode 5.背书Endorse 6.各种节点 ...
随机推荐
- 网络编程-UDP的服务器和客户端----keep on going never give up
1 //**************************************服务器********************************************** 2 #inclu ...
- java中基本数据类型、包装类及字符串之间的相互转换
基本数据类型:不支持面向对象的编程机制(没有属性和方法),即不支持面向对象,之所以提供8中基本数据类型,是为了方便常规数据的处理. 包装类:通过包装类可以将基本数据类型的值包装为引用数据类型的对象,使 ...
- JAVA基础——运算符号
运算符(java) 算数运算符:+,-,*,/,%(取余),++,-- 赋值运算符:= 关系运算符:<, >, >= ,<= ,== , != 逻辑运算符:&& ...
- [bug] Openresty:content_by_lua_file 404
参考 http://www.javaear.com/question/28087228.html https://github.com/openresty/openresty.org/issues/1 ...
- [转载]libvirt(virsh命令总结)
libvirt(virsh命令总结) virsh回车进入交互式界面: version pwd hostname 显示本节点主机名 nodeinfo 显示节点信息 list --all 显示所有云主机 ...
- Linux 操作系统(四)用户组管理&进程管理&任务调度
以下实例均在Centos7下验证 Centos7 查看命令帮助 man xxx 用户组管理 useradd useradd user1 password user1 cat /etc/passwd # ...
- linux进阶之nmtui和nmcli配置网络
CentOS7配置网络推荐使用NetworkManager服务(不推荐network服务). 图形化方式:nmtui或Applications->System Tools->Setting ...
- python基础之流程控制(if判断和while、for循环)
程序执行有三种方式:顺序执行.选择执行.循环执行 一.if条件判断 1.语句 (1)简单的 if 语句 (2)if-else 语句 (3)if-elif-else 结构 (4)使用多个 elif 代码 ...
- 7.2-5 usermod
7.2 usermod:修改用户信息 usermod 命令用于修改系统已经存在的用户的账号信息. -c comment 修改用户password文件中用户的说明栏,同useradd ...
- rocketmq常见问题及使用 新手篇
一 部署阶段 1.启动命令 nameServer启动:nohup sh bin/mqnamesrv -n ip地址:9876 & broker启动:nohup sh bin/mqbroker ...