422 lines
7.5 KiB
Markdown
422 lines
7.5 KiB
Markdown
---
|
||
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<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 调用返回错误码
|
||
- 服务端未响应
|
||
|
||
**诊断步骤**:
|
||
```java
|
||
// 检查 RPC 结果
|
||
RpcResult<String> 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)。
|