添加:ZHub 管理接口文档和客户端使用指南

This commit is contained in:
2025-09-23 21:48:31 +08:00
parent 88011cf20b
commit 5af775e525
35 changed files with 4133 additions and 412 deletions

View File

@@ -3,6 +3,6 @@
"position": 3,
"link": {
"type": "generated-index",
"description": "分布式系统常用组件"
"description": "ZHub 高级功能配置,包含权限管理、性能优化、安全实践等"
}
}

View File

@@ -0,0 +1,148 @@
---
sidebar_position: 1
title: API 参考
description: ZHub 完整 API 参考文档
---
# API 参考
ZHub 客户端和管理接口的完整参考。
## 客户端 API
### 创建连接
```java
// 基础连接
ZHubClient zhub = new ZHubClient("127.0.0.1:1216", "group1", "app1");
// 带认证连接
ZHubClient zhub = new ZHubClient("127.0.0.1:1216", "group1", "app1", "token123");
```
**参数**
- `addr`: 服务地址 `IP:端口`
- `groupId`: 组名
- `appId`: 应用ID唯一
- `auth`: 认证码(可选)
### 消息操作
#### 发布订阅
```java
// 发布消息
zhub.publish("user.login", "用户登录");
// 订阅消息
zhub.subscribe("user.login", message -> {
System.out.println("收到: " + message);
});
```
#### 广播消息
```java
// 广播给所有客户端
zhub.broadcast("topic-abc", "hello!");
```
#### 延时消息
```java
// 30秒后发送
zhub.delay("order.timeout", "订单超时", 30000);
```
### RPC 调用
#### 提供服务
```java
// 提供 RPC 服务
zhub.rpcSubscribe("user.getInfo", IType.STRING, request -> {
String userId = request.getValue();
return request.render("用户信息: " + userId);
});
```
#### 调用服务
```java
// 调用 RPC 服务
RpcResult<String> result = zhub.rpc("user.getInfo", "user123", IType.STRING);
if (result.isSuccess()) {
System.out.println("结果: " + result.getResult());
}
```
### 定时任务
```java
// 订阅定时任务
zhub.timer("T:A", () -> {
System.out.println("定时执行");
});
```
### 分布式锁
```java
// 获取锁
Lock lock = zhub.tryLock("resource-key", 30);
if (lock.success()) {
try {
// 执行业务逻辑
} finally {
lock.unLock();
}
}
```
---
## 管理接口
### 查看服务状态
```bash
# 查看服务信息
curl http://127.0.0.1:711/_/info
# 查看版本
curl http://127.0.0.1:711/_/version
```
### 管理操作
```bash
# 清理内存
curl http://127.0.0.1:711/_/cleanup
# 重载定时任务
curl http://127.0.0.1:711/timer/reload
# 重载权限配置
curl http://127.0.0.1:711/auth/reload
```
### 发送消息
```bash
# 发布消息
curl -X POST http://127.0.0.1:711/message/send \
-d "type=publish&name=user.login&value=用户登录"
```
---
## 常用类型
### IType 类型
```java
IType.STRING // 字符串
IType.INT // 整数
IType.LONG // 长整数
IType.DOUBLE // 浮点数
IType.MAP // 键值对
```
### 错误码
| 错误码 | 说明 |
|--------|------|
| 0 | 成功 |
| 501 | 请求失败 |
| 505 | 请求超时 |
| 401 | 认证失败 |

View File

@@ -0,0 +1,191 @@
---
sidebar_position: 5
title: 权限配置
description: ZHub 权限配置和认证管理
---
# ZHub 权限配置
## 配置方式
- **app.ini**: 开启/关闭权限验证
- **auth.yml**: 详细权限配置
## 权限控制
- **连接认证**通过Token验证客户端身份
- **主题权限**:控制对特定主题的读写权限
- **操作类型**:区分读取(r)和写入(w)操作
## 基础配置
**开启权限验证**
```ini
[service]
auth=1 # 开启连接授权
```
**关闭权限验证**
```ini
[service]
auth=0 # 关闭连接授权(内网环境)
```
---
## auth.yml 配置文件
### 配置文件结构
```yaml
# auth.yml 权限配置文件
users:
- id: 1
username: "admin"
password: "admin123"
status: "active"
groups: ["admin"]
reads: ["*"] # 读取权限
writes: ["*"] # 写入权限
- id: 2
username: "client-001"
password: "client123"
status: "active"
groups: ["client"]
reads: ["user.*", "order.*"] # 可读取 user.* 和 order.* 主题
writes: ["user.*"] # 可写入 user.* 主题
groups:
- name: "admin"
description: "管理员组"
reads: ["*"]
writes: ["*"]
- name: "client"
description: "客户端组"
reads: ["user.*", "order.*"]
writes: ["user.*"]
```
### 配置说明
#### 用户配置 (users)
- **id**: 用户唯一标识
- **username**: 用户名
- **password**: 密码
- **status**: 用户状态 (active/inactive)
- **groups**: 所属用户组列表
- **reads**: 读取权限列表,支持正则表达式
- **writes**: 写入权限列表,支持正则表达式
#### 用户组配置 (groups)
- **name**: 组名
- **description**: 组描述
- **reads**: 组读取权限
- **writes**: 组写入权限
---
## 客户端连接配置
### Java 项目
```java
// 带认证的连接
ZHubClient zhub = new ZHubClient(
"127.0.0.1:1216", // 服务地址
"groupid-x", // 消费者组
"appid-unique-001", // 应用ID必须唯一
"token-12345" // 认证令牌
);
```
### SpringBoot 项目
```yaml
# application.yml
zhub:
addr: 127.0.0.1:1216
groupid: groupid-x
appid: appid-unique-002
auth: token-12345
```
---
## 重要注意事项
### AppID 唯一性
:::warning 关键要求
- **每个客户端必须使用不同的 appid**
- RPC 消息回复使用 appid 标识
- 相同 appid 会导致 RPC 消息回复失败
:::
### 权限管理
```bash
# 重新加载权限配置
curl http://127.0.0.1:711/auth/reload
```
### 内网环境
```ini
# app.ini - 关闭权限验证(仅内网环境)
[service]
auth=0
```
### 权限配置示例
```yaml
users:
- id: 1
username: "user-service"
reads: ["user.*"] # 匹配 user.login, user.profile 等
writes: ["user.*"]
- id: 2
username: "order-service"
reads: ["order.*", "user.basic.*"]
writes: ["order.*"]
- id: 3
username: "admin-service"
reads: ["*"] # 匹配所有主题
writes: ["*"]
```
---
## 管理接口
```bash
# 重新加载权限配置
curl http://127.0.0.1:711/auth/reload
# 查看服务状态
curl http://127.0.0.1:711/_/info
```
## 最佳实践
### Topic 命名规范
```
team.service.action
# 示例:
user.profile.update
order.payment.process
```
### 权限最小化
```yaml
# 只给必要的权限
- id: 1
username: "order-service"
reads: ["order.*", "user.basic.*"]
writes: ["order.*"]
```
### 环境配置
- **开发环境**: 可关闭权限验证 (`auth=0`)
- **生产环境**: 必须开启权限验证 (`auth=1`)
- 使用强随机 Token
- 定期轮换 Token

View File

@@ -0,0 +1,169 @@
---
sidebar_position: 6
title: Docker 部署
description: ZHub Docker 容器化部署指南
---
# Docker 部署
ZHub 支持 Docker 容器化部署,提供简化的构建和运行方式。
## 快速开始
### 1. 准备文件
从 [https://zhub.dev/release/latest/](https://zhub.dev/release/latest/) 下载软件包并解压:
```bash
# 解压后目录结构
zhub/
├── zhub.sh # 可执行文件
├── app.ini # 配置文件
└── auth.yml # 权限配置文件(可选)
```
### 2. 构建镜像
创建 `Dockerfile` 文件:
```dockerfile
# 使用Alpine Linux作为基础镜像
FROM alpine:latest
# 设置工作目录
WORKDIR /opt/zhub
# 复制解压后的文件
COPY zhub.sh ./
COPY app.ini ./
COPY auth.yml ./
# 给执行文件添加执行权限
RUN chmod +x ./zhub.sh
# 暴露端口
# 711: 管理接口端口
# 1216: 服务端口
EXPOSE 711 1216
# 设置启动命令
CMD ["./zhub.sh"]
```
构建镜像:
```bash
# 构建镜像
docker build -t zhub:latest .
```
### 3. 运行容器
```bash
# 基础运行
docker run -d -p 711:711 -p 1216:1216 --name zhub zhub:latest
# 带数据持久化
docker run -d \
-p 711:711 \
-p 1216:1216 \
-v /host/data:/opt/zhub/data \
--name zhub \
zhub:latest
```
### 4. 验证部署
```bash
# 检查服务状态
curl http://localhost:711/_/info
# 查看容器日志
docker logs -f zhub
```
## 生产环境配置
### 数据持久化
```bash
# 挂载数据目录
docker run -d \
-p 711:711 \
-p 1216:1216 \
-v /host/data:/opt/zhub/data \
--name zhub \
zhub:latest
```
### 自定义配置
```bash
# 挂载自定义配置文件
docker run -d \
-p 711:711 \
-p 1216:1216 \
-v /host/config/app.ini:/opt/zhub/app.ini \
-v /host/config/auth.yml:/opt/zhub/auth.yml \
--name zhub \
zhub:latest
```
## Docker Compose 部署
### 基础配置
创建 `docker-compose.yml` 文件:
```yaml
version: '3.8'
services:
zhub:
image: zhub:latest
container_name: zhub
ports:
- "711:711" # 管理端口
- "1216:1216" # 服务端口
volumes:
- ./data:/opt/zhub/data
restart: unless-stopped
```
### 启动服务
```bash
# 启动服务
docker-compose up -d
# 查看服务状态
docker-compose ps
# 停止服务
docker-compose down
```
## 故障排除
### 常见问题
```bash
# 查看容器日志
docker logs zhub
# 检查端口占用
netstat -tulpn | grep :1216
netstat -tulpn | grep :711
# 检查服务状态
curl http://localhost:711/_/info
```
### 调试模式
```bash
# 以调试模式运行
docker run -it --rm \
-p 711:711 \
-p 1216:1216 \
-v ./data:/opt/zhub/data \
zhub:latest
```

497
docs/tutorial-extras/faq.md Normal file
View File

@@ -0,0 +1,497 @@
---
sidebar_position: 11
title: 常见问题
description: ZHub 常见问题解答
---
# 常见问题
本文档收集了 ZHub 使用过程中的常见问题和解答。
---
## 基础问题
### Q: ZHub 是什么?
A: ZHub 是一个高性能的事件发布订阅服务组件,支持发布-订阅、广播消息、延时消息、RPC调用、分布式定时调度、分布式锁等功能。运行包仅有1M+初始启动内存10M-。
### Q: ZHub 支持哪些编程语言?
A: 目前主要支持:
- **Java**: 提供完整的客户端 SDK
- **Go**: 服务端使用 Go 语言开发
- **其他语言**: 可以通过 HTTP API 接入
### Q: ZHub 的性能如何?
A: ZHub 具有以下性能特点:
- 运行包仅 1M+
- 初始启动内存 10M-
- 支持高并发消息处理
- 低延迟消息传递
---
## 安装和配置
### Q: 如何安装 ZHub
A: 安装步骤:
1. 下载 `zhub.zip` 发布包
2. 解压到目标目录
3. 配置 `app.ini` 文件
4. 运行 `./zhub.sh`Linux`./zhub.exe`Windows
### Q: 如何配置 ZHub
A: 主要配置文件是 `app.ini`
```ini
[service]
watch=0.0.0.0:711 # 管理端口
addr=0.0.0.0:1216 # 服务端口
auth=0 # 是否开启认证
[data]
dir=./data # 数据目录
[log]
handlers=console # 日志处理器
level=debug # 日志级别
```
### Q: 如何开启权限验证?
A: 在 `app.ini` 中设置 `auth=1`,并配置 `auth.yml` 文件:
```yaml
users:
- id: 1
username: "client-001"
password: "password123"
status: "active"
reads: ["*"]
writes: ["*"]
```
---
## 客户端使用
### Q: 如何创建客户端连接?
A: Java 客户端连接:
```java
// 基础连接
ZHubClient zhub = new ZHubClient("127.0.0.1:1216", "group1", "app1");
// 带认证连接
ZHubClient zhub = new ZHubClient("127.0.0.1:1216", "group1", "app1", "token");
```
### Q: 为什么需要唯一的 appid
A: appid 用于标识客户端实例,特别是在 RPC 调用中:
- RPC 消息回复地址使用 appid 标识
- 多个客户端使用相同 appid 会导致 RPC 消息回复找不到目标
- 建议使用有意义的命名:`project-module-001`
### Q: 如何发布和订阅消息?
A: 基础用法:
```java
// 订阅消息
zhub.subscribe("topic", message -> {
System.out.println("收到消息: " + message);
});
// 发布消息
zhub.publish("topic", "Hello ZHub!");
```
---
## 功能使用
### Q: 如何实现 RPC 调用?
A: RPC 使用示例:
```java
// 服务端
zhub.rpcSubscribe("user.getInfo", IType.STRING, request -> {
String userId = request.getValue();
return request.render("用户信息: " + userId);
});
// 客户端
RpcResult<String> result = zhub.rpc("user.getInfo", "user123", IType.STRING);
System.out.println("结果: " + result.getResult());
```
### Q: 如何实现分布式锁?
A: 分布式锁使用:
```java
// 阻塞式获取锁
Lock lock = zhub.lock("resource-key", 30);
try {
if (lock.success()) {
// 执行业务逻辑
}
} finally {
lock.unLock();
}
// 非阻塞式获取锁
Lock lock = zhub.tryLock("resource-key", 30);
if (lock.success()) {
try {
// 执行业务逻辑
} finally {
lock.unLock();
}
}
```
### Q: 如何实现定时任务?
A: 定时任务使用:
```java
// 订阅定时任务
zhub.timer("T:A", () -> {
System.out.println("定时任务执行");
});
```
需要在数据库中配置定时任务:
```sql
INSERT INTO tasktimer (timerid, name, expr, single, remark, status) VALUES
('T1', 'T:A', '*/5 * * * * ?', 1, '每5秒执行一次', 10);
```
---
## 权限和安全
### Q: 如何配置用户权限?
A: 在 `auth.yml` 中配置用户权限:
```yaml
users:
- id: 1
username: "user-service"
password: "password123"
status: "active"
groups: ["user-service"]
reads: ["user.*"] # 读取权限
writes: ["user.*"] # 写入权限
```
### Q: 如何实现细粒度权限控制?
A: 使用正则表达式控制 Topic 权限:
```yaml
users:
- id: 1
username: "client-001"
reads: ["user.*", "order.*"] # 可读取 user.* 和 order.* 主题
writes: ["user.*"] # 只能写入 user.* 主题
```
### Q: Token 过期了怎么办?
A: 解决方案:
1. **延长 Token 过期时间**
```yaml
tokens:
- id: 1
token: "token-12345"
expiration: "2030-12-31T23:59:59Z" # 设置较长时间
```
2. **重新加载权限配置**
```bash
curl http://127.0.0.1:711/auth/reload
```
3. **仅在开发环境关闭权限验证**
```ini
[service]
auth=0 # 仅适用于完全隔离的开发测试环境
```
:::warning 安全提醒
- 生产环境强烈建议开启权限验证,即使在内网环境
- 关闭权限验证存在安全风险,仅适用于开发测试环境
:::
---
## 数据库配置
### Q: 支持哪些数据库?
A: ZHub 支持以下数据库:
- **MySQL**: 默认支持
- **PostgreSQL**: 支持
### Q: 如何配置数据库连接?
A: 在 `app.ini` 中配置:
```ini
[ztimer]
db.addr=127.0.0.1:3306
db.user=root
db.password=123456
db.database=zhub
db.schema=public # PostgreSQL 模式名
db.type=mysql # mysql|postgres
```
### Q: 如何初始化数据库表?
A: MySQL 初始化:
```sql
CREATE TABLE `tasktimer` (
`timerid` varchar(64) NOT NULL DEFAULT '' PRIMARY KEY,
`name` varchar(32) NOT NULL DEFAULT '',
`expr` varchar(32) NOT NULL DEFAULT '',
`single` int NOT NULL DEFAULT '1',
`remark` varchar(128) NOT NULL DEFAULT '',
`status` smallint NOT NULL DEFAULT '10'
);
```
PostgreSQL 初始化:
```sql
CREATE TABLE tasktimer (
timerid varchar(64) NOT NULL DEFAULT '' PRIMARY KEY,
name varchar(32) NOT NULL DEFAULT '',
expr varchar(32) NOT NULL DEFAULT '',
single int NOT NULL DEFAULT 1,
remark varchar(128) NOT NULL DEFAULT '',
status smallint NOT NULL DEFAULT 10
);
```
---
## 性能优化
### Q: 如何提高消息处理性能?
A: 性能优化建议:
1. **异步处理消息**
```java
zhub.subscribe("topic", message -> {
CompletableFuture.runAsync(() -> {
processMessage(message);
});
});
```
2. **批量处理消息**
```java
private final List<String> messageBatch = new ArrayList<>();
zhub.subscribe("topic", message -> {
synchronized (messageBatch) {
messageBatch.add(message);
if (messageBatch.size() >= 100) {
processBatch(new ArrayList<>(messageBatch));
messageBatch.clear();
}
}
});
```
3. **使用连接池**
```java
// 复用连接,避免频繁创建
private static final ZHubClient zhub = new ZHubClient(...);
```
### Q: 如何监控性能?
A: 监控方法:
1. **使用管理接口**
```bash
curl http://127.0.0.1:711/_/info
```
2. **客户端监控**
```java
public class PerformanceMonitor {
private final AtomicLong messageCount = new AtomicLong(0);
public void monitorMessage(String message) {
messageCount.incrementAndGet();
// 处理消息
}
}
```
---
## 故障排除
### Q: 客户端连接失败怎么办?
A: 排查步骤:
1. **检查服务是否运行**
```bash
ps aux | grep zhub
```
2. **检查端口是否监听**
```bash
netstat -tulpn | grep :1216
```
3. **检查网络连接**
```bash
telnet 127.0.0.1 1216
```
4. **检查防火墙设置**
```bash
ufw status
iptables -L
```
### Q: 消息丢失怎么办?
A: 消息丢失排查:
1. **检查网络连接**:确保网络稳定
2. **检查客户端处理**:确保消息处理逻辑正确
3. **检查服务端资源**:确保服务端有足够资源
4. **使用管理接口清理内存**
```bash
curl http://127.0.0.1:711/_/cleanup
```
### Q: RPC 调用超时怎么办?
A: RPC 超时解决:
1. **增加超时时间**
```java
RpcResult<String> result = zhub.rpc("rpc-topic", "data", IType.STRING, 30000);
```
2. **使用异步 RPC**
```java
CompletableFuture<RpcResult<String>> future =
zhub.rpcAsync("rpc-topic", "data", IType.STRING);
```
3. **检查服务端处理时间**:优化服务端处理逻辑
### Q: 定时任务不执行怎么办?
A: 定时任务排查:
1. **检查数据库连接**
```bash
curl http://127.0.0.1:711/_/info
```
2. **重新加载定时任务**
```bash
curl http://127.0.0.1:711/timer/reload
```
3. **检查任务状态**
```sql
SELECT * FROM tasktimer WHERE status = 10;
```
---
## 部署问题
### Q: 如何部署到生产环境?
A: 生产环境部署建议:
1. **使用 Docker 部署**
```bash
docker run -d -p 711:711 -p 1216:1216 --name zhub zhub:latest
```
2. **配置数据持久化**
```bash
docker run -d -v /host/data:/opt/zhub/data zhub:latest
```
3. **配置环境变量**
```bash
docker run -d -e ZHUB_AUTH=1 zhub:latest
```
---
## 版本升级
### Q: 如何升级 ZHub
A: 升级步骤:
1. **备份数据**:备份数据目录和配置文件
2. **停止服务**:停止当前 ZHub 服务
3. **替换文件**:替换为新版本文件
4. **启动服务**:启动新版本服务
5. **验证功能**:验证各项功能正常
### Q: 升级后配置不兼容怎么办?
A: 配置兼容性处理:
1. **检查配置文件**:对比新旧配置文件
2. **更新配置格式**:按照新版本要求更新配置
3. **测试功能**:测试各项功能是否正常
4. **回滚准备**:准备回滚方案
---
## 性能优化
### Q: 如何优化 ZHub 性能?
A: 性能优化建议:
1. **异步处理**:避免阻塞消息处理
```java
zhub.subscribe("topic", message -> {
CompletableFuture.runAsync(() -> {
processMessage(message);
});
});
```
2. **错误处理**:添加异常捕获
```java
zhub.subscribe("topic", message -> {
try {
processMessage(message);
} catch (Exception e) {
logger.error("消息处理失败", e);
}
});
```
3. **内存管理**:定期清理内存
```bash
curl http://127.0.0.1:711/_/cleanup
```
### Q: 如何监控 ZHub 状态?
A: 监控方法:
1. **服务状态**`curl http://127.0.0.1:711/_/info`
2. **内存使用**`free -h`
3. **网络连接**`netstat -tulpn | grep :1216`
## 技术支持
### Q: 如何获取技术支持?
A: 技术支持渠道:
1. **查看文档**:参考官方文档
2. **查看日志**:检查服务端和客户端日志
3. **联系作者**
- 作者: 绝尘
- 微信: zhub_dev
- 邮箱: lxy208@126.com

View File

@@ -1,5 +1,314 @@
---
sidebar_position: 2
sidebar_position: 3
title: 分布式锁
description: ZHub 分布式锁功能详解
---
# 分布式锁
ZHub 提供了分布式锁功能,支持多客户端环境下的资源互斥访问控制。
---
## 功能特性
- **分布式互斥**: 多个客户端实例之间互斥访问共享资源
- **自动超时**: 支持锁超时自动释放,避免死锁
- **非阻塞获取**: 支持尝试获取锁,立即返回结果
- **自动释放**: 支持手动释放锁,确保资源及时释放
---
## 基础使用
### 1. 阻塞式获取锁
```java
// 获取锁,会阻塞直到获取成功或超时
Lock lock = zhub.lock("resource-key", 30); // 30秒超时
try {
if (lock.success()) {
System.out.println("获取到锁,开始处理业务");
// 执行业务逻辑
Thread.sleep(5000); // 模拟业务处理
} else {
System.out.println("获取锁失败");
}
} finally {
lock.unLock(); // 释放锁
}
```
### 2. 非阻塞式获取锁
```java
// 尝试获取锁,立即返回结果
Lock lock = zhub.tryLock("resource-key", 30);
if (lock.success()) {
try {
System.out.println("获取到锁,开始处理业务");
// 执行业务逻辑
} finally {
lock.unLock(); // 释放锁
}
} else {
System.out.println("未获取到锁,资源被其他客户端占用");
}
```
---
## 高级用法
### 1. 锁超时处理
```java
public void processWithTimeout(String resourceKey, int timeoutSeconds) {
Lock lock = zhub.tryLock(resourceKey, timeoutSeconds);
if (!lock.success()) {
System.out.println("资源被占用,请稍后重试");
return;
}
try {
// 业务处理
processResource(resourceKey);
} finally {
lock.unLock();
}
}
```
### 2. 锁重试机制
```java
public boolean processWithRetry(String resourceKey, int maxRetries) {
for (int i = 0; i < maxRetries; i++) {
Lock lock = zhub.tryLock(resourceKey, 10);
if (lock.success()) {
try {
// 业务处理
processResource(resourceKey);
return true;
} finally {
lock.unLock();
}
}
// 等待一段时间后重试
try {
Thread.sleep(1000 * (i + 1)); // 递增等待时间
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
break;
}
}
return false;
}
```
### 3. 锁监控和统计
```java
public class LockMonitor {
private final ZHubClient zhub;
private final Map<String, LockInfo> lockStats = new ConcurrentHashMap<>();
public void acquireLock(String key, int timeout) {
long startTime = System.currentTimeMillis();
Lock lock = zhub.lock(key, timeout);
if (lock.success()) {
long acquireTime = System.currentTimeMillis() - startTime;
lockStats.put(key, new LockInfo(key, acquireTime, System.currentTimeMillis()));
System.out.println("锁获取成功,耗时: " + acquireTime + "ms");
}
}
public void releaseLock(String key) {
LockInfo info = lockStats.remove(key);
if (info != null) {
long holdTime = System.currentTimeMillis() - info.acquireTime;
System.out.println("锁持有时间: " + holdTime + "ms");
}
}
static class LockInfo {
String key;
long acquireTime;
long acquireDuration;
LockInfo(String key, long acquireDuration, long acquireTime) {
this.key = key;
this.acquireDuration = acquireDuration;
this.acquireTime = acquireTime;
}
}
}
```
---
## 实现原理
### 服务端实现
ZHub 服务端锁管理结构:
```go
// 锁结构
type Lock struct {
Key string
UUID string
Duration int
Conn *ZConn
CreateTime time.Time
}
// 锁管理
type ZBus struct {
locks map[string][]*Lock // 锁映射表
// ... 其他字段
}
```
### 客户端实现
ZHub 客户端锁实现结构:
```java
public class Lock {
protected String name; // 锁名称
protected String uuid; // 锁唯一标识
protected int duration; // 锁持续时间
protected boolean success; // 获取是否成功
protected ZHubClient hubClient; // 客户端引用
}
```
---
## 最佳实践
### 1. 锁命名规范
```java
// 推荐:使用有意义的锁名称
String lockKey = "user:update:" + userId;
String lockKey = "order:process:" + orderId;
String lockKey = "cache:refresh:" + cacheType;
// 避免:使用无意义的锁名称
String lockKey = "lock1";
String lockKey = "temp";
```
### 2. 超时时间设置
```java
// 根据业务处理时间设置合理的超时时间
int shortTaskTimeout = 5; // 短任务5秒
int mediumTaskTimeout = 30; // 中等任务30秒
int longTaskTimeout = 300; // 长任务5分钟
// 避免设置过短或过长的超时时间
int tooShort = 1; // 太短,可能导致获取失败
int tooLong = 3600; // 太长,可能导致资源长时间占用
```
### 3. 异常处理
```java
public void safeProcess(String resourceKey) {
Lock lock = null;
try {
lock = zhub.lock(resourceKey, 30);
if (lock.success()) {
// 业务处理
processResource(resourceKey);
}
} catch (Exception e) {
logger.error("处理资源时发生异常", e);
} finally {
if (lock != null && lock.success()) {
try {
lock.unLock();
} catch (Exception e) {
logger.error("释放锁时发生异常", e);
}
}
}
}
```
### 4. 性能优化
```java
// 使用 tryLock 避免长时间阻塞
public boolean tryProcess(String resourceKey) {
Lock lock = zhub.tryLock(resourceKey, 5);
if (!lock.success()) {
return false; // 快速失败
}
try {
processResource(resourceKey);
return true;
} finally {
lock.unLock();
}
}
```
---
## 注意事项
### 1. 死锁预防
- 避免嵌套锁的使用
- 设置合理的锁超时时间
- 确保锁的释放逻辑正确
### 2. 性能考虑
- 锁的粒度要适中,不要过细或过粗
- 避免长时间持有锁
- 考虑使用非阻塞的 tryLock
### 3. 错误处理
- 始终在 finally 块中释放锁
- 处理锁获取失败的情况
- 记录锁的使用情况用于监控
---
## 监控和调试
### 1. 锁状态查询
```bash
# 通过管理接口查看锁状态
curl http://127.0.0.1:711/_/info
```
### 2. 日志监控
```java
// 在客户端代码中添加锁使用日志
logger.info("尝试获取锁: " + resourceKey);
Lock lock = zhub.lock(resourceKey, 30);
if (lock.success()) {
logger.info("锁获取成功: " + resourceKey);
} else {
logger.warn("锁获取失败: " + resourceKey);
}
```
### 3. 性能指标
- 锁获取成功率
- 锁平均持有时间
- 锁等待时间
- 锁竞争频率

View File

@@ -0,0 +1,132 @@
---
sidebar_position: 8
title: 安全最佳实践
description: ZHub 安全配置和最佳实践指南
---
# 安全最佳实践
ZHub 安全配置和最佳实践指南,帮助您构建安全的分布式系统。
## 认证和授权
### 启用权限验证
**服务端配置**
```ini
# app.ini - 生产环境配置
[service]
auth=1 # 生产环境必须开启连接授权
```
:::warning 重要安全提醒
**生产环境强烈建议开启权限验证**
- 关闭权限验证 (`auth=0`) 意味着任何客户端都可以无限制访问所有主题
- 即使在内网环境,也存在内部威胁、误操作、配置错误等风险
- 仅在完全隔离的开发测试环境可考虑关闭权限验证
:::
**客户端配置**
```java
// 使用认证令牌连接
ZHubClient zhub = new ZHubClient(
"127.0.0.1:1216",
"group1",
"app1",
"your-secure-token"
);
```
### 权限配置
**最小权限原则**
```yaml
# auth.yml
users:
- id: 1
username: "user-service"
password: "secure-password"
status: "active"
groups: ["user-service"]
reads: ["user.*"] # 只读用户相关主题
writes: ["user.*"] # 只写用户相关主题
- id: 2
username: "order-service"
password: "secure-password"
status: "active"
groups: ["order-service"]
reads: ["order.*", "user.basic.*"] # 只读订单和用户基础信息
writes: ["order.*"] # 只写订单相关主题
```
**权限隔离**
```yaml
# 不同团队权限隔离
groups:
- name: "user-team"
description: "用户服务团队"
reads: ["user.*"]
writes: ["user.*"]
- name: "order-team"
description: "订单服务团队"
reads: ["order.*", "user.basic.*"]
writes: ["order.*"]
- name: "admin-team"
description: "管理员团队"
reads: ["*"]
writes: ["*"]
```
## 网络安全
### 网络隔离
**内网部署**
```ini
# app.ini - 只监听内网地址
[service]
watch=192.168.1.100:711 # 管理端口只监听内网
addr=192.168.1.100:1216 # 服务端口只监听内网
```
**防火墙配置**
```bash
# 只允许内网访问
iptables -A INPUT -p tcp --dport 1216 -s 192.168.1.0/24 -j ACCEPT
iptables -A INPUT -p tcp --dport 711 -s 192.168.1.0/24 -j ACCEPT
iptables -A INPUT -p tcp --dport 1216 -j DROP
iptables -A INPUT -p tcp --dport 711 -j DROP
```
## 监控
### 基础监控
**服务状态监控**
```bash
# 检查服务状态
curl http://127.0.0.1:711/_/info
# 检查权限配置
curl http://127.0.0.1:711/auth/reload
```
## 最佳实践
### 安全配置检查清单
- [ ] 启用认证和授权 (`auth=1`)
- [ ] 配置最小权限原则
- [ ] 实施网络隔离
- [ ] 启用访问日志
- [ ] 定期安全审计
### 定期维护
- 定期检查权限配置
- 定期更新认证令牌
- 监控服务状态和连接情况

View File

@@ -1,5 +1,444 @@
---
sidebar_position: 2
title: 定时调度
description: ZHub 定时调度功能详解
---
# 定时调度
# 定时调度
ZHub 提供了强大的定时调度功能,支持基于 Cron 表达式和简单时间间隔的定时任务。
---
## 功能特性
- **Cron 表达式**: 支持标准的 Cron 表达式语法
- **简单间隔**: 支持秒、分、时、天等时间单位
- **数据库持久化**: 支持将定时任务配置保存到数据库
- **任务执行**: 支持定时任务执行
- **动态重载**: 支持运行时重新加载定时任务配置
---
## 基础使用
### 1. 简单定时任务
```java
// 订阅定时任务
zhub.timer("T:A", () -> {
System.out.println("收到定时调度事件T:A");
// 执行定时任务逻辑
});
// 每5秒执行一次
zhub.timer("T:B", () -> {
System.out.println("每5秒执行一次");
});
```
### 2. 基于 Cron 表达式的定时任务
```java
// 每天早上8点执行
zhub.timer("daily-report", () -> {
System.out.println("生成日报");
});
// 每周一上午9点执行
zhub.timer("weekly-summary", () -> {
System.out.println("生成周报");
});
```
---
## 时间表达式语法
### 1. 简单时间间隔
ZHub 支持以下时间单位格式:
```java
// 支持的时间单位
"5s" // 5秒
"10m" // 10分钟
"2H" // 2小时
"1d" // 1天
"1M" // 1个月
"1y" // 1年
// 纯数字表示毫秒
"5000" // 5000毫秒
```
### 2. Cron 表达式
ZHub 支持标准 Cron 表达式格式:
```java
// 标准 Cron 表达式格式:分 时 日 月 周
"0 8 * * *" // 每天8点
"0 0 1 * *" // 每月1号0点
"0 9 * * 1" // 每周一9点
"*/5 * * * *" // 每5分钟
"0 0 0 1 1" // 每年1月1日0点
```
### 3. 复杂 Cron 表达式
```java
// 工作日每天9点和18点执行
"0 9,18 * * 1-5"
// 每月1号和15号执行
"0 0 1,15 * *"
// 每小时的0分和30分执行
"0,30 * * * *"
// 每5分钟执行
"*/5 * * * *"
```
---
## 数据库配置
### 1. 数据库表结构
ZHub 定时任务数据库表结构:
```sql
CREATE TABLE `tasktimer` (
`timerid` varchar(64) NOT NULL DEFAULT '' COMMENT '[主键]UUID',
`name` varchar(32) NOT NULL DEFAULT '' COMMENT '[任务名称]',
`expr` varchar(32) NOT NULL DEFAULT '' COMMENT '[时间表达式]',
`single` int NOT NULL DEFAULT '1' COMMENT '[单实例消费]1单对象0不限',
`remark` varchar(128) NOT NULL DEFAULT '' COMMENT '[备注]',
`status` smallint NOT NULL DEFAULT '10' COMMENT '[状态]10启用,60停用',
PRIMARY KEY (`timerid`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
```
### 2. 配置示例
```sql
-- 插入定时任务配置
INSERT INTO `tasktimer` (`timerid`, `name`, `expr`, `single`, `remark`, `status`) VALUES
('T1', 'T:A', '*/5 * * * * ?', 1, '每5秒执行一次', 10),
('T2', 'T:B', '15s', 1, '每15秒执行一次', 10),
('T3', 'T:C', '0 0 0 * * 1', 0, '每周一00:00执行', 10),
('T4', 'T:D', '0 0 24 * * ?', 1, '每天00:00执行', 10);
```
### 3. 服务端配置
`app.ini` 中配置数据库连接:
```ini
[ztimer]
db.addr=127.0.0.1:3306
db.user=root
db.password=123456
db.database=zhub
db.schema=public # PostgreSQL 模式名
db.type=mysql # mysql|postgres
```
---
## 高级功能
### 1. 单实例执行
```java
// 单实例执行:只有一个客户端实例会执行任务
zhub.timer("single-task", () -> {
System.out.println("只有一个实例执行此任务");
});
```
### 2. 多实例执行
```java
// 多实例执行:所有客户端实例都会执行任务
zhub.timer("multi-task", () -> {
System.out.println("所有实例都会执行此任务");
});
```
### 3. 动态重载配置
```bash
# 通过管理接口重新加载定时任务配置
curl http://127.0.0.1:711/timer/reload
```
### 4. 本地定时任务
ZHub 客户端还提供本地定时任务功能:
```java
// 本地延时任务(适用于短时间延时)
Timers.delay(() -> {
System.out.println("延时5秒后执行");
}, 5000);
// 本地重试任务
Timers.tryDelay(() -> {
// 返回 true 表示成功false 表示需要重试
return processTask();
}, 1000, 3); // 每1秒重试一次最多重试3次
```
---
## 实际应用场景
### 1. 数据同步任务
```java
public class DataSyncService {
private final ZHubClient zhub;
public void init() {
// 每小时同步一次数据
zhub.timer("data-sync", () -> {
syncData();
});
// 每天凌晨2点清理过期数据
zhub.timer("data-cleanup", () -> {
cleanupExpiredData();
});
}
private void syncData() {
System.out.println("开始同步数据...");
// 数据同步逻辑
}
private void cleanupExpiredData() {
System.out.println("开始清理过期数据...");
// 数据清理逻辑
}
}
```
### 2. 监控和告警
```java
public class MonitorService {
private final ZHubClient zhub;
public void init() {
// 每30秒检查系统状态
zhub.timer("system-check", () -> {
checkSystemHealth();
});
// 每天生成监控报告
zhub.timer("daily-report", () -> {
generateDailyReport();
});
}
private void checkSystemHealth() {
// 系统健康检查逻辑
if (isSystemHealthy()) {
System.out.println("系统状态正常");
} else {
sendAlert("系统异常,请检查");
}
}
}
```
### 3. 缓存刷新
```java
public class CacheService {
private final ZHubClient zhub;
public void init() {
// 每5分钟刷新缓存
zhub.timer("cache-refresh", () -> {
refreshCache();
});
// 每天凌晨3点预热缓存
zhub.timer("cache-warmup", () -> {
warmupCache();
});
}
private void refreshCache() {
System.out.println("刷新缓存...");
// 缓存刷新逻辑
}
}
```
---
## 最佳实践
### 1. 任务命名规范
```java
// 推荐:使用有意义的任务名称
zhub.timer("user:data-sync", () -> {});
zhub.timer("order:status-check", () -> {});
zhub.timer("system:health-check", () -> {});
// 避免:使用无意义的名称
zhub.timer("task1", () -> {});
zhub.timer("timer", () -> {});
```
### 2. 异常处理
```java
zhub.timer("safe-task", () -> {
try {
// 任务逻辑
processTask();
} catch (Exception e) {
logger.error("定时任务执行失败", e);
// 发送告警或记录错误
}
});
```
### 3. 性能优化
```java
// 避免在定时任务中执行耗时操作
zhub.timer("light-task", () -> {
// 快速执行的任务
updateStatus();
});
// 耗时操作应该异步执行
zhub.timer("heavy-task", () -> {
CompletableFuture.runAsync(() -> {
// 异步执行耗时操作
processHeavyTask();
});
});
```
### 4. 监控和日志
```java
public class MonitoredTimer {
private final ZHubClient zhub;
private final Logger logger = LoggerFactory.getLogger(MonitoredTimer.class);
public void init() {
zhub.timer("monitored-task", () -> {
long startTime = System.currentTimeMillis();
try {
processTask();
long duration = System.currentTimeMillis() - startTime;
logger.info("定时任务执行成功,耗时: {}ms", duration);
} catch (Exception e) {
long duration = System.currentTimeMillis() - startTime;
logger.error("定时任务执行失败,耗时: {}ms", duration, e);
}
});
}
}
```
---
## 故障排除
### 1. 任务不执行
**可能原因**
- 数据库连接配置错误
- 任务状态为停用status=60
- 时间表达式格式错误
**解决方法**
```bash
# 检查数据库连接
curl http://127.0.0.1:711/_/info
# 重新加载配置
curl http://127.0.0.1:711/timer/reload
# 检查任务状态
SELECT * FROM tasktimer WHERE status = 10;
```
### 2. 任务重复执行
**可能原因**
- 多个客户端实例都订阅了同一个任务
- 单实例配置错误
**解决方法**
```sql
-- 确保单实例配置正确
UPDATE tasktimer SET single = 1 WHERE name = 'task-name';
```
### 3. 任务执行时间不准确
**可能原因**
- 系统时间不同步
- 任务执行时间过长
**解决方法**
- 同步系统时间
- 优化任务执行逻辑
- 考虑拆分长时间任务
---
## 监控和调试
### 1. 任务执行状态
```bash
# 查看所有定时任务状态
curl http://127.0.0.1:711/_/info | jq '.timersize'
```
### 2. 日志监控
```java
// 在任务中添加详细日志
zhub.timer("logged-task", () -> {
logger.info("定时任务开始执行: {}", LocalDateTime.now());
try {
processTask();
logger.info("定时任务执行完成: {}", LocalDateTime.now());
} catch (Exception e) {
logger.error("定时任务执行异常: {}", e.getMessage(), e);
}
});
```
### 3. 性能监控
```java
// 监控任务执行时间
public class PerformanceMonitor {
public void monitorTask(String taskName, Runnable task) {
long startTime = System.currentTimeMillis();
try {
task.run();
} finally {
long duration = System.currentTimeMillis() - startTime;
if (duration > 5000) { // 超过5秒记录警告
logger.warn("任务 {} 执行时间过长: {}ms", taskName, duration);
}
}
}
}
```

View File

@@ -0,0 +1,421 @@
---
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)。

View File

@@ -0,0 +1,278 @@
---
sidebar_position: 11
title: 日志管理
description: ZHub 日志配置、格式分析、故障排查和监控指南
keywords: [ZHub日志, 日志管理, 日志分析, 故障排查, 监控]
---
# 日志管理
ZHub 日志文件配置、分析和故障排查指南。
## 目录
- [日志配置](#日志配置)
- [日志文件位置](#日志文件位置)
- [服务端日志](#日志内容分析)
- [Java客户端日志](#java-客户端日志)
- [日志分析](#日志分析)
- [日志轮转](#日志轮转)
- [故障排查](#故障排查)
## 日志配置
### 基础配置
**app.ini 配置**
```ini
[log]
level=info # 日志级别: debug, info, error
handlers=console # 日志处理器: console, file
file=zhub.log # 日志文件名
```
### 日志级别说明
| 级别 | 说明 | 使用场景 |
|------|------|----------|
| debug | 调试信息 | 开发调试,包含详细的执行流程 |
| info | 一般信息 | 生产环境,记录重要操作 |
| error | 错误信息 | 严重错误,需要关注 |
## 日志文件位置
### 默认位置
```bash
# 当前目录下的日志文件
./zhub.log
```
### 自定义位置
```ini
# app.ini 中指定日志目录
[log]
file=/var/log/zhub/zhub.log
```
## 日志内容分析
### 连接接入日志
**连接建立**
```
2024/01/15 10:30:15.123456 zbus.go:291: [Info] conn start: 127.0.0.1:12345 [1]
```
- 格式:`[Info] conn start: IP:端口 [连接序号]`
- 连接序号:每个新连接递增的数字标识
**连接断开**
```
2024/01/15 10:30:20.123456 zbus.go:302: [Info] conn closed: 127.0.0.1:12345 [ 1 ]
```
- 格式:`[Info] conn closed: IP:端口 [ 连接序号 ]`
- 包含正常断开和异常断开
**认证过程**
```
2024/01/15 10:30:15.123456 zbus-message-handler.go:84: [Info] [1] -Auth: publish [user-login]
2024/01/15 10:30:15.123456 zbus-message-handler.go:122: [Info] [1] cmd: publish, auth [OK]
```
- `-Auth:` 表示权限不足
- `auth [OK]` 表示认证成功
### 消息收发日志
**消息发布**
```
2024/01/15 10:30:15.123456 zbus-message-handler.go:45: [1] cmd: publish user-login {"userId":"12345"}
```
- 格式:`[连接序号] cmd: publish 主题名 消息内容`debug级别
- 仅在debug级别下显示
**消息订阅**
```
2024/01/15 10:30:15.123456 zbus-message-handler.go:45: [1] cmd: subscribe user-login order-create
2024/01/15 10:30:15.123456 zbus-message-handler.go:122: [Info] [1] cmd: subscribe, auth [OK]
```
- 格式:`[连接序号] cmd: subscribe 主题列表`debug级别
- 支持多主题订阅,空格分隔
**广播消息**
```
2024/01/15 10:30:15.123456 zbus-message-handler.go:45: [1] cmd: broadcast topic-abc hello!
```
- 格式:`[连接序号] cmd: broadcast 主题名 消息内容`debug级别
**延时消息**
```
2024/01/15 10:30:15.123456 zbus-message-handler.go:45: [1] cmd: delay order-timeout 30s 订单超时
```
- 格式:`[连接序号] cmd: delay 主题名 延时时间 消息内容`debug级别
### RPC 调用日志
**RPC 调用**
```
2024/01/15 10:30:15.123456 zbus-message-handler.go:45: [1] cmd: rpc user-get-info {"ruk":"app1::12345"}
```
- 格式:`[连接序号] cmd: rpc 服务名 RPC参数`debug级别
- RPC参数包含ruk回复标识
**RPC 服务离线**
```
2024/01/15 10:30:15.123456 zbus-message-handler.go:132: [1] : rpc user-get-info no subscribe
```
- 格式:`[连接序号] : rpc 服务名 no subscribe`
- 表示没有客户端订阅该RPC服务
**RPC 权限不足**
```
2024/01/15 10:30:15.123456 zbus-message-handler.go:84: [Info] [1] -Auth: rpc [user-get-info]
```
- 格式:`[Info] [连接序号] -Auth: rpc [服务名]`
### 定时任务日志
**定时任务执行**
```
2024/01/15 10:30:00.123456 monitor.go:56: [Info] broadcast timer T:A 执行
2024/01/15 10:30:05.123456 monitor.go:56: [Info] broadcast timer T:B 执行
```
- 格式:`[Info] broadcast timer 任务名 执行`
- 来自monitor模块的定时任务执行日志
**定时任务订阅**
```
2024/01/15 10:30:15.123456 zbus-message-handler.go:45: [1] cmd: timer T:A T:B
```
- 格式:`[连接序号] cmd: timer 任务列表`debug级别
- 客户端订阅定时任务时记录
## Java 客户端日志
### 消息接收日志
**订阅消息**
```
FINEST: topic[user.login]: {"userId":"12345","username":"张三"}
```
- 格式:`FINEST: topic[主题名]: 消息内容`
- 记录接收到的订阅消息
**广播消息**
```
FINEST: topic[topic-abc]: hello!
```
- 格式:`FINEST: topic[主题名]: 消息内容`
### 定时任务日志
**任务触发**
```
FINEST: timer[T:A]:
```
- 格式:`FINEST: timer[任务名]: `
**任务执行完成**
```
FINEST: timer [T:A] : elapsed time 15 ms
```
- 格式:`FINEST: timer [任务名] : elapsed time 耗时 ms`
### RPC 调用日志
**RPC响应**
```
FINEST: rpc-back:[user.getInfo]: {"retcode":0,"result":"用户信息"}
```
- 格式:`FINEST: rpc-back:[服务名]: 响应内容`
**RPC错误**
```
WARNING: rpc-back[user.getInfo] event accept error :{"retcode":500,"result":"服务错误"}
```
- 格式:`WARNING: rpc-back[服务名] event accept error :响应内容`
### 错误日志
**超时错误**
```
SEVERE: timer [T:A] time out: 5 S
```
- 格式:`SEVERE: timer [任务名] time out: 超时时间 S`
**处理异常**
```
WARNING: topic[user.login] event accept error :{"userId":"12345"}
SEVERE: topic[user.login] event deal time out: 5 S, value: {"userId":"12345"}
```
- 格式:`WARNING: topic[主题名] event accept error :消息内容`
- 格式:`SEVERE: topic[主题名] event deal time out: 超时时间 S, value: 消息内容`
## 日志分析
### 关键日志识别
**连接状态监控**
- `conn start:` - 新连接建立
- `conn closed:` - 连接断开
- `-Auth:` - 权限认证失败
**消息处理监控**
- `cmd: publish` - 消息发布debug级别
- `cmd: subscribe` - 消息订阅
- `cmd: rpc` - RPC调用
- `no subscribe` - 服务离线
**Java客户端监控**
- `topic[主题名]:` - 消息接收
- `timer[任务名]:` - 定时任务触发
- `rpc-back:[服务名]:` - RPC响应
- `time out:` - 超时错误
- `event accept error` - 处理异常
- `event deal time out` - 处理超时
**错误信息识别**
- `-Error:` - 系统错误
- `Recovered:` - 异常恢复
- `-Auth:` - 权限不足
### 监控要点
1. **连接稳定性**:关注连接建立和断开的频率
2. **权限问题**:监控`-Auth:`日志,排查权限配置
3. **服务可用性**:关注`no subscribe`日志确保RPC服务正常
4. **系统健康**:检查`-Error:``Recovered:`日志
5. **客户端性能**:监控`time out:`日志,关注处理超时
6. **消息处理**:观察`topic[主题名]:`日志,确保消息正常接收
## 日志轮转
### 手动轮转
```bash
# 重命名当前日志文件
mv zhub.log zhub.log.$(date +%Y%m%d)
# 重启服务
./zhub.sh restart
```
## 故障排查
### 常见问题
**1. 日志文件过大**
- 定期清理旧日志文件
- 调整日志级别为info
**2. 日志级别过高**
- 生产环境建议使用info级别
- 开发环境可使用debug级别
### 最佳实践
1. **定期检查**:关注错误和权限相关日志
2. **监控连接**:观察连接建立和断开情况
3. **服务状态**确保RPC服务正常运行
4. **日志轮转**:定期清理旧日志文件
5. **级别设置**生产环境使用info级别