• 【kafka微服务实践】手把手教你搭建一个基于docker的kafka的微服务


    1、kafka简介

    Kafka最初于2011年在 LinkedIn 开发,自那时起经历了很多改进,后来捐献给Apache基金,如今发展成为一个完整的平台,采用Scala和Java开发的开源流处理软件。

    Kafka 是我工作多年使用最多的消息中间件 ,特点是拥有巨大吞吐量(数百万/秒),作为当下最流行的分布式,可水平扩展,可容错的“消息系统”。

    2020年,Kafka 依旧炙手可热,一线大公司即使不用Kafka,但是自研产品也都是基于Kafka,或者完全借鉴Kafka设计思想,理论上来说,如果你还没熟练掌握一个MQ框架,Kafka绝对是不错的选择。

    kafka中重要关键字

    构建一个 Kafka cluster 首先需要理解 topics, producers, consumers, and brokers 的概念,弄懂这几个概念才能更好地了解Kafka的工作机制。
    Producer:消息的生产方,如支付系统确认用户已经支付,支付系统要通知订单系统和物流系统,支付系统就是生产者。

    Consumer:消费的接收方,Producer 的案例中,物流系统就是消费方,前两个都比较简单,我就不多说了。

    Topic:每条发布到MQ集群的消息都有一个类别,这个类别被称为topic,可以理解成一类消息的名字。所有的消息都已topic作为单位进行归类。

    Partition:Kafka 物理上分区的概念,每个 Topic 会分散在一个或多个 Partition。一个 Topic 的数据太大了,就分成小片,Kafka 为分区引入多副本模型,副本之间采用“一个leader多follower”的设计,通过多副本实现故障自动转移,保证可用性。

    Broker:可以理解成一个服务器的节点,集群包含一个或多个服务器,这种服务器被称为 broker。对应用来说,生产者把消费发出去了,就不管了。消费者慢条斯理地按照自己的速率来消费。这段时间可能有大量消息产生,消费者压力还是在一定范围内。做生产者和消费者之间解耦的就是一个缓存服务broker。

    Kafka Cluster:集群就是 Broker 的集合,多个 Broker 组成一个高可用集群。
    Producer 与 Consumer的关系
    在这里插入图片描述
    topic 和 Partition 的关系

    一个 topic 可以分别存储到多个 Partition,每个 Partition 有序的。

    在这里插入图片描述

    为什么选择kafka呢

    Kafka 特有的功能:

    1、相比同类中间件 RabbitMQ or ActiveMQ,Kafka 支持批量拉取消息,大大增加了Kafka的消息吞吐量

    2、支持多种发送场景:

    1)发送并忘记。

    2)同步发送 。

    3)异步发送+回调函数。

    3种方式虽然在时间上有所差别,但并不是说时间越快的越好,具体使用哪种方式要看具体的业务场景,比如业务要求消息必须是按顺序发送,可以使用第2种同步发送,并且只能在一个partation上。如果业务只关心消息的吞吐量,容许少量消息发送失败,也不关注消息的发送顺序,那么可以使用发送并忘记的方式。如果业务需要知道消息发送是否成功,并且对消息的顺序不关心,那么可以用异步+回调的方式来发送消息

    3、分布式可高可扩展。Kafka 集群可以透明的扩展,增加新的服务器进集群。

    只说了 Kafka 的优势,那别的同类产品就不好了吗?当然不是,存在即真理,每个产品能生存下来,一定有它自己的优势,比如 RabbitMQ,在吞吐量方面稍逊于 Kafka ,但是他们的出发点不一样,RabbitMQ 支持对消息的可靠的传递,支持事务,不支持批量的操作,技术选型中,选择最适合你的,你最了解熟悉的。
    kafka优势总结 :
    分布式 高性能 持久性和扩展性
    支持多分区 高吞吐量 数据可持久化
    支持多副本 低延迟 容错性高
    支持多订阅者 高并发 支持水平在线扩展
    基于ZooKeeper调度 时间复杂度为O(1) 消息分发自动平衡

    2、搭建kafka服务

    方式一:手动搭建

    百度 :安装 kafka 安装,出来一堆的教程,
    1)Kafka安装教程
    2)kafka入门、安装详解
    3) kafka 安装部署教程
    总结 :手动安装大致过程 :官网下载二进制文件,需要修改配置文件,手动启动并停止,
    过程感受 :设置的步骤很多,对机器的依赖比较大,过程较为繁琐,也能走得通,配置集群时就会有设置步骤较多

    方式二 :docker微服务方式

    百度:基于docker安装 kafka 安装,找到几个较为好的教程
    1)基于docker搭建kafka
    2)

    步骤1:拉取镜像

    在docker上安装kafka需要先安装zookeeper,我们可以使用docker pull先把zookeeper和kafka的镜像拉取下来

    docker pull zookeeper
    docker pull bitnami/kafka
    
    • 1
    • 2

    步骤2:运行zookeeper

    docker run -d --name zookeeper -p 2181:2181 -t registry.test.com/library/zookeeper
    
    • 1

    步骤3:运行kafka

    docker run -d --name kafka -p 9092:9092 -e KAFKA_BROKER_ID=0 -e KAFKA_ZOOKEEPER_CONNECT=10.10.0.0:2181 -e ALLOW_PLAINTEXT_LISTENER=yes -e KAFKA_ADVERTISED_LISTENERS=PLAINTEXT://10.10.0.0:9092 -e KAFKA_LISTENERS=PLAINTEXT://0.0.0.0:9092 -t bitnami/kafka
    
    • 1

    步骤4:创建topic

    # 查询kafka容器ID
    docker ps |grep kafka
    # 进入kafka容器
    docker exec -it 53cc0e000953 /bin/bash
    # 创建topic mykafkadk
    /opt/kafka/bin/kafka-topics.sh --zookeeper 10.160.32.28:2181 --create --replication-factor 1 --partitions 1 --topic mykafkadk
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    步骤5:创建生产者和消费者

    cd /opt/kafka
    
    ./bin/kafka-console-producer.sh --broker-list 192.168.1.111:9092 --topic test
    
    ./bin/kafka-console-consumer.sh --bootstrap-server 192.168.1.111:9092 --topic test --from-beginning
    
    • 1
    • 2
    • 3
    • 4
    • 5

    示例:

    请添加图片描述

    运行第二个kafka微服务的命令

    运行安装第二个kafka时需要修改如下参数:

    1) name

    2)端口号

    3)KAFKA_BROKER_ID

    docker run -d --name kafka1 -p 9093:9093 -e KAFKA_BROKER_ID=2 -e KAFKA_ZOOKEEPER_CONNECT=10.10.0.0:2181 -e ALLOW_PLAINTEXT_LISTENER=yes KAFKA_ADVERTISED_LISTENERS=PLAINTEXT://10.10.0.0:9093 -e KAFKA_LISTENERS=PLAINTEXT://0.0.0.0:9093 -t bitnami/kafka
    
    • 1

    创建两个kafka公用的topic:

    /opt/kafka/bin/kafka-console-producer.sh --broker-list 10.160.32.28:9093 --topic kafkatesttopic1
    
    • 1

    发送消息:

    /opt/kafka/bin/kafka-console-producer.sh --broker-list 10.160.32.28:9093 --topic kafkatesttopic1
    
    • 1

    消费消息 :

    /opt/kafka/bin/kafka-console-consumer.sh --bootstrap-server 10.160.32.28:9093 --topic kafkatesttopic1 --from-beginning
    
    • 1

    docker 内部配置集群kafka搭建

    1.文件目录

    -根目录
        -dockerData 目录
            -kafka-jiqun 目录
                -docker-compose.yaml 集群启动配置文件
                -start.sh 启动器
                -stop.sh  停止删除器  
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    2.编辑文件docker-compose.yaml 根据你的情况进行修改 主要是-目录-ip-端口

    针对一个zookeeper情况:
    *********************************************************************************
    version: "3"
    
    services:
      zookeeper:
        image: zookeeper
        build:
          context: ./
        container_name: zookeeper-jiqun
        ports:
          - 2182:2181
        volumes:
          - /dockerData/kafka-jiqun/zookeeper/data:/data
          - /dockerData/kafka-jiqun/zookeeper/datalog:/datalog
          - /dockerData/kafka-jiqun/zookeeper/logs:/logs
        restart: always
    
      kafka_node_0:
        depends_on:
          - zookeeper
        build:
          context: ./
        container_name: kafka-node-0
        image: wurstmeister/kafka
        environment:
          KAFKA_BROKER_ID: 0
          KAFKA_ZOOKEEPER_CONNECT: 192.168.19.132:2182
          KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://192.168.19.132:9093
          KAFKA_LISTENERS: PLAINTEXT://0.0.0.0:9093
          KAFKA_NUM_PARTITIONS: 3
          KAFKA_DEFAULT_REPLICATION_FACTOR: 2
        ports:
          - 9093:9093
        volumes:
          - /dockerData/kafka-jiqun/kafka/node_0:/kafka
        restart: unless-stopped
    
      kafka_node_1:
        depends_on:
          - kafka_node_0
        build:
          context: ./
        container_name: kafka-node-1
        image: wurstmeister/kafka
        environment:
          KAFKA_BROKER_ID: 1
          KAFKA_ZOOKEEPER_CONNECT: 192.168.19.132:2182
          KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://192.168.19.132:9094
          KAFKA_LISTENERS: PLAINTEXT://0.0.0.0:9094
          KAFKA_NUM_PARTITIONS: 3
          KAFKA_DEFAULT_REPLICATION_FACTOR: 2
        ports:
          - 9094:9094
        volumes:
          - /dockerData/kafka-jiqun/kafka/node_1:/kafka
        restart: unless-stopped
    
      kafka_node_2:
        depends_on:
          - kafka_node_1
        build:
          context: ./
        container_name: kafka-node-2
        image: wurstmeister/kafka
        environment:
          KAFKA_BROKER_ID: 2
          KAFKA_ZOOKEEPER_CONNECT: 192.168.19.132:2182
          KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://192.168.19.132:9095
          KAFKA_LISTENERS: PLAINTEXT://0.0.0.0:9095
          KAFKA_NUM_PARTITIONS: 3
          KAFKA_DEFAULT_REPLICATION_FACTOR: 2
        ports:
          - 9095:9095
        volumes:
          - /dockerData/kafka-jiqun/kafka/node_2:/kafka
        restart: unless-stopped
    *********************************************************************************
       
    
    针对多个zookeeper:
    ********************************************************************************* 
    version: "3"
    services:
      zookeeper-node-0:
        image: zookeeper
        build:
          context: ./
        container_name: zookeeper-node-0
        ports:
          - 2182:2181
        volumes:
          - /dockerData/kafka-jiqun/zookeeper/zookeeper-node-0/data:/data
          - /dockerData/kafka-jiqun/zookeeper/zookeeper-node-0/datalog:/datalog
          - /dockerData/kafka-jiqun/zookeeper/zookeeper-node-0/logs:/logs
        restart: always
      zookeeper-node-1:
        image: zookeeper
        build:
          context: ./
        container_name: zookeeper-node-1
        ports:
          - 2183:2181
        volumes:
          - /dockerData/kafka-jiqun/zookeeper/zookeeper-node-1/data:/data
          - /dockerData/kafka-jiqun/zookeeper/zookeeper-node-1/datalog:/datalog
          - /dockerData/kafka-jiqun/zookeeper/zookeeper-node-1/logs:/logs
        restart: always
      zookeeper-node-2:
        image: zookeeper
        build:
          context: ./
        container_name: zookeeper-node-2
        ports:
          - 2184:2181
        volumes:
          - /dockerData/kafka-jiqun/zookeeper/zookeeper-node-2/data:/data
          - /dockerData/kafka-jiqun/zookeeper/zookeeper-node-2/datalog:/datalog
          - /dockerData/kafka-jiqun/zookeeper/zookeeper-node-2/logs:/logs
        restart: always
    
      kafka_node_0:
        depends_on:
          - zookeeper-node-0
          - zookeeper-node-1
          - zookeeper-node-2
        build:
          context: ./
        container_name: kafka-node-0
        image: wurstmeister/kafka
        environment:
          KAFKA_BROKER_ID: 0
          KAFKA_ZOOKEEPER_CONNECT: 192.168.19.132:2182,192.168.19.132:2183,192.168.19.132:2184
          KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://192.168.19.132:9093
          KAFKA_LISTENERS: PLAINTEXT://0.0.0.0:9093
          KAFKA_NUM_PARTITIONS: 3
          KAFKA_DEFAULT_REPLICATION_FACTOR: 2
        ports:
          - 9093:9093
        volumes:
          - /dockerData/kafka-jiqun/kafka/node_0:/kafka
        restart: unless-stopped
    
      kafka_node_1:
        depends_on:
          - kafka_node_0
        build:
          context: ./
        container_name: kafka-node-1
        image: wurstmeister/kafka
        environment:
          KAFKA_BROKER_ID: 1
          KAFKA_ZOOKEEPER_CONNECT: 192.168.19.132:2182,192.168.19.132:2183,192.168.19.132:2184
          KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://192.168.19.132:9094
          KAFKA_LISTENERS: PLAINTEXT://0.0.0.0:9094
          KAFKA_NUM_PARTITIONS: 3
          KAFKA_DEFAULT_REPLICATION_FACTOR: 2
        ports:
          - 9094:9094
        volumes:
          - /dockerData/kafka-jiqun/kafka/node_1:/kafka
        restart: unless-stopped
    
      kafka_node_2:
        depends_on:
          - kafka_node_1
        build:
          context: ./
        container_name: kafka-node-2
        image: wurstmeister/kafka
        environment:
          KAFKA_BROKER_ID: 2
          KAFKA_ZOOKEEPER_CONNECT: 192.168.19.132:2182,192.168.19.132:2183,192.168.19.132:2184
          KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://192.168.19.132:9095
          KAFKA_LISTENERS: PLAINTEXT://0.0.0.0:9095
          KAFKA_NUM_PARTITIONS: 3
          KAFKA_DEFAULT_REPLICATION_FACTOR: 2
        ports:
          - 9095:9095
        volumes:
          - /dockerData/kafka-jiqun/kafka/node_2:/kafka
        restart: unless-stopped
    ********************************************************************************* 
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157
    • 158
    • 159
    • 160
    • 161
    • 162
    • 163
    • 164
    • 165
    • 166
    • 167
    • 168
    • 169
    • 170
    • 171
    • 172
    • 173
    • 174
    • 175
    • 176
    • 177
    • 178
    • 179
    • 180
    • 181
    • 182
    • 183
    • 184

    3.编辑start.sh启动器 这个不谢也没事就是不断的得写里面的命令

    #! /bin/bash
    sudo docker-compose up -d
    
    
    • 1
    • 2
    • 3

    4.编辑stop.sh停止-移除器 这个不谢也没事就是不断的得写里面的命令

    针对一个zookeeper的情况:
    ***************************************************
    #!/bin/bash
    sudo docker stop kafka-node-0
    sudo docker stop kafka-node-1
    sudo docker stop kafka-node-2
    sudo docker stop zookeeper-jiqun
    sudo docker rm -f kafka-node-0
    sudo docker rm -f kafka-node-1
    sudo docker rm -f kafka-node-2
    sudo docker rm -f zookeeper-jiqun
    ***************************************************
    针对多个zookeeper的情况:
    ***************************************************
    #!/bin/bash
    sudo docker stop kafka-node-0
    sudo docker stop kafka-node-1
    sudo docker stop kafka-node-2
    sudo docker stop zookeeper-node-0
    sudo docker stop zookeeper-node-1
    sudo docker stop zookeeper-node-2
    sudo docker rm -f kafka-node-0
    sudo docker rm -f kafka-node-1
    sudo docker rm -f kafka-node-2
    sudo docker rm -f zookeeper-node-0
    sudo docker rm -f zookeeper-node-1
    sudo docker rm -f zookeeper-node-2
    ***************************************************
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    5.检查docker-componse 是否存在

    命令:
    sudo docker-compose --version
    
    如果没有进行以下操作
    安装docker-componse:
    sudo  wget https://github.com/docker/compose/releases/download/1.23.0-rc3/docker-compose-Linux-x86_64
    
    移动:
    sudo  mv docker-compose-Linux-x86_64 /usr/local/bin/docker-compose
    
    授权:
    sudo chmod +x /usr/local/bin/docker-compose
    
    执行:
    sudo ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose
    
    验证:
    sudo docker-compose --version
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    6.上述没有问题 启动集群

    命令:
    sudo  bash start.sh
    
    • 1
    • 2

    7.上述没有问题 停止集群

    命令:
    sudo  bash stop.sh
    
    • 1
    • 2

    3、python连接kafka的简单实现

    Python 接 Kafka 的标准库,kafka-python 和 pykafka。kafka-python 使用的人多是比较成熟的库,kafka-python 并没有zk的支持。pykafka 是 Samsa 的升级版本,使用 samsa 连接zookeeper,生产者直接连接 kafka 服务器列表,消费者才用zookeeper。

    Python 连接 Kafka 简单实现

  • 相关阅读:
    千万级别的表分页查询非常慢,怎么办?
    【每日一题】逃离火灾
    JAVA小游戏 “拼图”
    ECS框架浅析
    linux开发技术栈
    如何进行Java项目的构建和部署?
    Java程序员不掌握SpringBoot怎么进大厂,你就想摆烂吗,还不来看看,卷死他们!
    推荐!十个平台工程工具助力开发人员提升效率和体验
    【计算机操作系统慕课版】第二章课后习题笔记(创作周年纪念版)
    Redis大白话(●三●)
  • 原文地址:https://blog.csdn.net/cy15625010944/article/details/126118569