消息队列和同步请求的区别

无论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 概念详解和应用的更多相关文章

  1. .NET 云原生架构师训练营(模块二 基础巩固 RabbitMQ Masstransit 详解)--学习笔记

    2.6.7 RabbitMQ -- Masstransit 详解 Consumer 消费者 Producer 生产者 Request-Response 请求-响应 Consumer 消费者 在 Mas ...

  2. JWT基础概念详解

    JWT基础概念详解 JWT介绍 之前我们文章讲过分布式session如何存储,其中就讲到过Token.JWT.首先,我们来回顾一下使用Token进行身份认证. 客户端发送登录请求到服务器 服务器在用户 ...

  3. RabbitMQ Exchange详解以及Spring中Topic实战

    前言 AMQP,即Advanced Message Queuing Protocol,高级消息队列协议,是应用层协议的一个开放标准,为面向消息的中间件设计.消息中间件主要用于组件之间的解耦. 业务需求 ...

  4. java入门---对象和类&概念详解&实例

        Java作为一种面向对象语言.支持以下基本概念: 多态 继承 封装 抽象 类 对象 实例 方法 重载     这篇文章,我们主要来看下: 对象:对象是类的一个实例(对象不是找个女朋友),有状态 ...

  5. Android屏幕密度(Density)和分辨率概念详解

    移动设备有大有小,那么如何适应不同屏幕呢,这给我们编程人员造成了很多困惑.我也是突然想到这些问题,然后去网上搜搜相关东西,整理如下.   首先,对下面这些长度单位必须了解. Android中的长度单位 ...

  6. Storm 学习之路(二)—— Storm核心概念详解

    一.Storm核心概念 1.1 Topologies(拓扑) 一个完整的Storm流处理程序被称为Storm topology(拓扑).它是一个是由Spouts 和Bolts通过Stream连接起来的 ...

  7. Storm 系列(二)—— Storm 核心概念详解

    一.Storm核心概念 1.1 Topologies(拓扑) 一个完整的 Storm 流处理程序被称为 Storm topology(拓扑).它是一个是由 Spouts 和 Bolts 通过 Stre ...

  8. 图像处理术语解释:灰度、色相、饱和度、亮度、明度、阿尔法通道、HSL、HSV、RGBA、ARGB和PRGBA以及Premultiplied Alpha(Alpha预乘)等基础概念详解

    ☞ ░ 前往老猿Python博文目录 ░ 一.引言 由于老猿以前没接触过图像处理,在阅读moviepy代码时,对类的有些处理方法代码看不懂是什么含义,为此花了4天时间查阅了大量资料,并加以自己的理解和 ...

  9. 1-Hyperledger Fabric概念详解

    目录 一.Hyperledger Fabric概述 二.基本术语 1.共享账本ledger 2.通道Channel 3.组织Org 4.智能合约Chaincode 5.背书Endorse 6.各种节点 ...

随机推荐

  1. 匿名函数lambda / map()方法

    lambda一般配合其他方法使用,一般使用在只用过一次就不用的函数,那就没必要特意去定义 lambda能支持的最复杂的语句就是三元运算 例如: lambda x,y: x*y if x < y ...

  2. Linux_搭建NFS服务(基础)

    [RHEL8]-NFSserver :[Centos7]-NFSclient !!!测试环境我们首关闭防火墙和selinux(NFSserver和NFSclient都需要) [root@localho ...

  3. SQL注入和XSS攻击

    SQL注入 定义:黑客通过在请求的数据中填入特殊字符,影响服务器数据库操作程序正常执行,从而达到攻击的目的. 形式: 拼接SQL: 登录验证:前台输入 username:yan password:12 ...

  4. redux 源码浅析

    redux 源码浅析 redux 版本号: "redux": "4.0.5" redux 作为一个十分常用的状态容器库, 大家都应该见识过, 他很小巧, 只有 ...

  5. 二:使用VS2019 + .net 6创建 webapi 项目

    0.创建一个.net 6项目.由于目前.net 6还是预览版,所以需要添加预览版SDK功能.工具 -> 选项 -> 环境 -> 预览功能 ,勾选使用.net sdk预览版. 1.新建 ...

  6. GO语言面向对象04---接口的继承

    package main import "fmt" type Animal interface { Eat(food string) (shit string) GoDie() } ...

  7. 用python调试Appium和雷电模拟器连接时出现Original error: Could not find 'adb.exe' in PATH

    用python调试Appium和雷电模拟器连接时出现Original error: Could not find 'adb.exe' in PATH 确定环境变量没错,用管理员启动Appium就不会出 ...

  8. GPU上的图像和信号处理

    GPU上的图像和信号处理 NVIDIA Performance Primitives(NPP)库提供GPU加速的图像,视频和信号处理功能,其执行速度比仅CPU实施快30倍.拥有5000多个用于图像和信 ...

  9. OFRecord 数据格式

    OFRecord 数据格式 深度学习应用需要复杂的多阶段数据预处理流水线,数据加载是流水线的第一步,OneFlow 支持多种格式数据的加载,其中 OFRecord 格式是 OneFlow 原生的数据格 ...

  10. CPU性能PK

    CPU性能PK AMD vs Intel 2020: Who Makes the Best CPUs? 英文原文链接:https://www.tomshardware.com/features/amd ...