使用 Docker 快速启动 Apache Pulsar Standalone从镜像运行到生产消费的完整指南【免费下载链接】pulsarApache Pulsar - distributed pub-sub messaging system项目地址: https://gitcode.com/gh_mirrors/pulsar28/pulsar本指南介绍如何通过官方apachepulsar/pulsarDocker 镜像在本机以 standalone单机模式启动一个 Apache Pulsar 实例用于本地开发与功能验证。文章完整覆盖docker run启动命令的参数语义、数据持久化与容器用户权限的底层原理并基于仓库源码说明镜像的构建方式与环境变量注入机制最后通过 Python 客户端演示消息的发送与接收以及使用 Admin API 统计 topic 的实时状态。读完本文你将能够独立在 Docker 中拉起一个可用的 Pulsar standalone 集群并用客户端完成端到端的消息收发与监控。环境准备安装 DockerApache Pulsar 官方 Docker 镜像要求本机已安装 Docker 社区版Community edition。安装完成后请确保 Docker daemon 正常运行Windows 用户需要额外将 Docker Desktop 配置为Linux containers模式因为官方镜像基于 Linux 构建。在 Docker 中启动 Pulsar Standalone对于 macOS、Linux 与 Windows可执行如下命令一次性拉起 standalone 集群$ docker run -it -p 6650:6650 -p 8080:8080 \ --mount sourcepulsardata,target/pulsar/data \ --mount sourcepulsarconf,target/pulsar/conf \ apachepulsar/pulsar:{{pulsar:version}} bin/pulsar standalone{{pulsar:version}}是文档站点渲染时的版本占位符实际操作时请替换为你想要使用的具体版本号例如2.10.0、2.9.1等官方 release 版本。命令逐项拆解参数含义-p 6650:6650将容器的 6650 端口映射到宿主机该端口用于 Pulsar 的二进制协议服务broker 与客户端通信。对应 conf/standalone.conf 中的brokerServicePort6650-p 8080:8080将容器的 8080 端口映射到宿主机该端口用于 HTTP 管理接口REST Admin API与 Web 服务。对应配置项webServicePort8080--mount sourcepulsardata,target/pulsar/data将数据卷pulsardata挂载到容器内的/pulsar/data用于持久化 BookKeeper 的 ledger 数据与 ZooKeeper 元数据--mount sourcepulsarconf,target/pulsar/conf将数据卷pulsarconf挂载到容器内的/pulsar/conf用于持久化配置文件避免每次重启容器都回到全新状态bin/pulsar standalone容器入口点执行的启动命令即以 standalone 模式运行 Pulsar关于卷的更多细节可以执行docker volume inspect sourcename查看卷的挂载信息、创建时间与存储位置。standalone 模式会在单个进程中同时拉起 ZooKeeper、BookKeeper 与 Pulsar Broker使本地开发环境零依赖即可运行。容器用户与目录权限说明官方镜像自 2.10.0 起默认以非 root 用户运行该用户 UID 为10000所属组为 GID0root group。这一设计既提升了容器安全性进程不以 root 身份运行又保证了在 OpenShift 等强制随机 UID 的平台上可正常运行。因此当你挂载宿主机目录或命名卷时需要确保挂载点对 UID 10000 或 GID 0 有写权限。镜像在构建阶段已经对/pulsar下的conf、data、download、logs等目录执行了chmod -R gw使 root group 可写详见 docker/pulsar/Dockerfile。从源码看容器内各组件默认会向以下目录写入数据/pulsar/dataBookKeeper 与 ZooKeeper 的存储目录/pulsar/logsFunction Worker 与pulsar-admin的日志目录/pulsar/downloadFunctions 运行时下载依赖的目录/pulsar根目录Hadoop 相关组件会向该目录写入。这也是镜像必须给予 root group 写权限的根本原因。若你挂载的是自建目录请为 UID 10000 或 GID 0 授予写权限否则启动时可能因权限不足而失败。验证启动是否成功启动成功后终端会打印 INFO 级别日志关键标志性输出如下08:18:30.970 [main] INFO org.apache.pulsar.broker.web.WebService - HTTP Service started at http://0.0.0.0:8080 ... 07:53:37.322 [main] INFO org.apache.pulsar.broker.PulsarService - messaging service is ready, bootstrap service port 8080, broker url pulsar://localhost:6650, clusterstandalone, configsorg.apache.pulsar.broker.ServiceConfiguration98b63c1 ...出现messaging service is ready即表示 broker 已就绪可以开始接入客户端。提示standalone 集群启动时会自动创建public/default命名空间该命名空间专门用于开发测试。Pulsar 中所有 topic 都归属于某个命名空间命名空间是 topic 管理与隔离的基本单位。关于 topic 与命名空间的完整概念参见 Topics 概念文档。使用 Pulsar 客户端与集群交互Pulsar 为多种语言提供了官方客户端库包括 Java、Go见 client-libraries-go.md、Python 和 C见 client-libraries-cpp.md。连接本地 standalone 集群时可使用以下两个 root URL 之一pulsar://localhost:6650二进制协议服务地址供客户端建立消息连接http://localhost:8080HTTP 管理接口地址供 Admin API 使用。下面以 Python 客户端为例演示从安装到完成端到端消息收发的完整流程。安装 Pulsar Python 客户端直接从 PyPI 安装官方客户端库$ pip install pulsar-client需要说明的是官方 docker/pulsar/Dockerfile 在构建镜像时已经通过 docker/pulsar/scripts/install-pulsar-client.sh 将匹配 Python 版本的 wheel 包安装进镜像pip3 install /pulsar/pulsar-client/${WHEEL_FILE}[all]因此你既可以在宿主机上pip install也可以直接进入容器内使用已内置的客户端。消费消息创建消费者并订阅 topicimport pulsar client pulsar.Client(pulsar://localhost:6650) consumer client.subscribe(my-topic, subscription_namemy-sub) while True: msg consumer.receive() print(Received message: %s % msg.data()) consumer.acknowledge(msg) client.close()该脚本先通过pulsar.Client(pulsar://localhost:6650)建立到 broker 的连接然后以订阅名my-sub订阅 topicmy-topic。consumer.receive()会阻塞等待下一条消息处理完成后必须调用consumer.acknowledge(msg)进行确认Broker 才会推进消费位点mark delete position。默认情况下订阅类型为Exclusive即同一订阅下同一时刻只允许一个消费者活跃。生产消息另开一个终端运行生产者发送测试消息import pulsar client pulsar.Client(pulsar://localhost:6650) producer client.create_producer(my-topic) for i in range(10): producer.send((hello-pulsar-%d % i).encode(utf-8)) client.close()生产者向my-topic连续发送 10 条消息内容为hello-pulsar-0至hello-pulsar-9。由于 topic 不存在时会由 broker 自动创建对应配置allowAutoTopicCreation因此无需预先建 topic。此时回到消费者终端应当能看到这 10 条消息依次被接收并打印。获取 Topic 统计信息Pulsar 提供 REST、Java 与命令行工具等多种方式控制系统运行的方方面面API 全景参见 Admin API Overview。最简单的方式是用curl直接探测某个 topic 的统计信息$ curl http://localhost:8080/admin/v2/persistent/public/default/my-topic/stats | python -m json.toolURL 的路径结构为/admin/v2/persistent/{tenant}/{namespace}/{topic}/stats这里查询的是public租户、default命名空间下my-topic的实时统计。python -m json.tool用于将返回的 JSON 格式化输出便于阅读。返回字段解读典型的返回结果如下节选{ msgRateIn: 0.0, msgThroughputIn: 0.0, msgRateOut: 1.8332950480217471, msgThroughputOut: 91.33142602871978, bytesInCounter: 7097, msgInCounter: 143, bytesOutCounter: 6607, msgOutCounter: 133, averageMsgSize: 0.0, msgChunkPublished: false, storageSize: 7097, backlogSize: 0, offloadedStorageSize: 0, publishers: [ { accessMode: Shared, msgRateIn: 0.0, msgThroughputIn: 0.0, averageMsgSize: 0.0, chunkedMessageRate: 0.0, producerId: 0, metadata: {}, address: /127.0.0.1:35604, connectedSince: 2021-07-04T09:05:43.04788Z, clientVersion: 2.8.0, producerName: standalone-2-5 } ], waitingPublishers: 0, subscriptions: { my-sub: { msgRateOut: 1.8332950480217471, msgThroughputOut: 91.33142602871978, bytesOutCounter: 6607, msgOutCounter: 133, msgRateRedeliver: 0.0, chunkedMessageRate: 0, msgBacklog: 0, backlogSize: 0, msgBacklogNoDelayed: 0, blockedSubscriptionOnUnackedMsgs: false, msgDelayed: 0, unackedMessages: 0, type: Exclusive, activeConsumerName: 3c544f1daa, msgRateExpired: 0.0, totalMsgExpired: 0, lastExpireTimestamp: 0, lastConsumedFlowTimestamp: 1625389101290, lastConsumedTimestamp: 1625389546070, lastAckedTimestamp: 1625389546162, lastMarkDeleteAdvancedTimestamp: 1625389546163, consumers: [ { msgRateOut: 1.8332950480217471, msgThroughputOut: 91.33142602871978, bytesOutCounter: 6607, msgOutCounter: 133, msgRateRedeliver: 0.0, chunkedMessageRate: 0.0, consumerName: 3c544f1daa, availablePermits: 867, unackedMessages: 0, avgMessagesPerEntry: 6, blockedConsumerOnUnackedMsgs: false, lastAckedTimestamp: 1625389546162, lastConsumedTimestamp: 1625389546070, metadata: {}, address: /127.0.0.1:35472, connectedSince: 2021-07-04T08:58:21.287682Z, clientVersion: 2.8.0 } ], isDurable: true, isReplicated: false, allowOutOfOrderDelivery: false, consumersAfterMarkDeletePosition: {}, nonContiguousDeletedMessagesRanges: 0, nonContiguousDeletedMessagesRangesSerializedSize: 0, durable: true, replicated: false } }, replication: {}, deduplicationStatus: Disabled, nonContiguousDeletedMessagesRanges: 0, nonContiguousDeletedMessagesRangesSerializedSize: 0 }对关键字段的理解可以帮助你快速定位问题topic 级别msgRateIn/msgRateOut表示每秒进出消息速率msgThroughputIn/msgThroughputOut为每秒字节吞吐msgInCounter/msgOutCounter为累计进出消息数storageSize为 topic 存储占用backlogSize为积压字节数publishers 数组列出当前连接的生产者含producerName如standalone-2-5、address、connectedSince、clientVersion与accessMode此处为Sharedsubscriptions 对象按订阅名此处为my-sub展示消费侧状态其中type: Exclusive表示独占订阅msgBacklog为待消费积压条数unackedMessages为未确认消息数consumers数组列出消费者明细含availablePermits可用配额与avgMessagesPerEntry平均每 entry 消息数deduplicationStatus显示消息去重状态replication字段为空表示未配置跨集群复制。深入理解官方 Docker 镜像的构成社区为每个官方 release 发布两个 Docker 镜像详见 docker/README.md镜像说明apachepulsar/pulsar包含运行一个 Pulsar 集群所需的全部组件broker、bookkeeper、zookeeper 等apachepulsar/pulsar-all在apachepulsar/pulsar基础上额外集成了大量 Connector连接器与 Offloader分层存储卸载器两个镜像自 2.10.0 起默认都以非 root 用户运行UID 10000且属于 root group。镜像的多阶段构建从 docker/pulsar/Dockerfile 可以看到镜像采用多阶段构建第一阶段基于busybox将 release tarball 解压为/pulsar并把 docker/pulsar/scripts 下的一系列运维脚本复制进bin/目录第二阶段基于ubuntu:20.04安装 OpenJDK 11 与 Python 3 运行环境供 Pulsar Functions 使用设置JAVA_HOME最后以USER 10000切换到非 root 用户。镜像中默认日志级别由环境变量PULSAR_ROOT_LOGGERINFO,CONSOLE控制。用环境变量覆盖容器配置镜像内置的 docker/pulsar/scripts/apply-config-from-env.py 提供了一种零侵入的配置注入方式凡是形如PULSAR_PREFIX_配置项的环境变量都会在容器启动时被写入对应的.conf文件。例如要修改 broker 的webServicePort只需在docker run时传入docker run -it -p 6650:6650 -p 8080:8080 \ -e PULSAR_PREFIX_webServicePort8081 \ -e PULSAR_PREFIX_brokerServicePort6651 \ --mount sourcepulsardata,target/pulsar/data \ --mount sourcepulsarconf,target/pulsar/conf \ apachepulsar/pulsar:{{pulsar:version}} bin/pulsar standalone脚本会先扫描目标配置文件中的keyvalue行用同名环境变量覆盖其值对于配置文件中不存在的键则追加到文件末尾。若环境变量名含password字样日志中会用********掩码显示避免敏感信息泄露。基于官方镜像构建定制镜像如果你觉得pulsar-all镜像过大又只想使用其中某一个 Connector 或 Offloader可以按 docker/README.md 的示例构建定制镜像。以下 Dockerfile 以apachepulsar/pulsar-all作为构建源向基础镜像中加入 Cassandra Connector 与 jcloud 分层存储 OffloaderARG VERSION # Load the pulsar-all image as a builder image FROM apachepulsar/pulsar-all:${VERSION} as pulsar-all FROM apachepulsar/pulsar:${VERSION} # Add the cassandra connector COPY --frompulsar-all /pulsar/connectors/pulsar-io-cassandra-*.nar /pulsar/connectors # Add the jcloud offloader COPY --frompulsar-all /pulsar/connectors/tiered-storage-jcloud-*.nar /pulsar/offloaders注意COPY指令不支持构建参数的展开因此上述示例在COPY中使用了通配符来匹配.nar文件。构建命令如下以 2.9.1 为例docker build --build-arg VERSION2.9.1 -t pulsar-custom:2.9.1 .非 root 容器的排障思路镜像以非 root 用户运行会带来一些排障上的不便例如非 root 用户无法随意安装调试工具。常用的应对手段包括方式一构建包含调试工具的定制镜像。在官方镜像基础上临时切换回 root 安装工具再切回非 root 用户FROM apachepulsar/pulsar:2.10.0 # Switch to root user to download tools USER 0 # Install your preferred utilities RUN apt-get update \ apt-get install -y vim net-tools unzip \ apt-get clean \ rm -rf /var/lib/apt/lists/* # Assuming you still want to run as a non root user by default USER 10000方式二借助宿主机的docker exec。使用docker exec --user root -it container bash以 root 身份进入容器排查。方式三在 Kubernetes 中通过 Pod 的securityContext覆盖容器默认用户。从 Standalone 走向集群部署Standalone 模式适合本地开发与功能验证生产环境通常采用多节点集群部署broker、bookkeeper、zookeeper 分离部署。standalone 启动时默认使用的配置即为 conf/standalone.conf其中clusterNamestandalone标识了集群名。若希望在非 Docker 环境中直接体验同款 standalone 集群可参考 使用 Standalone 模式快速开始。小结通过本文你已经掌握了完整的 Docker 化 Pulsar standalone 使用链路用docker run一条命令拉起镜像理解6650/8080双端口、数据卷持久化与非 root 用户UID 10000权限模型的含义通过 Python 客户端完成 topic 的订阅消费与消息生产用curl调用 Admin REST API 获取 topic 级与订阅级的实时统计指标从 docker/pulsar/Dockerfile 与 docker/pulsar/scripts/apply-config-from-env.py 等源码层面理解了镜像构建、环境变量注入与定制镜像的方法。这套流程可以作为后续深入学习 Pulsar 消息模型、多集群部署、分层存储与 Functions 的基础环境随时可以用docker run快速重建一个干净的开发环境。【免费下载链接】pulsarApache Pulsar - distributed pub-sub messaging system项目地址: https://gitcode.com/gh_mirrors/pulsar28/pulsar创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考