轻量级 CI/CD 实战(三):Kafka消费者Docker容器化部署

轻量级 CI/CD 实战(三): Kafka 消费者容器化部署

目录

背景与目标

在日志分析系统中,Nginx 日志通过 Filebeat 发送到 Kafka 集群,需部署一个长期运行的消费者程序,将日志解析后写入 MySQL 并缓存到 Redis。

为提升部署效率、避免环境依赖冲突,采用 Docker 容器化方案,实现:

  • 服务开机自启(--restart=always
  • 网络直连宿主机(--network host
  • 代码更新后快速重建

项目结构

项目存放于 /opt/log_consumer/,目录结构如下:

bash 复制代码
/opt/log_consumer/
├── consumer.py          # 主程序:Kafka消费 + MySQL写入 + Redis缓存
├── requirements.txt     # Python依赖列表
└── Dockerfile           # Docker镜像构建定义

关键配置文件

Dockerfile

使用官方 python:3.9-slim 镜像,轻量且兼容性好:

bash 复制代码
# 使用轻量 Python 镜像
FROM python:3.9-slim

# 设置工作目录
WORKDIR /app

# 复制依赖文件
COPY requirements.txt .

# 安装 Python 依赖(禁用缓存确保干净构建)
RUN pip install --no-cache-dir -r requirements.txt

# 复制主程序
COPY consumer.py .

# 启动命令
CMD ["python", "consumer.py"]

requirements.txt

bash 复制代码
kafka-python==2.0.2
PyMySQL==1.1.0
redis==5.0.1

consumer.py 注意事项

Kafka 消费者初始化时,必须使用集群主机名,不可用 localhost 或 127.0.0.1:

bash 复制代码
consumer = KafkaConsumer(
    'nginx-logs',
    bootstrap_servers=["kafka1:9092", "kafka2:9092", "kafka3:9092"],  # ← 关键!
    auto_offset_reset='latest',
    enable_auto_commit=True,
    group_id='log-consumer-group'
)

同时确保:

所有依赖库已正确导入

每行参数末尾加英文逗号 ,(避免 SyntaxError)

异常处理完善(防止进程意外退出)

部署流程

清理旧容器

容器名称冲突是常见错误,务必先删除旧容器

bash 复制代码
docker stop log-consumer 2>/dev/null && docker rm log-consumer 2>/dev/null

即使容器已停止,仍占用名称,必须 rm

语法预检

避免因语法错误导致容器无限重启

bash 复制代码
cd /opt/log_consumer
python3 -m py_compile consumer.py

无输出即表示语法正确。

构建镜像

bash 复制代码
docker build -t log-consumer .

构建成功后,可通过 docker images 查看镜像

启动容器

使用 host 网络模式直连 Kafka,开启自启:

bash 复制代码
docker run -d \
  --network host \
  --name log-consumer \
  --restart=always \
  log-consumer

--network host:容器共享宿主机网络,可直接访问 kafka1:9092

验证运行状态

查看实时日志:

bash 复制代码
docker logs -f log-consumer

成功标志(你的程序应输出类似内容):

bash 复制代码
OK MySQL连接成功
OK Redis连接成功
OK Kafka消费者创建成功
TARGET 开始监听日志...

常见问题排查

容器不断重启

现象:docker ps 显示容器状态为 Restarting

原因:程序启动后立即退出(如语法错误、连接失败)

解决:

bash 复制代码
停止容器:docker stop log-consumer
前台运行查看错误:docker run -it --network host --rm log-consumer
根据报错修复代码

Kafka 连接失败(NoBrokersAvailable)

现象:日志报 kafka.errors.NoBrokersAvailable

原因:

bootstrap_servers 写成 localhost:9092(这里检查kafka配置文件)

Kafka 未监听外网 IP

防火墙阻断 9092 端口

解决:

bash 复制代码
使用 kafka1:9092 等主机名(需 DNS 或 hosts 解析)
在宿主机测试:telnet kafka1 9092

Python 语法错误

现象:SyntaxError: invalid syntax,报错行看似正常

原因:

上一行缺少逗号(最常见!)

中文标点混入

文件含 BOM 头或 CRLF 换行符

kafka3:9092末尾要加上逗号,否则系统将这一行和下一行当作同一行处理就报错了

解决:

bash 复制代码
用 cat -A 检查隐藏字符
用 python3 -m py_compile 提前校验
重写可疑行(手动输入英文标点)

一键重启脚本

bash 复制代码
#!/bin/bash
cd /opt/log_consumer

# 停旧容器
docker stop log-consumer 2>/dev/null
docker rm log-consumer 2>/dev/null

# 构建新镜像
docker build -t log-consumer .

# 启动
docker run -d --network host --name log-consumer --restart=always log-consumer

echo "✅ 消费者已启动,查看日志:docker logs -f log-consumer"

总结

通过容器化 Kafka 消费者,我们实现了:

环境隔离:依赖不污染宿主机

快速部署:6 条命令完成上线

高可用:崩溃自动重启

标准化:任何人拿到代码均可一键运行


作者:subencai

环境:CentOS 7 + Docker 24.0 + Kafka 3.3

最后更新:2025年11月

相关推荐
元拓数智2 小时前
智能分析落地卡壳?先补好「数据关系+语义治理」这层技术基建
大数据·分布式·ai·spark·数据关系·语义治理
CodeMartain4 小时前
Dify Windows 原生部署(无 Docker、纯本地)
运维·docker·容器
llrraa20106 小时前
配置docker国内镜像源
运维·docker·容器
GIS数据转换器6 小时前
农村生活污水治理智慧管控平台
大数据·人工智能·分布式·数据分析·生活·智慧城市
华为云开发者联盟8 小时前
告别繁琐操作,华为云码道 + Docker重塑远程开发体验
人工智能·学习·docker·华为云·软件开发·华为云码道
m_136878 小时前
Docker Desktop WSL2 启动失败:ext4.vhdx 拒绝访问(E_ACCESSDENIED)完整解决方案
docker
Trouvaille ~8 小时前
【Redis篇】初识 Redis:特性、应用场景与版本演进
数据结构·数据库·redis·分布式·缓存·中间件·持久化
米高梅狮子10 小时前
Ceph 分布式存储 部署
linux·运维·数据库·分布式·ceph·docker·华为云
郭龙_Jack10 小时前
跨境电商 平台 - ERP - 内部子系统 交互方式总图
分布式·教育电商
喝醉酒的小白10 小时前
Kafka 集群应急故障排查手册
分布式·kafka