Rabbitmq,Rocketmq,Kafka基本概念介绍和常见消息确保方案

1.Rabbitmq

 首先说的是rabbitmq,为什么先提它呢,因为它是这么多款开源mq里面完全遵循AMQP(Advanced Message Queue )的开源实现的。

概念:结合下图来理解

上图表述了消息生产,通过server到消息被消费的过程。那么来看看rabbitmq中几个名词概念。

Queue

   Queue(队列)RabbitMQ的作用是存储消息,队列的特性是先进先出。上图可以清晰地看到Client A和Client B是生产者,生产者生产消息最终被送到RabbitMQ的内部对象Queue中去,而消费者则是从Queue队列中取出数据。可以简化成表示为:

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

 

 Exchange

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

  在绑定(Binding)Exchange和Queue的同时,一般会指定一个Binding Key,生产者将消息发送给Exchange的时候,一般会产生一个Routing Key,当Routing Key和Binding Key对应上的时候,消息就会发送到对应的Queue中去。那么Exchange有四种类型,不同的类型有着不同的策略。

那么Exchange Type有多少种呢?

  • 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,使用较少。

类型名称类型描述
fanout把所有发送到该Exchange的消息路由到所有与它绑定的Queue中
direct通过key来决定消息去向哪个queue
topic支持通配符方式路由queue
headersExchange不依赖于routing key与binding key的匹配规则来路由消息,而是根据发送的消息内容中的headers属性进行匹配。

补充说明:

        ConnectionFactory、Connection、Channel都是RabbitMQ对外提供的API中最基本的对象。Connection是RabbitMQ的socket链接,它封装了socket协议相关部分逻辑。ConnectionFactory为Connection的制造工厂。
  Channel是我们与RabbitMQ打交道的最重要的一个接口,我们大部分的业务操作是在Channel这个接口中完成的,包括定义Queue、定义Exchange、绑定Queue与Exchange、发布消息等。 通过channel可以减少tcp连接数量,相反是在tcp连接基础上开启channel进行数据流动。

 

2、Rockmq

RocketMQ是阿里开源的一款十分优秀的消息队列,rocketMQ具有很多其他消息队列不具有的特性,更重要的是rocketMQ是用java开发的学习成本较低,并且经历了双11的数据洪峰的考验。下图是部署图

 

接下来来了解rockmq的概念模型,它跟rabbitmq在概念上有很大的不同,因为它不是按照amqp概念来实现的。

  • Topic

  首先需要提到的概念是Topic。 Topic在不同的语境下被赋予了两种不同的语义:

  1)    消息的Topic属性值    在描述Consumer的订阅设置信息或消息的属性时。

  2)    Topic属性为某个值的消息(单个消息或消息集合) 在描述Broker,Producer和Consumer的对应关系,Queue以及负载均衡策略时。

  3)   topic 是生产者发送消息和消费者提取消息的一种分类。主题与生产者和消费者的关系很松散。更具体的说,一个主题可能那个有0,1或多个生产者向其发送信息;相反,一个消费组可以发送不同主题的消息。从消费者来看,一个主题可能被0,1或多个消费组群组订阅。类似,一个消费者群组可能订阅一个或多个主题,只要该组的实例一直保持它们的订阅。

  • Name Server

  它是一个几乎无状态节点,可集群部署,节点之间无任何信息同步。(2.X版本之前rocketMQ使用zookeeper做topic路由管理)。Name Server 是专为 RocketMQ设计的轻量级名称服务,代码小于1000行,具有简单、可集群横吐扩展、无状态等特点。将要支持的主备自动切换功能会强依赖 Name Server。

  • Broker

Broker 部署相对复杂,Broker分为Master与Slave,一个Master可以对应多个Slave,但是一个Slave只能对应一个Master,Master与Slave的对应关系通过指定相同的BrokerName,不同的BrokerId来定义,BrokerId为0表示Master,非0表示Slave。Master也可以部署多个。每个Broker与Name Server 集群中的所有节点建立长连接,定时注册Topic信息到所有Name Server。
它同样存储与消息相关的元数据,包括消费组群组,消费进度偏移量和主题/队列信息。

  •  Producer

Producer 与Name Server集群中的其中一个节点(随机选择,但不同于上一次)建立长连接,定期从Name Server取Topic路由信息,并向提供Topic服务的Master建立长连接,且定时向Master发送心跳。Producer完全无状态,可集群部署。

  •  Consumer

Consumer与Name Server集群中的其中一个节点(随机选择,但不同于上一次)建立长连接,定期从Name Server 取Topic路由信息,并向提供Topic服务的Master、Slave建立长连接,且定时向Master、Slave发送心跳。Consumer既可以从Master订阅消息,也可以从Slave订阅消息,订阅规则由Broker配置决定(目前版本没有找到可配置的地方,可以在原码里修改)。

  • Producer Group


用来表示一个収送消息应用,一个Producer Group下包含多个Producer实例,可以是多台机器,也可以是一台机器的多个迕程,或者一个进程的多个Producer对象。一个Producer Group可以发送多个Topic消息,Producer Group作用如下:

  1.   标识一类 Producer

  2.   可以通过运维工具查询这个发送消息应用下有多个Producer实例
  3.   发送分布式事务消息时,如果 Producer中途意外宕机,Broker会主动回调 Producer Group内的任意一台机器来确认事务状 态。
  • Consumer Group


用来表示一个消费消息应用,一个Consumer Group下包含多个Consumer实例,可以是多台机器,也可以是多个进程,或者是一个进程的多个Consumer对象。一个Consumer Group下的多个Consumer以均摊方式消费消息,如果设置为广播方式,那么这个 Consumer Group下的每个实例都消费全量数据。

它们之间的关系如下图:

 

  •  Queue

它跟rabbitmq中的queue不一样。结合下图解释

       从本质上来说,RocketMQ中的Queue是数据分片的产物。为了更好地理解Queue的定义,我们还需要引入一个新的概念:Topic分片。在分布式数据库和分布式缓存领域,分片概念已经有了清晰的定义。同理,对于RocketMQ,一个Topic可以分布在各个Broker上,我们可以把一个Topic分布在一个Broker上的子集定义为一个Topic分片。对应上图,TopicA有3个Topic分片,分布在Broker1,Broker2和Broker3上,TopicB有2个Topic分片,分布在Broker1和Broker2上,TopicC有2个Topic分片,分布在Broker2和Broker3上。

     将Topic分片再切分为若干等分,其中的一份就是一个Queue。每个Topic分片等分的Queue的数量可以不同,由用户在创建Topic时指定。Queue的存在对于Consumer负载均衡有关键性作用

 

3、kafka

Kafka是最初由Linkedin公司开发,是一个分布式、支持分区的(partition)、多副本的(replica),基于zookeeper协调的分布式消息系统,它的最大的特性就是可以实时的处理大量数据以满足各种需求场景:比如基于hadoop的批处理系统、低延迟的实时系统、storm/Spark流式处理引擎,web/nginx日志、访问日志,消息服务等等,用scala语言编写,Linkedin于2010年贡献给了Apache基金会并成为顶级开源 项目。下图是部署图

Kafka基本概念

Message(消息):传递的数据对象,主要由四部分构成:offset(偏移量)、key、value、timestamp(插入时间); 其中offset和timestamp在kafka集群中产生,key/value在producer发送数据的时候产生

Broker(代理者):Kafka集群中的机器/服务被成为broker, 是一个物理概念。

Topic(主题):维护Kafka上的消息类型被称为Topic,是一个逻辑概念。

Partition(分区):具体维护Kafka上的消息数据的最小单位,一个Topic可以包含多个分区;Partition特性:ordered & immutable。(在数据的产生和消费过程中,不需要关注数据具体存储的Partition在那个Broker上,只需要指定Topic即可,由Kafka负责将数据和对应的Partition关联上)

Producer(生产者):负责将数据发送到Kafka对应Topic的进程

Consumer(消费者):负责从对应Topic获取数据的进程

Consumer Group(消费者组):每个consumer都属于一个特定的group组,一个group组可以包含多个consumer,但一个组中只会有一个consumer消费数据。

这里对于Kafka的介绍,我发现一篇更加好的博客:

 https://blog.csdn.net/lingbo229/article/details/80761778

 

 

4、三者都是如何做消息回溯,防止重复消费的,消息丢失。

  三者的实现思路其实大部分是类似的,无外乎以下几点

1.消息持久化

2.ACK确认机制

3.设置集群镜像模式

4.消息补偿机制

5、偏移量保存

解决的几个问题就是,何时持久化数据,何时删除,哪些数据需要持久化保存,从哪里开始恢复,如何保证节点高可用。

向大家推荐两篇博客:

https://www.cnblogs.com/jajian/p/10257555.html

https://www.jianshu.com/p/7a6deaba34d2

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值