Apache Pulsar 生产部署:Docker 单机集群与 Prometheus 监控的最小可行路径
Apache Pulsar 生产部署:Docker 单机集群与 Prometheus 监控的最小可行路径
【免费下载链接】pulsarApache Pulsar - distributed pub-sub messaging system项目地址: https://gitcode.com/gh_mirrors/pulsar28/pulsar
Apache Pulsar 是一套支持多租户的分布式发布订阅消息系统。这篇 Apache Pulsar 生产部署实战带你用 docker-compose 拉起 ZooKeeper、Bookie、Broker、Proxy 完整集群,再接上 Prometheus 和 Grafana,让 Pulsar Docker 服务从黑盒变成可观测的白盒。
先想清楚你的场景
在动手拉容器之前,先确认你的负载形态,它决定了集群规模:
- 高吞吐数据管道:日志、埋点类 topic 每天写入几十亿条,要求 bookie 层 HA 和磁盘隔离,开发机上跑不出这种压力画像。
- 低延迟在线消费:风控、计费场景对投递 P99 有硬性预算,broker 抖动直接打进你的 SLA,需要独立部署和监控告警。
- 多团队共享集群:不同业务线共享 namespace,靠资源配额和背压策略隔离,配置项和权限模型必须按生产标准来。
部署前先把下表过一遍,缺一项都会在后面卡住:
| 项目 | 本文基线 | 说明 |
|---|---|---|
| Docker / Compose | 20.10 以上 / v2 | 官方镜像 docker/pulsar/Dockerfile 基于 Ubuntu 20.04 + OpenJDK 11 构建 |
| GPU / 显存 | 不需要 | Pulsar 是 JVM 服务,无 GPU 依赖,资源以内存和磁盘为核心 |
| 运行时语言环境 | Java 11(镜像内置) | 客户端语言不限,Python 客户端由install-pulsar-client.sh预装 |
| 主机规格 | 16 vCPU / 64 GB / 400 GB SSD | bookie 是磁盘密集型,务必用 SSD;单节点跑满 9 容器建议内存 ≥48 GB |
| 网络端口 | 6650 / 8000 / 8080 / 9090 / 3000 | 业务与监控端口,详见 Checklist |
部署路径怎么选
| 方式 | 适用规模 | 复杂度 | 运维成本 | 推荐度 |
|---|---|---|---|---|
| 源码解压裸机 | 个人验证、压测机 | 低 | 低,但环境漂移全靠人肉 | ★★ |
| Docker 单容器(standalone) | 单节点演示、集成测试 | 低 | 低 | ★★★ |
| docker-compose 多服务 | 单机模拟完整集群(≤10 节点规模) | 中 | 中 | ★★★★(本文路线) |
| Kubernetes / Helm | 多团队、多集群、需弹性扩缩 | 高 | 高 | 按需 |
单机起步就选 docker-compose:它用 1 台机器模拟出 zk×3 + bookie×3 + broker×3 + proxy 的分布式拓扑,升级和回滚只需要换镜像 tag,仓库里现成的 kitchen-sink 编排文件 可以直接当脚手架。K8s 留给多集群、需要滚动升级和自动伸缩的阶段,本文不展开。
把 Pulsar 塞进容器
镜像怎么建
这段解决"只装我需要的 NAR,不让官方大镜像膨胀到 3 GB+"的问题:基于官方镜像做多阶段构建,只挑连接器。
# 以官方 release tag 锁定版本,禁止在生产使用 latest FROM apachepulsar/pulsar-all:2.10.6 AS builder # 基础镜像只有 broker/bookie/zk 二进制,约 1.6 GB FROM apachepulsar/pulsar:2.10.6 # 只把用到的 NAR 连接器拷进镜像 COPY --from=builder /pulsar/connectors/pulsar-io-cassandra-*.nar /pulsar/connectors # 分层缓存:只有 NAR 变更才重建 COPY ./pulsar-custom/ /pulsar/connectors # 官方镜像默认以非 root 用户 10000 运行,安全基线别改 USER 10000官方镜像本身是多阶段构建:busybox 阶段解包二进制,Ubuntu 阶段装 JDK 11 和 Python 依赖,最后切到非 root 用户,细节见 Docker 构建说明。生产上建议直接用 release tag,而不是自己mvn打包后塞进去。
服务怎么编排
这段解决"单机上把 Pulsar 的分布式角色拆成独立容器、并能一键重建"的问题:
# 片段取自仓库 kitchen-sink,生产按需裁剪 services: zk1: # ZooKeeper,元数据三副本 image: apachepulsar/pulsar:2.10.6 command: exec bin/pulsar zookeeper environment: { ZOOKEEPER_SERVERS: zk1,zk2,zk3 } bk1: # Bookie,消息落盘 image: apachepulsar/pulsar:2.10.6 command: exec bin/pulsar bookie environment: { zkServers: zk1:2181,zk2:2181,zk3:2181 } broker1: # Broker,消息进出 image: apachepulsar/pulsar:2.10.6 command: exec bin/pulsar broker environment: zookeeperServers: zk1:2181,zk2:2181,zk3:2181 configurationStoreServers: zk1:2181,zk2:2181,zk3:2181 ports: - "6650:6650" # 客户端二进制协议 - "8080:8080" # HTTP 服务 + /metrics prometheus: # 独立容器只负责抓取与存储 image: prom/prometheus:2.47.0 ports: ["9090:9090"] volumes: [ "./prometheus.yml:/etc/prometheus/prometheus.yml" ] grafana: # 独立容器负责展示,与抓取解耦 image: grafana/grafana:10.2.3 ports: ["3000:3000"]Prometheus 和 Grafana 必须单独拆容器:它们与 Pulsar 生命周期完全无关,Pulsar 滚动升级时监控不能断;单独容器也让抓取目标(broker1:8080)和展示层各自独立扩缩,互不拖累。
消息与状态放哪
Pulsar 是"数据系统"而非模型服务,这里的数据分三类,挂载策略不同:
- Ledger 数据(核心数据):bookie 的消息落盘目录挂到宿主机 SSD 独立目录并持久化,
docker compose重建容器不能丢数据。 - ZooKeeper 状态:三节点各挂独立卷,初始化状态(
/initialized-<cluster>)存在这里,误删等于集群清零。 - NAR / 分层存储 offloader:随镜像分层走,不走卷;升级即换 tag,天然可回滚。
官方镜像把配置注入做成了"运行时环境变量 →bin/apply-config-from-env.py渲染到conf/*.conf"的机制,所以你不需要为每套环境重新打镜像,compose 里的environment就是配置入口(PULSAR_MEM也是这条路)。
让服务从黑盒到白盒:Pulsar Prometheus 指标采集
Pulsar 各组件原生暴露 Prometheus 格式端点:Broker 在:8080/metrics,bookie 在:8000/metrics(conf/bookkeeper.conf已默认启用PrometheusMetricsProvider),ZooKeeper 在:8000/:8001/metrics。抓取配置见 监控文档。
暴露哪些指标
| 指标 | 类型 | 为什么关心 |
|---|---|---|
pulsar_topics_in/pulsar_topics_out | Counter | 分区级收发速率,容量规划和限流的第一手数据 |
pulsar_backlog_size | Gauge | 积压字节数,消费延迟和存储容量的领先指标 |
pulsar_num_consumers | Gauge | 消费组规模突变,能最早暴露消费者掉线 |
jvm_memory_bytes | Gauge | 堆 + 堆外用量,OOM 前兆,告警必接 |
jvm_gc_collection_seconds | Histogram | GC 停顿直接决定投递 P99 |
pulsar_replication_rate | Gauge | 跨集群同步速率,geo 容灾链路是否追得上的唯一口径 |
topic / consumer / producer / cursor 级别指标默认关闭,按需要在 conf/broker.conf 打开:exposeConsumerLevelMetricsInPrometheus、exposeProducerLevelMetricsInPrometheus等。topic 数上万时把metricsServletTimeoutMs调大,避免 /metrics 被掐断。
最小可用监控栈
# prometheus.yml:只列核心目标,端口与 compose 保持一致 scrape_configs: - job_name: pulsar static_configs: - targets: ["broker1:8080", "bk1:8000", "zk1:8000"]Grafana 导入零配置:仓库 grafana/dashboards/ 内置 broker、bookkeeper、zookeeper、namespace、topic、jvm 六份 JSON 面板,在 Dashboards → Import 里逐个导入,数据源指向http://prometheus:9090即可。
日志别乱打
- 级别:生产默认
INFO(官方镜像已设PULSAR_ROOT_LOGGER=INFO,CONSOLE),DEBUG 只用于临时排障窗口,用完必须关回。 - 结构化字段:每条日志带
component(broker/bookie/zk)、cluster、namespace,没有这三个字段,多集群排障只能靠猜。 - 统一走 log4j2:禁止用
print或echo替代 logger;自定义 Functions 和 IO connector 的日志接入 conf/log4j2.yaml 同一套输出链路。
Pulsar 容器化上线 Checklist
- 镜像 tag 固定到具体版本(
2.10.6),全环境禁用latest(compose 文件) - TLS 证书、token 密钥放 secret 管理器,运行时注入,不落镜像(
broker.conf的 TLS 段) - 每容器 JVM 限额留 30% 余量:
-Xms2g -Xmx2g -XX:MaxDirectMemorySize=4g是默认,按实际容量改(conf/pulsar_env.sh 的PULSAR_MEM) docker compose ps全部 Up 后,浏览器逐个验证zk1:8000/metrics、bk1:8000/metrics、broker1:8080/metrics可访问- 回滚路径演练过一次:旧 tag 镜像仍保留在本地 registry(
docker pull可秒级恢复) - ZooKeeper snapshot 与 bookie ledgers 每日备份并落异地存储
- 运维手册包含端口表(6650/8000/8080/9090/3000)与
pulsar-admin常用命令 - 告警分级写死:backlog 持续增长 10 min → P1;
pulsar_num_consumers归零 → P1;GC P99 > 2s 持续 5 min → P2 - 客户端到 proxy 的 6650 走内网,公网只暴露 proxy 且开 TLS
exposeTopicLevelMetricsInPrometheus等指标开关与实际 topic 规模匹配,防止 /metrics 超时(broker.conf)
大概率会踩的 3 个坑
1. OOM:容器反复被 kill
- 现象:
docker inspect bk1 | grep -i oom出现OOMKilled: true,压测流量一上就复现。 - 原因:Pulsar 同时吃堆内存和堆外 direct memory,默认 2g 堆 + 4g 堆外,宿主机分给容器的内存不够。
- 解法:
# compose environment 中按实际容量设置 PULSAR_MEM="-Xms1g -Xmx1g -XX:MaxDirectMemorySize=2g"
2. 端口冲突:单机全角色同机跑不起来
- 现象:bookie 或 broker 启动即失败,日志出现
Address already in use。 - 原因:bookie 的 Prometheus 端口默认 8000,与本地 ZooKeeper stats 端口(8000/8001)在同一宿主机混部时撞车。
- 解法:
# conf/bookkeeper.conf prometheusStatsHttpPort=8002 # 同步更新 prometheus.yml 的 targets
3. Bookie 卡死不启动
- 现象:
watch-znode.py一直等/initialized-<cluster>,bookie/broker 全部挂起。 - 原因:集群元数据未初始化,或 ZooKeeper 数据卷被清掉了。
- 解法:
docker compose up -d pulsar-init # 重跑 [init-cluster.sh](https://link.gitcode.com/i/7bdec2d9e6a969ab0e9da85eaa5c03c3)
接下来可以看什么
到这里你已经有一套能收发消息、指标可抓、面板可见的生产形态 Pulsar。上面是最短闭环,离真实生产还差 TLS 认证、分层存储和跨集群复制这些层。继续深入可以从这三处入手:镜像构建与裁剪逻辑看 Docker 构建说明,完整集群编排参考 kitchen-sink compose,指标开关和端点细节看 监控文档 与 Grafana 面板。本文覆盖的是最小可行路径,生产规模请按团队情况扩展。
【免费下载链接】pulsarApache Pulsar - distributed pub-sub messaging system项目地址: https://gitcode.com/gh_mirrors/pulsar28/pulsar
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考