当前使用的事件总线采用的是Kafka分布式消息队列来完成的,近来项目需要接入到事件总线中,故开启了kafka的学习之旅(之前一直在听说kafka这玩意儿,但是学习计划中还没有将它安排进去,借着这个机会学习kafka也算是弥补了这方面的一些遗憾~)

关于kafka是神马东西这里就不在累述了,网上的资料一大堆

下面分享一些自己对kafka的理解,如有不妥之处还望指出~

(1)何为分布式消息队列?有何特点?

1、一旦涉及到分布式这个概念,其就必须解决两个问题:可靠性和可扩展性。

kafka通过事件回溯机制来实现高可靠性:当出现一些不可预料的异常导致生产的消息没有被相应的消费者消费掉时,kafka可以进行回滚操作,将消息队列恢复到这个异常事件的地方让消费者可以重新消费,保证每个消息都有相应的消费者消费掉

kafka支持水平扩展,brocker(kafka集群上的一个或多个服务器)越多,集群的吞吐率越高,如果你觉得你的kafka不够用了,简单,加大集群规模,就像使用调节按钮一样简单方便

2、既然叫消息队列,那么它就有队列的特征,顺序、按个存取。保证事件能够按照规定的顺序被处理掉,就像挂号排队一样,一个个领号,在按顺序一个个处理

(2)那么为什么要用这个分布式消息队列呢?

大多数的应用都需要处理一些事件,例如某个用户点击了什么东西,这个动作要进行一些额外的处理,但是处理的行为定义在另外一个程序中(当系统框架大了之后这种行为很常见)。常规的解决方法就是调用接口

但是这么做有一个很明显的问题,两个应用之间产生了耦合,它们需要知道对方的存在,接口的调用方式是什么。

当系统不是很大的时候这么做并没有什么缺陷,反而会比较方便

但假如应用中要处理n个不同类型的事件,分别由n个不同的程序提供接口进行处理,在应用中必须要知道每个处理程序的调用方式,一方的修改会影响到另外一方。如果有n个应用中有n个事件需要n个程序来处理,互相调来调去,堆在一起很容易就变成了死亡代码

这时候独立的消息队列就可以很简单的解决这个问题,生产事件的应用只管往队列上发事件,不关心有没有人去处理,怎么处理,发了之后就不管了

而处理事件的程序从消息队列中取得事件,不用关心是谁发的,怎么发的

于是消息队列将整个系统都解耦了

之前讲到过,kafka中的消息都是按顺序,一个个存取的,那么问题来了:按顺序一个个处理的话,如果应用A要处理消息a,应用B要处理消息b,消息a排在消息b之前,现在应用A不处理消息a了,而应用B马上就要处理消息b,怎么解决?

其实很简单,kafka并不只有一个队列,不同应用发送的事件可以存放在不同的topic中而不互相影响,狭义上来讲可以将topic这个概念就看成是一个消息队列,而kafka中可以存在n个topic

(3)kafka的构架:

kafka由以下几个部分组成:

Brocker:Kafka集群包含一个或多个服务器,这种服务器被称为broker。生产者向Brocker发送事件,消费者从Brocker中拿事件

Topic:之前提到过,可以将topic看成是一个消息队列,每个事件都必须指定其要存在在哪个topic中(这里倒是可以当成事件的分类来看待),topic是存在于brocker之中的

Partition:每个topic都可以包含一个或者多个partition,顾名思义,就是分区的意思,这里和hadoop的mr程序的partitioner分区有些相似,可以将topic中的各个事件按照规则分开存放

Producer:即生产者,负责发送事件到kafka brocker

Consumer:即消费者,从kafka brocker读取事件

Consumer Group:每个Consumer属于一个特定的Consumer Group(可为每个Consumer指定group name,若不指定group name则属于默认的group)。

kafka通过Consumer Group来实现消息的广播和单播,一个事件发送到一个Consumer Group中,那么这个Group中只能有一个Consumer消费这个事件,但是其他的Consumer Group也可以由其中的一个Consumer来消费这个事件

示意图

如果要实现广播,让每个Consumer都能收到某个Topic中的事件,只要让各个Consumer处在不同的Consumer Group中即可;单播则是将所有的Consumer放在一个Consumer Group中

kafka构架图

图中的zk起到的作用就是负载均衡,将集群中的变化及时同步到各个节点中,保证集群是一致的

(4)kafka下载、运行测试

Apache下载地址

进入之后选择Binary Downloads

选择任意的一个版本即可(官方建议下载2.10)

下载下来的tgz包lib目录中有开发kafka客户端程序的相关jar包

将其解压缩之后直接就可使用(因为公司已有kafka集群,可以仅仅拿来当客户端来连接测试使用)

进入kafka目录执行以下命令:

显示kafka中的topic列表

bin/kafka-topics.sh –list –zookeeper 54.223.171.230:2181

54.223.171.230:2181为集群zk节点对应的hostname:port

生产事件

bin/kafka-console-producer.sh –broker-list amazontest:9092 –topic omni

amazontest:9092–为brocker的hostname:port

omni–为要发送到的topic

消费事件

bin/kafka-console-consumer.sh –zookeeper 54.223.171.230:2181 –topic omni –from-beginning

54.223.171.230:2181–消费事件要从zk中获得,所以使用zk的地址

omni–从指定的topic中获得事件

运行过程中出现一个异常,如下图:

原因是我在本地连接远程kafka集群,而amazontest是定义在程序服务器上的主机名,本地并不知道这个hostname映射到哪个ip,在/etc/hosts中加入此映射关系即可正常

最后推荐一篇文章(上面的图都是偷这里面的)

Kafka剖析(一):Kafka背景及架构介绍

初识Kafka:构架、生产消费模型以及其他相关概念的更多相关文章

  1. Python并发编程-生产消费模型

    生产消费模型初步 #产生两个子进程,Queue可以在子进程之间传递消息 from multiprocessing import Queue,Process import random import t ...

  2. kafka之三:kafka java 生产消费程序demo示例

    kafka是吞吐量巨大的一个消息系统,它是用scala写的,和普通的消息的生产消费还有所不同,写了个demo程序供大家参考.kafka的安装请参考官方文档. 首先我们需要新建一个maven项目,然后在 ...

  3. Python学习之路并发编程--信号量、事件、队列及生产消费模型

    1. 信号量 对于多进程来说,多个进程同时修改数据,就可能出现安全隐患,所以引入了锁,这一机制,但锁只能有一把来控制一个的开关,当你需要几把锁的时候,就可能用到信号量的概念.他是用了锁的原理,内置了一 ...

  4. 并发编程:生产消费模型、死锁与Rlock、线程、守护线程、信号量、锁

    一.生产者消费者模型1 二.生产者消费者模型2 三.守护线程 四.常用方法 五.启动线程的另一种方式 六.锁 七.锁死 八.死锁 九.单个锁能不能死锁 十.信号旗 一.生产者消费者模型1 import ...

  5. Day9 进程同步锁 进程队列 进程池 生产消费模型 进程池 paramike模块

    进程同步锁: 当运行程序的时候,有可能你的程序同时开多个进程,开进程的时候会将多个执行结果打印出来,这样的话打印的信息都是错乱的,怎么保证打印信息是有序的呢? 其实也就是相当于让进程独享资源. fro ...

  6. RocketMQ生产消费模型选择

    一. 生产者,根据某个标识将消息放到同一个队列中 在发送消息时,使用SelectMessageQueueByHash,该类根据传入进去的arg,进行hash计算,将消息分配到相应的队列中. publi ...

  7. JAVA 多线程制作大球吃小球 一、实现球的自动生成及运动 生产消费模型

    前几天用多线程实现了创建小球并移动,想到大鱼吃小鱼,便突发奇想要写一个大球吃小球.首先第一步自然是先把界面弄好啦 public class BallUI extends JPanel { privat ...

  8. 并发编程: 生产消费模型、死锁与Rlock、线程、守护线程、信号量、锁

    一.守护进程 二.互斥锁 三.抢票 四.进程间通讯 五.进程间通讯2 一.守护进程 """ 进程间通讯的另一种方式 使用queue queue 队列 队列的特点: 先进的 ...

  9. 使用wait/notify实现生产消费模型

    public class A { private Deque<Integer> list = new LinkedList<>(); private int max = 10; ...

随机推荐

  1. Oracle expdp

    exp                客户端工具expdp             服务端工具 expdp help=y  帮助命令directory         导出目录逻辑名 --查询默认数据 ...

  2. django自带的orm增删改

    # 转载请留言联系 模型管理器 模型管理器:objects属性 每个模型类默认都有一个叫 objects 的类属性,它由django自动生成 我们把 objects 称为 模型管理器,其类型为: dj ...

  3. Ansi,UTF8,Unicode,ASCII编码的区别 ---我看完了 明白了很多

    来自:http://blog.csdn.net/xiongxiao/article/details/3741731 ------------------------------------------ ...

  4. happens-before规则

    happens-before原则: happens-before它是判断数据是否存在竞争.线程是否安全的主要依据.为了保证线程安全我们可以让2个操作具有happens-before关系.(JDK5 开 ...

  5. java.lang.NumberFormatException: multiple points 异常

    平时使用SimpleDateFormat的时候都是在单线程的情况下使用的,今天在改写别人的代码,发现每个类中都会写大量的SimpleDateFormat实例.作为一个程序特有的洁癖开始对代码进行优化. ...

  6. Selenium2+python自动化60-异常后截图(screenshot)【转载】

    前言 在执行用例过程中由于是无人值守的,用例运行报错的时候,我们希望能对当前屏幕截图,留下证据. 在写用例的时候,最后一步是断言,可以把截图的动作放在断言这里,那么如何在断言失败后截图呢? 一.截图方 ...

  7. java两种实现二分查找方式

    二分查找法适用于 升序排列的数组,如果你所要操作的数组不是升序排序的,那么请用排序算法,排序一下. 说明:使用二分查找法相比顺序查找  节约了时间的开销,但是增加了空间使用.因为需要动态记录 起始索引 ...

  8. 团队开发中git分支的使用

    1.Github上保持两个分支:master和develop. master是主分支,对项目进行tag或发布版本等操作,都必须在该分支上进行.最好设为不可提交只能合并的. develop是开发分支,从 ...

  9. JAVA MAC 配置

    1下载对应的JDK,并安装 查看是否成功 java -version 2配置环境变量 sudo vim /etc/profile 入一下内容: JAVA_HOME="/Library/Jav ...

  10. (八)for语句

    (1)语法 (2)批量ping主机 这里有个重点就是把每次ping主机的动作放到后台运行 #!/bin/bash >ip.txt for i in {1..254} do ip=192.168. ...