ZooKeeper 启动后 2181 端口未监听排查与修复记录
一、问题描述
在 Linux 服务器中执行 ZooKeeper 启动命令后,控制台提示服务已经运行:
./zkServer.sh start
启动输出如下:
ZooKeeper JMX enabled by default
Using config: /usr/local/zookeeper/bin/../conf/zoo.cfg
Starting zookeeper ... already running as process 4446.
但继续检查端口时,发现 2181 和配置中的管理端口 8085 均未监听:
sudo netstat -tunlp | grep 2181
sudo netstat -tunlp | grep 8085
这说明现象上看似"已经启动",但实际上 ZooKeeper 并没有正常对外提供服务。
二、问题分析
1. 表面现象与真实状态不一致
zkServer.sh start 返回 already running as process 4446,只能说明启动脚本检测到了一个已有的进程号,并不代表 ZooKeeper 当前一定运行正常,更不代表端口已经成功监听。
2. 启动脚本的判断机制
ZooKeeper 的 zkServer.sh 脚本会根据 zoo.cfg 中的 dataDir 路径,默认在该目录下生成 PID 文件:
/usr/local/zookeeper/data/zookeeper_server.pid
脚本再次启动时,会优先读取该 PID 文件中的进程号,并判断该进程是否存在。如果进程号存在,就会直接提示:
already running as process xxxx
因此,当 PID 文件残留、内容失效、或者对应进程状态异常时,就会出现"脚本判断已启动,但服务实际不可用"的问题。
3. 本次问题的根因
本次问题最终确认是:
-
dataDir目录下残留了旧的 PID 文件 -
启动脚本读取到了旧的进程号
-
脚本误认为 ZooKeeper 已经在运行
-
实际上 2181 端口并没有被正常监听
根因文件如下:
/usr/local/zookeeper/data/zookeeper_server.pid
三、排查过程
1. 先确认配置文件
查看 zoo.cfg,确认 ZooKeeper 的基础配置如下:
tickTime=2000
initLimit=10
syncLimit=5
dataDir=/usr/local/zookeeper/data
dataLogDir=/usr/local/zookeeper/dataLog
admin.serverPort=8085
clientPort=2181
从配置上看,客户端端口为 2181,管理端口为 8085,理论上正常启动后应至少能看到 2181 监听。
2. 检查端口监听状态
执行以下命令检查端口:
sudo netstat -tunlp | grep 2181
sudo netstat -tunlp | grep 8085
检查结果为空,说明 ZooKeeper 实际没有成功监听端口。
3. 检查启动脚本提示
进入 bin 目录再次执行启动命令:
./zkServer.sh start
脚本提示:
Starting zookeeper ... already running as process 4446.
这一步进一步说明,问题不在"启动命令没有执行",而在于"脚本错误地判断服务已运行"。
4. 结合目录结构定位 PID 文件位置
根据 ZooKeeper 启动脚本机制,以及当前配置中的 dataDir=/usr/local/zookeeper/data,可以判断 PID 文件默认不在安装根目录,而是在 dataDir 下。
因此,本次重点排查文件为:
/usr/local/zookeeper/data/zookeeper_server.pid
5. 锁定问题
当端口未监听、但启动脚本又提示 already running 时,最典型的原因就是 PID 文件残留。
也就是说:
-
ZooKeeper 之前可能异常退出
-
PID 文件没有被正常清理
-
后续重启时脚本误判为服务仍在运行
至此,问题定位完成。
四、解决问题过程
1. 删除残留 PID 文件
执行以下命令删除无效 PID 文件:
rm -f /usr/local/zookeeper/data/zookeeper_server.pid
2. 重新启动 ZooKeeper
重新执行启动命令:
cd /usr/local/zookeeper/bin
./zkServer.sh start
3. 再次验证端口
启动后重新检查:
sudo netstat -tunlp | grep 2181
此时 2181 端口恢复正常监听,说明 ZooKeeper 已重新启动成功,问题修复完成。
五、最终结论
本次问题并不是 ZooKeeper 正常运行而端口未显示,而是 ZooKeeper 实际未成功提供服务,启动脚本又被残留 PID 文件误导,导致出现"显示已启动、实际未监听"的假象。
最终修复方式为:
rm -f /usr/local/zookeeper/data/zookeeper_server.pid
cd /usr/local/zookeeper/bin
./zkServer.sh start
修复后,2181 端口恢复正常。
六、经验总结
-
zkServer.sh start提示already running时,不能直接认为服务一定正常。 -
端口是否监听,才是判断 ZooKeeper 是否真正可用的重要依据。
-
ZooKeeper 的 PID 文件默认位于
dataDir目录下,而不是安装根目录。 -
如果出现"无法启动但提示已运行"的情况,应优先检查并清理残留的
zookeeper_server.pid文件。