- 解耦
上述的图是RPC的调用,但是有一个最大的问题就是耦合度太高。假如用户发送请求到订单系统,它会分别去调支付系统,库存系统,物流系统,假如其中的一台服务器突然不工作了,这时候整个订单系统就会出现异常,用户体验度就会差,所以耦合度太高了,那么就采用MQ的形式进行如下解耦:
详解:它是如何解耦的呢?用户请求到订单系统后,会把数据先封装然后传到MQ中,其它三个系统是一直监控着MQ的,它们发现MQ中有自己需要的信息后,就会去自行消费,但是如果出现了其中一台系统因故障而不能正常工作时,用户时无法感知到有故障的,因为用户把消息是传给了订单系统,而订单系统又把数据完整的传给了 MQ,这时订单系统会响应给用户信息的,接下来 *** 作的事就交给MQ和其它子系统了,所以就达到了解耦的效果。当服务系统又能正常工作时,该服务会继续消费之前还没有消费的数据。那么对于用户来说就是为无感的。
- 异步
以上为同步的图,简单说一下吧。数据的请求和响应是要花费一定的时间的。当我们的业务需要很多子系统时,那么响应给用户的时间就会随之增加,这显然是用户无法忍受的,所以就会直接造成该网站的访问量极低,这也是公司最不想看到的,所以针对同步出现的问题可以用MQ的异步来解决。
相比于同步的策略而言,异步不必以排队的形式去等待,而是分别去发送消息给对应的子系统,但是这种形式适合任何场景吗?重点:异步的方式不能适用于响应给用户的数据跟MQ的子系统有关的情况。如果这种情况使用了MQ的异步,那么会适得其反,消耗的时间会比同步的要更多,用户的体验度更差。
- 流量削峰
上图是直接应对当某一个时刻有大量的数据进行访问时的系统,那么这时肯定会造成服务压力巨大甚至导致服务崩溃,用户体验度降低。针对这一种情况可以用MQ来解决:
某一时刻有大量的请求过来,假如每秒有5000个请求,这时候会先放到MQ种进行存储,MQ会响应给用户消息,用户体验度增加。子系统去消费数据时可以制定一个策略,让它每秒从MQ种拉取2000个请求进行消费即可,这时服务器的压力机会减小。
流量削峰还有其经济考量
QPS:指每秒的请求数。
优点上面已经说了。说说缺点:
系统可用性降低 如何保证消息队列的高可用适用集群即可:在这里只讲了两种中间件的集群策略:
-
RabbitMQ高可用-镜像集群
-
KafKa集群:
是以副本的形式来保证高可用的。他会把数据平均分到不同的机器上,假如某一台集群挂了,其它机器还是会有信息的,消费者只会消费主机,而从机就只是作为从机来备份数据的,当请求发送给MQ后,从机会自动拉取数据,知道每一个从机都同步完成后,就会手动发送ACK这个动作,告知主机,主机收到后,消费者可以去主机上消费了。 -
RocketMQ高可用-双主双从
- 消息为什么会丢
- 如何保证消息不丢失
- 为什么会出现消息重复
- 为什么会出现消息被重复消费
3. 如何解决
使用分布式事务:保证不同数据库的数据一致性:要么成功,要么失败。
场景:我要保证先消费M1在消费M2。
这种情况很显然是不一定保证顺序性消费的。假如由于网络原因导致M2先到达MQ,而M1后到达,那么从源头就没能保证消息的顺序到达。
优化的方案:
可以保证消息的顺序到达,但是可以保证消费方一定能顺序消费吗,由于网络原因导致M2先到达,M1后到达,那么这样就不能保证顺序消费了。
在优化:生产者:MQ Server:消费者=1:1:1
M1先到达,M2后到达,根据队列的特性:先进先出,这样就保证了顺序到达,然后M1被消费者消费,然后告知MQ我已消费完了,MQ会把该条记录删除,然后消费M2,消费完后告知MQ我已消费完了。但是有一个极大的缺点,就是这种点对点模式会使整个系统的处理速度很低。这种方式也叫全局顺序消费:就是一次只能处理一个用户的请求,在没有处理结束后其他的请求是不能被处理的。所以吞吐量和容错性大大降低。
现在我们保证的是不仅仅要顺序消费还要并行处理多个请求。
于是引出局部顺序性消费
详解:一个用户要发M1和M2两个信息,顺序是M1先,M2后,这时它俩被定义为一组,同时这组被赋予全局唯一性id,然后把这组消息发到一个队列中,然后多个消费者去消费这组 数据,由于队列为先进先出的,所以M1肯定是先被执行的,当消费者拿到M1后,那么就会把这个MQ上锁,其它消费者是不能在拿数据的,但是这时候其它MQ并没有被上锁,所以可以实现并行处理多个请求的效果,这个锁也被称为分段锁。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)