python使用kafka以及docker部署

模块安装

1.在使用python调用kafka的时候我选择的模块是confluent_kafka这个模块,首先安装模块

pip install confluent_kafka

模块使用

我们知道kafka是一个消息队列,那么就必须有一个生产者和消费者,生产者负责向kafka队列中放入消息而消费者负责从kafka队列中获取消息,并且执行消息相关任务,所以我们就要基于confluent_kafka有一个生产者和消费者

生产者代码

from confluent_kafka import Producer

producer = Producer({'bootstrap.servers': bootstrap_servers})
producer.produce(topic, key=key_bytes, value=message)
producer.flush()

# 上面是一个生产者实例代码
# 1.从confluent_kafka从该模块中导入我们的生产者类Producer
# 2.我们生产者需要指定我们kafka的IP地址和端口,bootstrap_servers就我们IP+端口,kafka的默认端口
    是9092,我们本地这个参数就是"localhost:9092",这样python代码会成功连接我们的kafka

# 3.我们连接kafka之后就要发送消息到kafka中,这个时候就要注意我们需要填写的参数
    # topic:kafka的主题,kafka的队列中可以创建多个主题,不同主题可以理解为不同的通道
    # key  我们发送消息的key,可以理解为python字典的key,可以做判断
    # Value  就是我们发送的消息,我们可以通过key来判断同一个主题中是否是我们需要消费的消息

消费者代码

from confluent_kafka import Consumer
def consume(topic):
    c = Consumer({
        'bootstrap.servers': bootstrap_servers,
        'group.id': '3',  # 消费者组ID,不同于消费者2的组ID
        'auto.offset.reset': 'earliest'  # 从最早的消息开始消费
    })
    c.subscribe([topic])
    while True:
        msg = c.poll(timeout=1.0)
        if msg is None:
            continue
        if msg.error():
            print("消费错误: {}".format(msg.error()))
            continue
        print('消费者1接收到消息: {}'.format(msg.value().decode('utf-8')))
        key = msg.key().decode()
        if key == '127.0.0.1':
            print('消费者1接收到消息: {}'.format(msg.value().decode('utf-8')))


# 同样的我们需要导入我们消费者类

# 1.我们消费者对象产生的时候注意几个参数
    # bootstrap.servers  kafka的IP:端口
    # group.id  消费者组IP,在同一个TOPIC中,不同的组id的消费者他们的消费是不会互相影响的
    # auto.offset.reset  消费逻辑,earliest代表从最早的消息开始消费,latest表示从最新的开始消   费,这两个可以这么理解,当我们消费者还没有启动的时候,如果我们生产者向队列中生产消息,如果参数是earliest,那么会从生产者丢入的第一个消息开始消费,如果是latest他只会消费他启动以后生产者生产的消息
# 2.c.subscribe([topic]) 就是去消费指定的主题消息
# 3.c.poll(timeout=1.0) 每隔一秒去消费一次,如果没有消费消息会堵塞住,等待队列中有消息

以上是我们的生产者与消费者大概就是这样的,这其中最关键的就是主题,我们不管是生产还是消费的时候都要指定一个主题,当生产者与消费者在同一个主题他们在能真正的完成生产与消费,关于创建主题,我们可以通过kafka自有的命令来创建主题,如下:

kafka自有创建主题

windows系统为例:

创建主题:

首先我们要进入我们kafka的安装目录下使用:

.\bin\windows\kafka-topics.bat --create --bootstrap-server localhost:9092 --replication-factor 1 --partitions 1 --topic test_topic

这个命令的意思是我们使用bat文件启动kafka,使用的配置文件是server.properties这个配置文件,所以我们可以改变这个配置文件来修改我们kafka启动配置,可以看一些文件的参数

kafka的配置文件

server.properties

我们主要看一些关键参数

############################# Socket Server Settings #############################

# The address the socket server listens on. If not configured, the host name will be equal to the value of
# java.net.InetAddress.getCanonicalHostName(), with PLAINTEXT listener name, and port 9092.
#   FORMAT:
#     listeners = listener_name://host_name:port
#   EXAMPLE:
#     listeners = PLAINTEXT://your.host.name:9092
#listeners=PLAINTEXT://:9092

# Listener name, hostname and port the broker will advertise to clients.
# If not set, it uses the value for "listeners".
#advertised.listeners=PLAINTEXT://your.host.name:9092

这一部分表示的是kafka的监听,我们如果想要外部机器访问我们的kafka就需要配置advertised.listeners这个参数为我们服务器的地址,否则我们通过python是无法向kafka生产消息,会直接报错

############################# Log Basics #############################

# A comma separated list of directories under which to store log files
log.dirs=C:\\kafka\\kafka_2.13-3.2.1\\logs

# The default number of log partitions per topic. More partitions allow greater
# parallelism for consumption, but this will also result in more files across
# the brokers.
num.partitions=1

log.dirs这一部分主要是我们kafka日志的存放位置,我们可以进行修改

num.partitions=1 这一部分主要是我们kafka的默认分区数量,kafka的分区其实可以理解为帮助我们提升消费的速度,当我们分区数量不为1的时候,生产者生产的消息会放入我们该topic下的不同分区,我们可以用多个消费者去消费不同分区的内容,这样可以起到一个并发消费,但是因为分区消费的顺序是没办法控制的,所以只适合无序的生产消费

############################# Internal Topic Settings  #############################
# The replication factor for the group metadata internal topics "__consumer_offsets" and "__transaction_state"
# For anything other than development testing, a value greater than 1 is recommended to ensure availability such as 3.
offsets.topic.replication.factor=1

这个表示我们每个分区复制的份数

上面大概是一些重要的配置,修改这些参数就可以更改我们kafka启动后的配置

封装代码

kafka支持生产者,消费者,创建主题,那么我们也可以使用confluent_kafka来实现这些

代码如下:

from confluent_kafka import Producer
from confluent_kafka.admin import AdminClient, NewTopic

bootstrap_servers = "127.0.0.1:9092"


class BaseKafka(object):
    def __init__(self):
        self.producer = Producer({'bootstrap.servers': bootstrap_servers})
        self.admin_client = AdminClient({"bootstrap.servers": bootstrap_servers})

    def send_message(self, topic, key, message):
        key_bytes = key.encode('utf-8')
        self.producer.produce(topic, key=key_bytes, value=message)
        self.producer.flush()

    def create_topic(self, topic,num_partitions=1,replication_factor=1):
        """创建kafka topic"""

        # 定义要创建的主题及其配置,主题名,分区数量以及分区复制的份数
        new_topic = NewTopic(topic, num_partitions=num_partitions, replication_factor=replication_factor)

        # 创建主题
        fs = self.admin_client.create_topics([new_topic])

        # 等待创建完成
        for topic, future in fs.items():
            try:
                future.result()  # 等待直到主题创建完成或抛出异常
            except Exception as e:
                raise e

    def check_topic(self):

        # 获取 Kafka 集群中的所有 topic
        topics = self.admin_client.list_topics().topics

        # 返回所有 topic 名称
        topic_list = []
        for topic_name in topics:
            topic_list.append(topic_name)
        return topic_list

docker安装kafka

我们选择使用docker-compose.yml来安装kafka

version: '2.1'

services:
  zoo1:
    image: zookeeper:3.4.9
    hostname: zoo1
    ports:
      - "2181:2181"
    environment:
      ZOO_MY_ID: 1
      ZOO_PORT: 2181
      ZOO_SERVERS: server.1=zoo1:2888:3888
    volumes:
      - ./zk-single-kafka-single/zoo1/data:/data
      - ./zk-single-kafka-single/zoo1/datalog:/datalog

  kafka1:
    image: confluentinc/cp-kafka:5.3.1
    hostname: kafka1
    ports:
      - "9092:9092"
    environment:
      KAFKA_ADVERTISED_LISTENERS: LISTENER_DOCKER_INTERNAL://kafka1:19092,LISTENER_DOCKER_EXTERNAL://${DOCKER_HOST_IP:-127.0.0.1}:9092
      KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: LISTENER_DOCKER_INTERNAL:PLAINTEXT,LISTENER_DOCKER_EXTERNAL:PLAINTEXT
      KAFKA_INTER_BROKER_LISTENER_NAME: LISTENER_DOCKER_INTERNAL
      KAFKA_ZOOKEEPER_CONNECT: "zoo1:2181"
      KAFKA_BROKER_ID: 1
      KAFKA_LOG4J_LOGGERS: "kafka.controller=INFO,kafka.producer.async.DefaultEventHandler=INFO,state.change.logger=INFO"
      KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1

    volumes:
      - ./zk-single-kafka-single/kafka1/data:/var/lib/kafka/data
    depends_on:
      - zoo1

# LISTENER_DOCKER_INTERNAL://kafka1:19092,LISTENER_DOCKER_EXTERNAL://${DOCKER_HOST_IP:-127.0.0.1}:9092

这个参数是比较重要的,如果我们想要外部访问我们的kafka一定要将这个参数设置为我们服务器的地址

  • 27
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值