精华内容
下载资源
问答
  • Spring Boot整合Rabbit MQ消息队列(

    万次阅读 2020-08-19 10:45:37
    对消息队列有写权限的进程可以向消息队列中按照一定的规则添加新消息对消息队列有读权限的进程可以从消息队列中读走消息,而消息队列就是在消息的传输过程中保存消息的容器,你可以简单的把消息队列理解为类似...

    综合概述

    消息队列

    消息队列就是一个消息的链表,可以把消息看作一个记录,具有特定的格式以及特定的优先级。对消息队列有写权限的进程可以向消息队列中按照一定的规则添加新消息,对消息队列有读权限的进程则可以从消息队列中读走消息,而消息队列就是在消息的传输过程中保存消息的容器,你可以简单的把消息队列理解为类似快递柜,快递员(消息发布者)往快递柜(消息队列)投递物件(消息),接受者(消息订阅者)从快递柜(消息队列)接收物件(消息),当然消息队列往往还包含一些特定的消息传递和接收机制。

    消息队列作为分布式系统中重要的组件,可以有效解决应用耦合,异步消息,流量削锋等系列问题,有利于实现高性能,高可用,可伸缩和最终一致性架构。目前使用较多的消息队列有ActiveMQ,RabbitMQ,ZeroMQ,Kafka,MetaMQ,RocketMQ等,各种消息队列也都各有特点,比如Kafka提供高性能、高吞吐量,但可靠性有所欠缺,所以比较适合像日志处理这类对性能要求高但对可靠性要求没那么严格的业务,再比如RabbitMQ支持了各种协议,实现较为臃肿,性能和吞吐量都一般,但却提供了很好的可靠性,比较适合像银行金融一类对可靠性要求较高的业务。

    应用场景

    以下简单介绍几个消息队列在实际应用中的使用场景(以下场景资料引用自网络)。

    1 异步处理

    场景说明:用户注册后,需要发注册邮件和注册短信。传统的做法有两种 1.串行的方式;2.并行方式

    (1)串行方式:将注册信息写入数据库成功后,发送注册邮件,再发送注册短信。以上三个任务全部完成后,返回给客户端

     

    (2)并行方式:将注册信息写入数据库成功后,发送注册邮件的同时,发送注册短信。以上三个任务完成后,返回给客户端。与串行的差别是,并行的方式可以提高处理的时间

     

    假设三个业务节点每个使用50毫秒钟,不考虑网络等其他开销,则串行方式的时间是150毫秒,并行的时间可能是100毫秒。

    因为CPU在单位时间内处理的请求数是一定的,假设CPU1秒内吞吐量是100次。则串行方式1秒内CPU可处理的请求量是7次(1000/150)。并行方式处理的请求量是10次(1000/100)

    小结:如以上案例描述,传统的方式系统的性能(并发量,吞吐量,响应时间)会有瓶颈。如何解决这个问题呢?

    引入消息队列,将不是必须的业务逻辑,异步处理。改造后的架构如下:

     

    按照以上约定,用户的响应时间相当于是注册信息写入数据库的时间,也就是50毫秒。注册邮件,发送短信写入消息队列后,直接返回,因此写入消息队列的速度很快,基本可以忽略,因此用户的响应时间可能是50毫秒。因此架构改变后,系统的吞吐量提高到每秒20 QPS。比串行提高了3倍,比并行提高了两倍

    2 应用解耦

    场景说明:用户下单后,订单系统需要通知库存系统。传统的做法是,订单系统调用库存系统的接口。如下图

     

    传统模式的缺点:

    • 假如库存系统无法访问,则订单减库存将失败,从而导致订单失败

    • 订单系统与库存系统耦合

    如何解决以上问题呢?引入应用消息队列后的方案,如下图:

     

    • 订单系统:用户下单后,订单系统完成持久化处理,将消息写入消息队列,返回用户订单下单成功

    • 库存系统:订阅下单的消息,采用拉/推的方式,获取下单信息,库存系统根据下单信息,进行库存操作

    • 假如:在下单时库存系统不能正常使用。也不影响正常下单,因为下单后,订单系统写入消息队列就不再关心其他的后续操作了。实现订单系统与库存系统的应用解耦

    3 流量削锋

    流量削锋也是消息队列中的常用场景,一般在秒杀或团抢活动中使用广泛

    应用场景:秒杀活动,一般会因为流量过大,导致流量暴增,应用挂掉。为解决这个问题,一般需要在应用前端加入消息队列。

    • 可以控制活动的人数

    • 可以缓解短时间内高流量压垮应用

     

    • 用户的请求,服务器接收后,首先写入消息队列。假如消息队列长度超过最大数量,则直接抛弃用户请求或跳转到错误页面

    • 秒杀业务根据消息队列中的请求信息,再做后续处理

    4 日志处理

    日志处理是指将消息队列用在日志处理中,比如Kafka的应用,解决大量日志传输的问题。架构简化如下

     

    • 日志采集客户端,负责日志数据采集,定时写受写入Kafka队列

    • Kafka消息队列,负责日志数据的接收,存储和转发

    • 日志处理应用:订阅并消费kafka队列中的日志数据

    以下是新浪kafka日志处理应用案例:

     

    (1)Kafka:接收用户日志的消息队列

    (2)Logstash:做日志解析,统一成JSON输出给Elasticsearch

    (3)Elasticsearch:实时日志分析服务的核心技术,一个schemaless,实时的数据存储服务,通过index组织数据,兼具强大的搜索和统计功能

    (4)Kibana:基于Elasticsearch的数据可视化组件,超强的数据可视化能力是众多公司选择ELK stack的重要原因

    5 消息通讯

    消息通讯是指,消息队列一般都内置了高效的通信机制,因此也可以用在纯的消息通讯。比如实现点对点消息队列,或者聊天室等

    点对点通讯:

     

    客户端A和客户端B使用同一队列,进行消息通讯。

    聊天室通讯:

     

    客户端A,客户端B,客户端N订阅同一主题,进行消息发布和接收。实现类似聊天室效果。

    以上实际是消息队列的两种消息模式,点对点或发布订阅模式。模型为示意图,供参考。

    Rabbit MQ

    AMQP,即 Advanced Message Queuing Protocol,高级消息队列协议,是应用层协议的一个开放标准,为面向消息的中间件设计。消息中间件主要用于组件之间的解耦和通讯。AMQP的主要特征是面向消息、队列、路由(包括点对点和发布/订阅)、可靠性和安全。

    RabbitMQ是一个开源的AMQP实现,服务器端用 Erlang 语言编写,支持多种客户端,如:Java、Python、Ruby、.NET、JMS、C、PHP、ActionScript、XMPP、STOMP等,支持AJAX。用于在分布式系统中存储转发消息,具有很高的易用性和可用性。

     

    接下来,我们先来了解几个相关概念(以下相关介绍资料引用自网络)。

    ConnectionFactory、Connection、Channel

    ConnectionFactory、Connection、Channel都是RabbitMQ对外提供的API中最基本的对象。Connection是RabbitMQ的socket链接,它封装了socket协议相关部分逻辑。ConnectionFactory为Connection的制造工厂。 Channel是我们与RabbitMQ打交道的最重要的一个接口,我们大部分的业务操作是在Channel这个接口中完成的,包括定义Queue、定义Exchange、绑定Queue与Exchange、发布消息等。

    Queue

    Queue(队列)是RabbitMQ的内部对象,用于存储消息。

    RabbitMQ中的消息都只能存储在Queue中,生产者(下图中的P)生产消息并最终投递到Queue中,消费者(下图中的C)可以从Queue中获取消息并消费。

    生产者Send Message “A”被传送到Queue中,消费者发现消息队列Queue中有订阅的消息,就会将这条消息A读取出来进行一些列的业务操作。这里只是一个消费正对应一个队列Queue,也可以多个消费者订阅同一个队列Queue,当然这里就会将Queue里面的消息平分给其他的消费者,但是会存在一个一个问题就是如果每个消息的处理时间不同,就会导致某些消费者一直在忙碌中,而有的消费者处理完了消息后一直处于空闲状态,因为前面已经提及到了Queue会平分这些消息给相应的消费者。这里我们就可以使用prefetchCount来限制每次发送给消费者消息的个数。详情见下图所示:

    这里的prefetchCount=1是指每次从Queue中发送一条消息来。等消费者处理完这条消息后Queue会再发送一条消息给消费者。

    Message acknowledgment

    在实际应用中,可能会发生消费者收到Queue中的消息,但没有处理完成就宕机(或出现其他意外)的情况,这种情况下就可能会导致消息丢失。为了避免这种情况发生,我们可以要求消费者在消费完消息后发送一个回执给RabbitMQ,RabbitMQ收到消息回执(Message acknowledgment)后才将该消息从Queue中移除;如果RabbitMQ没有收到回执并检测到消费者的RabbitMQ连接断开,则RabbitMQ会将该消息发送给其他消费者(如果存在多个消费者)进行处理。这里不存在timeout概念,一个消费者处理消息时间再长也不会导致该消息被发送给其他消费者,除非它的RabbitMQ连接断开。 这里会产生另外一个问题,如果我们的开发人员在处理完业务逻辑后,忘记发送回执给RabbitMQ,这将会导致严重的bug——Queue中堆积的消息会越来越多;消费者重启后会重复消费这些消息并重复执行业务逻辑…

    另外pub message是没有ack的。

    Message durability

    如果我们希望即使在RabbitMQ服务重启的情况下,也不会丢失消息,我们可以将Queue与Message都设置为可持久化的(durable),这样可以保证绝大部分情况下我们的RabbitMQ消息不会丢失。但依然解决不了小概率丢失事件的发生(比如RabbitMQ服务器已经接收到生产者的消息,但还没来得及持久化该消息时RabbitMQ服务器就断电了),如果我们需要对这种小概率事件也要管理起来,那么我们要用到事务。由于这里仅为RabbitMQ的简单介绍,所以这里将不讲解RabbitMQ相关的事务。

    Exchange

    首先明确一点就是生产者产生的消息并不是直接发送给消息队列Queue的,而是要经过Exchange(交换器),由Exchange再将消息路由到一个或多个Queue,当然这里还会对不符合路由规则的消息进行丢弃掉,这里指的是后续要谈到的Exchange Type。那么Exchange是怎样将消息准确的推送到对应的Queue的呢?那么这里的功劳最大的当属Binding,RabbitMQ是通过Binding将Exchange和Queue链接在一起,这样Exchange就知道如何将消息准确的推送到Queue中去。简单示意图如下所示:

            

    在绑定(Binding)Exchange和Queue的同时,一般会指定一个Binding Key,生产者将消息发送给Exchange的时候,一般会产生一个Routing Key,当Routing Key和Binding Key对应上的时候,消息就会发送到对应的Queue中去。那么Exchange有四种类型,不同的类型有着不同的策略。也就是表明不同的类型将决定绑定的Queue不同,换言之就是说生产者发送了一个消息,Routing Key的规则是A,那么生产者会将Routing Key=A的消息推送到Exchange中,这时候Exchange中会有自己的规则,对应的规则去筛选生产者发来的消息,如果能够对应上Exchange的内部规则就将消息推送到对应的Queue中去。那么接下来就来详细讲解下Exchange里面类型。

    Exchange Types

    • fanout

            fanout类型的Exchange路由规则非常简单,它会把所有发送到该Exchange的消息路由到所有与它绑定的Queue中。

           

        上图所示,生产者(P)生产消息1将消息1推送到Exchange,由于Exchange Type=fanout这时候会遵循fanout的规则将消息推送到所有与它绑定Queue,也就是图上的两个Queue最后两个消费者消费。

    • direct

            direct类型的Exchange路由规则也很简单,它会把消息路由到那些binding key与routing key完全匹配的Queue中

             

         当生产者(P)发送消息时Rotuing key=booking时,这时候将消息传送给Exchange,Exchange获取到生产者发送过来消息后,会根据自身的规则进行与匹配相应的Queue,这时发现Queue1和Queue2都符合,就会将消息传送给这两个队列,如果我们以Rotuing key=create和Rotuing key=confirm发送消息时,这时消息只会被推送到Queue2队列中,其他Routing Key的消息将会被丢弃。

    • topic

          前面提到的direct规则是严格意义上的匹配,换言之Routing Key必须与Binding Key相匹配的时候才将消息传送给Queue,那么topic这个规则就是模糊匹配,可以通过通配符满足一部分规则就可以传送。它的约定是:

    1. routing key为一个句点号“. ”分隔的字符串(我们将被句点号“. ”分隔开的每一段独立的字符串称为一个单词),如“stock.usd.nyse”、“nyse.vmw”、“quick.orange.rabbit”
    2. binding key与routing key一样也是句点号“. ”分隔的字符串
    3. binding key中可以存在两种特殊字符“*”与“#”,用于做模糊匹配,其中“*”用于匹配一个单词,“#”用于匹配多个单词(可以是零个)

          

      当生产者发送消息Routing Key=F.C.E的时候,这时候只满足Queue1,所以会被路由到Queue中,如果Routing Key=A.C.E这时候会被同是路由到Queue1和Queue2中,如果Routing Key=A.F.B时,这里只会发送一条消息到Queue2中。

    • headers

            headers类型的Exchange不依赖于routing key与binding key的匹配规则来路由消息,而是根据发送的消息内容中的headers属性进行匹配。
    在绑定Queue与Exchange时指定一组键值对;当消息发送到Exchange时,RabbitMQ会取到该消息的headers(也是一个键值对的形式),对比其中的键值对是否完全匹配Queue与Exchange绑定时指定的键值对;如果完全匹配则消息会路由到该Queue,否则不会路由到该Queue。

    展开全文
  • 消息中间件()MQ详解及四大MQ比较

    万次阅读 多人点赞 2018-08-29 22:05:58
    消息中间件相关知识 1、概述 消息队列已经逐渐成为企业IT系统内部通信的核心手段。它具有低耦合、可靠投递、广播、流量控制、最终一致性等系列功能,成为异步RPC的主要手段之。当今市面上有很多主流的消息...

    一、消息中间件相关知识

    1、概述

    消息队列已经逐渐成为企业IT系统内部通信的核心手段。它具有低耦合、可靠投递、广播、流量控制、最终一致性等一系列功能,成为异步RPC的主要手段之一。当今市面上有很多主流的消息中间件,如老牌的ActiveMQ、RabbitMQ,炙手可热的Kafka,阿里巴巴自主开发RocketMQ等。

     

    2、消息中间件的组成

          2.1 Broker

    消息服务器,作为server提供消息核心服务

          2.2 Producer

    消息生产者,业务的发起方,负责生产消息传输给broker,

          2.3 Consumer

    消息消费者,业务的处理方,负责从broker获取消息并进行业务逻辑处理

          2.4 Topic

    主题,发布订阅模式下的消息统一汇集地,不同生产者向topic发送消息,由MQ服务器分发到不同的订阅者,实现消息的       广播

          2.5 Queue

    队列,PTP模式下,特定生产者向特定queue发送消息,消费者订阅特定的queue完成指定消息的接收

          2.6 Message

    消息体,根据不同通信协议定义的固定格式进行编码的数据包,来封装业务数据,实现消息的传输

     

    3 消息中间件模式分类

          3.1 点对点

    PTP点对点:使用queue作为通信载体 

    说明: 
    消息生产者生产消息发送到queue中,然后消息消费者从queue中取出并且消费消息。 
    消息被消费以后,queue中不再存储,所以消息消费者不可能消费到已经被消费的消息。 Queue支持存在多个消费者,但是对一个消息而言,只会有一个消费者可以消费。

    3.2 发布/订阅

    Pub/Sub发布订阅(广播):使用topic作为通信载体 

    说明: 
    消息生产者(发布)将消息发布到topic中,同时有多个消息消费者(订阅)消费该消息。和点对点方式不同,发布到topic的消息会被所有订阅者消费。

    queue实现了负载均衡,将producer生产的消息发送到消息队列中,由多个消费者消费。但一个消息只能被一个消费者接受,当没有消费者可用时,这个消息会被保存直到有一个可用的消费者。 
    topic实现了发布和订阅,当你发布一个消息,所有订阅这个topic的服务都能得到这个消息,所以从1到N个订阅者都能得到一个消息的拷贝。

     

    4 消息中间件的优势

          4.1 系统解耦

    交互系统之间没有直接的调用关系,只是通过消息传输,故系统侵入性不强,耦合度低。

          4.2 提高系统响应时间

    例如原来的一套逻辑,完成支付可能涉及先修改订单状态、计算会员积分、通知物流配送几个逻辑才能完成;通过MQ架构设计,就可将紧急重要(需要立刻响应)的业务放到该调用方法中,响应要求不高的使用消息队列,放到MQ队列中,供消费者处理。

          4.3 为大数据处理架构提供服务

    通过消息作为整合,大数据的背景下,消息队列还与实时处理架构整合,为数据处理提供性能支持。

          4.4 Java消息服务——JMS

    Java消息服务(Java Message Service,JMS)应用程序接口是一个Java平台中关于面向消息中间件(MOM)的API,用于在两个应用程序之间,或分布式系统中发送消息,进行异步通信。 
    JMS中的P2P和Pub/Sub消息模式:点对点(point to point, queue)与发布订阅(publish/subscribe,topic)最初是由JMS定义的。这两种模式主要区别或解决的问题就是发送到队列的消息能否重复消费(多订阅)。

     

    5 消息中间件应用场景

           5.1 异步通信

    有些业务不想也不需要立即处理消息。消息队列提供了异步处理机制,允许用户把一个消息放入队列,但并不立即处理它。想向队列中放入多少消息就放多少,然后在需要的时候再去处理它们。

          5.2 解耦

    降低工程间的强依赖程度,针对异构系统进行适配。在项目启动之初来预测将来项目会碰到什么需求,是极其困难的。通过消息系统在处理过程中间插入了一个隐含的、基于数据的接口层,两边的处理过程都要实现这一接口,当应用发生变化时,可以独立的扩展或修改两边的处理过程,只要确保它们遵守同样的接口约束。

          5.3 冗余

    有些情况下,处理数据的过程会失败。除非数据被持久化,否则将造成丢失。消息队列把数据进行持久化直到它们已经被完全处理,通过这一方式规避了数据丢失风险。许多消息队列所采用的”插入-获取-删除”范式中,在把一个消息从队列中删除之前,需要你的处理系统明确的指出该消息已经被处理完毕,从而确保你的数据被安全的保存直到你使用完毕。

          5.4 扩展性

    因为消息队列解耦了你的处理过程,所以增大消息入队和处理的频率是很容易的,只要另外增加处理过程即可。不需要改变代码、不需要调节参数。便于分布式扩容。

          5.5 过载保护

    在访问量剧增的情况下,应用仍然需要继续发挥作用,但是这样的突发流量无法提取预知;如果以为了能处理这类瞬间峰值访问为标准来投入资源随时待命无疑是巨大的浪费。使用消息队列能够使关键组件顶住突发的访问压力,而不会因为突发的超负荷的请求而完全崩溃。

          5.6 可恢复性

    系统的一部分组件失效时,不会影响到整个系统。消息队列降低了进程间的耦合度,所以即使一个处理消息的进程挂掉,加入队列中的消息仍然可以在系统恢复后被处理。

          5.7 顺序保证

    在大多使用场景下,数据处理的顺序都很重要。大部分消息队列本来就是排序的,并且能保证数据会按照特定的顺序来处理。

          5.8 缓冲

    在任何重要的系统中,都会有需要不同的处理时间的元素。消息队列通过一个缓冲层来帮助任务最高效率的执行,该缓冲有助于控制和优化数据流经过系统的速度。以调节系统响应时间。

          5.9 数据流处理

    分布式系统产生的海量数据流,如:业务日志、监控数据、用户行为等,针对这些数据流进行实时或批量采集汇总,然后进行大数据分析是当前互联网的必备技术,通过消息队列完成此类数据收集是最好的选择。

     

    6 消息中间件常用协议

          6.1 AMQP协议

    AMQP即Advanced Message Queuing Protocol,一个提供统一消息服务的应用层标准高级消息队列协议,是应用层协议的一个开放标准,为面向消息的中间件设计。基于此协议的客户端与消息中间件可传递消息,并不受客户端/中间件不同产品,不同开发语言等条件的限制。 
    优点:可靠、通用

          6.2 MQTT协议

    MQTT(Message Queuing Telemetry Transport,消息队列遥测传输)是IBM开发的一个即时通讯协议,有可能成为物联网的重要组成部分。该协议支持所有平台,几乎可以把所有联网物品和外部连接起来,被用来当做传感器和致动器(比如通过Twitter让房屋联网)的通信协议。 
    优点:格式简洁、占用带宽小、移动端通信、PUSH、嵌入式系统

          6.3 STOMP协议

    STOMP(Streaming Text Orientated Message Protocol)是流文本定向消息协议,是一种为MOM(Message Oriented Middleware,面向消息的中间件)设计的简单文本协议。STOMP提供一个可互操作的连接格式,允许客户端与任意STOMP消息代理(Broker)进行交互。 
    优点:命令模式(非topic\queue模式)

          6.4 XMPP协议

    XMPP(可扩展消息处理现场协议,Extensible Messaging and Presence Protocol)是基于可扩展标记语言(XML)的协议,多用于即时消息(IM)以及在线现场探测。适用于服务器之间的准即时操作。核心是基于XML流传输,这个协议可能最终允许因特网用户向因特网上的其他任何人发送即时消息,即使其操作系统和浏览器不同。 
    优点:通用公开、兼容性强、可扩展、安全性高,但XML编码格式占用带宽大

          6.5 其他基于TCP/IP自定义的协议

    有些特殊框架(如:redis、kafka、zeroMq等)根据自身需要未严格遵循MQ规范,而是基于TCP\IP自行封装了一套协议,通过网络socket接口进行传输,实现了MQ的功能。

     

    7 常见消息中间件MQ介绍

          7.1 RocketMQ

    阿里系下开源的一款分布式、队列模型的消息中间件,原名Metaq,3.0版本名称改为RocketMQ,是阿里参照kafka设计思想使用java实现的一套mq。同时将阿里系内部多款mq产品(Notify、metaq)进行整合,只维护核心功能,去除了所有其他运行时依赖,保证核心功能最简化,在此基础上配合阿里上述其他开源产品实现不同场景下mq的架构,目前主要多用于订单交易系统。

    具有以下特点:

    • 能够保证严格的消息顺序
    • 提供针对消息的过滤功能
    • 提供丰富的消息拉取模式
    • 高效的订阅者水平扩展能力
    • 实时的消息订阅机制
    • 亿级消息堆积能力

    官方提供了一些不同于kafka的对比差异: 
    https://rocketmq.apache.org/docs/motivation/

          7.2 RabbitMQ

    使用Erlang编写的一个开源的消息队列,本身支持很多的协议:AMQP,XMPP, SMTP,STOMP,也正是如此,使的它变的非常重量级,更适合于企业级的开发。同时实现了Broker架构,核心思想是生产者不会将消息直接发送给队列,消息在发送给客户端时先在中心队列排队。对路由(Routing),负载均衡(Load balance)、数据持久化都有很好的支持。多用于进行企业级的ESB整合。

          7.3 ActiveMQ

    Apache下的一个子项目。使用Java完全支持JMS1.1和J2EE 1.4规范的 JMS Provider实现,少量代码就可以高效地实现高级应用场景。可插拔的传输协议支持,比如:in-VM, TCP, SSL, NIO, UDP, multicast, JGroups and JXTA transports。RabbitMQ、ZeroMQ、ActiveMQ均支持常用的多种语言客户端 C++、Java、.Net,、Python、 Php、 Ruby等。

          7.4 Redis

    使用C语言开发的一个Key-Value的NoSQL数据库,开发维护很活跃,虽然它是一个Key-Value数据库存储系统,但它本身支持MQ功能,所以完全可以当做一个轻量级的队列服务来使用。对于RabbitMQ和Redis的入队和出队操作,各执行100万次,每10万次记录一次执行时间。测试数据分为128Bytes、512Bytes、1K和10K四个不同大小的数据。实验表明:入队时,当数据比较小时Redis的性能要高于RabbitMQ,而如果数据大小超过了10K,Redis则慢的无法忍受;出队时,无论数据大小,Redis都表现出非常好的性能,而RabbitMQ的出队性能则远低于Redis。

          7.5 Kafka

    Apache下的一个子项目,使用scala实现的一个高性能分布式Publish/Subscribe消息队列系统,具有以下特性:

    • 快速持久化:通过磁盘顺序读写与零拷贝机制,可以在O(1)的系统开销下进行消息持久化;
    • 高吞吐:在一台普通的服务器上既可以达到10W/s的吞吐速率;
    • 高堆积:支持topic下消费者较长时间离线,消息堆积量大;
    • 完全的分布式系统:Broker、Producer、Consumer都原生自动支持分布式,依赖zookeeper自动实现复杂均衡;
    • 支持Hadoop数据并行加载:对于像Hadoop的一样的日志数据和离线分析系统,但又要求实时处理的限制,这是一个可行的解决方案。

          7.6 ZeroMQ

    号称最快的消息队列系统,专门为高吞吐量/低延迟的场景开发,在金融界的应用中经常使用,偏重于实时数据通信场景。ZMQ能够实现RabbitMQ不擅长的高级/复杂的队列,但是开发人员需要自己组合多种技术框架,开发成本高。因此ZeroMQ具有一个独特的非中间件的模式,更像一个socket library,你不需要安装和运行一个消息服务器或中间件,因为你的应用程序本身就是使用ZeroMQ API完成逻辑服务的角色。但是ZeroMQ仅提供非持久性的队列,如果down机,数据将会丢失。如:Twitter的Storm中使用ZeroMQ作为数据流的传输。

    ZeroMQ套接字是与传输层无关的:ZeroMQ套接字对所有传输层协议定义了统一的API接口。默认支持 进程内(inproc) ,进程间(IPC) ,多播,TCP协议,在不同的协议之间切换只要简单的改变连接字符串的前缀。可以在任何时候以最小的代价从进程间的本地通信切换到分布式下的TCP通信。ZeroMQ在背后处理连接建立,断开和重连逻辑。

    特性:

    • 无锁的队列模型:对于跨线程间的交互(用户端和session)之间的数据交换通道pipe,采用无锁的队列算法CAS;在pipe的两端注册有异步事件,在读或者写消息到pipe的时,会自动触发读写事件。
    • 批量处理的算法:对于批量的消息,进行了适应性的优化,可以批量的接收和发送消息。
    • 多核下的线程绑定,无须CPU切换:区别于传统的多线程并发模式,信号量或者临界区,zeroMQ充分利用多核的优势,每个核绑定运行一个工作者线程,避免多线程之间的CPU切换开销。

     

    二、主要消息中间件的比较

     

    综合选择RabbitMq 

    展开全文
  • 如果你对消息队列背后的实现原理关注不多,其实了解消息队列背后的实现非常重要。 不仅知其然还要知其所以然,这才是个优秀的工程师需要具备的特征。 今天,我们就起来探讨设计消息队列背后的技术。 消息...

    消息队列作为系统解耦,流量控制的利器,成为分布式系统核心组件之一。

    如果你对消息队列背后的实现原理关注不多,其实了解消息队列背后的实现非常重要。

    不仅知其然还要知其所以然,这才是一个优秀的工程师需要具备的特征。

    今天,我们就一起来探讨设计一个消息队列背后的技术。

    消息队列整体设计思路

    主要是设计一个整体的消息被消费的数据流。

    这里会涉及到:消息生产Producer、Broker(消息服务端)、消息消费者Consumer。

    高并发架构系列:如何从0到1设计一个MQ消息队列

    1.Producer(消息生产者):发送消息到Broker。

    2.Broker(服务端):Broker这个概念主要来自于Apache的ActiveMQ,特指消息队列的服务端。

    主要功能就是:把消息从发送端传送到接收端,这里会涉及到消息的存储、消息通讯机制等。

    3.Consumer(消息消费者):从消息队列接收消息,consumer回复消费确认。

    Broker(消息队列服务端)设计重点

    1)消息的转储:在更合适的时间点投递,或者通过一系列手段辅助消息最终能送达消费机。

    2)规范一种范式和通用的模式,以满足解耦、最终一致性、错峰等需求。

    3)其实简单理解就是一个消息转发器,把一次RPC做成两次RPC,发送者把消息投递到broker,broker再将消息转发一手到接收端。

    总结起来就是两次RPC加一次转储,如果要做消费确认,则是三次RPC。

    为了实现上述消息队列的基础功能:

    • 消息的传输
    • 存储
    • 消费

    就需要涉及到如下三个方面的设计:

    • 通信协议
    • 存储选择
    • 消费关系维护

    通讯协议

    消息Message:既是信息的载体,消息发送者需要知道如何构造消息,消息接收者需要知道如何解析消息,它们需要按照一种统一的格式描述消息,这种统一的格式称之为消息协议。

    传统的通信协议标准有XMPP和AMQP协议等,现在更多的消息队列从性能的角度出发使用自己设计实现的通信协议。

    1.JMS

    JMS(Java MessageService)实际上是指JMS API。JMS是由Sun公司早期提出的消息标准,旨在为java应用提供统一的消息操作,包括创建消息、发送消息、接收消息等。

    JMS通常包含如下一些角色:

    高并发架构系列:如何从0到1设计一个MQ消息队列

    JMS提供了两种消息模型:

    • 点对点
    • 以及publish-subscribe(发布订阅)模型。

    当采用点对点模型时,消息将发送到一个队列,该队列的消息只能被一个消费者消费。

    高并发架构系列:如何从0到1设计一个MQ消息队列

    而采用发布订阅模型时,消息可以被多个消费者消费。

    在发布订阅模型中,生产者和消费者完全独立,不需要感知对方的存在。

    2.AMQP

    AMQP是 Advanced Message Queuing Protocol,即高级消息队列协议。

    AMQP不是一个具体的消息队列实现,而 是一个标准化的消息中间件协议。

    目标是让不同语言,不同系统的应用互相通信,并提供一个简单统一的模型和编程接口。 目前主流的ActiveMQ和RabbitMQ都支持AMQP协议。

    AMQP是一种协议,更准确的说是一种binary wire-level protocol(链接协议)。这是其和JMS的本质差别,AMQP不从API层进行限定,而是直接定义网络交换的数据格式。

    JMS和AMQP比较

    JMS: 只允许基于JAVA实现的消息平台的之间进行通信

    AMQP: AMQP允许多种技术同时进行协议通信

    3.Kafka的通信协议

    Kafka的Producer、Broker和Consumer之间采用的是一套自行设计的基于TCP层的协议。Kafka的这套协议完全是为了Kafka自身的业务需求而定制的。

    高并发架构系列:如何从0到1设计一个MQ消息队列

    存储选型

    对于分布式系统,存储的选择有以下几种

    • 内存
    • 本地文件系统
    • 分布式文件系统
    • nosql
    • DB

    从速度上内存显然是最快的,对于允许消息丢失,消息堆积能力要求不高的场景(例如日志),内存会是比较好的选择。

    DB则是最简单的实现可靠存储的方案,很适合用在可靠性要求很高,最终一致性的场景(例如交易消息),对于不需要100%保证数据完整性的场景,要求性能和消息堆积的场景,hbase也是一个很好的选择。

    理论上,从速度来看,文件系统>分布式KV(持久化)>分布式文件系统>数据库,而可靠性却截然相反。

    还是要从支持的业务场景出发作出最合理的选择,如果你们的消息队列是用来支持支付/交易等对可靠性要求非常高,但对性能和量的要求没有这么高,而且没有时间精力专门做文件存储系统的研究,DB是最好的选择。

    对于不需要100%保证数据完整性的场景,要求性能和消息堆积的场景,hbase也是一个很好的选择,典型的比如 kafka的消息落地可以使用hadoop。

    消费关系处理

    现在我们的消息队列初步具备了转储消息的能力。

    下面一个重要的事情就是解析发送接收关系,进行正确的消息投递了。

    市面上的消息队列定义了一堆让人晕头转向的名词,如JMS 规范中的Topic/Queue,Kafka里面的Topic/Partition/ConsumerGroup,RabbitMQ里面的Exchange等等。

    抛开现象看本质,无外乎是单播与广播的区别。

    所谓单播,就是点到点;而广播,是一点对多点。

    为了实现广播功能,我们必须要维护消费关系,通常消息队列本身不维护消费订阅关系,可以利用zookeeper等成熟的系统维护消费关系,在消费关系发生变化时下发通知。

    消息队列需要支持高级特性

    除了上述的消息队列基本功能以外,消息队列在某些特殊的场景还需要支持事务,消息重试等功能。

    高并发架构系列:如何从0到1设计一个MQ消息队列

    • 消息的顺序
    • 投递可靠性保证
    • 消息持久化
    • 支持不同消息模型
    • 多实例集群功能
    • 事务特性等
    展开全文
  • python练习:编写个程序,要求用户输入10个整数,然后输出其中最大的奇数,如果用户没有输入奇数,输出消息进行说明。 重难点:通过input函数输入的行消息为字符串格式,必须转换为整型,否则不能进行排序...

    python练习:编写一个程序,要求用户输入10个整数,然后输出其中最大的奇数,如果用户没有输入奇数,则输出一个消息进行说明。

    重难点:通过input函数输入的行消息为字符串格式,必须转换为整型,否则不能进行排序交换位置。通过索引的方式可以查看字符串中的每一个字符,双层for循环进行冒泡排序。for循环的倒序输出方式:for z in range(9,1,-1):。break直接跳出循环。通过标志位判断是否输出过奇数。

     1 print("————————————————————————————")
     2 num=input('请输入十个整数:')#通过input函数输入,这时返回值为行信息的字符串
     3 for m in range(10):
     4     print(int(num[m]))#通过索引查看每一个值
     5 num=list(map(int,num))#把字符串序列转化为整型序列
     6 print(num)
     7 a=0
     8 for i in range(10):#循环写10
     9     for j in range(i+1,10):#双层循环,进行冒泡排序
    10         if( int(num[i])>int(num[j])):
    11             num[i],num[j]=num[j],num[i]
    12 print(num)
    13 for z in range(9,1,-1):#倒序输出,正序输出range(0,10),注意是(9,1)不是(9,0)也不是(10,0)
    14     if(int(num[z])%2==1):
    15         print(num[z])
    16         a=a+1
    17         break;#输出一个奇数的话,直接跳出循环
    18 if(a==0):#设立标志位,记录是否输出过奇数
    19     print('用户没有输入奇数。')

     

    转载于:https://www.cnblogs.com/ming-4/p/10245735.html

    展开全文
  • 如果用户没有输入奇数,输出消息进行说明   #循环从控制台输入程序 num_list=[] for i in range(10): num=int(input("第"+str(i+1) + "个数")) #这里必须把i转为字符串类型,因为...
  • 一则我们说到了一个多个的RabbitMQ消息队列通信的实现方法,生产者发送的消息只能被一个消费者接收并处理,上则请阅读:http://blog.csdn.net/u012631731/article/details/78450389 本则说的是广播式的消息通信...
  • 5G消息

    万次阅读 2020-12-29 10:21:06
    在讲5G消息之前,我们先来聊聊RCS,循序渐进,层的剥开5G消息的神秘面纱。 “5G消息”,其实和5G并没有什么关系。它既不是5G特有的功能,也不是5G时代新开发出来的业务。它的真实身份,是2008年就已经诞生的...
  • Java架构之消息队列 ():消息队列的概述

    万次阅读 多人点赞 2018-10-08 16:09:38
     消息队列的概述 二、消息队列之RabbitMQ的使用 三、消息队列之Kafka的使用 四、消息队列之RabbitMQ的原理详解 五、消息队列之Kafka的原理详解 六、消息队列之面试集锦 1.消息队列的概述 消息队列...
  • 一则文章讲解了RabbitMQ的安装和简单一消息通信实现方法,具体可参考上一篇文章:http://blog.csdn.net/u012631731/article/details/72887588 这则文章讲述一个生产者和多个消费者的消息通信。 直接上源码,...
  • 消息中间件MQ与RabbitMQ面试题(2020最新版)

    万次阅读 多人点赞 2020-03-01 11:11:21
    MQ的优点消息队列有什么优缺点?RabbitMQ有什么优缺点?你们公司生产环境用的是什么消息中间件?Kafka、ActiveMQ、RabbitMQ、RocketMQ 有什么优缺点?MQ 有哪些常见问题?如何解决这些问题?什么是RabbitMQ?...
  • TCP+多线程,让发送消息和接收消息各占条线程

    千次阅读 热门讨论 2018-04-22 18:01:43
    客户端和服务器只有一方可以发送消息,另一方只能等待(接收消息),而且不能连续发送消息。因为发送消息和接受消息共有条线程,需要来回的切换。这时我们就要专门为发送消息和接受消息各创建个线程,就可以...
  • 我们将消息队列这个组件加入到了我们的商城系统里,并且通过秒杀这个实际的案例进行了实际演练,知道了它高并发写流量做削峰填谷,非关键业务逻辑做异步处理,不同的业务系统做解耦合。场景:现...
  • 本系列文章由zhmxy555编写,转载请注明出处。 http://blog.csdn.net/zhmxy555/article/details/7390624作者:毛星云 邮箱: ...在那个物质并不充裕的时代,台配置并不高的电脑,款名叫《仙剑奇侠传》的游戏,
  • Kafka消息中间件(

    千次阅读 2018-12-14 09:58:01
    Kafka可以说是现在所有开源消息组件之中性能最高的产品,但是同时也需要认识到个问题:Kafka是项不断继续发展的技术,所以来说对于其的稳定性永远无法评估。Kafka官网地址: http://kafka.apache.org/ Kafka...
  • 消息中间件和JMS介绍()

    万次阅读 2017-04-26 08:37:48
    面向消息的中间件(MOM),提供了以松散耦合的灵活方式集成应用程序的种机制。它们提供了基于存储和转发的应用程序之间的异步数据发送,即应用程序彼此不直接通信,而是与作为中介的MOM通信。 消息中间件一般有两...
  • Windows的消息机制

    万次阅读 2018-03-14 00:18:36
    个线程被创建时,系统假定该线程不会被用于任何与用户界面相关的任务,所以不会为它分配相应的资源(如消息队列等),因为这样可以减少线程系统资源的占用。 但是,一旦这个线程调用个与图形用户界面有关的...
  • 消息中间件()JMS与ActiveMQ

    千次阅读 2016-04-16 13:33:54
    实践中存在的问题(引自...、如何解决消息发送一致性 1.消息发送一致性定义 消息发送一致性是指产生消息的业务动作与发送消息的一致,也就是说,如果业务操作成功了,那么由这个操作产生的消息一定要发送出去,
  • 本文介绍了个简易的实时消息推送系统。 需求分析 后台同时对接了网页,微信公众号,iOS以及Android客户端。在某些特定场景下,比如个用户接收到其他用户的提问,我们就需要向这个用户推送消息。用户或者在...
  • 常用消息队列对比

    万次阅读 2018-03-05 22:31:26
    作为中间件,消息队列是分布式...所以消息队列可以解决应用解耦、异步消息、流量削锋等问题,是实现高性能、高可用、可伸缩和最终一致性架构中不可以或缺的环。下面对消息队列就直接使用MQ表示。现在比较常见的MQ...
  • 分布式专题|面了个六年开发,居然不知道怎么保证消息可靠性?
  • MQ——你认识的消息队列是这样吗

    万次阅读 2018-07-10 12:52:19
    九自问: ...需要说明一下,本文不是《消息队列从入门到精通》这种课程,因此只是提供个复习思路,而不是去教你们怎么调用消息队列的API。建议对消息队列不了解的人,去找点消息队列的博客看看,再看...
  • 它内部维护了消息队列,即MessageQueue。Looper的职责就是负责抽取MessageQueue中的消息让他去找宿主。 对于一些普通的程序开发工作而言,只需要了解Handler的用法即可,几乎接触不到Looper,更别说是Message...
  • 在实现利用消息队列的进程间通信之前,先了解一下基本的概念和...简单理解就是,每个消息队列都有个ID号,而这个号用来区分不同的消息队列,从而保证不同消息队列之间不冲突。而每个消息队列内部也维护了个独立...
  • RocketMQ源码深度解析消息存储

    万次阅读 2017-08-07 01:09:05
    前言:RocketMQ的消息持久化是基于文件系统,而从效率来看文件系统>kv存储>关系型数据库。那么,到底是如何存储的,相信源码进行解析,将会是我们大大提高对消息存储的认识。
  • 使用ActiveMQ+MQTT实现Android点消息通知

    万次阅读 热门讨论 2013-12-20 16:37:20
    ActiveMQ使用MQTT协议,加上android上的paho包,即可简单实现消息通知功能,但是mqtt协议只支持topic,而且不能用selector,使得点点的消息投递变成问题。 有两个解决思路: 每个clientId建个topic、实现某些...
  • Android消息循环机制

    万次阅读 2016-06-19 01:56:37
    转载请注明出处:...实际上应用程序启动的时候,会创建个UI线程,然后该线程关联消息队列,相关操作封装个个消息放入队列中,主线程会不断循环从队
  • 手机通过socket发送消息到服务器,服务器每接收到消息之后,都会把这条消息放进个messageList里面,服务器会不停地检测messageList是否含有消息,如果有的话就会根据messageList里面item的数据,推送到相应的...
  • 、前言 从这篇博客开始小编就从个简单的实例来展示一下消息队列中MSMQ的基本使用方法,展示一下他对消息的增删改查,消息队列有很多种样式,做.NET开发的程序猿,最容易安装的就是MSMQ,所以小编先向大家介绍...
  • Spring Boot 整合消息中间件 RabbitMQ

    万次阅读 2017-02-16 16:03:12
    RabbitMQ 是消息中间件的种,实现了 AMQP 标准。消息中间件的工作过程可以用生产者-消费者模型来表示。生产者发消息消息队列中去,消费者监听指定的消息队列,并且当消息队列收到消息之后,接收消息队列传来的...
  • 附录A Windows 常用消息大全 表A-1 Windows消息分布 消息范围 说 明 0 ~ WM_USER – 1 系统消息 WM_USER ~ 0x7FFF 自定义窗口类整数消息 WM_APP ~ 0...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,062,634
精华内容 425,053
关键字:

一则消息对吗