美文网首页
从发布-订阅模式到消息队列

从发布-订阅模式到消息队列

作者: caibmck | 来源:发表于2018-09-11 22:43 被阅读0次

发布-订阅模式

发布-订阅模式又称为观察者模式(网上也有很多说这两种模式区别,个人觉得区别不大),在发布-订阅模式中,主要是两大块。就是发布和订阅,那么发布(publish)和订阅(subscribe)之前的关联点就是主题(topic).
举个生活的例子,午餐定外卖,燕姐(broker)在外卖群里发布了两个可以点的餐馆,都城和辉记(这个可以称为主题),小明(Consumer)点了辉记的,文哥(Consumer)点了都城的(这个可以称为订阅),都城餐馆(producer)和辉记餐馆(producer)做好了饭菜就回给外卖小哥送过来(消息协议),饭菜到了燕姐那里之后,那么小明和文哥就能去燕姐那里去拿(pull),也可以燕姐送过来(push)。这就是我们生活中最常见的发布-订阅模式。

从上文中可以得到,外卖群是一个载体(MQ),承载消息的存储和传送,从这里可以引出消息队列的这个概念,下面,继续说下消息队列。

消息队列

MQ (Message Queue) 又称消息队列. 队列我们都知道,那什么是消息呢?消息指的是同一台机器的进程之间,或不同机器之间传输的数据。最简单的说,我们一个Rpc 请求,所带的数据就是一个消息。这就是传统的通信模式。但是这种模式有很多缺陷,例如当网络不好的时候,这种调用可能会丢失。

队列提供了一种一步通信协议,这意味着消息的发送者和接收者不需要同时于消息保持联系,发送者的消息会存储在队列中,直到接收者拿到它。 一般我们把消息的发送者称为生产者,消息的接收者称为消费者。由于生产者和消费者之间是不透明的,他们靠中间的纽带-队列来联系,那么在队列中,是消费者占主动还是生产者占主动呢,其实根据不同的获取消息的方式可以分为 pull or push 着两种。按字面上的理解,就是pull 是消费者需要自己控制去队列拉取消息,而push则是生产者占主动位置,将产生的消息push 给消费者,而这种push 可以点对点,也可以是一对多,而这种一对多的模式就是我们常说的广播模式

在分布式系统中,消息中间件是非常重要的组件,主要解决应用耦合,异步消息,流量削峰等问题。

常用的消息队列中间件有 activeMQ,RabbitMQ,ZeroMQ,Kafka,MetaMQ,RocketMQ
(可参考 https://mp.weixin.qq.com/s/ad7jibTb5nTzh3nDQYKFeg? 觉得这篇文章写得很不错也很详细)

这次我主要写的是kafka 这个消息中间件,kafka 是采用pull 这种模式来消费信息的,生产者将消息放入队列中,而消费者可以通过epull 方法获取消息来消费,下面还是先说下kafka 的几个关键概念吧

kafka 的基本介绍

Kafka是最初由Linkedin公司开发,是一个分布式、分区的、多副本的、多订阅者,基于zookeeper协调的分布式日志系统(也可以当做MQ系统),常见可以用于web/nginx日志、访问日志,消息服务等等,Linkedin于2010年贡献给了Apache基金会并成为顶级开源项目

主要应用场景是:日志收集系统和消息系统。

Kafka主要设计目标如下:

  • 以时间复杂度为O(1)的方式提供消息持久化能力,即使对TB级以上数据也能保证常数时间的访问性能。

  • 高吞吐率。即使在非常廉价的商用机器上也能做到单机支持每秒100K条消息的传输。

  • 支持Kafka Server间的消息分区,及分布式消费,同时保证每个partition内的消息顺序传输。

同时支持离线数据处理和实时数据处理。

Kafka的设计原理分析

Kafka的设计原理

一个典型的kafka集群中包含若干producer,若干broker,若干consumer,以及一个Zookeeper集群。Kafka通过Zookeeper管理集群配置,选举leader,以及在consumer group发生变化时进行rebalance。producer使用push模式将消息发布到broker,consumer使用pull模式从broker订阅并消费消息。

Kafka专用术语:
  • Broker:消息中间件处理结点,一个Kafka节点就是一个broker,多个broker可以组成一个Kafka集群。

  • Topic:一类消息,Kafka集群能够同时负责多个topic的分发。

  • Partition:topic物理上的分组,一个topic可以分为多个partition,每个partition是一个有序的队列。

  • Segment:partition物理上由多个segment组成。

  • offset:每个partition都由一系列有序的、不可变的消息组成,这些消息被连续的追加到partition中。partition中的每个消息都有一个连续的序列号叫做offset,用于partition唯一标识一条消息。

  • Producer:负责发布消息到Kafka broker。

  • Consumer:消息消费者,向Kafka broker读取消息的客户端。

  • Consumer Group:每个Consumer属于一个特定的Consumer Group。

kafka 的消息传输的事务特点:
  • at most once :最多一次,这个和JMS中"非持久化"消息类似,发送一次,无论成败,将不会重发。消费者fetch消息,然后保存offset,然后处理消息;当client保存offset之后,但是在消息处理过程中出现了异常,导致部分消息未能继续处理。那么此后"未处理"的消息将不能被fetch到,这就是"at most once"
  • at least once :消息至少发送一次,如果消息未能接受成功,可能会重发,直到接收成功。消费者fetch消息,然后处理消息,然后保存offset。如果消息处理成功之后,但是在保存offset阶段zookeeper异常导致保存操作未能执行成功,这就导致接下来再次fetch时可能获得上次已经处理过的消息,这就是"at least once",原因offset没有及时的提交给zookeeper,zookeeper恢复正常还是之前offset状态。
  • exactly once :消息只会发送一次。kafka中并没有严格的去实现(基于2阶段提交),我们认为这种策略在kafka中是没有必要的。
Kafka消息存储格式

Topic & Partition

一个topic可以认为一个一类消息,每个topic将被分成多个partition,每个partition在存储层面是append log文件。

在Kafka文件存储中,同一个topic下有多个不同partition,每个partition为一个目录,partiton命名规则为topic名称+有序序号,第一个partiton序号从0开始,序号最大值为partitions数量减1

每个partion(目录)相当于一个巨型文件被平均分配到多个大小相等segment(段)数据文件中。但每个段segment file消息数量不一定相等,这种特性方便old segment file快速被删除。

每个partiton只需要支持顺序读写就行了,segment文件生命周期由服务端配置参数决定。

这样做的好处就是能快速删除无用文件,有效提高磁盘利用率。

segment file组成:由2大部分组成,分别为index file和data file,此2个文件一一对应,成对出现,后缀".index"和“.log”分别表示为segment索引文件、数据文件.

segment文件命名规则:partion全局的第一个segment从0开始,后续每个segment文件名为上一个segment文件最后一条消息的offset值。数值最大为64位long大小,19位数字字符长度,没有数字用0填充。

partion segment
Kafka消息分组,消息消费原理

同一Topic的一条消息只能被同一个Consumer Group内的一个Consumer消费,但多个Consumer Group可同时消费这一消息。

消息消费原理

这是Kafka用来实现一个Topic消息的广播(发给所有的Consumer)和单播(发给某一个Consumer)的手段。一个Topic可以对应多个Consumer Group。如果需要实现广播,只要每个Consumer有一个独立的Group就可以了。要实现单播只要所有的Consumer在同一个Group里。用Consumer Group还可以将Consumer进行自由的分组而不需要多次发送消息到不同的Topic。

参考:

http://www.linkedkeeper.com/detail/blog.action?bid=1016&hmsr=toutiao.io&utm_medium=toutiao.io&utm_source=toutiao.io

相关文章

  • 从发布-订阅模式到消息队列

    发布-订阅模式 发布-订阅模式又称为观察者模式(网上也有很多说这两种模式区别,个人觉得区别不大),在发布-订阅模式...

  • 消息队列一

    消息队列有两种模式,一种是队列模式,一种订阅-发布模式. 队列模式就是一个点对点,生产者生产消息发入到队列,然后消...

  • Kafka简介

    概念 基于发布/订阅模式的分布式消息队列 分布式 基于发布和订阅模式的消息队列本身最新定位:分布式流式事件处理平台...

  • Redis消息队列(Message queues)

    Redis消息队列(Message queues) 场景 + 发布者订阅者模式:发布者生产消息放到队列里,多个监听...

  • RabbitMQ工作模式 - 路由模式(Direct 模式) -

    RabbitMQ路由模式大体上跟发布订阅模式一样,区别在于发布订阅模式将消息转发给所有绑定的队列,而路由模式将消息...

  • 为何要用Kafka实现消息系统

    消息系统非消息队列,Kafka具有消息队列和发布/订阅两种模式,两种传统的消息模式,但重要的是,Kafka同时兼容...

  • 基于TableStore构建简易海量Topic消息队列

    前言 消息队列,通常有两种场景,一种是发布者订阅模式,一种是生产者消费者模式。发布者订阅模式,即发布者生产消息放入...

  • MQ

    1. 消息队列的通信模型 点对点模式 发布/订阅 2.kafka使用场景 消息队列 追踪网站活动 Metrics(...

  • rabbitmq简介

    消息模型 消费者(consumer)订阅某个队列。生产者(producer)创建消息,然后发布到队列(queue)...

  • Java高频面试集-消息队列MQ

    学习 1、MQ消息队列分类有哪些? 消息队列分类:点对点和发布/订阅两种: 1.1、点对点: 支持此模式:rabb...

网友评论

      本文标题:从发布-订阅模式到消息队列

      本文链接:https://www.haomeiwen.com/subject/wempgftx.html