文章目录
MQ
本人最先接触的MQ,其实并不是activeMQ,而是IBM-MQ。
IBM MQ 基础知识
借助 MQ on Containers、 MQ on Cloud、 MQ on Ubuntu 或 MQ on Windows 快速启动并运行队列管理器。
IBM MQ 是一个强大且安全可靠的消息传递解决方案。它可以简化并加速跨多个平台的不同应用程序的集成,并且支持多种 API 和语言。
IBM MQ 使应用程序能够以可靠且可扩展的方式进行通信和交换数据,从而使一个应用程序与另一个应用程序解耦。通过这种方式,MQ 可以帮助集成在不同框架、语言、平台、云和位置上运行的应用程序。您可以按照自己的方式编写应用程序,因为您知道 MQ 可以解决问题,并将这些应用程序集成起来。
IBM MQ 允许服务器基础架构跨越数据中心、大型机和云框架。IBM MQ 能够以软件和硬件两种方式实现,在独立应用程序之间提供企业级通信。此外,它还降低了开发这些应用程序的复杂性。
IBM MQ 如何简化应用程序之间的通信方式?
在两个或多个应用程序之间搭建消息传递基础架构意味着这些应用程序不能直接通信。实际上,它们通过中间件进行交互。
更具体地说,就是一个应用程序将另一个应用程序的信息放置在消息中,而消息被放置在消息队列中。
因此,消息传递不需要应用程序同时可用,因为可以使用队列。这种模型称为异步消息传递。
消息、队列和通道
消息 是应用程序生产和使用的数据包。
队列 是可寻址的位置,用于传递消息和在需要使用前可靠地存储消息。
队列管理器 是托管队列的 MQ 服务器。
通道 是队列管理器相互之间以及与应用程序之间进行通信的途径。
对比一下
第一个,看CPU与内存之间的Cache
再对比一下电商的秒杀。
还没懂,没有关系。
我们来看一下秘书与老板的关系(我指的是工作中的正常关系)
老板处理的事情比较重要,前面的大堆的不管快不管慢的,先让秘书接下来,然后没用的直接扔掉,有用的排成序列,给老板安排日程!
这个过程像不像 电商的秒杀??不是会员的秒杀?对不起,你的会员身份不配,直接扔掉,然后,会员的秒杀,先接下来。排队等着,我去后面查库存。前面的安排完了,后面的嘿嘿嘿,对不起老板没空,没档期!!
ActiveMQ
Apache ActiveMQ是Apache软件基金会所研发的开放源代码消息中间件;由于ActiveMQ是一个纯Java程序,因此只需要操作系统支持Java虚拟机,ActiveMQ便可执行。
从定义上看,Apache 还是一个消息队列呀。
直到他跟spring 一结合。一下子量变引起了质变。
关于jms概念以及activemq这里不做具体赘述,activemq是apache的一款项目,介绍里号称是最方便最强大的jms实现方式。其实jms与webservice功能是一样的,侧重点不同而已。都是提供多系统之间的交互通信方式,前者相对于后者更加轻量级,可以实现延迟通信,避免系统高峰期交互通信,也不需要暴露接口等,开发起来更加方便,但是如果项目要求即时性很高那么就选择后者,当然他们两者也可以整合起来一起使用。
微服务架构和分布式架构
分布式的架构
微服务的架构
简单一点说,就是原来的一个系统,现在分成了N个模块
复杂了就:
或者
那么问题就来了。
当分成不同的模块之后,如果一笔业务仍然需要跨越两个系统的表。那怎么处理?
这就引出了分布式事务。
1 两阶段提交(2PC)
两阶段提交(Two-phase Commit,2PC),通过引入协调者(Coordinator)来协调参与者的行为,并最终决定这些参与者是否要真正执行事务。有一下两个阶段
准备阶段
协调者询问参与者事务是否执行成功,参与者发回事务执行结果
两阶段提交存在的问题
那这个问题就多了。
同步阻塞 所有事务参与者在等待其它参与者响应的时候都处于同步阻塞状态,无法进行其它操作。
单点问题 协调者在 2PC 中起到非常大的作用,发生故障将会造成很大影响。特别是在阶段二发生故障,所有参与者会一直等待状态,无法完成其它操作。
数据不一致 在阶段二,如果协调者只发送了部分 Commit 消息,此时网络发生异常,那么只有部分参与者接收到 Commit 消息,也就是说只有部分参与者提交了事务,使得系统数据不一致。
太过保守 任意一个节点失败就会导致整个事务失败,没有完善的容错机制。
2 补偿事务(TCC)
TCC 其实就是采用的补偿机制,其核心思想是:针对每个操作,都要注册一个与其对应的确认和补偿(撤销)操作。它分为三个阶段:
Try 阶段主要是对业务系统做检测及资源预留
Confirm 阶段主要是对业务系统做确认提交,Try阶段执行成功并开始执行 Confirm阶段时,默认 Confirm阶段是不会出错的。即:只要Try成功,Confirm一定成功。
Cancel 阶段主要是在业务执行错误,需要回滚的状态下执行的业务取消,预留资源释放。
缺点: 缺点还是比较明显的,在2,3步中都有可能失败。TCC属于应用层的一种补偿方式,所以需要程序员在实现的时候多写很多补偿的代码,在一些场景中,一些业务流程可能用TCC不太好定义及处理。
两阶段提交与补偿事务 都存在着重大的设计问题,就是原本分开的两个模块再次“紧耦合”了。
就是A模块的业务,为啥要让A模块的程序去等待??
3 本地消息表(异步确保)
有点像老程序的短信群发。用一个数据表来做中间媒介。
本地消息表与业务数据表处于同一个数据库中,这样就能利用本地事务来保证在对这两个表的操作满足事务特性,并且使用了消息队列来保证最终一致性。
在分布式事务操作的一方完成写业务数据的操作之后向本地消息表发送一个消息,本地事务能保证这个消息一定会被写入本地消息表中。
之后将本地消息表中的消息转发到 Kafka 等消息队列中,如果转发成功则将消息从本地消息表中删除,否则继续重新转发。
在分布式事务操作的另一方从消息队列中读取一个消息,并执行消息中的操作
看上去还是不太优雅。
4 MQ 事务消息
终于,MQ闪亮登场
也就是说在业务方法内要想消息队列提交两次请求,一次发送消息和一次确认消息。如果确认消息发送失败了RocketMQ会定期扫描消息集群中的事务消息,这时候发现了Prepared消息,它会向消息发送者确认,所以生产方需要实现一个check接口,RocketMQ会根据发送端设置的策略来决定是回滚还是继续发送确认消息。这样就保证了消息发送与本地事务同时成功或同时失败。
其实,不管是RabbitMQ,Kafka,ActiveMQ ,RocketMQ 都在第三种或第四种方式中做事件。
消息中间件的使用场景
消息中间件的使用场景总结就是六个字:解耦、异步、削峰
说简单一点,他们的责任就是女秘书,解放出老板的晚上休息时间。(给你一张图,自己体会)
1.解耦
如果我方系统A要与三方B系统进行数据对接,推送系统人员信息,通常我们会使用接口开发来进行。但是如果运维期间B系统进行了调整,或者推送过程中B系统网络进行了调整,又或者后续过程中我们需要推送信息到三方C系统中,这样的话就需要我们进行频繁的接口开发调整,还需要考虑接口推送消息失败的场景。
如果我们使用消息中间件进行消息推送,我们只需要按照一种约定的数据结构进行数据推送,其他三方系统从消息中间件取值消费就可以,即便是三方系统出现宕机或者其他调整,我们都可以正常进行数据推送。
总结:通过一个 MQ,Pub/Sub 发布订阅消息这么一个模型,A 系统就跟其它系统彻底解耦了。
2.异步
继续我们上述的消息推送业务,如果我们现在需要同时推送消息到BCD三个系统中,而BCD系统接收到消息后需要进行复杂的逻辑处理,以及读库写库处理。如果一个三方系统进行消息处理需要1s,那我们遍历推送完一次消息,就需要三秒。
而如果我们使用消息中间件,我们只需要推送到消息中间件,然后进行接口返回,可能只需要20ms,大大提升了用户体验。消息推送后BCD系统各自进行消息消费即可,不需要我们等待。
3.削峰
还是上述我们的应用场景,假设某一时间段内,每秒都有一条消息推送,如果我们使用接口进行推送,BCD三个系统处理完就需要三秒。这样会导致用户前端体验较差,而且系统后台一直处于阻塞状态,后续的消息推送接口一直在等待。
如果我们使用消息中间件,我们只需要将消息推送至消息中间件中,BCD系统对积压的消息进行相应的处理。
在上述高频发的消息时间段内,会在消息中间中产生消息积压,BCD系统在上述时间段外对积压消息进行相应的处理即可。
四种消息中间件的对比
本人不负责其公正性。(我个人感觉哪个都能满足99%的项目需要)
就目前而言,喜欢spring的,都说kafka 最牛逼 。还号称永不丢消息。
但是,国内的微服务开发其实是阿里的dubbo + zookeeper起来的。RocketMQ 也很牛逼呀。
但是,随着微服务的使用越来越多,大家发现 ,rabbitMQ 速度最快呀。吞吐量不够,那只是开始的内存开销的问题,而且,吞吐量不够,机器来凑呀。
说来说去,好象没有一个是完胜!
RabbitMQ是什么
RabbitMQ是一个由erlang语言编写的、开源的、在AMQP基础上完整的、可复用的企业消息系统。
RabbitMQ的作用及原理
RabbitMQ的通信方式
1:简单队列
最简单的工作队列,其中一个消息生产者,一个消息消费者,一个队列。也称为点对点模式
2:工作队列模式
一个消息生产者,一个交换器,一个消息队列,多个消费者。同样也称为点对点模式
3:发布订阅模式
Pulish/Subscribe,无选择接收消息,一个消息生产者,一个交换机(交换机类型为fanout),多个消息队列,多个消费者
生产者只需把消息发送到交换机,绑定这个交换机的队列都会获得一份一样的数据。
4:路由模式
在发布/订阅模式的基础上,有选择的接收消息,也就是通过 routing 路由进行匹配条件是否满足接收消息。
5:主体模式
topics(主题)模式跟routing路由模式类似,只不过路由模式是指定固定的路由键 routingKey,而主题模式是可以模糊匹配路由键 routingKey,类似于SQL中 = 和 like 的关系。
6:RPC模式
与上面其他5种所不同之处,该模式是拥有请求/回复的。也就是有响应的,上面5种都没有。
RPC是指远程过程调用,也就是说两台服务器A,B,一个应用部署在A服务器上,想要调用B服务器上应用提供的处理业务,处理完后然后在A服务器继续执行下去,把异步的消息以同步的方式执行。
说rabbit比较简单,事实上,对于初学者来说,可能也是复杂的要命。
总结
提示:这里对文章进行总结:
其实,不管是这些MQ怎么对比,怎么使用,他们的作用是相同的,就是女秘书。专业的叫法就是解耦、异步、削峰。而重要的问题就是两点。
能削多大的峰。
跟削的时候,会不会丢消息。
如果说你的业务发起的不到1万用户,不用说了,你单机都够了,根本不需要MQ!
一般用到MQ的都是这样的数量级。
一个消费者一秒是 1000 条,一秒 3 个消费者是 3000 条,一分钟就是 18 万条。由于消费者宕机导致现在MQ中积压几百万数据。
事实上,很多的时候,跟本没有这么大的并发。有人经常举例说全国人抢车票,但是,问题是不可能几亿人都是去一个地方,也不是同一个出发点,也不会抢同一辆车。那当你选择了起,终点与车次之后,跟你同时抢这一辆车的才是并发,想像一样,去北京的人会抢去成都的车票么?所以,MQ并不能代替系统设计!