在 Apache Pulsar 分布式集群搭建过程中,bookiesanity失败和brokers list查不到节点是出现频率最高的两个卡点。很多教程让你改完bookkeeper.conf和broker.conf就直接启动,但三台节点上的advertisedAddress、zkServers、zookeeperServers、configurationStoreServers只要有一台没对齐主机名或 IP,bookie 就注册不上,broker 也认不到集群。这篇从排障视角出发,先把配置逐台核对清楚,再借助 TaoToken 接入 Codex 做配置对照,最后用bookiesanity和brokers list两条命令确认集群真正通了。TaoToken 官网入口:https://taotoken.net/?utm_source=taotoken_aicg_blog_end
一、原问题与场景:bookiesanity 为什么在三节点上过不去
Pulsar 集群模式最少需要三组组件:ZooKeeper 集群、BookKeeper 集群(bookie)和 broker 集群。安装包本身已经包含这些组件库,不需要单独下载 ZooKeeper 和 BookKeeper。实际搭建时,ZooKeeper 往往用外置集群,因为 HBase 等其他组件也会依赖它。
典型的三节点规划是这样的:
| 主机名 | IP 示例 | 角色 |
|---|---|---|
| pulsar1 | 192.168.8.108 | zk + bookie + broker |
| pulsar2 | 192.168.8.109 | zk + bookie + broker |
| pulsar3 | 192.168.8.110 | zk + bookie + broker |
配置流程通常是:在 pulsar1 上改好bookkeeper.conf和broker.conf,然后scp -r pulsar/ pulsar2:$PWD、scp -r pulsar/ pulsar3:$PWD,再分别登录 pulsar2、pulsar3 把本机地址改成对应主机名或 IP。
问题就出在这一步。bookkeeper.conf里的advertisedAddress如果三台都还是pulsar1,bookie 启动后会向 ZooKeeper 注册成同一个地址,bookiesanity自然过不去。broker.conf里的advertisedAddress同理,三台 broker 都宣告自己是 pulsar1,brokers list要么只显示一个,要么直接报错。
还有一个高频坑是zkServers和zookeeperServers的写法。bookkeeper.conf里用的是zkServers=zookeeper1:2181,zookeeper2:2181,zookeeper3:2181,broker.conf里用的是zookeeperServers和configurationStoreServers,两者必须指向同一套 ZooKeeper 集群。如果主机名解析没做,或者端口写错,bookie 连不上 zk,bookiesanity会直接超时。
所以排障的核心不是反复重启,而是把三台节点上的四类地址逐台对齐:advertisedAddress、zkServers、zookeeperServers、configurationStoreServers。人工核对容易漏,这时候可以让 Codex 帮你做交叉比对。
二、TaoToken 前置:给 Codex 配好 Key 和 Base URL
TaoToken 在这里的角色很明确:它只负责给 Codex 提供 API Key 和 Base URL,不连接你的 Pulsar 节点,也不修改bookkeeper.conf。你的配置文件片段和bookiesanity输出,由你自己贴给 Codex,Codex 负责对照分析。
先打开 https://taotoken.net/?utm_source=taotoken_aicg_blog_end 注册账号,进入控制台创建 API Key。拿到 Key 之后,在 Codex 的配置里把 Base URL 填成:
https://taotoken.net/apiKey 填你刚创建的那串YOUR_API_KEY。如果你用的是 Claude Code 这类工具,对应改的是settings.json里的ANTHROPIC_BASE_URL和ANTHROPIC_API_KEY;如果用的是 Codex,改的是config.toml。不同工具的配置文件位置不一样,但核心就两项:Base URL 指向https://taotoken.net/api,Key 用你自己的。
配好之后,你可以先在模型对话里发一条简单消息,确认 Codex 能正常返回,再进入配置对照环节。这一步不要跳过,否则后面贴配置时如果请求不通,你会分不清是 Codex 的问题还是 Pulsar 的问题。
三、可复制配置:三台节点 bookkeeper.conf 与 broker.conf 对照清单
下面这份清单是排障时最该逐台核对的。假设三台主机名分别是 pulsar1、pulsar2、pulsar3,ZooKeeper 集群是 zookeeper1、zookeeper2、zookeeper3。
pulsar1 上的 bookkeeper.conf:
advertisedAddress=pulsar1 journalDirectory=/usr/local/pulsar/tmp/journal ledgerDirectories=/usr/local/pulsar/tmp/ledgers zkServers=zookeeper1:2181,zookeeper2:2181,zookeeper3:2181pulsar1 上的 broker.conf:
clusterName=pulsar-cluster zookeeperServers=zookeeper1:2181,zookeeper2:2181,zookeeper3:2181 configurationStoreServers=zookeeper1:2181,zookeeper2:2181,zookeeper3:2181 advertisedAddress=pulsar1pulsar2 上需要改的两处:
# bookkeeper.conf advertisedAddress=pulsar2 # broker.conf advertisedAddress=pulsar2pulsar3 上需要改的两处:
# bookkeeper.conf advertisedAddress=pulsar3 # broker.conf advertisedAddress=pulsar3注意,zkServers、zookeeperServers、configurationStoreServers这三项在三台节点上应该保持一致,都指向同一套 ZooKeeper 集群。只有advertisedAddress是每台不同。如果你在 pulsar2 或 pulsar3 上发现zkServers被改成了本机地址,那就是错的。
把这三台节点的配置片段分别贴给 Codex 时,建议按主机名分组,格式像这样:
【pulsar1 bookkeeper.conf】 advertisedAddress=pulsar1 zkServers=zookeeper1:2181,zookeeper2:2181,zookeeper3:2181 【pulsar2 bookkeeper.conf】 advertisedAddress=pulsar2 zkServers=zookeeper1:2181,zookeeper2:2181,zookeeper3:2181 【pulsar3 bookkeeper.conf】 advertisedAddress=pulsar3 zkServers=zookeeper1:2181,zookeeper2:2181,zookeeper3:2181然后让 Codex 检查:三台的advertisedAddress是否分别对应各自主机名,zkServers是否三台一致,broker.conf里的zookeeperServers和configurationStoreServers是否与bookkeeper.conf的zkServers指向同一组地址。Codex 会逐项给你比对结果,比人工翻三台机器快得多。
四、验证请求与成功结果:bookiesanity 和 brokers list
配置核对完,按顺序启动。先启动 ZooKeeper 集群,三个节点都启动后确认状态,必须看到一个 leader 和两个 follower 才继续。
然后初始化元数据,这一步只需要执行一次:
cd /usr/local/pulsar/bin ./pulsar initialize-cluster-metadata \ --cluster pulsar-cluster \ --zookeeper zookeeper1:2181,zookeeper2:2181,zookeeper3:2181 \ --configuration-store zookeeper1:2181,zookeeper2:2181,zookeeper3:2181 \ --web-service-url http://pulsar1:8080,pulsar2:8080,pulsar3:8080 \ --web-service-url-tls https://pulsar1:8443,pulsar2:8443,pulsar3:8443 \ --broker-service-url pulsar://pulsar1:6650,pulsar2:6650,pulsar3:6650 \ --broker-service-url-tls pulsar+ssl://pulsar1:6651,pulsar2:6651,pulsar3:6651接着初始化 bookkeeper 集群,出现提示输入 Y:
./bookkeeper shell metaformat启动 bookie,三个节点依次执行:
./pulsar-daemon start bookie三台都启动后,在每台上执行:
./bookkeeper shell bookiesanity看到Bookie sanity test succeeded才算 bookie 正常。如果失败,把完整输出贴给 Codex,同时附上该节点的bookkeeper.conf片段,让 Codex 对照advertisedAddress和zkServers找差异。
bookie 通过后启动 broker,三个节点依次执行:
./pulsar-daemon start broker然后在任意节点执行:
./pulsar-admin brokers list pulsar-cluster正常应该返回三个 broker 地址,类似:
"pulsar1:8080" "pulsar2:8080" "pulsar3:8080"如果只返回一个或报错,把brokers list的输出和三台broker.conf里的advertisedAddress、zookeeperServers、configurationStoreServers一起贴给 Codex,让它检查是否有节点宣告了重复地址,或者configurationStoreServers写错导致 broker 读不到集群元数据。
集群通了之后,就可以继续原文的客户端测试:
./pulsar-client consume persistent://public/default/test -s "consumer-test" ./pulsar-client produce persistent://public/default/test --messages "hello-pulsar"五、本篇常见错排查
错误一:bookiesanity 报连接超时。先检查bookkeeper.conf里的zkServers是否三台一致,再确认 ZooKeeper 集群是否真的有一个 leader 和两个 follower。如果 zk 本身没起来,bookie 连不上是必然的。
错误二:bookiesanity 通过但 brokers list 为空。重点看broker.conf里的configurationStoreServers。这一项如果写成了本机地址或者和zookeeperServers不一致,broker 读不到集群配置,就不会注册。三台的configurationStoreServers必须指向同一套 zk。
错误三:brokers list 只显示一个节点。大概率是 pulsar2 和 pulsar3 的broker.conf里advertisedAddress没改,三台都宣告成 pulsar1。逐台确认advertisedAddress是否等于本机主机名。
错误四:scp 之后改了配置但忘了重启。scp -r分发的是 pulsar1 的配置,pulsar2 和 pulsar3 改完advertisedAddress后必须重启 bookie 和 broker,否则还是用旧配置注册。
错误五:主机名解析不通。如果配置里用的是pulsar1、zookeeper1这类主机名,三台机器的/etc/hosts必须能互相解析。解析不通时,bookiesanity和brokers list都会失败。可以临时用 IP 替换主机名验证,但生产环境建议把 hosts 配好。
排查时把报错输出、对应节点的配置文件片段、以及你执行的具体命令一起贴给 Codex,让它按advertisedAddress、zkServers、zookeeperServers、configurationStoreServers四个维度逐项比对。Codex 不会替你改配置,但能快速指出哪一台的哪一项和其他两台不一致。
六、语义一致 CTA
如果你在排障过程中需要反复核对配置,或者想用 Codex 帮你做三节点配置交叉比对,可以先到 TaoToken 控制台创建 API Key,再按接入文档把 Base URL 配成https://taotoken.net/api。API Key 管理入口在控制台的 API Keys 页面,接入文档里有 Codex、Claude Code 等工具的配置示例。配置对照和报错分析属于接入与排障场景,走 API Keys 加接入文档这条路径最直接。
如果你不只是临时排障,而是长期要做 Pulsar 集群维护、配置审计或者 Agent 辅助运维,可以了解一下 Coding Plan,适合需要持续调用模型做配置检查和日志分析的场景。验证模型是否连通时,直接用模型对话发一条测试消息即可。集群配通之后,继续用pulsar-client做 consume 和 produce 测试,确认消息链路完整。