添加: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

@@ -1,77 +0,0 @@
---
sidebar_position: 1
---
# 快速开始
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
<Tabs>
<TabItem value="apple" label="Apple" default>
This is an apple 🍎
</TabItem>
<TabItem value="orange" label="Orange">
This is an orange 🍊
</TabItem>
<TabItem value="banana" label="Banana">
This is a banana 🍌
</TabItem>
</Tabs>
好的,以下是对应的文件名和目录结构:
- 1.md : 入门指南
- 1.1 安装和配置.md
- 1.2 Hello World.md
- 1.3 架构概述.md
- 2.md : 核心功能
- 2.1 控制器.md
- 2.2 过滤器.md
- 2.3 模板引擎.md
- 2.4 数据库访问.md
- 2.5 缓存.md
- 2.6 安全.md
- 2.7 日志.md
- 2.8 监控.md
- 3.md : 进阶功能
- 3.1 异步处理.md
- 3.2 高并发支持.md
- 3.3 集群部署.md
- 3.4 扩展机制.md
- 4.md : 工具支持
- 4.1 IDEA 插件.md
- 4.2 Maven 插件.md
- 4.3 工具集成.md
----
好的,以下是使用英文文件名的 Redkale 文档目录结构:
- getting-started: Getting Started
- 1-installation-and-configuration.md: Installation and Configuration
- 2-hello-world.md: Hello World
- 3-architecture-overview.md: Architecture Overview
- core-features: Core Features
- 1-controller.md: Controller
- 2-filter.md: Filter
- 3-template-engine.md: Template Engine
- 4-database-access.md: Database Access
- 5-cache.md: Cache
- 6-security.md: Security
- 7-logging.md: Logging
- 8-monitoring.md: Monitoring
- advanced-features.md: Advanced Features
- 1-asynchronous-processing.md: Asynchronous Processing
- 2-high-concurrency-support.md: High Concurrency Support
- 3-clustering-deployment.md: Clustering Deployment
- 4-extension-mechanism.md: Extension Mechanism
- tool-support.md: Tool Support
- 1-idea-plugin.md: IDEA Plugin
- 2-maven-plugin.md: Maven Plugin
- 3-tool-integration.md: Tool Integration
请注意,文件名以及目录结构只是一种规范,您可以根据实际需求进行修改和扩展。同时编写文档时要尽可能地清晰简洁、易于阅读和理解,并且遵循文档写作的标准规范和最佳实践。
请注意,本程序只能进行文档基础目录结构的整理,具体内容需要您自己针对 Redkale 进行整理编写。另外,如有需要,您还可以进一步细分和拓展目录结构,以适应实际需求。

View File

@@ -1,7 +0,0 @@
{
"label": "快速开始",
"position": 1,
"link": {
"type": "generated-index"
}
}

View File

@@ -0,0 +1,8 @@
{
"label": "管理接口 API",
"position": 2,
"link": {
"type": "generated-index",
"description": "ZHub 服务管理接口详细说明,包括服务监控、配置重载、资源清理等功能。"
}
}

View File

@@ -0,0 +1,141 @@
---
sidebar_position: 4
title: 重新加载权限配置接口
description: ZHub 权限配置重新加载接口
---
# 重新加载权限配置接口
## 接口说明
- **路径**: `GET /auth/reload`
- **功能**: 重新加载 `auth.yml` 权限配置文件
- **用途**: 修改权限配置后无需重启服务即可生效
## 使用示例
```bash
# 重新加载权限配置
curl http://127.0.0.1:711/auth/reload
```
## 使用场景
- 修改了 `auth.yml` 文件中的权限配置
- 添加或删除了用户权限
- 修改了连接授权规则
- 更新了角色权限设置
## 操作步骤
1. **修改配置**: 编辑 `auth.yml` 配置文件
2. **执行重载**: 调用 `/auth/reload` 接口
3. **验证生效**: 新的权限配置立即生效
## 权限配置文件
### auth.yml 结构
权限配置存储在 `auth.yml` 文件中,主要包含以下配置:
```yaml
# 用户权限配置
users:
- username: admin
password: admin123
roles: [admin]
- username: user1
password: user123
roles: [user]
# 角色权限配置
roles:
admin:
permissions:
- "topic:read"
- "topic:write"
- "admin:*"
user:
permissions:
- "topic:read"
# 连接授权规则
connection_rules:
- pattern: "admin.*"
required_roles: [admin]
- pattern: "user.*"
required_roles: [user]
```
### 配置示例
```yaml
# 添加新用户
users:
- username: newuser
password: newpass123
roles: [operator]
# 添加新角色
roles:
operator:
permissions:
- "topic:read"
- "topic:write"
- "monitor:*"
```
## 应用场景
1. **用户管理**: 添加或删除系统用户
2. **权限调整**: 修改用户或角色的权限设置
3. **安全策略**: 更新连接授权规则
4. **临时权限**: 为特定操作临时调整权限
## 权限类型
### 主题权限
- `topic:read`: 读取主题消息权限
- `topic:write`: 发布主题消息权限
- `topic:subscribe`: 订阅主题权限
### 管理权限
- `admin:*`: 所有管理权限
- `admin:config`: 配置管理权限
- `admin:monitor`: 监控管理权限
### 系统权限
- `system:*`: 系统级权限
- `system:shutdown`: 系统关闭权限
- `system:restart`: 系统重启权限
## 注意事项
:::warning 安全提醒
- 权限配置重载会立即生效,请谨慎操作
- 建议在非业务高峰期执行重载操作
- 重载前请备份当前的权限配置
- 确保不会意外撤销重要权限
:::
## 错误处理
如果重载过程中出现错误:
1. **配置检查**: 验证 `auth.yml` 文件格式是否正确
2. **权限验证**: 确保配置的权限和角色有效
3. **日志查看**: 检查服务日志中的错误信息
4. **配置恢复**: 如有必要,恢复之前的配置文件
## 安全建议
1. **定期审核**: 定期审核用户权限配置
2. **最小权限**: 遵循最小权限原则
3. **密码策略**: 使用强密码策略
4. **访问日志**: 记录权限相关的访问日志

View File

@@ -0,0 +1,53 @@
---
sidebar_position: 2
title: 清理内存接口
description: ZHub 服务内存清理接口
---
# 清理内存接口
## 接口说明
- **路径**: `GET /_/cleanup`
- **功能**: 清理可回收的内存资源
- **用途**: 释放无用的主题和消息,优化内存使用
## 清理条件
清理满足以下条件的主题:
- `subsize = 0` - 没有订阅者
- `mcount = offset` - 没有待消费的消息
## 使用示例
```bash
# 手动触发内存清理
curl http://127.0.0.1:711/_/cleanup
```
## 返回信息
接口返回清理操作的结果:
- **成功**: 返回 `"+OK"`
- **失败**: 返回错误信息
**响应示例**
```json
"+OK"
```
## 清理机制
**手动清理**:通过调用此接口立即触发清理操作
- 清理所有符合条件的主题
- 释放相关内存资源
## 应用场景
1. **内存优化**: 当发现内存占用过高时手动清理
2. **性能调优**: 在性能测试后清理测试数据
3. **资源回收**: 清理不再使用的主题和消息

View File

@@ -0,0 +1,70 @@
---
sidebar_position: 1
title: 查看注册情况接口
description: ZHub 服务注册情况查询接口
---
# 查看注册情况接口
## 接口说明
- **路径**: `GET /_/info`
- **功能**: 查看当前服务的注册情况,包括主题订阅、连接状态等信息
- **用途**: 监控服务运行状态,排查问题
## 使用示例
```bash
# 查看服务注册情况
curl http://127.0.0.1:711/_/info
```
## 返回信息
接口返回当前服务的详细状态信息,包括:
- **topics**: 主题详细信息,包含每个主题的组信息
- **topicsize**: 当前活跃的主题数量
- **timersize**: 定时任务数量
- **conns**: 连接信息列表包含远程地址、组ID、订阅主题等
- **connsize**: 当前连接数
**响应示例**
```json
{
"topics": {
"user.login": [
{
"name": "group1",
"subsize": 3,
"offset": 100,
"mcount": 120
}
]
},
"topicsize": 25,
"timersize": 10,
"conns": [
{
"remoteaddr": "127.0.0.1:12345",
"groupid": "test-group",
"topics": ["user.*"],
"timers": ["timer1"],
"user": "admin"
}
],
"connsize": 5
}
```
## 应用场景
1. **服务监控**: 定期检查服务运行状态
2. **问题排查**: 当服务出现异常时查看详细信息
3. **性能分析**: 了解当前的主题和连接数量
4. **运维管理**: 评估服务负载和资源使用情况
## 注意事项
- 该接口为只读操作,不会修改服务状态
- 返回的信息实时反映当前服务状态

View File

@@ -0,0 +1,34 @@
---
sidebar_position: 5
title: 其他管理接口
description: ZHub 其他管理接口说明
---
# 其他管理接口
除了核心的管理接口外ZHub 还提供了其他有用的管理接口,用于版本查询、消息发送和延时消息管理等功能。
---
## 版本信息接口
### 接口说明
- **路径**: `GET /_/version`
- **功能**: 查看服务版本信息
- **用途**: 确认服务版本,进行版本管理
### 使用示例
```bash
# 查看服务版本
curl http://127.0.0.1:711/_/version
```
### 返回信息
返回当前 ZHub 服务的版本信息,包括:
- 服务版本号
- 构建时间
---

View File

@@ -0,0 +1,61 @@
---
sidebar_position: 0
title: 管理接口概览
description: ZHub 服务管理接口总览
---
# ZHub 管理接口概览
管理接口通过 HTTP 访问,默认端口 `711`
**配置**:在 `app.ini` 中修改 `[service]` 部分的 `watch` 参数
## 接口列表
**核心接口**
- `GET /_/info` - 查看服务状态
- `GET /_/cleanup` - 清理内存
- `GET /timer/reload` - 重载定时配置
- `GET /auth/reload` - 重载权限配置
**辅助接口**
- `GET /_/version` - 查看版本信息
- `POST /message/send` - HTTP 发送消息
- `GET /topic/delay` - 查看延时消息状态
## 使用示例
```bash
# 查看服务状态
curl http://127.0.0.1:711/_/info
# 清理内存
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
# 查看版本
curl http://127.0.0.1:711/_/version
```
## 配置管理
**端口配置**
```ini
[service]
watch = 0.0.0.0:711 # 管理端口
```
## 安全注意事项
- 管理接口默认监听所有网络接口
- 生产环境建议添加认证机制
- 避免在公网环境暴露管理接口
## 监控建议
- 定期检查服务状态:`/_/info`
- 监控内存使用,必要时执行清理
- 修改配置后及时执行 reload 接口

View File

@@ -0,0 +1,51 @@
---
sidebar_position: 3
title: 重新加载定时调度配置接口
description: ZHub 定时调度配置重新加载接口
---
# 重新加载定时调度配置接口
## 接口说明
- **路径**: `GET /timer/reload`
- **功能**: 重新加载数据库中的定时调度配置
- **用途**: 当修改了数据库中的 timer 配置后,无需重启服务即可生效
## 使用示例
```bash
# 重新加载定时调度配置
curl http://127.0.0.1:711/timer/reload
```
## 使用场景
- 修改了 `tasktimer` 表中的定时任务配置
- 添加或删除了定时任务
- 修改了定时任务的执行表达式
- 更新了定时任务的执行参数
## 操作步骤
1. **修改配置**: 在数据库中修改 `zhub.tasktimer`
2. **执行重载**: 调用 `/timer/reload` 接口
3. **验证生效**: 新的定时配置立即生效
## 数据库配置
### tasktimer 表结构
定时任务配置存储在 `zhub.tasktimer` 表中,包含以下关键字段:
- `task_name`: 任务名称
- `cron_expression`: Cron 表达式
- `task_class`: 任务执行类
- `enabled`: 是否启用
- `parameters`: 任务参数
## 注意事项
:::info 重要提醒
- 重载操作会立即生效,请确保配置正确
:::

View File

@@ -1,90 +1,121 @@
--- ---
title: 快速上手
description: ZHub 轻量级消息中间件快速入门指南,包含安装配置、基础使用和功能特性介绍
sidebar_position: 1 sidebar_position: 1
--- ---
# ZHub 快速上手 # ZHub 快速上手
## 概述 ## 概述
> zhub是⼀个⾼性能事件发布订阅服务组件功能丰富包含发布-订阅、播消息、延时消息、 ZHub 是一个轻量级消息中间件,支持发布订阅、广播消息、延时消息、RPC调用等功能。运行包仅1M+启动内存10M-。
Rpc调⽤、分布式定时调度、分布式锁运⾏包仅有1M+;低服务资源消费,初始启动内存 10M-。
**核心特性**
- 消息顺序保证:单个主题内严格按发送顺序处理
- 高性能:内存处理,支持高并发
- 轻量级运行包1M+启动内存10M-
![zhub-fun.png](https://img.1216.top/docs/zhub/zhub-fun.png) ![zhub-fun.png](https://img.1216.top/docs/zhub/zhub-fun.png)
--- ---
## 开始 搭建 zhub 服务 ## 搭建 ZHub 服务
> 让我们在 **5到10分钟内完成 zhub 中间件安装、集成、测试**.
### 下载软件包 ### 下载软件包
- [zhub.zip (点击下载)](https://img.1216.top/docs/zhub/zhub.zip) 包含以下内容: **下载地址**: [https://zhub.dev/release/latest/](https://zhub.dev/release/latest/)
- `zhub-client-0.1.1.dev.jar` 常规Java 项目驱动包
- `zhub-client-spring-0.1.1.jar` springboot 项目驱动包 **支持平台**
- `zhub.exe` Window 运行包 - `zhub-linux-amd64.tar` - Linux AMD64
- `zhub.sh` Linux 运行包 - `zhub-linux-arm64.tar` - Linux ARM64
- `zhub` Mac 运行包 - `zhub-win-amd64.tar` - Windows AMD64
- `app.ini` 配置文件
![zhub-zip.png](https://img.1216.top/docs/zhub/dist-zip.png) **目录结构**
```
zhub/
├── zhub.sh # 可执行文件
├── app.ini # 服务配置
└── auth.yml # 权限配置(可选)
```
### 配置 app.ini ### 配置 app.ini
```bash ```ini
# app.ini
[service] [service]
watch=0.0.0.0:711 # 服务管理端口 watch=0.0.0.0:711 # 管理端口
addr=0.0.0.0:1216 # 服务端口 addr=0.0.0.0:1216 # 服务端口
auth=0 # 是否开启连接授权 0不开启、1开启 auth=0 # 权限验证 0关闭/1开启
[data] [data]
dir=./data # 数据目录 dir=./data # 数据目录
[log] [log]
handlers=console # console|file handlers=console # 日志输出
level=debug # info|debug|error level=debug # 日志级别
file=zhub.log
[ztimer] # ztimer 配置 (可选,如果不使用定时调度则可不配置)
# db.addr=127.0.0.1:3306 # timer 使用的MySql数据库配置
# db.user=root
# db.password=123456
# db.database=zhub
``` ```
**重要**
- 客户端 `appid` 必须唯一
- 生产环境建议开启权限验证
**性能注意事项**
- 服务端通道容量500条满时消息会被丢弃
- 定期执行内存清理:`curl http://127.0.0.1:711/_/cleanup`
- 监控服务状态:`curl http://127.0.0.1:711/_/info`
--- ---
### 初始化 ztimer 数据库 (可选,如果不使用定时调度则不需要配置) ### 初始化数据库(可选, 定时调度调度任务配置
**MySQL**
```sql ```sql
CREATE DATABASE zhub; CREATE DATABASE zhub;
CREATE TABLE `zhub`.`tasktimer` ( CREATE TABLE `zhub`.`tasktimer` (
`timerid` varchar(64) NOT NULL DEFAULT '' COMMENT '[主键]UUID', `timerid` varchar(64) NOT NULL DEFAULT '' PRIMARY KEY COMMENT '任务ID',
`name` varchar(32) NOT NULL DEFAULT '' COMMENT '[任务名称]', `name` varchar(32) NOT NULL DEFAULT '' COMMENT '任务名称',
`expr` varchar(32) NOT NULL DEFAULT '' COMMENT '[时间表达式]', `expr` varchar(32) NOT NULL DEFAULT '' COMMENT '时间表达式',
`single` int NOT NULL DEFAULT '1' COMMENT '[单实例消费]1单对象0不限', `single` int NOT NULL DEFAULT '1' COMMENT '单实例1是0否',
`remark` varchar(128) NOT NULL DEFAULT '' COMMENT '[备注]', `remark` varchar(128) NOT NULL DEFAULT '' COMMENT '备注',
`status` smallint NOT NULL DEFAULT '10' COMMENT '[状态]10启用,60停用', `status` smallint NOT NULL DEFAULT '10' COMMENT '状态10启用60停用'
PRIMARY KEY (`timerid`) USING BTREE ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='定时任务表';
) ENGINE=InnoDB DEFAULT CHARSET=utf8; ```
# 初始化 四个定时任务配置, 订阅名称分别为 T:AT:BT:CT:D
INSERT INTO `zhub`.`tasktimer` (`timerid`, `name`, `expr`, `single`, `remark`, `status`) VALUES **PostgreSQL**
('T1', 'T:A', '*/5 * * * * ?', 1, '每5秒执行一次', 10), ```sql
('T2', 'T:B', '15s', 1, '每15秒执行一次', 10), CREATE DATABASE zhub;
('T3', 'T:C', '0 0 0 * * 1', 0, '每周一00:00执行', 10), CREATE TABLE tasktimer (
('T4', 'T:D', '0 0 24 * * ?', 1, '每天00:00执行', 10); 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
);
-- 添加表和字段注释
COMMENT ON TABLE tasktimer IS '定时任务表';
COMMENT ON COLUMN tasktimer.timerid IS '任务ID';
COMMENT ON COLUMN tasktimer.name IS '任务名称';
COMMENT ON COLUMN tasktimer.expr IS '时间表达式';
COMMENT ON COLUMN tasktimer.single IS '单实例1是0否';
COMMENT ON COLUMN tasktimer.remark IS '备注';
COMMENT ON COLUMN tasktimer.status IS '状态10启用60停用';
``` ```
### 启动服务 ### 启动服务
```bash ```bash
# window # Linux/Mac
./zhub.exe chmod +x ./zhub.sh && ./zhub.sh
# linux (添加执行权限 chmod +x ./zhub.sh)
./zhub.sh # Windows
# 解压后直接运行
``` ```
**端口**:管理端口 711服务端口 1216
--- ---
## 连接使用 ## 连接使用
### 导入连接驱动 (根据不同的项目选择不同的导入方式) ### 导入依赖
import Tabs from '@theme/Tabs'; import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem'; import TabItem from '@theme/TabItem';
@@ -93,7 +124,7 @@ import TabItem from '@theme/TabItem';
<TabItem value="apple" label="普通Java项目" default> <TabItem value="apple" label="普通Java项目" default>
```xml ```xml
<!-- maven 导入依赖 (或直接导入下载包中的 zhub-client-0.1.1.dev.jar --> <!-- maven 导入依赖 (或直接导入下载包中的 zhub-client-0.1.0424.dev.jar -->
<repositories> <repositories>
<repository> <repository>
<id>maven-nexus</id> <id>maven-nexus</id>
@@ -105,9 +136,9 @@ import TabItem from '@theme/TabItem';
<dependencies> <dependencies>
<!-- 常规Java项目 --> <!-- 常规Java项目 -->
<dependency> <dependency>
<groupId>net.tccn</groupId> <groupId>dev.zhub</groupId>
<artifactId>zhub-client</artifactId> <artifactId>zhub-client</artifactId>
<version>0.1.1.dev</version> <version>0.1.0424.dev</version>
</dependency> </dependency>
</dependencies> </dependencies>
``` ```
@@ -116,7 +147,7 @@ import TabItem from '@theme/TabItem';
<TabItem value="orange" label="SpringBoot 项目"> <TabItem value="orange" label="SpringBoot 项目">
```xml ```xml
<!-- maven 导入依赖 (或直接导入下载包中的 zhub-client-spring-0.1.1.jar --> <!-- maven 导入依赖 (或直接导入下载包中的 zhub-client-spring-0.1.0424.dev.jar -->
<repositories> <repositories>
<repository> <repository>
<id>maven-nexus</id> <id>maven-nexus</id>
@@ -126,11 +157,11 @@ import TabItem from '@theme/TabItem';
</repositories> </repositories>
<dependencies> <dependencies>
<!-- 常规Java项目 --> <!-- SpringBoot项目 -->
<dependency> <dependency>
<groupId>net.tccn</groupId> <groupId>dev.zhub</groupId>
<artifactId>zhub-client-spring</artifactId> <artifactId>zhub-client-spring</artifactId>
<version>0.1.1.dev</version> <version>0.1.0424.dev</version>
</dependency> </dependency>
</dependencies> </dependencies>
``` ```
@@ -139,7 +170,7 @@ import TabItem from '@theme/TabItem';
<TabItem value="banana" label="Redkale项目"> <TabItem value="banana" label="Redkale项目">
```xml ```xml
<!-- maven 导入依赖 (或直接导入下载包中的 zhub-client-redkale-0.1.1.jar --> <!-- maven 导入依赖 (或直接导入下载包中的 zhub-client-redkale-0.1.0424.dev.jar -->
<repositories> <repositories>
<repository> <repository>
<id>maven-nexus</id> <id>maven-nexus</id>
@@ -149,11 +180,11 @@ import TabItem from '@theme/TabItem';
</repositories> </repositories>
<dependencies> <dependencies>
<!-- 常规Java项目 --> <!-- Redkale项目 -->
<dependency> <dependency>
<groupId>net.tccn</groupId> <groupId>dev.zhub</groupId>
<artifactId>zhub-client-redkale</artifactId> <artifactId>zhub-client-redkale</artifactId>
<version>0.1.1.dev</version> <version>0.1.0424.dev</version>
</dependency> </dependency>
</dependencies> </dependencies>
``` ```
@@ -167,19 +198,20 @@ import TabItem from '@theme/TabItem';
``` ```
// 参数说明①连接地址ip+端口, ②消费者组名称③连接APPID (接入的多个客户端使用不同的连接APPID) // 参数说明①连接地址ip+端口, ②消费者组名称③连接APPID (接入的多个客户端使用不同的连接APPID)
ZHubClient zhub = new ZHubClient("127.0.0.1:1216", "groupid-x", "appid-x"); // 开启权限验证时添加第四个参数:授权码
ZHubClient zhub = new ZHubClient("127.0.0.1:1216", "groupid-x", "appid-x", "token-12345");
``` ```
</TabItem> </TabItem>
<TabItem value="orange" label="SpringBoot 项目"> <TabItem value="orange" label="SpringBoot 项目">
```yml ```yaml
# application.yml # application.yml
zhub: zhub:
addr: 47.107.112.45:1216 addr: 127.0.0.1:1216
groupid: groupid-x groupid: groupid-x
appid: zhub_demo_1 appid: zhub_demo_1
# auth: token-12345 # 启用 auth情况下接入验权配置 auth: token-12345 # 开启权限验证时配置授权码
``` ```
```java ```java
// 自动注入连接对象 // 自动注入连接对象
@@ -189,10 +221,10 @@ zhub:
</TabItem> </TabItem>
<TabItem value="banana" label="Redkale项目"> <TabItem value="banana" label="Redkale项目">
```yaml ```properties
# source.properties # source.properties
redkale.cluster.zhub[zhub].addr = 127.0.0.1:1216 redkale.cluster.zhub[zhub].addr = 127.0.0.1:1216
redkale.cluster.zhub[zhub].auth = token-12345 redkale.cluster.zhub[zhub].auth = token-12345 # 开启权限验证时配置授权码
redkale.cluster.zhub[zhub].groupid = zcore-zhub redkale.cluster.zhub[zhub].groupid = zcore-zhub
# redkale.cluster.zhub[zhub].appid = zhub_demo_1 # (无需配置,取 redklae 配置的 appname) # redkale.cluster.zhub[zhub].appid = zhub_demo_1 # (无需配置,取 redklae 配置的 appname)
``` ```
@@ -206,68 +238,52 @@ redkale.cluster.zhub[zhub].groupid = zcore-zhub
--- ---
### 使用 zhub 收发消息 ### 快速体验
> 通过上面的操作,我们已经得到了一个 zhub 的连接实例,下面来看看具体的使用
>
1、消息发布-订阅 #### 1. 消息发布订阅
```java ```java
zhub.subscribe("topic-a", x -> { // 订阅消息
System.out.println("接收到 a 事件:" + x); zhub.subscribe("topic-a", x -> {
}); System.out.println("接收到消息:" + x);
});
// 发布消息
zhub.publish("topic-a", "Hello ZHub!");
``` ```
#### 2. RPC 远程调用
```java ```java
zhub.publish("topic-a", "123"); // 服务端:提供 RPC 服务
zhub.rpcSubscribe("user.getInfo", IType.STRING, request -> {
String userId = request.getValue();
return request.render("用户信息: " + userId);
});
// 客户端:调用 RPC 服务
RpcResult<String> result = zhub.rpc("user.getInfo", "user123", IType.STRING);
System.out.println("RPC 结果: " + result.getResult());
``` ```
2、rpc的订阅-调用
#### 3. 其他功能
```java ```java
zhub.rpcSubscribe("rpc-b", IType.STRING, r -> { // 广播消息
String str = r.getValue(); zhub.broadcast("topic", "message");
System.out.println("接收到 b 事件:" + str);
return r.render("接收到 b 事件:" + str); // 延时消息
}); zhub.delay("topic", "message", 5000);
```
```java
RpcResult<String> rpcResult = zhub.rpc("rpc-b", "hello rpc", IType.STRING);
String result = rpcResult.getResult();
System.out.println("rpc result:" + result);
```
3、广播消息
```java
zhub.broadcast("topic-a", "123");
```
4、延时消息
```java
zhub.delay("topic-a", "123", 1000 * 60 * 5);
```
5、定时调度
```java
zhub.timer("T:A", () -> {
System.out.println("收到定时调度事件T:A");
});
```
6、分布式锁
```java
// 获取锁,直到索取到锁后返回
Lock lock = zhub.lock("lock-a", 5);
try {
System.out.println("获取到锁");
} finally {
lock.unLock();
}
```
```java
// 尝试获取锁,立即返回
Lock lock = zhub.tryLock("lock-a", 5);
if (!lock.success()) {
System.out.println("未获取到锁");
return;
}
// 获取到锁
try {
System.out.println("获取到锁");
} finally {
lock.unLock();
}
``` ```
**详细文档**
- [发布订阅](./tutorial-basics/pub-sub.md)
- [广播与延时消息](./tutorial-basics/broadcast-delay.md)
- [RPC 远程调用](./tutorial-basics/rpc.md)
---
## 管理接口
- `GET /_/info` - 查看服务状态
- `GET /_/cleanup` - 清理内存
- `GET /timer/reload` - 重载定时配置
- `GET /auth/reload` - 重载权限配置
详细说明:[管理接口 API](./admin-apis/overview.md)

View File

@@ -3,6 +3,6 @@
"position": 5, "position": 5,
"link": { "link": {
"type": "generated-index", "type": "generated-index",
"description": "这里存放了各种常用的工具。" "description": "ZHub 相关工具和概念,包含类型令牌、微服务架构等"
} }
} }

View File

@@ -1,18 +0,0 @@
---
sidebar_position: 9
---
# 一些命令
```shell title='在 Windows 环境下,项目打包成 zip 文件:'
# rem 请将“my-site”替换为您想要命名的 zip 文件名称,这将创建一个名为 "my-site.zip" 的 zip 文件。
powershell Compress-Archive -Path build -DestinationPath my-site.zip
```
```shell title='docusaurus 常用命令'
pnpm run build # 构建
pnpm run start # 启动
pnpm run serve # 启动(服务模式)
```

View File

@@ -1,10 +1,14 @@
--- ---
sidebar_position: 1 sidebar_position: 1
title: IType 类型定义
description: ZHub 客户端 IType 接口类型定义
--- ---
# IType # IType 类型定义
> IType 中实现的 TypeToken IType 接口提供了 ZHub 客户端中常用的类型定义,用于 RPC 调用和消息订阅时的类型安全。
## 接口定义
```java ```java
package dev.zhub; package dev.zhub;
@@ -24,6 +28,49 @@ public interface IType {
} }
``` ```
## 使用示例
### RPC 调用
```java
// 字符串类型 RPC
RpcResult<String> result = zhub.rpc("user.getInfo", "user123", IType.STRING);
// 整数类型 RPC
RpcResult<Integer> count = zhub.rpc("user.getCount", "group1", IType.INT);
// Map 类型 RPC
RpcResult<Map<String, String>> userInfo = zhub.rpc("user.getDetails", "user123", IType.MAP);
``` ```
### 消息订阅
```java
// 订阅字符串消息
zhub.subscribe("user.notification", message -> {
System.out.println("收到通知: " + message);
});
// 订阅 Map 消息
zhub.subscribe("user.profile", IType.MAP, profile -> {
System.out.println("用户资料: " + profile.get("name"));
});
// 订阅整数消息
zhub.subscribe("user.count", IType.INT, count -> {
System.out.println("用户数: " + count);
});
``` ```
## 类型说明
- `STRING` - 字符串类型,用于文本消息
- `INT` - 整数类型用于计数器、ID
- `LONG` - 长整数类型,用于时间戳、大数值
- `DOUBLE` - 双精度浮点类型,用于价格、比率
- `MAP` - 键值对映射,用于结构化数据
- `LMAP` - Map 列表,用于批量数据
## 注意事项
- 优先使用 IType 中提供的类型
- 自定义类型使用 `new TypeToken<Type>(){}` 构建
- 字符串消息默认类型`new TypeToken<String>(){}`,无需显式声明

View File

@@ -1,14 +1,41 @@
--- ---
sidebar_position: 1 sidebar_position: 2
title: ZHub 与微服务
description: ZHub 在微服务架构中的应用场景
--- ---
# ZHub 与微服务 # ZHub 与微服务
- 服务注册与发现: ## 核心功能
> 在分布式系统中服务注册与发现是确保系统能够找到并调用正确服务的关键机制。ZHub 作为一个服务注册中心或服务发现机制的一部分它负责维护服务列表service-topic使得其他服务能够通过它找到并调用所需的服务。
- 负载均衡:
> 在分布式系统中负载均衡是确保请求均匀分布到各个服务实例上的关键机制。ZHub 是一个负载均衡器,它可负责将请求分发到不同的服务实例上,以提高系统的可用性和性能。
- 消息队列:
> 在微服务架构中消息队列可以用于异步处理请求和解耦服务之间的通信。ZHub 是一个消息队列服务,它可负责接收、存储和分发消息,使得服务可以在需要时处理这些消息。
- **消息通信**支持发布订阅、RPC调用等通信模式
- **异步处理**:解耦服务间通信,提高系统响应性
## 架构优势
- **服务解耦**:消息通信降低依赖,支持独立部署
- **异步处理**:提高响应性能,支持事件驱动
- **可靠性**:重试机制、监控管理
## 应用场景
```java
// 用户服务
zhub.publish("user.registered", userInfo);
zhub.subscribe("user.registered", new TypeToken<UserEvent>(){}, event -> processUserEvent(event));
// 订单服务
zhub.publish("order.created", orderInfo);
zhub.subscribe("order.created", new TypeToken<OrderEvent>(){}, event -> processOrderEvent(event));
// 支付服务
zhub.publish("payment.completed", paymentInfo);
zhub.subscribe("payment.completed", new TypeToken<PaymentEvent>(){}, event -> processPaymentEvent(event));
```
## 最佳实践
- **服务划分**:按业务领域划分,保持单一职责
- **消息设计**:清晰命名规范,可扩展格式
- **错误处理**:重试机制、死信队列、状态监控
- **监控管理**:连接状态、处理量、延迟监控

View File

@@ -3,6 +3,6 @@
"position": 2, "position": 2,
"link": { "link": {
"type": "generated-index", "type": "generated-index",
"description": "完成 ZHub 服务安装后,来看看一遍就会的基础使用文档~" "description": "ZHub 基础功能使用指南包含连接创建、发布订阅、RPC调用等核心功能"
} }
} }

View File

@@ -0,0 +1,112 @@
---
sidebar_position: 3
title: 广播与延时消息
description: ZHub 广播消息和延时消息功能详解,包含基础使用、应用场景和注意事项
---
# 广播与延时消息
## 广播消息
广播消息发送给所有连接的客户端。
### 基础使用
**字符串广播**
```java
// 发送广播
zhub.broadcast("topic-abc", "hello!");
// 订阅广播
zhub.subscribe("topic-abc", message -> {
System.out.println("收到公告: " + message);
});
```
**类型化广播**
```java
// 定义通知类型
public class SystemNotification {
private String type;
private String title;
private String content;
private long timestamp;
// getter/setter...
}
// 发送类型化广播
SystemNotification notification = new SystemNotification(
"maintenance", "hello!", "hello!", System.currentTimeMillis()
);
zhub.broadcast("topic-abc", notification);
// 订阅类型化广播
zhub.subscribe("topic-abc", new TypeToken<SystemNotification>(){}, notification -> {
System.out.println("通知: " + notification.getTitle());
});
```
### 应用场景
**示例场景**
```java
zhub.broadcast("topic-abc", "hello!");
zhub.broadcast("topic-def", "hello!");
```
**配置更新**
```java
zhub.broadcast("topic-xyz", "hello!");
zhub.subscribe("topic-xyz", message -> updateConfig(message));
```
**状态同步**
```java
zhub.broadcast("topic-123", "hello!");
zhub.subscribe("topic-123", message -> System.out.println("状态: " + message));
```
---
## 延时消息
延时消息在指定时间后发送,支持毫秒级精度。
### 基础使用
```java
// 延时5秒
zhub.delay("reminder-task", "执行提醒任务", 5000);
// 延时1小时
zhub.delay("cleanup-task", "执行清理任务", 60 * 60 * 1000);
// 延时1天
zhub.delay("report-generate", "生成日报", 24 * 60 * 60 * 1000);
```
### 应用场景
**任务提醒**
```java
zhub.delay("task-reminder", "任务即将到期", 5 * 60 * 1000);
zhub.subscribe("task-reminder", message -> sendReminder(message));
```
**订单超时**
```java
zhub.delay("order-timeout-check", orderId, 30 * 60 * 1000);
zhub.subscribe("order-timeout-check", orderId -> checkOrderTimeout(orderId));
```
**缓存过期**
```java
zhub.delay("cache-expire", key, expireMs);
zhub.subscribe("cache-expire", key -> cache.remove(key));
```
## 注意事项
- 延时时间不限制延迟时间
- 重启后延时消息丢失
- 广播消息影响所有客户端性能

View File

@@ -1,32 +0,0 @@
---
sidebar_position: 2
title: 广播消息
description: 发送、接收广播消息
---
:::tip
消息接收
广播消息的消息接收,与主题消息、延时消息 api一致且使用了相同 topic 命名空间
- 消息接收
- 广播消息发送
:::
## 消息接收
> [广播消息接收](publish-subscribe.md#订阅主题消息)
## 广播消息发送
> 和发布订阅消息基本差不多
```java
private ZHubClient zhub;
@RestMapping(name = "publish_test", auth = false, comment = "发送广播消息测试")
public String publishTest(String value) {
zhub.broadcast("topic-a", value);
return "send ok!";
}
```

View File

@@ -1,60 +1,177 @@
--- ---
sidebar_position: 0 sidebar_position: 1
title: 创建连接 title: 创建连接
description: 初始化客户端连接对象 description: 初始化客户端连接对象
--- ---
:::tip import Tabs from '@theme/Tabs';
目前已提供三种客户端连接使用 import TabItem from '@theme/TabItem';
- Java 项目 ## 支持的框架
- [普通 Java 项目](#java通用)
- [使用 Redkale 的 Java 项目](#redkale框架-项目里面使用)
- [Golang 项目](#golang-项目中使用)
::: 普通Java、SpringBoot、Redkale、Golang
--- <Tabs>
<TabItem value="java" label="普通Java项目" default>
## Java通用
> 在Java 项目中引入 zhub-client.jar
```java ```java
private ZHubClient zhub; private ZHubClient zhub;
@Before @Before
public void init() { public void init() {
// 参数说明:① ip:端⼝, ②消费者组名称, ③项⽬实例名(名称需全局唯⼀)④授权码 // 参数地址、组名、appid(唯一)、token
zhub = new ZHubClient("127.0.0.1:6066", "test-hub", "DEV-LOCAL", "user@pwd123"); zhub = new ZHubClient("127.0.0.1:1216", "test-hub", "DEV-LOCAL-001", "token-12345");
}
```
**说明**
- `appid` 必须唯一RPC 消息回复使用此标识
- `groupid` 协同消费组,同组内只有一个消费者处理消息
</TabItem>
<TabItem value="spring" label="SpringBoot项目">
**1. 依赖**
```xml
<dependency>
<groupId>dev.zhub</groupId>
<artifactId>zhub-client-spring</artifactId>
<version>0.1.0424.dev</version>
</dependency>
```
**2. 配置 application.yml**
```yaml
zhub:
addr: 127.0.0.1:1216
groupid: spring-boot-app
appid: spring-boot-001 # 必须唯一
auth: token-12345
```
**3. 配置类**
```java
@Configuration
public class ZHubConfig {
@Value("${zhub.addr}") private String addr;
@Value("${zhub.groupid}") private String groupId;
@Value("${zhub.appid}") private String appId;
@Value("${zhub.auth}") private String auth;
@Bean
public ZHubClient zhubClient() {
return new ZHubClient(addr, groupId, appId, auth);
} }
}
``` ```
--- **4. 使用**
```java
## Redkale框架 项目里面使用 @Service
public class UserService {
> 在Java的redkale 项目中引入 zhub-rekale.jar @Autowired
> 在配置文件中配置zhub组件 private ZHubClient zhub;
public void publishEvent(String userId, String event) {
zhub.publish("user-event", "{\"userId\":\"" + userId + "\",\"event\":\"" + event + "\"}");
}
@PostConstruct
public void init() {
zhub.subscribe("user-notification", message -> {
System.out.println("通知: " + message);
});
}
}
``` ```
# source.properties 中配置
############ ClusterSource @Resource(name="hub") ############ </TabItem>
redkale.cluster.zhub[hub].addr = 127.0.0.1:6066 <TabItem value="redkale" label="Redkale项目">
**配置文件**
```properties
# source.properties
redkale.cluster.zhub[hub].addr = 127.0.0.1:1216
redkale.cluster.zhub[hub].auth = user@pwd123 redkale.cluster.zhub[hub].auth = user@pwd123
redkale.cluster.zhub[hub].groupid = test-hub redkale.cluster.zhub[hub].groupid = test-hub
``` ```
> 在 service 中注入组件 **使用**
>
```java ```java
@Resource(name = "hub") @Resource(name = "hub")
protected ZHubClient zhub; protected ZHubClient zhub;
``` ```
## Golang 项目中使用 </TabItem>
<TabItem value="golang" label="Golang项目">
> 待补充 ```go
// Golang 连接示例
// TODO: 待补充
```
--- </TabItem>
</Tabs>
## 使用示例
<Tabs>
<TabItem value="subscribe" label="基础订阅" default>
```java
// 单个主题
zhub.subscribe("user-login", message -> System.out.println("登录: " + message));
// 类型化消息使用TypeToken
zhub.subscribe("user-profile", new TypeToken<UserProfile>(){}, profile ->
System.out.println("用户: " + profile.getUsername()));
```
</TabItem>
<TabItem value="multi" label="多主题订阅">
```java
// 逗号分隔
zhub.subscribe("user-login,user-logout,user-register", message ->
System.out.println("用户操作: " + message));
```
</TabItem>
<TabItem value="publish" label="发布消息">
```java
// 字符串消息
zhub.publish("user-login", "用户ID: 12345");
// 类型化消息
UserProfile profile = new UserProfile("12345", "张三", "zhangsan@example.com");
zhub.publish("user-profile", profile);
```
</TabItem>
</Tabs>
## 性能优化
### 异步处理
```java
// 避免阻塞消息处理
zhub.subscribe("topic-abc", message -> {
CompletableFuture.runAsync(() -> {
processMessage(message);
});
});
```
### 错误处理
```java
zhub.subscribe("topic-abc", message -> {
try {
processMessage(message);
} catch (Exception e) {
logger.error("消息处理失败", e);
}
});
```

View File

@@ -1,35 +0,0 @@
---
sidebar_position: 3
title: 延时消息
description: zhub 的延时消息使用
---
:::tip
首先完成 **[连接创建](create-connection.md)** ,便可进行**延时消息**的发送和接收,
- [订阅主题消息](#订阅主题消息)
- [发送延时消息](#发送延时消息)
:::
## 订阅主题消息
> 见 [主题的订阅](publish-subscribe.md#订阅主题消息)
## 发送延时消息
> 参数说明:①主题名称 ②消息内容 ③延时多久单位ms
> zhub.delay("topic-delay-a", "delay-value", 1000);
>
示例代码:
```java
private ZHubClient zhub;
@RestMapping(name = "delay_test", auth = false, comment = "发送延时主题消息测试")
public String delayTest(String value) {
zhub.delay("topic-delay-a", "delay-value", 1000);
return "send ok!";
}
```

View File

@@ -0,0 +1,242 @@
---
sidebar_position: 3
title: Golang 连接
description: 在 Go 项目中使用 ZHub 客户端
---
# Golang 项目中使用
> 在 Go 项目中使用 ZHub 客户端
---
## 安装依赖
```bash
go get github.com/your-org/zhub-client-go
```
:::info 说明
Go 客户端的实际包名请以官方发布为准,此处仅为示例
:::
---
## 基础连接
```go
package main
import (
"log"
"github.com/your-org/zhub-client-go"
)
func main() {
// 创建 ZHub 客户端
client := zhub.NewClient("127.0.0.1:1216", "go-group", "go-app-001", "token-12345")
// 连接服务
err := client.Connect()
if err != nil {
log.Fatal("连接失败:", err)
}
defer client.Close()
log.Println("ZHub 连接成功")
}
```
**参数说明**
- `127.0.0.1:1216`: 服务端地址
- `go-group`: 消费者组名称
- `go-app-001`: 应用实例ID必须唯一
- `token-12345`: 认证令牌(开启权限验证时)
---
## 基础使用
### 发布订阅
```go
// 订阅消息
client.Subscribe("user-login", func(message string) {
log.Println("收到消息:", message)
})
// 发布消息
err := client.Publish("user-login", "用户登录")
if err != nil {
log.Println("发布失败:", err)
}
```
### 广播消息
```go
// 广播消息给所有客户端
err := client.Broadcast("topic-abc", "hello!")
if err != nil {
log.Println("广播失败:", err)
}
```
### RPC 调用
```go
// 服务端:提供 RPC 服务
client.RpcSubscribe("user-get-info", func(request string) string {
return "用户信息: " + request
})
// 客户端:调用 RPC 服务
result, err := client.Rpc("user-get-info", "user123")
if err != nil {
log.Println("RPC 失败:", err)
} else {
log.Println("RPC 结果:", result)
}
```
### 延时消息
```go
// 延时5秒发送消息
err := client.Delay("task-reminder", "任务提醒", 5000)
if err != nil {
log.Println("延时消息失败:", err)
}
```
---
## 完整示例
```go
package main
import (
"log"
"time"
"github.com/your-org/zhub-client-go"
)
func main() {
// 创建客户端
client := zhub.NewClient("127.0.0.1:1216", "go-demo", "go-demo-001", "token-12345")
// 连接服务
err := client.Connect()
if err != nil {
log.Fatal("连接失败:", err)
}
defer client.Close()
log.Println("ZHub 连接成功")
// 订阅消息
client.Subscribe("user-login", func(message string) {
log.Println("收到用户登录消息:", message)
})
// 发布消息
err = client.Publish("user-login", "用户ID: 12345")
if err != nil {
log.Println("发布失败:", err)
}
// 广播消息
err = client.Broadcast("topic-abc", "hello!")
if err != nil {
log.Println("广播失败:", err)
}
// 延时消息
err = client.Delay("task-reminder", "任务提醒", 5000)
if err != nil {
log.Println("延时消息失败:", err)
}
// 提供 RPC 服务
client.RpcSubscribe("user-get-info", func(userId string) string {
return "用户信息: " + userId
})
// 调用 RPC 服务
result, err := client.Rpc("user-get-info", "user123")
if err != nil {
log.Println("RPC 失败:", err)
} else {
log.Println("RPC 结果:", result)
}
// 保持程序运行
time.Sleep(time.Minute)
}
```
---
## 注意事项
### 1. AppID 唯一性
:::warning 重要
- **每个客户端必须使用不同的 appid**
- RPC 通讯消息回复地址使用 appid 标识
- 相同 appid 会导致 RPC 消息回复找不到目标客户端
:::
**推荐命名规则**
- `go-service-001`
- `go-worker-002`
- `go-gateway-001`
### 2. 错误处理
```go
// 建议的错误处理方式
if err := client.Publish("topic-abc", "message"); err != nil {
log.Printf("发布消息失败: %v", err)
// 根据业务需要决定是否重试
}
```
### 3. 连接管理
```go
// 检查连接状态
if !client.IsConnected() {
log.Println("客户端未连接")
return
}
// 重连机制
for {
if !client.IsConnected() {
err := client.Connect()
if err != nil {
log.Printf("重连失败: %v", err)
time.Sleep(time.Second * 5)
continue
}
log.Println("重连成功")
}
time.Sleep(time.Second)
}
```
---
## 版本信息
- **客户端版本**: 待发布
- **支持 Go 版本**: 1.19+
- **包管理**: go mod
:::info 说明
- Go 客户端提供基础的发布订阅、广播、RPC 功能
- 连接参数与 Java 客户端保持一致
- 详细 API 请参考客户端源码文档
:::

View File

@@ -0,0 +1,214 @@
---
sidebar_position: 2
title: 发布订阅
description: ZHub 消息发布订阅功能详解,包含基础使用、多主题订阅、类型化消息和最佳实践
---
# 发布订阅
## 基础概念
- **发布者**:发送消息到指定主题
- **订阅者**:订阅主题并处理消息
- **主题**:消息分类标识,支持正则表达式匹配
- **消费组GroupID**:协同消费机制,同组内只有一个消费者处理消息
## 重要说明
**发布订阅**:使用具体主题名称
```java
zhub.subscribe("user-login", message -> { ... });
zhub.publish("user-login", "用户登录");
```
**消费组机制**:同组内消息只被一个消费者处理
```java
// 消费者A和B属于同一组消息只会被其中一个处理
ZHubClient consumerA = new ZHubClient("127.0.0.1:1216", "order-group", "app-a", "token");
ZHubClient consumerB = new ZHubClient("127.0.0.1:1216", "order-group", "app-b", "token");
// 消费者C属于不同组会收到所有消息
ZHubClient consumerC = new ZHubClient("127.0.0.1:1216", "notification-group", "app-c", "token");
```
**权限配置**:支持正则表达式
```yaml
users:
- id: 1
username: "user-service"
reads: ["user.*"] # 匹配所有 user.* 主题
writes: ["user.*"]
```
---
## 协同消费
### 消费组机制
**工作原理**:同组内只有一个消费者处理消息,不同组独立消费
```java
// 负载均衡:同组内竞争消费
ZHubClient service1 = new ZHubClient("127.0.0.1:1216", "order-group", "app-1", "token");
ZHubClient service2 = new ZHubClient("127.0.0.1:1216", "order-group", "app-2", "token");
// 只有其中一个处理消息
// 消息广播:不同组都收到消息
ZHubClient notify1 = new ZHubClient("127.0.0.1:1216", "notify-group-1", "notify-1", "token");
ZHubClient notify2 = new ZHubClient("127.0.0.1:1216", "notify-group-2", "notify-2", "token");
// 两个都会收到消息
```
**应用场景**
- **负载均衡**:同组内多个服务竞争处理
- **消息广播**:不同组都接收消息
- **数据去重**:同组内确保只处理一次
---
## 基础使用
### 1. 基础发布订阅
**字符串消息**
```java
// 订阅
zhub.subscribe("user-login", message -> {
System.out.println("用户登录: " + message);
});
// 发布
zhub.publish("user-login", "用户ID: 12345");
```
**类型化消息**
```java
// 定义消息类型
public class UserLoginEvent {
private String userId;
private String username;
private long loginTime;
// getter/setter...
}
// 订阅类型化消息使用TypeToken
zhub.subscribe("user-login", new TypeToken<UserLoginEvent>(){}, event -> {
System.out.println("用户: " + event.getUsername());
});
// 发布类型化消息
UserLoginEvent event = new UserLoginEvent("12345", "张三", System.currentTimeMillis());
zhub.publish("user-login", event);
```
**基础类型**
```java
// 整数消息使用IType
zhub.subscribe("user-count", IType.INT, count -> {
System.out.println("用户数: " + count);
});
zhub.publish("user-count", 100);
// Map 消息使用IType
zhub.subscribe("user-info", IType.MAP, info -> {
System.out.println("用户信息: " + info);
});
Map<String, String> userInfo = Map.of("userId", "12345", "username", "张三");
zhub.publish("user-info", userInfo);
```
### 2. 多主题订阅
**分别订阅**
```java
zhub.subscribe("user-profile", message -> {
System.out.println("用户资料: " + message);
});
zhub.subscribe("user-login", message -> {
System.out.println("用户登录: " + message);
});
```
**逗号分隔订阅**
```java
// 同时订阅多个主题
zhub.subscribe("user-profile,user-login,user-logout", message -> {
System.out.println("用户消息: " + message);
});
// 类型化消息使用TypeToken
zhub.subscribe("order-create,order-payment", new TypeToken<OrderEvent>(){}, event -> {
System.out.println("订单事件: " + event.getOrderId());
});
```
### 3. 广播消息
```java
// 广播给所有客户端
zhub.broadcast("topic-abc", "hello!");
```
---
## 高级功能
### 1. 延时消息
```java
// 延时5分钟后发送消息
zhub.delay("reminder-email", "发送提醒邮件", 5 * 60 * 1000);
```
### 2. 消息过滤
```java
zhub.subscribe("user-notification", message -> {
if (message.contains("VIP")) {
System.out.println("VIP用户消息: " + message);
}
});
```
### 3. 批量处理
```java
private final List<String> messageBatch = new ArrayList<>();
zhub.subscribe("data-sync", message -> {
synchronized (messageBatch) {
messageBatch.add(message);
if (messageBatch.size() >= 100) {
processBatch(new ArrayList<>(messageBatch));
messageBatch.clear();
}
}
});
```
---
## 最佳实践
**Topic 命名**`user-profile-update``order-payment-success`
**异常处理**
```java
zhub.subscribe("critical-task", message -> {
try {
processTask(message);
} catch (Exception e) {
logger.error("处理失败", e);
}
});
```
## 消息特性
- **顺序保证**:单个主题内消息严格按发送顺序处理
- **非持久化**:默认不持久化,重启后消息丢失
- **高性能**:内存处理,支持高并发消息传递
- **容量限制**服务端通道容量500条满时消息会被丢弃
## 注意事项
- 避免创建大量对象
- 注意消息积压服务端通道容量500条满时消息会被丢弃

View File

@@ -1,41 +0,0 @@
---
sidebar_position: 1
title: 发布&订阅
description: zhub 创建客户端连接、订阅主题、发送主题消息
---
:::tip
发布-订阅Publish-Subscribe消息中间件可以用于实现发布-订阅模式。发布者将消息发布到一个或多个主题Topic而订阅者订阅感兴趣的主题。当有新的消息发布到主题时所有订阅了该主题的订阅者都会接收到消息。这样可以实现一对多的消息传递降低发送方和接收方之间的耦合性。
首先完成 **[连接创建](create-connection.md)** ,便可进行消息的发送和接收,
- [订阅主题消息](#订阅主题消息)
- [发送主题消息](#发送主题消息)
:::
## 订阅主题消息
```java
// 事件订阅
zhub.subscribe("topic-a", x -> {
System.out.println("接收到主题 topic-a 事件,消息内容:" + x);
});
```
## 发送主题消息
测试发送主题消息
```java
private ZHubClient zhub;
@RestMapping(name = "publish_test", auth = false, comment = "发送主题消息测试")
public String publishTest(String value) {
zhub.publish("topic-a", value);
return "send ok!";
}
```
这个时候,将会在订阅端收到主题订阅消息,并在控制台输出: `接收到主题 topic-a 事件消息内容xx` 的消息内容

View File

@@ -1,36 +1,167 @@
--- ---
sidebar_position: 4 sidebar_position: 4
title: 远程调用 RPC title: RPC 远程调用
description: RPC 远程调用Remote Procedure CallRPC description: ZHub RPC 远程调用功能详解,包含基础类型、类型化调用和多客户端示例
--- ---
# RPC远程调用 # RPC 远程调用
:::tip ![rpc-flow.png](https://img.1216.top/docs/zhub/rpc-flow.png)
RPC 是一种通过网络将远程过程调用Remote Procedure CallRPC封装成消息并传送到远程服务器上的过程。
:::
![zhub-fun.png](https://img.1216.top/docs/zhub/rpc-flow.png)
## 使用场景 ## 使用场景
> 在分布式环境下,通过 RPC 可以在两个应用之间进行消息传递,实现远程调用。
## rpc的订阅-调用基础示例 - **微服务间通信**:用户服务调用订单服务
### 被调用端 - **数据查询服务**:统一的数据查询接口
- **业务逻辑封装**:封装复杂业务逻辑供其他模块调用
- **第三方服务集成**:调用外部 API
## 基础示例
**重要**RPC 通讯要求每个客户端使用唯一的 appid消息回复使用此标识。
### 基础类型 RPC
**服务端**
```java ```java
// 订阅 rpc-b 事件, 参数类型为 String // 订阅 RPC 服务
zhub.rpcSubscribe("rpc-b", IType.STRING, r -> { zhub.rpcSubscribe("rpc-b", IType.STRING, r -> {
String str = r.getValue(); String str = r.getValue();
System.out.println("接收到 b 事件:" + str); System.out.println("接收到: " + str);
return r.render("接收到 b 事件:" + str); return r.render("处理结果: " + str);
}); });
``` ```
### 调用端
```java **客户端**
// 调用 rpc-b 事件, 参数类型为 String返回类型为 String ```java
RpcResult<String> rpcResult = zhub.rpc("rpc-b", "hello rpc", IType.STRING); // 调用 RPC 服务
String result = rpcResult.getResult(); RpcResult<String> result = zhub.rpc("rpc-b", "hello rpc", IType.STRING);
System.out.println("rpc result:" + result); System.out.println("结果: " + result.getResult());
```
### 类型化 RPC
**定义类型**
```java
// 请求类型
public class UserQueryRequest {
private String userId;
private String queryType;
// getter/setter...
}
// 响应类型
public class UserInfoResponse {
private String userId;
private String username;
private String email;
private long lastLoginTime;
// getter/setter...
}
```
**服务端**
```java
zhub.rpcSubscribe("user-get-info", new TypeToken<UserQueryRequest>(){}, request -> {
String userId = request.getUserId();
String queryType = request.getQueryType();
return request.render(new UserInfoResponse(userId, "张三", "zhangsan@example.com", System.currentTimeMillis()));
});
```
**客户端**
```java
UserQueryRequest request = new UserQueryRequest("12345", "basic");
RpcResult<UserInfoResponse> result = zhub.rpc("user-get-info", request, new TypeToken<UserInfoResponse>(){});
if (result.isSuccess()) {
UserInfoResponse userInfo = result.getResult();
System.out.println("用户: " + userInfo.getUsername());
} else {
System.out.println("调用失败: " + result.getError());
}
```
### 多客户端示例
**服务端**
```java
ZHubClient serviceProvider = new ZHubClient("127.0.0.1:1216", "service-group", "service-provider-001", "token-12345");
// 单个 RPC 服务
serviceProvider.rpcSubscribe("user-get-info", IType.STRING, request -> {
return request.render("用户信息: " + request.getValue());
});
// 多个 RPC 服务使用TypeToken
serviceProvider.rpcSubscribe("user-get-info,user-get-profile", new TypeToken<UserQueryRequest>(){}, request -> {
switch (request.getQueryType()) {
case "getInfo":
return request.render(new UserInfoResponse(request.getUserId(), "张三", "zhangsan@example.com", System.currentTimeMillis()));
case "getProfile":
return request.render(new UserProfileResponse(request.getUserId(), "张三", 25, "北京"));
default:
return request.render(new UserInfoResponse(request.getUserId(), "未知用户", "", 0));
}
});
```
**客户端A**
```java
ZHubClient clientA = new ZHubClient("127.0.0.1:1216", "client-group", "client-a-001", "token-12345");
RpcResult<String> result = clientA.rpc("user-get-info", "user123", IType.STRING);
System.out.println("结果: " + result.getResult());
```
**客户端B**
```java
ZHubClient clientB = new ZHubClient("127.0.0.1:1216", "client-group", "client-b-002", "token-12345");
UserQueryRequest request = new UserQueryRequest("user456", "basic");
RpcResult<UserInfoResponse> result = clientB.rpc("user-get-info", request, new TypeToken<UserInfoResponse>(){});
if (result.isSuccess()) {
System.out.println("用户: " + result.getResult().getUsername());
}
```
## 类型化 RPC
### 使用 TypeToken 构建具体类型
**服务端**
```java
// 定义请求和响应类型
public class OrderRequest {
private String orderId;
private String queryType;
// getter/setter...
}
public class OrderResponse {
private String orderId;
private String status;
private BigDecimal amount;
// getter/setter...
}
// 订阅类型化 RPC
zhub.rpcSubscribe("order-get-details", new TypeToken<OrderRequest>(){}, request -> {
OrderResponse response = new OrderResponse();
response.setOrderId(request.getOrderId());
response.setStatus("已支付");
response.setAmount(new BigDecimal("99.99"));
return request.render(response);
});
```
**客户端**
```java
// 调用类型化 RPC
OrderRequest request = new OrderRequest("ORDER-123", "details");
RpcResult<OrderResponse> result = zhub.rpc("order-get-details", request, new TypeToken<OrderResponse>(){});
if (result.isSuccess()) {
OrderResponse order = result.getResult();
System.out.println("订单状态: " + order.getStatus());
System.out.println("订单金额: " + order.getAmount());
}
``` ```

View File

@@ -3,6 +3,6 @@
"position": 3, "position": 3,
"link": { "link": {
"type": "generated-index", "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 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级别

View File

@@ -6,8 +6,8 @@ const darkCodeTheme = require('prism-react-renderer/themes/dracula')
/** @type {import('@docusaurus/types').Config} */ /** @type {import('@docusaurus/types').Config} */
const config = { const config = {
title: 'ZHub', title: 'ZHub - 轻量级消息中间件',
tagline: '轻量级消息中间件', tagline: '高性能、轻量级消息中间件支持发布订阅、RPC调用、延时消息等功能',
favicon: 'img/favicon.ico', favicon: 'img/favicon.ico',
// Set the production url of your site here // Set the production url of your site here
@@ -22,8 +22,8 @@ const config = {
// GitHub pages deployment config. // GitHub pages deployment config.
// If you aren't using GitHub pages, you don't need these. // If you aren't using GitHub pages, you don't need these.
organizationName: 'facebook', // Usually your GitHub org/user name. organizationName: 'zhub', // Usually your GitHub org/user name.
projectName: 'docusaurus', // Usually your repo name. projectName: 'zhub-docs', // Usually your repo name.
onBrokenLinks: 'throw', onBrokenLinks: 'throw',
onBrokenMarkdownLinks: 'warn', onBrokenMarkdownLinks: 'warn',
@@ -32,8 +32,8 @@ const config = {
// metadata like html lang. For example, if your site is Chinese, you may want // metadata like html lang. For example, if your site is Chinese, you may want
// to replace "en" with "zh-Hans". // to replace "en" with "zh-Hans".
i18n: { i18n: {
defaultLocale: 'en', defaultLocale: 'zh-Hans',
locales: ['en'], locales: ['zh-Hans'],
}, },
presets: [ presets: [
@@ -70,7 +70,7 @@ const config = {
navbar: { navbar: {
title: 'ZHub', title: 'ZHub',
logo: { logo: {
alt: 'My Site Logo', alt: 'ZHub Logo',
src: 'img/logo.svg', src: 'img/logo.svg',
}, },
items: [ items: [
@@ -113,6 +113,18 @@ const config = {
darkTheme: darkCodeTheme, darkTheme: darkCodeTheme,
additionalLanguages: ['java'], additionalLanguages: ['java'],
}, },
metadata: [
{name: 'keywords', content: '消息中间件,消息队列,RPC,发布订阅,微服务,Java,SpringBoot'},
{name: 'description', content: 'ZHub 是一个轻量级、高性能的消息中间件支持发布订阅、RPC调用、延时消息、广播等功能适用于微服务架构'},
{property: 'og:type', content: 'website'},
{property: 'og:title', content: 'ZHub - 轻量级消息中间件'},
{property: 'og:description', content: '高性能、轻量级的消息中间件支持发布订阅、RPC调用、延时消息等功能'},
{property: 'og:image', content: 'https://zhub.dev/img/docusaurus-social-card.jpg'},
{name: 'twitter:card', content: 'summary_large_image'},
{name: 'twitter:title', content: 'ZHub - 轻量级消息中间件'},
{name: 'twitter:description', content: '高性能、轻量级的消息中间件支持发布订阅、RPC调用、延时消息等功能'},
{name: 'twitter:image', content: 'https://zhub.dev/img/docusaurus-social-card.jpg'},
],
}), }),
} }

11
static/robots.txt Normal file
View File

@@ -0,0 +1,11 @@
User-agent: *
Allow: /
# Sitemap
Sitemap: https://zhub.dev/sitemap.xml
# 禁止爬取构建文件
Disallow: /build/
Disallow: /node_modules/
Disallow: /static/js/
Disallow: /static/css/