Kafka Producer/Consumer 关系解释及测试demo

Producer/Consumer

Kafka的生产者(Producer)和消费者(Consumer)的关系,可以通过一个餐厅的例子来形象地说明。

1. 餐厅的故事

想象一个忙碌的餐厅,这里有:

  • 厨师(Producers):负责准备美味的菜肴。
  • 服务台(Kafka Topic):菜肴准备好后,厨师会将它们放到服务台上,服务台有多个部分,每部分代表一个不同类型的菜(即Kafka中的不同Partition)。
  • 服务员(Consumers):负责从服务台上取走菜肴,并将它们送到顾客手中。

在这个餐厅中,有时候会有特别多的订单,厨师需要快速高效地准备菜肴。每当一道菜准备好,他们就会把它放到对应的部分在服务台上。服务台非常长,可以容纳很多菜肴,让不同的服务员能够同时服务多个顾客,提高效率。

2. Kafka的工作方式

  • Producers(厨师):在Kafka中,生产者的角色是发布消息到Topic中。就像厨师准备好菜肴后,会将它们放到服务台的对应部分。
  • Kafka Topic(服务台):Topic是消息的分类,可以细分为多个Partitions(服务台的多个部分),这样可以提高并行处理的能力。每个Partition都是一个独立的队列。
  • Consumers(服务员):消费者从Topic中读取消息。如果有多个消费者在同一个Consumer Group中,它们可以像一队服务员那样协作,每个人负责从服务台的一部分取菜,这样可以更快地服务所有顾客。每个消费者负责读取特定Partition中的消息,确保每条消息都能被及时处理。

3. 生动的场景

假设一天晚上,餐厅接到了一个大型宴会的预订,需要同时准备多道菜。这时,厨师们(Producers)开始忙碌起来,每准备好一道菜,就会放到服务台(Topic)的指定位置(Partition)。服务员们(Consumers)各自负责一部分服务台,快速地将菜肴送到顾客手中。

在这个过程中,如果某一部分的菜准备得特别快,服务台上的这一部分就会堆积更多的菜肴。负责这一部分的服务员需要加快速度,以确保所有的菜肴都能及时送出。这就像在Kafka中,如果某个Partition的消息积压,负责这个Partition的消费者就需要更快地处理消息,以防止延迟。

通过这个例子,我们可以看到,Kafka的Producer和Consumer之间是如何通过Topic(服务台)和Partition(服务台的不同部分)协作的,以实现高效、可靠的消息处理。

4. 测试Demo

4.1 KafkaProducer

from kafka import KafkaProducer, KafkaConsumer
from kafka.errors import kafka_errors
import traceback
import json
import time

import logging

logging.basicConfig(level=logging.INFO, format='%(asctime)s %(levelname)s %(message)s')

def process():
    # Kafka配置,需自行修改
    bootstrap_servers = ['ip:port']
    producer_topic = 'XXX_topic'

    # Kafka生产者
    producer = KafkaProducer(
                bootstrap_servers=bootstrap_servers,
                value_serializer=lambda m: json.dumps(m).encode('utf-8'),
                api_version=(1,0,0)
            )

    data = {
        "task_id": 1,
        "image_path": "XXX",
        "video_path": "XXX",
        "guidence_text": "XXX",
    }

    # Kafka请求监听
    try:
        res = data

        # 发送结果到Kafka
        producer.send(producer_topic, res)
        logging.info(f"send data to {producer_topic}")
        time.sleep(3)
    except Exception as e:
        # 记录错误日志
        logging.error(f"Error processing kafka request: {e}")


if __name__ == "__main__":
    process()

4.2 KafkaConsumer

from kafka import KafkaConsumer
import json
import logging

logging.basicConfig(level=logging.INFO, format='%(asctime)s %(levelname)s %(message)s')

def consume_messages():
    # Kafka配置
    bootstrap_servers = ['ip:port']
    consumer_topic = 'XXX'
    consumer_group = 'XXX'

    # Kafka消费者
    consumer = KafkaConsumer(
        consumer_topic,
        bootstrap_servers=bootstrap_servers,
        group_id=consumer_group,
        # auto_offset_reset='earliest',  # 从最早的消息开始读取
        auto_offset_reset= "latest",
        value_deserializer=lambda m: json.loads(m.decode('utf-8'))  # 解码JSON格式的消息
    )

    logging.info(f"Started consuming messages from {consumer_topic}")

    # 消费消息
    try:
        for message in consumer:
            msg = message.value
            logging.info(f"Received message: {msg}")
            print(f"msg:{msg}")

    except KeyboardInterrupt:
        logging.info("Stopping consumer...")
    except Exception as e:
        logging.error(f"Error while consuming messages: {e}")
    finally:
        consumer.close()

if __name__ == "__main__":
    consume_messages()

  • 8
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
好的,根据您提供的代码,这是一个使用Kafka实现消息生产者和消费者的Demo。代码中的producer_demo和consumer_demo函数目前为空,需要我们填充代码来实现生产者和消费者的功能。 下面是完整代码: ```python from kafka import KafkaProducer, KafkaConsumer from kafka.errors import kafka_errors import traceback import json # 生产者函数 def producer_demo(): try: # 创建KafkaProducer实例 producer = KafkaProducer(bootstrap_servers=['localhost:9092']) # 发送三条消息 for i in range(3): data = {'count_num': i} # 转换为JSON格式并发送 producer.send('test', json.dumps(data).encode('utf-8')) print("send", i) # 关闭连接 producer.close() except kafka_errors.KafkaError: traceback.print_exc() # 消费者函数 def consumer_demo(): try: # 创建KafkaConsumer实例 consumer = KafkaConsumer('test', bootstrap_servers=['localhost:9092']) # 循环消费消息 for msg in consumer: # 解析消息的key和value key = msg.key.decode('utf-8') value = json.loads(msg.value.decode('utf-8')) print(f"receive, key: {key}, value: {value['count_num']}") # 关闭连接 consumer.close() except kafka_errors.KafkaError: traceback.print_exc() # 先执行消费者函数 consumer_demo() # 再执行生产者函数 producer_demo() ``` 以上代码中,我们使用了KafkaProducerKafkaConsumer模块来实现消息的生产和消费。在producer_demo函数中,我们使用KafkaProducer实例的send方法来发送三条消息,并使用json.dumps函数将数据转换为JSON格式。在consumer_demo函数中,我们使用KafkaConsumer实例来订阅'test'主题,并循环消费所有消息。在循环中,我们使用msg.key和msg.value获取消息的key和value,并使用json.loads函数将value转换为Python对象。最后,我们分别先执行consumer_demo函数,再执行producer_demo函数,可以看到输出结果符合预期。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

莫余

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值