Apache Pulsar 生产部署:Docker 单机集群与 Prometheus 监控的最小可行路径

发布时间:2026/11/3 19:14:42
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 / Compose20.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 SSDbookie 是磁盘密集型,务必用 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_outCounter分区级收发速率,容量规划和限流的第一手数据
pulsar_backlog_sizeGauge积压字节数,消费延迟和存储容量的领先指标
pulsar_num_consumersGauge消费组规模突变,能最早暴露消费者掉线
jvm_memory_bytesGauge堆 + 堆外用量,OOM 前兆,告警必接
jvm_gc_collection_secondsHistogramGC 停顿直接决定投递 P99
pulsar_replication_rateGauge跨集群同步速率,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),仅供参考