zoukankan      html  css  js  c++  java
  • 【消息队列】--- 消息队列的使用场景

     文章整理自知乎:https://www.zhihu.com/question/34243607

    【解释一】:

    个人认为消息队列的主要特点是异步处理,主要目的是减少请求响应时间和解耦。所以主要的使用场景就是将比较耗时而且不需要即时(同步)返回结果的操作作为消息放入消息队列。同时由于使用了消息队列,只要保证消息格式不变,消息的发送方和接收方并不需要彼此联系,也不需要受对方的影响,即解耦和

    使用场景的话,举个例子:
    假设用户在你的软件中注册,服务端收到用户的注册请求后,它会做这些操作:
    1. 校验用户名等信息,如果没问题会在数据库中添加一个用户记录
    2. 如果是用邮箱注册会给你发送一封注册成功的邮件,手机注册则会发送一条短信
    3. 分析用户的个人信息,以便将来向他推荐一些志同道合的人,或向那些人推荐他
    4. 发送给用户一个包含操作指南的系统通知
    5. 等等……

    但是对于用户来说,注册功能实际只需要第一步,只要服务端将他的账户信息存到数据库中他便可以登录上去做他想做的事情了。至于其他的事情,非要在这一次请求中全部完成么?值得用户浪费时间等你处理这些对他来说无关紧要的事情么?所以实际当第一步做完后,服务端就可以把其他的操作放入对应的消息队列中然后马上返回用户结果,由消息队列异步的进行这些操作

    或者还有一种情况,同时有大量用户注册你的软件,在高并发情况下注册请求开始出现一些问题,例如邮件接口承受不住,或是分析信息时的大量计算使cpu满载,这将会出现虽然用户数据记录很快的添加到数据库中了,但是却卡在发邮件或分析信息时的情况,导致请求的响应时间大幅增长,甚至出现超时,这就有点不划算了。面对这种情况一般也是将这些操作放入消息队列(生产者消费者模型),消息队列慢慢的进行处理,同时可以很快的完成注册请求,不会影响用户使用其他功能。

    所以在软件的正常功能开发中,并不需要去刻意的寻找消息队列的使用场景,而是当出现性能瓶颈时,去查看业务逻辑是否存在可以异步处理的耗时操作,如果存在的话便可以引入消息队列来解决。否则盲目的使用消息队列可能会增加维护和开发的成本却无法得到可观的性能提升,那就得不偿失了。
     
    【解释二】:
     
    “消息队列”(Message queue)是在消息的传输过程中保存消息的容器。“消息” 是在两台计算机间传送的数据单位。消息可以非常简单,例如只包含文本字符串;也可以更复杂,可能包含嵌入对象。

    使用消息队列的场景和好处

    《大型网站技术架构》第四章和第七章均有提到消息队列对应用性能及扩展性的提升。

    1.通过异步处理提高系统性能

    如上图,在不使用消息队列服务器的时候,用户的请求数据直接写入数据库,在高并发的情况下数据库压力剧增,使得响应速度变慢。但是在使用消息队列之后,用户的请求数据发送给消息队列之后立即返回,再由消息队列的消费者进程从消息队列中获取数据,异步写入数据库。由于消息队列服务器处理速度快于数据库(消息队列也比数据库有更好的伸缩性),因此响应速度得到大幅改善。

    通过以上分析我们可以得出消息队列具有很好的削峰作用的功能——即通过异步处理,将短时间高并发产生的事务消息存储在消息队列中,从而削平高峰期的并发事务 举例:在电子商务一些秒杀、促销活动中,合理使用消息队列可以有效抵御促销活动刚开始大量订单涌入对系统的冲击。如下图所示:

    因为用户请求数据写入消息队列之后就立即返回给用户了,但是请求数据在后续的业务校验、写数据库等操作中可能失败。因此使用消息队列进行异步处理之后,需要适当修改业务流程进行配合,比如用户在提交订单之后,订单数据写入消息队列,不能立即返回用户订单提交成功,需要在消息队列的订单消费者进程真正处理完该订单之后,甚至出库后,再通过电子邮件或短信通知用户订单成功,以免交易纠纷。这就类似我们平时手机订火车票和电影票。

    2.降低系统耦合性

    我们知道模块分布式部署以后聚合方式通常有两种:1.分布式消息队列和2.分布式服务。

    先来简单说一下分布式服务:

    目前使用比较多的用来构建SOA(Service Oriented Architecture面向服务体系结构)分布式服务框架是阿里巴巴开源的Dubbo.如果想深入了解Dubbo的可以看我写的关于Dubbo的这一篇文章:《高性能优秀的服务框架-dubbo介绍》

    再来谈我们的分布式消息队列:

    我们知道如果模块之间不存在直接调用,那么新增模块或者修改模块就对其他模块影响较小,这样系统的可扩展性无疑更好一些。

    我们最常见的事件驱动架构类似生产者消费者模式,在大型网站中通常用利用消息队列实现事件驱动结构。如下图所示:

    作者:Snailclimb
    链接:https://www.zhihu.com/question/34243607/answer/372537590
    来源:知乎
    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

    消息队列使利用发布-订阅模式工作,消息发送者(生产者)发布消息,一个或多个消息接受者(消费者)订阅消息。 从上图可以看到消息发送者(生产者)和消息接受者(消费者)之间没有直接耦合,消息发送者将消息发送至分布式消息队列即结束对消息的处理,消息接受者从分布式消息队列获取该消息后进行后续处理,并不需要知道该消息从何而来。对新增业务,只要对该类消息感兴趣,即可订阅该消息,对原有系统和业务没有任何影响,从而实现网站业务的可扩展性设计

    消息接受者对消息进行过滤、处理、包装后,构造成一个新的消息类型,将消息继续发送出去,等待其他消息接受者订阅该消息。因此基于事件(消息对象)驱动的业务架构可以是一系列流程。

    另外为了避免消息队列服务器宕机造成消息丢失,会将成功发送到消息队列的消息存储在消息生产者服务器上,等消息真正被消费者服务器处理后才删除消息。在消息队列服务器宕机后,生产者服务器会选择分布式消息队列服务器集群中的其他服务器发布消息。

    备注: 不要认为消息队列只能利用发布-订阅模式工作,只不过在解耦这个特定业务环境下是使用发布-订阅模式的,比如在我们的ActiveMQ消息队列中还有点对点工作模式,具体的会在后面的文章给大家详细介绍,这一篇文章主要还是让大家对消息队列有一个更透彻的了解。

    常见的消息队列介绍

    1.ActiveMQ

    官网:

    简介:

    ActiveMQ 是Apache出品,最流行的,能力强劲的开源消息总线。ActiveMQ 是一个完全支持JMS1.1和J2EE 1.4规范的 JMS Provider实现,尽管JMS规范出台已经是很久的事情了,但是JMS在当今的J2EE应用中间仍然扮演着特殊的地位。

    特点:

    1. 支持来自Java,C,C ++,C#,Ruby,Perl,Python,PHP的各种跨语言客户端和协议
    2. 完全支持JMS客户端和Message Broker中的企业集成模式
    3. 支持许多高级功能,如消息组,虚拟目标,通配符和复合目标
    4. 完全支持JMS 1.1和J2EE 1.4,支持瞬态,持久,事务和XA消息
    5. Spring支持,以便ActiveMQ可以轻松嵌入到Spring应用程序中,并使用Spring的XML配置机制进行配置
    6. 专为高性能集群,客户端 - 服务器,基于对等的通信而设计
    7. CXF和Axis支持,以便ActiveMQ可以轻松地放入这些Web服务堆栈中以提供可靠的消息传递
    8. 可以用作内存JMS提供程序,非常适合单元测试JMS
    9. 支持可插拔传输协议,例如in-VM,TCP,SSL,NIO,UDP,多播,JGroups和JXTA传输
    10. 使用JDBC和高性能日志支持非常快速的持久性

    2.RabbitMQ

    官网:

    简介:

    RabbitMQ 是一个由 Erlang 语言开发的 AMQP 的开源实现。RabbitMQ轻巧且易于部署在云端。 它支持多种消息传递协议。 RabbitMQ可以部署在分布式和联合配置中,以满足高规模,高可用性需求。RabbitMQ可运行在许多操作系统和云环境中,并为大多数流行语言提供广泛的开发工具。(来自官网翻译)

    AMQP (Advanced MessageQueue):高级消息队列协议。它是应用层协议的一个开放标准,为面向消息的中间件设计,基于此协议的客户端与消息中间件可传递消息,并不受产品、开发语言等条件的限制。

    RabbitMQ最初广泛应用于金融行业,根据官网描述,它具有如下特点:

    特点:
    1. 异步消息传递:支持多种消息协议,消息队列,传送确认,灵活的路由到队列,多种交换类型;
    2. 支持几乎所有最受欢迎的编程语言:Java,C,C ++,C#,Ruby,Perl,Python,PHP等等;
    3. 可以部署为高可用性和吞吐量的集群; 跨多个可用区域和区域进行联合;
    4. 可插入的身份验证,授权,支持TLS和LDAP。;
    5. 提供了一个易用的用户界面,使得用户可以监控和管理消息 Broker 的许多方面;
    6. 提供了许多插件,来从多方面进行扩展,也可以编写自己的插件。

    3. Kafka

    官网:

    简介:

    Kafka是由Apache软件基金会开发的一个开源流处理平台,由Scala和Java编写。Kafka是一种高吞吐量的分布式发布订阅消息系统,它可以处理消费者规模的网站中的所有动作流数据。 这种动作(网页浏览,搜索和其他用户的行动)是在现代网络上的许多社会功能的一个关键因素。 这些数据通常是由于吞吐量的要求而通过处理日志和日志聚合来解决。 对于像Hadoop的一样的日志数据和离线分析系统,但又要求实时处理的限制,这是一个可行的解决方案。Kafka的目的是通过Hadoop的并行加载机制来统一线上和离线的消息处理,也是为了通过集群来提供实时的消息。

    Kafka它主要用于处理活跃的流式数据,因此Kafaka在大数据系统中使用较多。

    特点:
    1. 同时为发布和订阅提供高吞吐量。据了解,Kafka每秒可以生产约25万消息(50 MB),每秒处理55万消息(110 MB)。
    2. 可进行持久化操作。将消息持久化到磁盘,因此可用于批量消费,例如ETL,以及实时应用程序。通过将数据持久化到硬盘以及replication防止数据丢失。
    3. 分布式系统,易于向外扩展。所有的producer、broker和consumer都会有多个,均为分布式的。无需停机即可扩展机器。
    4. 消息被处理的状态是在consumer端维护,而不是由server端维护。当失败时能自动平衡。
    5. 支持online和offline的场景。

    4. RocketMQ

    官网:

    简介:

    RocketMQ是阿里开源的消息中间件,目前在Apache孵化,使用纯Java开发,具有高吞吐量、高可用性、适合大规模分布式系统应用的特点。RocketMQ思路起源于Kafka,但并不是简单的复制,它对消息的可靠传输及事务性做了优化,目前在阿里集团被广泛应用于交易、充值、流计算、消息推送、日志流式处理、binglog分发等场景,支撑了阿里多次双十一活动。

    特点:
    1. 支持发布/订阅(Pub/Sub)和点对点(P2P)消息模型
    2. 在一个队列中可靠的先进先出(FIFO)和严格的顺序传递
    3. 支持拉(pull)和推(push)两种消息模式
    4. 单一队列百万消息的堆积能力
    5. 支持多种消息协议,如 JMS、MQTT 等
    6. 分布式高可用的部署架构,满足至少一次消息传递语义
    7. 提供 docker 镜像用于隔离测试和云集群部署
    8. 提供配置、指标和监控等功能丰富的 Dashboard

    其实对于这些消息队列的产品,每一种都在某一领域占有一席,虽然ActiveMQ目前在社区已经不是很活跃,但是其下一代产品Apollo已经问世。ZeroMQ小而美,RabbitMQ大而稳,Kakfa和RocketMQ快而强劲。RocketMQ虽然目前还很多不完善,但是一旦在Apache孵化成为顶级项目,全球程序猿开始贡献,前途也是不可限量的。



  • 相关阅读:
    FLEX 几何学
    tcpip协议详解二知识进阶
    打造模块化的Flex应用
    java网络编程知识整理
    ActionScript实现数组快速去重算法
    Adobe Flex迷你教程 — CursorManager使用
    TCP连接中的TIME_WAIT状态二
    TCP连接中的TIME_WAIT状态
    flex 帮助文档制作(HTML)
    Intellij IDEA下flex国际化配置
  • 原文地址:https://www.cnblogs.com/xuelisheng/p/10142888.html
Copyright © 2011-2022 走看看