消息队列之zeroMQ、rabbitMQ、kafka

      首先消息是网络通讯的载体,队列可以理解是一种先进先出的数据结构,消息队列是存放消息的容器,是分布式系统中的重要组件。消息队列的优势在于:解耦、异步、削峰,把相关性不

强的模块独立分开视为解耦,异步就是非必要逻辑异步方式处理,加快响应速度,削峰是避免短期高并发导致系统问题进行缓冲队列处理。消息队列的缺点在于:加强系统复杂性、系统可用性降低,使

用了消息队列系统出现问题排查的范围就变大、需要考虑消息队列导致的问题。

          本文说明主流的消息队列,针对使用过的zeroMQ和rabbitMQ、Kakfa:

          zeroMQ:C语言开发,号称最快的消息队列,本着命名zero的含义,中油中间架构使用简单,表面上是基于socket的封装套接字API,在多个节点应用场景下非常灵活、架构的可扩展性很强,

实现N到M的协同处理;

            zmq的socket模式: req、rep、push、pull、pub、sub、router、dealer。

          (1)req和rep:请求回应模型,req和rep都可以请求和回答,不同的只是req是先send再rec,rep是先rec再send。支持N个请求端一个接收端,也支持N个接收端一个请求端。N个接收端采

用rr负载均衡。 哪个是“一”端,哪个就bind端口,“N”端就只能connect,所以,req+rep无论谁bind端口,肯定要有一个是“一”。

          (2)  router和dealer:随时可以发送和接收的req和rep,看起来router+dealer跟 req+rep属于同类功能。因为router和dealer可以随时发送接收,所以它们可以用来做路由。一个router用来响

应N个req,然后它在响应处理的时候,再通过另一个socket把请求扔出去,接收者是另外的M个rep,这就做到N:M。

         (3)pub和sub :订阅和推送,对应发布者和订阅者。

         (4)push和pull:就是管道,一个只推数据,一个只拉数据。

           rabbitMQ:使用erlang语言开发,高并发特点,基于AMQP(即Advanced Message Queuing Protocol)的开源高级消费队列,AMQP的主要特征是面向消息、队列、路由(包括点对点和发布/

订阅)、可靠性、安全),企业级适应性和稳定性,并且有WEB管理界面方便用户查看和管理。以下是rabbitMQ的结构图:


rabbitMQ结构图

         (1)Producer:数据发送方,一般一个Message有两个部分:payload(有效载荷)和label(标签),payload是数据实际载体,label是exchange的名字或者一个tag,决定发给哪个Consumer;

         (2)Exchange:内部消息交换器,exchange从生产者那收到消息后,一般会指定一个Routing Key,来指定这个消息的路由规则,当然Routing Key需要与Exchange Type及Binding key联合使用

才能最终生效,根据路由规则,匹配查询表中的routing key,分发消息到queue中;

         (3)binding:即绑定,绑定(Binding)Exchange与Queue的同时,一般会指定一个Binding key,但不一定会生效,依赖于Exchange Type;

         (4)Queue:即队列是rabbitmq内部对象,用于存储消息,一个message可以被同时拷贝到多个queue中,queue对load balance的处理是完美的。对于多个Consumer来说,RabbitMQ 使用循

环的方式(round-robin)的方式均衡的发送给不同的Consumer;

         (5)Connection与Channel:Connection就是一个TCP的连接,Producer和Consumer都是通过TCP连接到RabbitMQ Server,Channel是为了节省开销建立在上述的TCP连接中的接口,大部

分的业务操作是在Channel这个接口中完成的,包括定义Queue、定义Exchange、绑定Queue与Exchange、发布消息等;

        (6)Consumer:即数据的接收方,如果有多个消费者同时订阅同一个Queue中的消息,Queue中的消息会被平摊给多个消费者;

        (7)Broker: 即RabbitMQ Server,其作用是维护一条从Producer到Consumer的路线,保证数据能够按照指定的方式进行传输;

       (8)Virtual host:即虚拟主机,当多个不同的用户使用同一个RabbitMQ server提供的服务时,可以划分出多个vhost,每个用户在自己的vhost创建exchange/queue;


         rabbitMQ消息转发中的路由转发是重点,生产者Producer在发送消息时,都需要指定一个RoutingKey和Exchange,Exchange收到消息后可以看到消息中指定的RoutingKey,再根据当前

Exchange的ExchangeType,按一定的规则将消息转发到相应的queue中去。三种Exchage type:

       (1)Direct exchange :直接转发路由,原理是通过消息中的routing key,与binding 中的binding-key 进行比对,若二者匹配,则将消息发送到这个消息队列;

          比如:消息生成者生成一个message(payload是1,routing key为苹果),两个binding(binding key分别为苹果、香蕉);exchange比对消息的routing key和binding key后,将消息发给了queue1,消息消费者1获得queue1的消息;

       (2)Topic exchange: 通配路由,是direct exchange的通配符模式,

          比如:消息生成者生成一个message(payload是1,routing key为quick.orange.rabbit),两个binding(binding key分别为*.orange.*.*.rabbit);exchange比对消息的routing key和binding key

后,exchange将消息分发给两个queue,两个消费者获得queue的消息;

     (3)Fanout exchange: 复制分发路由,原理是不需要routkey,当exchange收到消息后,将消息复制多份转发给与自己绑定的消息队列,

          比如:消息生成者生成一个message(payload是1,routing key为苹果),两个binding(binding key分别为苹果、香蕉);exchange将消息分发给两个queue,两个消费者获得queue的消息;

       rabbiMQ如何保证消息的可靠性?

     (1)Message durability:消息持久化,非持久化消息保存在内存中,持久化消息写入内存同时也写入磁盘;

     (2)Message acknowledgment:消息确认机制,可以要求消费者在消费完消息后发送一个回执给RabbitMQ,RabbitMQ收到消息回执(Message acknowledgment)后才将该消息从Queue中移

除。通过ACK。每个Message都要被acknowledged(确认,ACK)。

     (3)生产者消息确认机制:AMQP事务机制、生产者消息确认机制(publisher confirm)。


     最后, 对比一下zeroMQ、rabbitMQ、kafka主流的消息队列的性能情况:

      对比方向                                                                          概要

      吞吐量                             万级 RabbitMQ 的吞吐量要比 十万级甚至是百万级Kafka 低一个数量级。ZeroMQ号称最快的消息队列系统,尤其针对大吞吐量的需求场景。

      可用性                            都可以实现高可用。RabbitMQ 都是基于主从架构实现高可用性。 kafka 也是分布式的,一个数据多个副本,少数机器宕机,不会丢失数据,不会导致不可用

      时效性                             RabbitMQ 基于erlang开发,所以并发能力很强,性能极其好,延时很低,达到微秒级。其他两个个都是 ms 级。

      功能支持                          Kafka 功能较为简单,主要支持简单的MQ功能,在大数据领域实时计算以及日志采集被大规模使用;ZeroMQ能够  实现RabbitMQ不擅长的高级/复杂 的队列

      消息丢失                          RabbitMQ有ack模型,也有事务模型,保证至少不会丢数据,  Kafka 理论上不会丢失,但不排除批量情况下。

      开发环境                          RabbitMQ需要erlang支持、kafka基于zookeeper管理部署、zeroMQ程序编译调用即可

      封装库                               基于c++开发,使用RabbitMQ-C,cppKafka,而zeroMQ基于C语言开发,无需封装

你可能感兴趣的:(消息队列之zeroMQ、rabbitMQ、kafka)