一、消息队列概述消息队列中间件是分布式系统中的重要组件,主要解决应用解耦、异步消息、流量切割等问题。实现高性能、高可用性、可扩展性和最终一致性的架构。目前使用的消息队列有ActiveMQ、RabbitMQ、ZeroMQ、Kafka、MetaMQ、RocketMQ。2.消息队列的应用场景下面介绍消息队列在实际应用中的常见使用场景。异步处理、应用解耦、切流、消息通信四种场景。2.1异步处理场景说明:用户注册后,需要发送注册邮件和注册短信。传统的方法有两种:1.串口方式;2.并联方式串口方式:注册信息写入数据库成功后,发送注册邮件,然后发送注册短信。以上三项工作全部完成后,返回给客户端。b.并行模式:将注册信息写入数据库成功后,在发送注册邮件的同时发送注册短信。以上三项工作完成后,返回给客户端。与串行的区别在于并行方式可以提高处理时间。假设三个业务节点各用50毫秒,不考虑网络等其他开销,串行方式是150毫秒,并行方式可能是100毫秒。毫秒。因为单位时间内CPU处理的请求数是一定的,假设1秒内CPU的吞吐量是100次。那么在串口模式下CPU可以在1秒内处理7个请求(1000/150)。并行模式下处理的请求数是10倍(1000/100)总结:如上案例所述,传统系统的性能(并发、吞吐量、响应时间)会出现瓶颈。如何解决这个问题呢?消息队列的引入将不需要业务逻辑,异步处理。修改后的架构如下:根据上面的约定,用户的响应时间相当于注册信息写入数据库的时间,即50毫秒。注册邮箱,发送短信写入消息队列后,直接返回,所以写入消息队列的速度很快,基本可以忽略不计,所以用户的响应时间可能是50毫秒。因此,架构变更后,系统的吞吐量提升至每秒20QPS。比串行高3倍,比并行高2倍。2.2应用解耦场景描述:用户下单后,订单系统需要通知库存系统。传统上,订单系统调用库存系统的接口。如下图所示:传统模式的缺点:如果无法访问库存系统,订单将无法减少库存,导致订单失败。订单系统与库存系统的耦合如何解决上述问题呢?引入应用消息队列后的解决方案如下:订单系统:用户下单后,订单系统完成持久化处理,将消息写入消息队列,成功返回用户的订单。库存系统:订阅订单消息,通过pull/push方式获取订单信息。盘点系统根据订单信息进行盘点操作如果:下单时盘点系统不能正常使用。不影响正常下单,因为下单后,订单系统写入消息队列,不再关心后续其他操作。实现订单系统和库存系统的应用解耦2.3流量调峰流量调峰在消息队列中也是比较常见的场景,一般用在秒杀或者抢团活动中。应用场景:在秒杀活动中,一般会因为流量过大,导致流量剧增,导致应用挂掉。为了解决这个问题,一般需要在应用的前端添加一个消息队列。A。它可以控制活跃的人数。b.可以缓解短时间内高流量的请求让应用用户不堪重负。服务器收到后,先写入消息队列。如果消息队列长度超过最大数量,则直接丢弃用户请求或重定向错误页面。秒杀业务根据消息队列中的请求信息进行后续处理。2.4日志处理日志处理是指在日志处理中使用消息队列,例如Kafka的应用,解决海量日志传输的问题。架构简化如下:日志采集客户端负责日志数据的采集,定时向Kafka队列进行写入和接收写入。Kafka消息队列,负责日志数据的接收、存储和转发。日志处理应用:订阅消费kafka队列中的日志数据。2.5消息通信消息通信是指消息队列一般都内置了高效的通信机制,因此也可以用于纯消息通信。比如实现点对点的消息队列,或者聊天室等。点对点通信:客户端A和客户端B使用同一个队列进行消息通信。聊天室通信:客户端A、客户端B、客户端N订阅同一个主题发布和接收消息。实现类似聊天室的效果。以上其实就是消息队列的两种消息模式,点对点或者发布订阅模式。该模型是供参考的示意图。3、消息中间件示例3.1电子商务系统消息队列采用高可用、持久的消息中间件。比如ActiveMQ,RabbitMQ,RocketMq。应用程序完成主要逻辑处理后,写入消息队列。消息是否发送成功可以开启消息的确认方式。(消息队列返回接收消息成功状态后,应用程序再次返回,以保证消息的完整性)扩展进程(发送短信,投递处理)订阅队列消息。使用推或拉来获取消息并处理它们。消息在对应用进行解耦的同时,带来了数据的一致性问题,可以使用最终一致性的方法来解决。比如主要数据写入数据库,扩展应用根据消息队列结合数据库方法实现基于消息队列的后续处理。3.2日志采集系统分为四个部分:Zookeeper注册中心、日志采集客户端、Kafka集群和Storm集群(OtherApp)。Zookeeper注册中心,提出负载均衡和地址校验×××日志收集客户端,用于收集应用系统日志,并向kafka队列推送数据Kafka集群:接收、路由、存储、转发等消息处理Storm集群:和OtherApp是同级,使用pull方法消费队列中的数据。MQ选型对比文档综合选型RabbitMqKafka是linkedin开源的MQ系统。其主要特点是基于Pull模式处理消息消费,追求高吞吐量。开头的目的用于日志的收集和传输。从0.8开始,支持复制,不支持事务。适用于产生大量数据的互联网服务的数据采集业务。RabbitMQ是一个使用Erlang语言开发,基于AMQP协议实现的开源消息队列系统。AMQP的主要特点是面向消息、队列、路由(包括点对点和发布/订阅)、可靠性和安全性。AMQP协议多用于企业系统,对数据的一致性、稳定性、可靠性要求较高,对性能和吞吐量的要求次之。RocketMQ是阿里巴巴开源的消息中间件。采用纯Java开发,具有高吞吐量、高可用性等特点,适用于大型分布式系统应用。RocketMQ思想起源于Kafka,但不是Kafka的翻版。它优化了消息的可靠传输和事务性能。目前广泛应用于交易、充值、流计算、消息推送、日志流处理、binglog分发等场景。ZeroMQ只是一个网络编程的模式库,它对常见的网络请求形式(组管理、链接管理、发布订阅等)进行建模和组件化,简而言之,在socket之上,在MQ之下。对于MQ来说,网络传输只是其中的一部分,更多需要处理的是消息存储、路由、Broker服务发现和搜索、事务、消费方式(ack、复投等??)、集群服务等。RabbitMQ/Kafka/ZeroMQ都可以提供消息队列服务,但是区别很大。在面向服务的架构中,通过消息代理(如RabbitMQ/Kafka等)使用生产者-消费者模型在服务之间进行异步通信是一个好主意。因为服务间的依赖已经从强耦合变成了松耦合。消息代理会提供持久化机制,当消费者负载高或连接断开时,消息会被保存下来不会丢失。也就是说,生产者和消费者不需要同时在线,这在传统的请求-响应模式下是很难实现的,需要一个中间件来专门做这件事。其次,消息代理可以基于消息本身实现简单的路由策略,消费者可以基于此实现负载均衡和业务分离。缺点也有,就是需要额外搭建一个messagebroker集群(但是利大于弊)。ZeroMQ不同于RabbitMQ/Kafka。它只是一个异步消息库,提供基于套接字的类似消息代理的机制。如果使用ZeroMQ,需要修改自己的业务代码,不利于服务解耦。RabbitMQ支持AMQP(二进制)、STOMP(文本)、MQTT(二进制)、HTTP(将其他协议封装在里面)等协议。Kafka使用自己的协议。Kafka自身的服务和消费者都需要依赖Zookeeper。RabbitMQ在消息堆积很多的时候性能会下降,但是Kafka不会。毕竟AMQP设计的初衷并不是为了持久化海量消息,而Kafka本来就是用来处理海量日志的。总的来说,RabbitMQ和Kafka都是优秀的分布式消息代理服务。只要合理部署,基本可以满足生产条件下的任何需求。
