业务什么是消息队列列是应用于業务的解耦和分离应具备分布式,高可靠性高性能,高实时性高稳定性,高扩展性等特性
.net 生态闭环:官方开源项目->第三方参与学习->第三方改进并提交新功能或bug->官方合并新功能或bug->官方发布新版本
為什么开源? .net 开源生态本身弱,而强大是你与我不断学习,点滴分享,相互协助共同营造良好的.net生态环境。
开源理念: 开源是一种态度分享是┅种精神,学习仍需坚持进步仍需努力,.net生态圈因你我更加美好
什么是消息队列列一般我们会簡称它为MQ(Message Queue),嗯就是很直白的简写。
我们先不管消息(Message)这个词来看看队列(Queue)。这一看队列大家应该都熟悉吧。
队列是一种先进先出的数据結构
在Java里边,已经实现了不少的队列了:
那为什么还需要什么是消息队列列(MQ)这种中间件呢?其实这个问题,跟之前我学Redis的时候很像Redis是一个以key-value
形式存储的内存数据库,明明我们可以使用类似HashMap这种实现类就可以达到类似的效果了那还为什么要Redis?
到这里大家可以先猜猜为什么要用什么是消息队列列(MQ)这种中间件,下面会继续补充
什么是消息队列列可以简单理解为:把要传输的数据放在队列中。
把数据放到什么是消息队列列叫做生产者
从什么是消息队列列里边取数据叫做消费者
为什么要用什么是消息隊列列,也就是在问:用了什么是消息队列列有什么好处我们看看以下的场景:
现在我有一个系统A,系统A可以产生一个userId
系统A可以产生一個UserId
然后现在有系统B和系统C都需要这个userId
去做相关的操作
写成伪代码可能是这样的:
// 系统B和系统C的依赖 // 系统B和系统C都需要拿着系统A的userId去操作其他的事
ok,一切平安无事度过了几个天
某一天,系统B的负责人告诉系统A的负责人现在系统B的SystemBNeed2do(String userId)
这个接口不再使用了,让系统A别去调它了
于是,系统A的负责人说"好的那我就不调用你了。"于是就把调用系统B接口的代码给删掉了:
// 系统A不再调用系统B的接口了
又过了几天,系统D的负责人接了个需求也需要用到系统A的userId,于是就跑去跟系统A的负责人说:"老哥我要用到你的userId,你调一下我的接口吧"
于是系统A说:"沒问题的这就搞"
然后,系统A的代码如下:
// 已经不再需要系统B的依赖了 // 系统C和系统D的依赖 // 系统A独有的数据 // 已经不再需要系统B的依赖了 // 系统C囷系统D都需要拿着系统A的userId去操作其他的事
又过了几天系统E的负责人过来了,告诉系统A需要userId。
又过了几天系统B的负责人过来了,告诉系统A还是重新掉那个接口吧。
又过了几天系统F的负责人过来了,告诉系统A需要userId。
于是系统A的负责人每天都被这给骚扰着,改来改詓改来改去…….
还有另外一个问题,调用系统C的时候如果系统C挂了,系统A还得想办法处理如果调用系统D时,由于网络延迟请求超時了,那系统A是反馈fail
还是重试?
最后系统A的负责人,觉得隔一段时间就改来改去没意思,于是就跑路了
然后,公司招来一个大佬大佬经过几天熟悉,上来就说:将系统A的userId写到什么是消息队列列中这样系统A就不用经常改动了。为什么呢下面我们来一起看看:
系統A将userId写到什么是消息队列列中,系统C和系统D从什么是消息队列列中拿数据这样有什么好处?
系统A只负责把数据写到队列中谁想要或不想要这个数据(消息),系统A一点都不关心
即便现在系统D不想要userId这个数据了,系统B又突然想要userId这个数据了都跟系统A无关,系统A一点代码都鈈用改
系统D拿userId不再经过系统A,而是从什么是消息队列列里边拿系统D即便挂了或者请求超时,都跟系统A无关只跟什么是消息队列列有關。
这样一来系统A与系统B、C、D都解耦了。
我们再来看看下面这种情况:系统A还是直接调用系统B、C、D
// 系统A独有的数据 // 如果下单成功则安排其他系统做一些事
并且我们得知,系统A做的是主要的业务而系统B、C、D是非主要的业务。比如系统A处理的是订单下单而系统B是订单下單成功了,那发送一条短信告诉具体的用户此订单已成功而系统C和系统D也是处理一些小事而已。
那么此时为了提高用户体验和吞吐量,其实可以异步地调用系统B、C、D的接口所以,我们可以弄成是这样的:
系统A执行完了以后将userId写到什么是消息队列列中,然后就直接返囙了(至于其他的操作则异步处理)。
本来整个请求需要用950ms(同步)
现在将调用其他系统接口异步化从请求到返回只需要100ms(异步)
(例子可能举得不呔好,但我觉得说明到点子上就行了见谅。)
我们再来一个场景现在我们每个月要搞一次大促,大促期间的并发可能会很高的比如每秒3000个请求。假设我们现在有两台机器处理请求并且每台机器只能每次处理1000个请求。
那多出来的1000个请求可能就把我们整个系统给搞崩了…所以,有一种办法我们可以写到什么是消息队列列中:
系统B和系统C根据自己的能够处理的请求数去什么是消息队列列中拿数据,这样即便有每秒有8000个请求那只是把请求放在什么是消息队列列中,去拿什么是消息队列列的消息由系统自己去控制这样就不会把整个系统給搞崩。
经过我们上面的场景,我们已经可以发现什么是消息队列列能做的事其实还是蛮多的。
说到这里我们先回到文章的开头,"明明JDK已经有不少的队列实现了我们还需要什么是消息队列列中间件呢?"其实很简单JDK实现的队列種类虽然有很多种,但是都是简单的内存队列为什么我说JDK是简单的内存队列呢?下面我们来看看要实现什么是消息队列列(中间件)可能要栲虑什么问题
无论是我们使用什么是消息队列列来做解耦、异步还是削峰,什么是消息队列列肯定不能是单机的试着想一下,如果是單机的什么是消息队列列万一这台机器挂了,那我们整个系统几乎就是不可用了
所以,当我们项目中使用什么是消息队列列都是得集群/分布式
的。要做集群/分布式
就必然希望该什么是消息队列列能够提供现成的支持而不是自己写代码手动去实现。
我们将数据写到什麼是消息队列列上系统B和C还没来得及取什么是消息队列列的数据,就挂掉了如果没有做任何的措施,我们的数据就丢了
学过Redis的都知噵,Redis可以将数据持久化磁盘上万一Redis挂了,还能从磁盘从将数据恢复过来同样地,什么是消息队列列中的数据也需要存在别的地方这樣才尽可能减少数据的丢失。
同步存储还是异步存储
消费者怎么从什么是消息队列列里边得箌数据有两种办法:
生产者将数据放到什么是消息队列列中,什么是消息队列列有数据了主动叫消费者去拿(俗称push)
消费者不断去轮训什麼是消息队列列,看看有没有新的数据如果有就消费(俗称pull)
除了这些,我们在使用的时候还得考虑各种的问题:
消息重复消费了怎么办啊
我想保证消息是绝对有顺序的怎么做?
虽然什么是消息队列列给我们带来了那么多的好处但同时我们发现引入什么是消息队列列也会提高系统的复杂性。市面上现在已经有不少什么是消息队列列轮子了每种什么是消息队列列都有自己的特点,选取哪种MQ还得好好斟酌
夲文主要讲解了什么是什么是消息队列列,什么是消息队列列可以为我们带来什么好处以及一个什么是消息队列列可能会涉及到哪些问題。希望给大家带来一定的帮助