跳到主要内容

故障排除

本文档提供了 ZHub 使用过程中常见问题的诊断和解决方案。


连接问题

1. 客户端连接失败

症状

  • 客户端无法连接到 ZHub 服务
  • 连接超时或连接被拒绝

可能原因

  • 服务未启动
  • 端口被占用
  • 网络连接问题
  • 防火墙阻止连接

诊断步骤

# 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

解决方案

# 启动服务
./zhub.sh

# 检查配置文件
cat app.ini

# 修改端口(如果冲突)
# 编辑 app.ini 文件
[service]
addr=0.0.0.0:1217 # 修改端口
watch=0.0.0.0:712 # 修改管理端口

2. 连接频繁断开

症状

  • 客户端连接后频繁断开重连
  • 日志中出现连接异常

可能原因

  • 网络不稳定
  • 服务端资源不足
  • 客户端配置问题

解决方案

// 客户端配置优化
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 格式错误
  • 权限配置错误

诊断步骤

# 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

解决方案

# 更新 auth.yml 中的 token 过期时间
tokens:
- id: 1
user_id: 1
token: "token-12345"
expiration: "2030-12-31T23:59:59Z" # 延长过期时间
status: "active"

2. Topic 权限不足

症状

  • 无法订阅或发布特定 Topic
  • 权限验证失败

解决方案

# 在 auth.yml 中添加权限
users:
- id: 2
username: "client-001"
reads: ["user.*", "order.*"] # 添加读取权限
writes: ["user.*"] # 添加写入权限

消息问题

1. 消息丢失

症状

  • 发送的消息未被接收
  • 消息处理不完整

可能原因

  • 网络问题
  • 客户端处理异常
  • 服务端资源不足

诊断步骤

# 1. 检查服务状态
curl http://127.0.0.1:711/_/info

# 2. 查看服务日志
tail -f zhub.log

# 3. 检查内存使用
curl http://127.0.0.1:711/_/cleanup

解决方案

// 客户端消息处理优化
zhub.subscribe("topic-name", message -> {
try {
// 处理消息
processMessage(message);
} catch (Exception e) {
logger.error("消息处理失败", e);
// 记录失败消息,后续重试
}
});

RPC 问题

1. RPC 调用超时

症状

  • RPC 调用长时间无响应
  • 超时异常

可能原因

  • 服务端处理时间过长
  • 网络延迟
  • 服务端异常

解决方案

// RPC 调用(基础版本)
RpcResult<String> 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 调用返回错误码
  • 服务端未响应

诊断步骤

// 检查 RPC 结果
RpcResult<String> result = zhub.rpc("rpc-topic", "data", IType.STRING);
if (result.getRetcode() != 0) {
logger.error("RPC 调用失败: code={}, msg={}",
result.getRetcode(), result.getRetmsg());
}

解决方案

// 服务端 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. 内存使用过高

症状

  • 服务端内存持续增长
  • 系统响应变慢

诊断步骤

# 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

解决方案

# 优化 app.ini 配置
[log]
level=info # 降低日志级别
handlers=file # 使用文件日志

[data]
dir=./data # 确保数据目录存在

2. 消息处理缓慢

症状

  • 消息处理延迟增加
  • 系统吞吐量下降

解决方案

// 使用异步处理
zhub.subscribe("topic-name", message -> {
CompletableFuture.runAsync(() -> {
processMessage(message);
});
});

定时任务问题

1. 定时任务不执行

症状

  • 配置的定时任务未执行
  • 任务状态异常

诊断步骤

# 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;"

解决方案

-- 检查定时任务配置
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. 定时任务重复执行

症状

  • 同一个定时任务被多次执行
  • 业务逻辑重复处理

解决方案

-- 确保单实例执行
UPDATE tasktimer SET single = 1 WHERE name = 'task-name';

分布式锁问题

1. 锁获取失败

症状

  • 无法获取分布式锁
  • 业务逻辑无法执行

解决方案

// 优化锁获取逻辑
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. 死锁问题

症状

  • 系统卡死
  • 资源无法释放

解决方案

// 避免死锁的最佳实践
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();
}
}

监控和诊断

基础监控

# 检查服务状态
curl http://127.0.0.1:711/_/info

# 查看服务日志
tail -f zhub.log

# 检查内存使用
free -h

联系支持

如果遇到无法解决的问题,请提供:

  1. 错误日志: 完整的错误信息
  2. 配置信息: app.ini 和 auth.yml 配置
  3. 复现步骤: 详细的问题复现步骤

更多技术支持信息请参考 FAQ 文档