一、消息队列在实际场景中的使用
流程A在处理时没有在当前线程同步的处理完而是直接发送了一条消息A1到队列里,然后消息队列过了一段时间(可能是几毫秒 几秒 几分钟)这个消息开始被处理,消息处理的过程就相当于流程A被处理;当然这只是一个简单的模型下面我们套用实际的场景来看一下,比如下单成功后发送短信提醒;如果没有消息队列我们会选择同步调用发短信的接口并等待短信发送成功,正常情况下这么做是没有问题的但是如果发短信的时候短信接口出问题了或者说调用超时了等意外情况,这个时候我们就需要设计对应的方案来解决前提是这些方案的设计会比较复杂;
但是当我们使用消息队列以后这个事情就会变得非常简单,使用消息队列以后有如下好处:
① 实现了异步解耦
② 设计变的更加简单了
③ 保证了数据的最终一致性;
④ 提高效率;
二、消息队列特性
1 与业务无关 : 只做消息分发
2 FIFO : 先投递先到达
3 容灾 : 节点的动态增删和消息的持久化
4 性能 : 吞吐量提升,系统内部通信效率提高
三、为什么需要消息队列
生产和消费的速度或稳定性等因素不一致;
四、消息队列的好处
1 业务解耦
2 最终一致性 : 用记录和补偿的方式来处理,在做所有的不确定事情之前先记录然后再去做,它的结果通常分为三种成功失败或者不确定(比如说超时等);如果是成功我们就可以清楚掉记录,如果是失败或者不确定我们可以通过定时任务将所有事情重新做一遍直到成功为止;
3 广播 : 如果没有消息队列每一个新的业务方介入都需要联调一次接口,使用消息队列只需要关心消息是否送达到消息队列,新接入的接口订阅相关的消息自己做处理就可以了;
4 错峰与流控 : 上下游对于事情的处理是不同的,比如WEB前端每秒承受上千万的请求都是可以的但是数据库的处理却非常有限;迫于成本的压力我们不能要求数据库的机器数量与前端资源一样;这样的问题同样存在于系统与系统之间,比如短信系统的速度卡在网关上边它与前端的并发量不是一个数量级的,用户玩几秒种收到短信也是可以的;针对于这样的场景如果没有消息队列也能实现但是系统的复杂度非常的高;
五、常用的消息队列介绍
① Kafka
Kafka是Apache下的一个子项目,是一个高性能 跨语言 分布式发布订阅消息队列系统;
1 Kafka的特性
① 快速持久化 : 它可以在o1的系统开销下实现消息的持久化;
② 高吞吐 : 在一台普通的服务器上就可以达到10w/秒的吞吐速率;
③ 天生的分布式 : 所有组件天生支持分布式且自动实现负载均衡;2 Kafka基础定义
① Broker : Kafka集群包含一个或多个服务器,这个服务器就被称为Producer;
② Topic : 指每条发布到Kafka的消息都有一个类别,这个类别叫做Topic;物理上不同Topic的消息是分开存储的,逻辑上一个Topic消息虽然保存在一个或者多Producer上但是用户只需指定消息的Topic就可以生产或者消费数据而不用关心数据存在哪里;
③ Partition : 是物理上的概念,每个Topic包含一个或者多个Partition;
④ Producer : 负责发布消息到Kafka的Broker里边;
⑤ consumer : 消息消费者,向Kafka broker读取消息的客户端;
⑥ Consumer Group : 每个Consumer属于一个特定的Consumer Group(可为每个Consumer指定group name,若不指定group name则属于默认的group);
② RabbitMQ
RabbitMQ是流行的开源消息队列系统,用erlang语言开发。RabbitMQ是AMQP(高级消息队列协议)的标准实现;
1 RabbitMQ的使用过程
(1)客户端连接到消息队列服务器,打开一个channel。
(2)客户端声明一个exchange,并设置相关属性。
(3)客户端声明一个queue,并设置相关属性。
(4)客户端使用routing key,在exchange和queue之间建立好绑定关系。
(5)客户端投递消息到exchange。2 RabbitMQ的概念
Broker:简单来说就是消息队列服务器实体。
Exchange:消息交换机,它指定消息按什么规则,路由到哪个队列。
Queue:消息队列载体,每个消息都会被投入到一个或多个队列。
Binding:绑定,它的作用就是把exchange和queue按照路由规则绑定起来。
Routing Key:路由关键字,exchange根据这个关键字进行消息投递。
vhost:虚拟主机,一个broker里可以开设多个vhost,用作不同用户的权限分离。
producer:消息生产者,就是投递消息的程序。
consumer:消息消费者,就是接受消息的程序。
channel:消息通道,在客户端的每个连接里,可建立多个channel,每个channel代表一个会话任务。