Loading

django中使用kafka

Django 集成 Kafka 的详细注释版

下面我会提供一个带有详细注释的 Django 集成 Kafka 的完整示例,帮助理解每个部分的用途和工作原理。

1. 安装依赖(已注释)

# 安装 Python 的 Kafka 客户端库
# confluent-kafka 是 Apache Kafka 的官方 Python 客户端
pip install confluent-kafka

2. Django 配置(settings.py)

# settings.py

# Kafka 配置字典
KAFKA_CONFIG = {
    # Kafka 集群的服务器地址,多个地址可以用逗号分隔
    'bootstrap.servers': 'localhost:9092',
    
    # 消费者组ID,同一个组内的消费者共享消息
    'group.id': 'django-group',
    
    # 当没有初始偏移量时从哪里开始消费:
    # 'earliest' - 从最早的消息开始
    # 'latest' - 只消费新消息
    'auto.offset.reset': 'earliest',
    
    # 可选配置:消息确认设置
    # 'acks': 'all'  # 确保消息被完全提交
}

3. Kafka 工具类(utils/kafka_client.py)

from confluent_kafka import Producer, Consumer
from django.conf import settings
import json

class KafkaProducer:
    """Kafka 生产者类,用于发送消息到 Kafka 主题"""
    
    def __init__(self):
        """初始化生产者实例"""
        # 使用 Django 设置中的配置创建生产者
        self.producer = Producer(settings.KAFKA_CONFIG)
    
    def delivery_report(self, err, msg):
        """
        消息发送回调函数
        参数:
            err: 错误对象,如果发送成功则为 None
            msg: 消息对象,包含元数据
        """
        if err is not None:
            print(f'消息发送失败: {err}')
        else:
            print(f'消息成功发送到主题 {msg.topic()} [分区 {msg.partition()}]')
    
    def send_message(self, topic, value, key=None):
        """
        发送消息到指定 Kafka 主题
        参数:
            topic: 目标主题名称
            value: 消息内容(会被转换为 JSON 字符串)
            key: 可选的消息键,用于分区路由
        """
        # 发送消息
        self.producer.produce(
            topic=topic,          # 主题名称
            key=key,             # 可选的消息键
            value=json.dumps(value),  # 将值转为 JSON 字符串
            callback=self.delivery_report  # 发送回调
        )
        # 刷新生产者缓冲区,确保消息被发送
        self.producer.flush()

class KafkaConsumer:
    """Kafka 消费者类,用于从主题消费消息"""
    
    def __init__(self, topics):
        """
        初始化消费者实例
        参数:
            topics: 要订阅的主题列表,如 ['topic1', 'topic2']
        """
        # 使用 Django 设置中的配置创建消费者
        self.consumer = Consumer(settings.KAFKA_CONFIG)
        # 订阅指定的主题列表
        self.consumer.subscribe(topics)
    
    def consume_messages(self):
        """开始消费消息的循环"""
        try:
            while True:
                # 轮询新消息,超时时间 1.0 秒
                msg = self.consumer.poll(1.0)
                
                # 没有消息时继续轮询
                if msg is None:
                    continue
                
                # 处理消息错误
                if msg.error():
                    print(f"消费者错误: {msg.error()}")
                    continue
                
                # 成功接收到消息
                print(f"收到消息: {msg.value().decode('utf-8')}")
                
        except KeyboardInterrupt:
            # 允许通过键盘中断退出消费循环
            pass
        finally:
            # 确保消费者正确关闭
            self.consumer.close()

4. Django 视图(views.py)

from django.http import JsonResponse
from .utils.kafka_client import KafkaProducer

def send_kafka_message(request):
    """
    处理发送消息到 Kafka 的视图函数
    支持 POST 方法,接收页面参数并发送用户活动事件
    """
    if request.method == 'POST':
        # 构造要发送的消息数据
        data = {
            'user_id': 123,  # 实际项目中可以从 request.user 获取
            'action': 'page_view',  # 活动类型
            'page': request.POST.get('page', 'home'),  # 页面名称
            'timestamp': str(datetime.now())  # 事件时间戳
        }
        
        # 创建 Kafka 生产者实例
        producer = KafkaProducer()
        
        # 发送消息到 'user_activity' 主题
        producer.send_message(
            topic='user_activity',  # 主题名称
            value=data             # 消息内容
        )
        
        # 返回成功响应
        return JsonResponse({'status': '消息已发送到 Kafka'})
    
    # 非 POST 请求返回错误
    return JsonResponse({'error': '无效请求'}, status=400)

5. Kafka 消费者管理命令

# kafka_app/management/commands/kafka_consumer.py
from django.core.management.base import BaseCommand
from ...utils.kafka_client import KafkaConsumer

class Command(BaseCommand):
    """自定义 Django 管理命令,用于启动 Kafka 消费者"""
    
    help = '启动 Kafka 消费者服务'
    
    def handle(self, *args, **options):
        """命令执行入口"""
        # 输出启动信息(绿色成功信息)
        self.stdout.write(
            self.style.SUCCESS('正在启动 Kafka 消费者...')
        )
        
        # 创建消费者实例,订阅 'user_activity' 主题
        consumer = KafkaConsumer(['user_activity'])
        
        # 开始消费消息
        consumer.consume_messages()

6. 工作流程说明

  1. 生产者流程:

    • 客户端调用 /send-message/ 端点
    • 视图函数创建消息数据
    • KafkaProducer 将消息序列化为 JSON
    • 消息被发送到 Kafka 集群的指定主题
    • 发送结果通过回调函数报告
  2. 消费者流程:

    • 通过管理命令启动消费者
    • 消费者订阅指定主题
    • 不断轮询新消息
    • 收到消息后打印内容
    • 可通过 Ctrl+C 停止消费

7. 关键点解释

  1. 生产者配置:

    • bootstrap.servers: Kafka 集群入口地址
    • flush(): 确保消息立即发送而不是批量发送
  2. 消费者配置:

    • group.id: 消费者组标识,同组消费者共享消息
    • auto.offset.reset: 控制消费起始位置
  3. 消息传递保证:

    • 当前示例使用最基本的发送确认
    • 生产环境可能需要更强的保证(如 'acks': 'all'
  4. 性能考虑:

    • 频繁创建生产者/消费者实例影响性能
    • 实际项目应考虑使用连接池或单例模式

这个注释版详细解释了每个组件的作用和配置选项,应该能帮助你更好地理解 Django 与 Kafka 的集成方式。

posted @ 2025-05-29 13:32  一只大学生  阅读(141)  评论(0)    收藏  举报