消息队列入门

前言

什么是消息队列?消息队列,一般我们会简称它为MQ(Message Queue),queue是队列,在java中,队列是一种数据结构,就是一端进,一端出:
1

而在java中,实现的消息队列也有很多:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-x9sLXuSK-1582021444860)(https://1716416169.github.io/消息队列入门/2.png)]

那么,既然java都实现了这么多的队列结构,为什么还需要消息队列中间键呢?(RabbitMQ,ActiveMQ,Kafka,阿里巴巴自主开发RocketMQ等),这是因为java实现的数据结构真的仅仅只是个数据结构,而消息队列能够干嘛则是这篇文章讨论的内容

消息队列的作用

1.解耦

在系统开发分工或者模块分明时,子系统之间的数据传递(消息传递)工作一般会由掌握数据的一方调用需要数据的一方的方法(接口)来完成,例如:A系统是主系统,而B,C,D系统则是A的子系统,但B,C,D都需要向A要数据(类似登录验证模块),那么A要向B,C,D发送数据则需要调用B,C,D的方法(setData()),这个过程看起来很正常,但如果负责B,C,D系统的人说他不想要数据了,或者他更改了数据结构(变成了setNeedDate()),那么作为A系统的负责人则因为代码的冗余(删除调用B,C,D方法的语句)或者接口的更改需要去修改源代码,这从低耦合高内聚的方面来说显然是不行的,万一B,C,D系统的人后续又要进行更改怎么办?万一有新的系统加入想获取A系统的数据怎么办?这时,消息队列就出现了

消息队列,我个人是把他看作一个数据库的,除了先进先出,为什么我会这么说?请看下图:

3

是不是很像一个数据库?那么回到上述问题中去,结合图片,你应该已经体会到了消息队列在其中是如何解决问题的:系统A发送的数据由消息队列来接收,但哪个系统会去使用,系统A并不在意或者说不需要知道,而系统B,C,D也只需要按照自己的意愿来选择是否要获取消息队列中的数据,A系统也就不需要根据B,C,D系统的改变而修改源代码了,这是不是就解决了系统A,B,C,D的高耦合状态(解耦成功)

2.异步

同样是1里的例子,如果没有消息队列,那么用户进行一次访问到得到回馈的时间=经过A系统的时间+经过B系统的时间+经过C系统的时间+经过D系统的时间+向用户进行反馈的时间(这里假设B,C,D系统进行的工作并不重要),但是,如果有了消息队列,那么如下图:

4

用户的一次请求要经过的路程就变为了经过A系统---->消息队列----->返回A系统并向用户发出反馈,那么时间也就由原来的变为了总时间=经过A系统的时间+经过消息队列的时间+向用户进行反馈的时间,然后B,C,D系统再进行异步操作,显然,这对于用户来说,一次请求的时间大大缩短了(用户体验up)

3.削峰/限流

打个比方,如果现在服务端有两个负责接收并处理用户请求的服务器A,B,并且他们的最大同时接入值和处理值为1000个,这时客服端向服务端发送了3000个请求,那么显然这两台服务器是不够用的,相信你已经猜到,没错,用消息队列来存储3000个请求,然后再由A,B来根据自己的情况从消息队列中获取请求进行处理

使用消息队列的问题

1.集群

既然使用了消息队列,那肯定就得集群,设想如果一个系统只有一台消息队列服务器,那么如果这台服务器失效,那不就GG了吗

2.数据丢失问题

消息队列是对请求或者其他数据进行存储,那么如果在需求数据的服务器还没有把数据取出去之前,服务器宕机了,那么存储的消息还存在吗

3.怎么得到消息队列的数据

这里涉及两钟方式,是需求者去主动取呢,还是消息队列主动推送呢

4.顺序

如果数据是有先后顺序的,那么服务器进行取数据时如何保证能以正确的顺序对数据进行取操作呢

5.脏数据

数据库知识里的典型问题,如果两台服务器同时进行取操作,那这么做才能保证后一台服务器不会取一个不存在的数据呢

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值