当前位置: 首页 > 科技观察

高并发架构设计(二)——消息队列应用场景及注意事项

时间:2023-03-22 16:27:13 科技观察

消息队列中间件是分布式系统中的重要组件之一,在高并发系统中更是必不可少。主要解决应用耦合、异步消息、流量切割等问题。实现高性能、高可用性、可扩展性和最终一致性的架构。最常用的消息队列有ActiveMQ、RabbitMQ、Kafka和RocketMQ。今天就来说说消息队列在高并发系统中的具体应用场景和注意事项。1.什么是消息队列?我们可以把消息队列看成是一个存储消息的容器。当我们需要使用消息时,直接从容器中取出即可。消息仅供您自己使用。Queue队列是一个先进先出的数据结构,所以在消费消息的时候,也是按照顺序消费的。2、为什么要使用消息队列一般来说,使用消息队列可以给我们的系统带来以下三个好处:异步处理,通过异步处理提高系统性能,减少响应流量调峰所需的时间,避免高并发访问直接解耦数据库挂载应用,降低系统耦合2.1.异步处理同步处理流程异步处理流程将用户的请求数据存储在消息队列中,并立即返回结果。然后,系统再次消费该消息。因为用户请求的数据写入消息队列后会立即返回给用户,但是请求的数据在后续的业务验证、写数据库等操作中可能会失败。因此,使用消息队列进行异步处理后,需要适当修改业务流程进行配合。比如用户提交订单后,订单数据被写入消息队列,用户不能立即返回订单提交成功。订单处理完毕,甚至发货后,会通过邮件或短信通知用户订单成功,避免交易纠纷。这类似于我们用手机预订火车票和电影票的方式。2.2流量调峰首先将短时高并发的事务消息存放在消息队列中,后端服务根据自身能力慢慢消费这些消息,避免直接把后端服务打垮。例如:在一些电商的限时抢购和促销活动中,合理使用消息队列可以有效抵御促销活动初期大量订单涌入对系统的冲击。如下图所示:2.3应用解耦使用消息队列也可以降低系统耦合。我们知道,如果模块之间没有直接调用,增加或修改模块对其他模块的影响较小,那么系统的扩展性无疑会更好。假设有这样一个场景:系统A向B、C、D三个系统发送数据,通过接口调用发送。如果系统E也想要这些数据怎么办?如果不再需要系统C怎么办?A系统的负责人都快崩溃了……这个场景下,A系统和其他乱七八糟的系统严重耦合,A系统产生了一个关键数据,很多系统都需要A系统发送这个数据。系统A总得考虑如果B、C、D、E这四个系统宕机了怎么办?您要重新发送消息吗?您要保存消息吗?你的头发是白的!如果使用MQ,A系统会生成一条消息。数据发送到MQ,系统需要数据自己在MQ消费。如果新系统需要数据,直接从MQ消费即可;如果一个系统不需要这个数据,取消对MQ消息的消费即可。这样系统A就不需要考虑向谁发送数据,不需要维护这段代码,也不需要考虑调用成功还是失败超时。如下图所示:生产者(客户端)向消息队列发送消息,接收者(服务端)处理消息,需要消费的系统可以直接去消息队列中取消息进行消费,无需与其他系统耦合,这显然也提高了系统的可扩展性。消息队列工作在发布-订阅模式。消息发送者(生产者)发布消息,一个或多个消息接收者(消费者)订阅消息。从上图我们可以看出,消息发送者(生产者)和消息接收者(消费者)之间没有直接的耦合。消息发送者将消息发送到分布式消息队列,完成对消息的处理。消息队列拿到消息进行后续处理后,不需要知道消息是从哪里来的。对于新业务,只要对这类新闻感兴趣,就可以订阅新闻,对原有系统和业务没有任何影响,实现系统业务的可扩展性设计。3、使用消息队列带来的一些问题系统可用性降低:系统可用性在一定程度上有所降低。系统引入的外部依赖越多,越容易挂掉。在加入MQ之前,我们不需要考虑消息丢失或者MQ挂掉等情况,但是引入MQ之后,我们需要考虑如何保证消息队列的高可用,否则MQ挂掉可能会导致整个系统崩溃!系统复杂性能提升:加入MQ后,我们需要保证消息不被重复消费,处理消息丢失,保证消息传递的顺序等!数据一致性问题:上面说了消息队列可以实现异步,消息队列带来的异步确实可以提高系统响应速度。但是,如果真正的消息消费者没有正确消费消息怎么办?这样会导致数据不一致!有四种类型,但我们在进行技术选型时应该使用哪一种呢?每个MQ都没有绝对的好坏,只是看它用在哪个场景,扬长避短,扬长避短。总结:ActiveMQ:ActiveMQ的社区比较成熟,但是相对于现在的情况,ActiveMQ的性能比较差,版本迭代很慢,所以不推荐使用。RabbitMQ:虽然在吞吐量上略逊于Kafka和RocketMQ,但它是基于erlang开发的,因此并发性强,性能优异,延迟低,达到微秒级。但也因为RabbitMQ是基于erlang开发的,国内很少有公司有实力做erlang源码层面的研究和定制。如果业务场景对并发量要求不高(十万级、百万级),那么这四种消息队列中,RabbitMQ一定是你的首选。大数据领域的实时计算、日志采集等场景,用Kafka是行业标准,绝对没问题,社区很活跃,绝对不会色情,更何况几乎是一个世界范围内该领域的事实规范。RocketMQ:阿里出品,Java开源项目,我们可以直接阅读源码,然后定制自己公司的MQ,RocketMQ有阿里巴巴实际业务场景的实战检验。RocketMQ社区比较活跃。目前RocketMQ已经捐赠给了Apache,但是在GitHub上的活跃度并不高。文档比较简单,接口不符合标准的JMS规范。一些系统需要为迁移修改很多代码。还有就是阿里引进的技术。你必须做好,以防这个技术被抛弃,社区变黄的风险。如果对自己公司的技术实力有绝对的信心,推荐使用RocketMQ。不然还是回去老老实实踏踏实实的做RabbitMQ吧。他们是活跃的开源社区,永远不会黄。Kafka:特点其实非常明显,就是只提供了较少的核心功能,但是提供了超高的吞吐量,ms级的延迟,极高的可用性和可靠性,分布可以任意扩展。同时,Kafka最好支持少量的topic,以保证其超高的吞吐量。kafka唯一的缺点就是有可能重复消费消息,这对数据的准确性会有非常轻微的影响。在大数据和日志采集领域,这种轻微的影响可以忽略不计。这个特性天然适用于大数据和日志的实时计算。收集。