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

无论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. RabbitMQ高级特性

    消息的可靠投递 在使用Rabbitmq的时候,作为消息发送方希望杜绝任何消息丢失或者投递失败场景.Rabbitmq为我们提供了两种方式用来控制消息的投递可靠性模式 confirm确认模式 return ...

  2. 探索专有领域的端到端ASR解决之道

    摘要:本文从<Shallow-Fusion End-to-End Contextual Biasing>入手,探索解决专有领域的端到端ASR. 本文分享自华为云社区<语境偏移如何解决 ...

  3. xrandr 直接输这个能显示可用的分辨和当前的分辨率 xrandr -s 1920x1200就设置成指定的分辨率

    利用 xrandr 命令修改屏幕分辨率 时间  2016-10-29 原文   http://blog.csdn.net/mao0514/article/details/52965700   问题背景 ...

  4. K8S的资源管理

    K8S的资源管理 管理K8S资源的三种基本方法: 陈述式资源管理方法-使用cli工具进行管理. 声明式资源管理方式-主要依耐资源配置清单. GUI式资源管理方法-主要依耐图形界面. 陈述式资源管理方法 ...

  5. 用于监视Linux上的内存使用情况的Bash脚本

    用于监视Linux上的内存使用情况的Bash脚本 2019-06-17 11:32:45作者:戴进稿源:云网牛站 在本文中,我们添加了两个shell脚本来监视Linux操作系统上的内存利用率,即用于监 ...

  6. 精确报告Linux内存使用情况实用脚本:ps_mem

    精确报告Linux内存使用情况实用脚本:ps_mem 2019-09-06 12:45 ps_mem内存工具 ps_mem 是一个可以帮助我们精确获取 Linux 中各个程序核心内存使用情况的简单 p ...

  7. 图解 Redis | 不就是 AOF 持久化嘛

    AOF 日志 试想一下,如果 Redis 每执行一条写操作命令,就把该命令以追加的方式写入到一个文件里,然后重启 Redis 的时候,先去读取这个文件里的命令,并且执行它,这不就相当于恢复了缓存数据了 ...

  8. python 中 list 的append与extend区别

    append 添加的是一个对象 extend 添加的是序列与原序列合并

  9. Python数模笔记-PuLP库(2)线性规划进阶

    1.基于字典的创建规划问题 上篇中介绍了使用 LpVariable 对逐一定义每个决策变量,设定名称.类型和上下界,类似地对约束条件也需要逐一设置模型参数.在大规模的规划问题中,这样逐个定义变量和设置 ...

  10. [leetcode] 212. 单词搜索 II(Java)

    212. 单词搜索 II 这leetcode的评判机绝对有问题!!同样的代码提交,有时却超时!害得我至少浪费两个小时来寻找更优的答案= =,其实第一次写完的代码就可以过了,靠!!!第207位做出来的 ...