--- sidebar_position: 10 title: 故障排除 description: ZHub 常见问题和解决方案 --- # 故障排除 本文档提供了 ZHub 使用过程中常见问题的诊断和解决方案。 --- ## 连接问题 ### 1. 客户端连接失败 **症状**: - 客户端无法连接到 ZHub 服务 - 连接超时或连接被拒绝 **可能原因**: - 服务未启动 - 端口被占用 - 网络连接问题 - 防火墙阻止连接 **诊断步骤**: ```bash # 1. 检查服务是否运行 ps aux | grep zhub # 2. 检查端口是否监听 netstat -tulpn | grep :1216 netstat -tulpn | grep :711 # 3. 测试端口连通性 telnet 127.0.0.1 1216 telnet 127.0.0.1 711 ``` **解决方案**: ```bash # 启动服务 ./zhub.sh # 检查配置文件 cat app.ini # 修改端口(如果冲突) # 编辑 app.ini 文件 [service] addr=0.0.0.0:1217 # 修改端口 watch=0.0.0.0:712 # 修改管理端口 ``` ### 2. 连接频繁断开 **症状**: - 客户端连接后频繁断开重连 - 日志中出现连接异常 **可能原因**: - 网络不稳定 - 服务端资源不足 - 客户端配置问题 **解决方案**: ```java // 客户端配置优化 ZHubClient zhub = new ZHubClient( "127.0.0.1:1216", "groupid", "appid", "token" ); // 重新创建客户端连接(使用正确的参数) zhub = new ZHubClient("127.0.0.1:1216", "groupid", "appid", "token"); ``` --- ## 权限问题 ### 1. 认证失败 **症状**: - 客户端连接时提示认证失败 - 日志显示 "invalid or expired token" **可能原因**: - Token 过期 - Token 格式错误 - 权限配置错误 **诊断步骤**: ```bash # 1. 检查权限配置 curl http://127.0.0.1:711/_/info # 2. 检查 auth.yml 文件 cat auth.yml # 3. 重新加载权限配置 curl http://127.0.0.1:711/auth/reload ``` **解决方案**: ```yaml # 更新 auth.yml 中的 token 过期时间 tokens: - id: 1 user_id: 1 token: "token-12345" expiration: "2030-12-31T23:59:59Z" # 延长过期时间 status: "active" ``` ### 2. Topic 权限不足 **症状**: - 无法订阅或发布特定 Topic - 权限验证失败 **解决方案**: ```yaml # 在 auth.yml 中添加权限 users: - id: 2 username: "client-001" reads: ["user.*", "order.*"] # 添加读取权限 writes: ["user.*"] # 添加写入权限 ``` --- ## 消息问题 ### 1. 消息丢失 **症状**: - 发送的消息未被接收 - 消息处理不完整 **可能原因**: - 网络问题 - 客户端处理异常 - 服务端资源不足 **诊断步骤**: ```bash # 1. 检查服务状态 curl http://127.0.0.1:711/_/info # 2. 查看服务日志 tail -f zhub.log # 3. 检查内存使用 curl http://127.0.0.1:711/_/cleanup ``` **解决方案**: ```java // 客户端消息处理优化 zhub.subscribe("topic-name", message -> { try { // 处理消息 processMessage(message); } catch (Exception e) { logger.error("消息处理失败", e); // 记录失败消息,后续重试 } }); ``` --- ## RPC 问题 ### 1. RPC 调用超时 **症状**: - RPC 调用长时间无响应 - 超时异常 **可能原因**: - 服务端处理时间过长 - 网络延迟 - 服务端异常 **解决方案**: ```java // RPC 调用(基础版本) RpcResult result = zhub.rpc("rpc-topic", "data", IType.STRING); if (result.getRetcode() == 0) { System.out.println("RPC 调用成功: " + result.getResult()); } else { System.err.println("RPC 调用失败: " + result.getRetmsg()); } ``` ### 2. RPC 调用失败 **症状**: - RPC 调用返回错误码 - 服务端未响应 **诊断步骤**: ```java // 检查 RPC 结果 RpcResult result = zhub.rpc("rpc-topic", "data", IType.STRING); if (result.getRetcode() != 0) { logger.error("RPC 调用失败: code={}, msg={}", result.getRetcode(), result.getRetmsg()); } ``` **解决方案**: ```java // 服务端 RPC 处理优化 zhub.rpcSubscribe("rpc-topic", IType.STRING, request -> { try { String data = request.getValue(); // 处理业务逻辑 String result = processData(data); return request.render(result); } catch (Exception e) { logger.error("RPC 处理异常", e); return request.retError("服务处理失败: " + e.getMessage()); } }); ``` --- ## 性能问题 ### 1. 内存使用过高 **症状**: - 服务端内存持续增长 - 系统响应变慢 **诊断步骤**: ```bash # 1. 检查内存使用 free -h top -p $(pgrep zhub) # 2. 查看服务状态 curl http://127.0.0.1:711/_/info # 3. 清理内存 curl http://127.0.0.1:711/_/cleanup ``` **解决方案**: ```ini # 优化 app.ini 配置 [log] level=info # 降低日志级别 handlers=file # 使用文件日志 [data] dir=./data # 确保数据目录存在 ``` ### 2. 消息处理缓慢 **症状**: - 消息处理延迟增加 - 系统吞吐量下降 **解决方案**: ```java // 使用异步处理 zhub.subscribe("topic-name", message -> { CompletableFuture.runAsync(() -> { processMessage(message); }); }); ``` --- ## 定时任务问题 ### 1. 定时任务不执行 **症状**: - 配置的定时任务未执行 - 任务状态异常 **诊断步骤**: ```bash # 1. 检查数据库连接 curl http://127.0.0.1:711/_/info # 2. 重新加载定时任务 curl http://127.0.0.1:711/timer/reload # 3. 检查数据库配置 mysql -u root -p -e "SELECT * FROM zhub.tasktimer WHERE status = 10;" ``` **解决方案**: ```sql -- 检查定时任务配置 SELECT timerid, name, expr, single, status FROM tasktimer; -- 更新任务状态 UPDATE tasktimer SET status = 10 WHERE name = 'task-name'; -- 检查时间表达式格式 UPDATE tasktimer SET expr = '*/5 * * * * ?' WHERE name = 'task-name'; ``` ### 2. 定时任务重复执行 **症状**: - 同一个定时任务被多次执行 - 业务逻辑重复处理 **解决方案**: ```sql -- 确保单实例执行 UPDATE tasktimer SET single = 1 WHERE name = 'task-name'; ``` --- ## 分布式锁问题 ### 1. 锁获取失败 **症状**: - 无法获取分布式锁 - 业务逻辑无法执行 **解决方案**: ```java // 优化锁获取逻辑 public boolean processWithLock(String resourceKey) { Lock lock = zhub.tryLock(resourceKey, 10); // 10秒超时 if (!lock.success()) { logger.warn("获取锁失败,资源被占用: {}", resourceKey); return false; } try { // 执行业务逻辑 processResource(resourceKey); return true; } finally { lock.unLock(); } } ``` ### 2. 死锁问题 **症状**: - 系统卡死 - 资源无法释放 **解决方案**: ```java // 避免死锁的最佳实践 public void safeProcess() { // 1. 避免嵌套锁 // 2. 设置合理的超时时间 // 3. 确保锁的释放 Lock lock1 = zhub.tryLock("resource1", 5); if (!lock1.success()) return; try { Lock lock2 = zhub.tryLock("resource2", 5); if (!lock2.success()) return; try { // 业务逻辑 } finally { lock2.unLock(); } } finally { lock1.unLock(); } } ``` --- ## 监控和诊断 ### 基础监控 ```bash # 检查服务状态 curl http://127.0.0.1:711/_/info # 查看服务日志 tail -f zhub.log # 检查内存使用 free -h ``` --- ## 联系支持 如果遇到无法解决的问题,请提供: 1. **错误日志**: 完整的错误信息 2. **配置信息**: app.ini 和 auth.yml 配置 3. **复现步骤**: 详细的问题复现步骤 更多技术支持信息请参考 [FAQ 文档](./faq.md)。