添加:ZHub 管理接口文档和客户端使用指南
This commit is contained in:
@@ -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 进行整理编写。另外,如有需要,您还可以进一步细分和拓展目录结构,以适应实际需求。
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
{
|
|
||||||
"label": "快速开始",
|
|
||||||
"position": 1,
|
|
||||||
"link": {
|
|
||||||
"type": "generated-index"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
8
docs/admin-apis/_category_.json
Normal file
8
docs/admin-apis/_category_.json
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
"label": "管理接口 API",
|
||||||
|
"position": 2,
|
||||||
|
"link": {
|
||||||
|
"type": "generated-index",
|
||||||
|
"description": "ZHub 服务管理接口详细说明,包括服务监控、配置重载、资源清理等功能。"
|
||||||
|
}
|
||||||
|
}
|
||||||
141
docs/admin-apis/auth-reload-api.md
Normal file
141
docs/admin-apis/auth-reload-api.md
Normal 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. **访问日志**: 记录权限相关的访问日志
|
||||||
53
docs/admin-apis/cleanup-api.md
Normal file
53
docs/admin-apis/cleanup-api.md
Normal 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. **资源回收**: 清理不再使用的主题和消息
|
||||||
|
|
||||||
70
docs/admin-apis/info-api.md
Normal file
70
docs/admin-apis/info-api.md
Normal 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. **运维管理**: 评估服务负载和资源使用情况
|
||||||
|
|
||||||
|
## 注意事项
|
||||||
|
|
||||||
|
- 该接口为只读操作,不会修改服务状态
|
||||||
|
- 返回的信息实时反映当前服务状态
|
||||||
34
docs/admin-apis/other-apis.md
Normal file
34
docs/admin-apis/other-apis.md
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
---
|
||||||
|
sidebar_position: 5
|
||||||
|
title: 其他管理接口
|
||||||
|
description: ZHub 其他管理接口说明
|
||||||
|
---
|
||||||
|
|
||||||
|
# 其他管理接口
|
||||||
|
|
||||||
|
除了核心的管理接口外,ZHub 还提供了其他有用的管理接口,用于版本查询、消息发送和延时消息管理等功能。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 版本信息接口
|
||||||
|
|
||||||
|
### 接口说明
|
||||||
|
|
||||||
|
- **路径**: `GET /_/version`
|
||||||
|
- **功能**: 查看服务版本信息
|
||||||
|
- **用途**: 确认服务版本,进行版本管理
|
||||||
|
|
||||||
|
### 使用示例
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 查看服务版本
|
||||||
|
curl http://127.0.0.1:711/_/version
|
||||||
|
```
|
||||||
|
|
||||||
|
### 返回信息
|
||||||
|
|
||||||
|
返回当前 ZHub 服务的版本信息,包括:
|
||||||
|
|
||||||
|
- 服务版本号
|
||||||
|
- 构建时间
|
||||||
|
---
|
||||||
61
docs/admin-apis/overview.md
Normal file
61
docs/admin-apis/overview.md
Normal 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 接口
|
||||||
51
docs/admin-apis/timer-reload-api.md
Normal file
51
docs/admin-apis/timer-reload-api.md
Normal 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 重要提醒
|
||||||
|
- 重载操作会立即生效,请确保配置正确
|
||||||
|
:::
|
||||||
258
docs/intro.md
258
docs/intro.md
@@ -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 服务
|
## 搭建 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/
|
||||||
|
├── 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:A、T:B、T:C、T: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 -> {
|
zhub.subscribe("topic-a", x -> {
|
||||||
System.out.println("接收到 a 事件:" + x);
|
System.out.println("接收到消息:" + x);
|
||||||
});
|
});
|
||||||
```
|
|
||||||
```java
|
|
||||||
zhub.publish("topic-a", "123");
|
|
||||||
```
|
|
||||||
2、rpc的订阅-调用
|
|
||||||
```java
|
|
||||||
zhub.rpcSubscribe("rpc-b", IType.STRING, r -> {
|
|
||||||
String str = r.getValue();
|
|
||||||
System.out.println("接收到 b 事件:" + str);
|
|
||||||
return r.render("接收到 b 事件:" + str);
|
|
||||||
});
|
|
||||||
```
|
|
||||||
```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 {
|
zhub.publish("topic-a", "Hello ZHub!");
|
||||||
System.out.println("获取到锁");
|
|
||||||
} finally {
|
|
||||||
lock.unLock();
|
|
||||||
}
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
#### 2. RPC 远程调用
|
||||||
|
```java
|
||||||
|
// 服务端:提供 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());
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 3. 其他功能
|
||||||
|
```java
|
||||||
|
// 广播消息
|
||||||
|
zhub.broadcast("topic", "message");
|
||||||
|
|
||||||
|
// 延时消息
|
||||||
|
zhub.delay("topic", "message", 5000);
|
||||||
|
```
|
||||||
|
**详细文档**:
|
||||||
|
- [发布订阅](./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)
|
||||||
@@ -3,6 +3,6 @@
|
|||||||
"position": 5,
|
"position": 5,
|
||||||
"link": {
|
"link": {
|
||||||
"type": "generated-index",
|
"type": "generated-index",
|
||||||
"description": "这里存放了各种常用的工具。"
|
"description": "ZHub 相关工具和概念,包含类型令牌、微服务架构等"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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 # 启动(服务模式)
|
|
||||||
|
|
||||||
```
|
|
||||||
@@ -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>(){}`,无需显式声明
|
||||||
|
|||||||
@@ -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));
|
||||||
|
```
|
||||||
|
|
||||||
|
## 最佳实践
|
||||||
|
|
||||||
|
- **服务划分**:按业务领域划分,保持单一职责
|
||||||
|
- **消息设计**:清晰命名规范,可扩展格式
|
||||||
|
- **错误处理**:重试机制、死信队列、状态监控
|
||||||
|
- **监控管理**:连接状态、处理量、延迟监控
|
||||||
|
|||||||
@@ -3,6 +3,6 @@
|
|||||||
"position": 2,
|
"position": 2,
|
||||||
"link": {
|
"link": {
|
||||||
"type": "generated-index",
|
"type": "generated-index",
|
||||||
"description": "完成 ZHub 服务安装后,来看看一遍就会的基础使用文档~"
|
"description": "ZHub 基础功能使用指南,包含连接创建、发布订阅、RPC调用等核心功能"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
112
docs/tutorial-basics/broadcast-delay.md
Normal file
112
docs/tutorial-basics/broadcast-delay.md
Normal 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));
|
||||||
|
```
|
||||||
|
|
||||||
|
## 注意事项
|
||||||
|
|
||||||
|
- 延时时间不限制延迟时间
|
||||||
|
- 重启后延时消息丢失
|
||||||
|
- 广播消息影响所有客户端性能
|
||||||
@@ -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!";
|
|
||||||
}
|
|
||||||
```
|
|
||||||
@@ -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` 协同消费组,同组内只有一个消费者处理消息
|
||||||
|
|
||||||
## Redkale框架 项目里面使用
|
</TabItem>
|
||||||
|
<TabItem value="spring" label="SpringBoot项目">
|
||||||
> 在Java的redkale 项目中引入 zhub-rekale.jar
|
|
||||||
> 在配置文件中配置zhub组件
|
|
||||||
|
|
||||||
|
**1. 依赖**
|
||||||
|
```xml
|
||||||
|
<dependency>
|
||||||
|
<groupId>dev.zhub</groupId>
|
||||||
|
<artifactId>zhub-client-spring</artifactId>
|
||||||
|
<version>0.1.0424.dev</version>
|
||||||
|
</dependency>
|
||||||
```
|
```
|
||||||
# source.properties 中配置
|
|
||||||
############ ClusterSource @Resource(name="hub") ############
|
**2. 配置 application.yml**
|
||||||
redkale.cluster.zhub[hub].addr = 127.0.0.1:6066
|
```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
|
||||||
|
@Service
|
||||||
|
public class UserService {
|
||||||
|
@Autowired
|
||||||
|
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);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
</TabItem>
|
||||||
|
<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);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|||||||
@@ -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!";
|
|
||||||
}
|
|
||||||
```
|
|
||||||
242
docs/tutorial-basics/golang-connection.md
Normal file
242
docs/tutorial-basics/golang-connection.md
Normal 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 请参考客户端源码文档
|
||||||
|
:::
|
||||||
214
docs/tutorial-basics/pub-sub.md
Normal file
214
docs/tutorial-basics/pub-sub.md
Normal 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条,满时消息会被丢弃
|
||||||
@@ -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` 的消息内容
|
|
||||||
@@ -1,36 +1,167 @@
|
|||||||
---
|
---
|
||||||
sidebar_position: 4
|
sidebar_position: 4
|
||||||
title: 远程调用 RPC
|
title: RPC 远程调用
|
||||||
description: RPC 远程调用,Remote Procedure Call,RPC
|
description: ZHub RPC 远程调用功能详解,包含基础类型、类型化调用和多客户端示例
|
||||||
---
|
---
|
||||||
|
|
||||||
# RPC 远程调用
|
# RPC 远程调用
|
||||||
|
|
||||||
:::tip
|

|
||||||
|
|
||||||
RPC 是一种通过网络将远程过程调用(Remote Procedure Call,RPC)封装成消息,并传送到远程服务器上的过程。
|
|
||||||
|
|
||||||
:::
|
|
||||||

|
|
||||||
|
|
||||||
## 使用场景
|
## 使用场景
|
||||||
> 在分布式环境下,通过 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
|
```java
|
||||||
// 调用 rpc-b 事件, 参数类型为 String,返回类型为 String
|
// 调用 RPC 服务
|
||||||
RpcResult<String> rpcResult = zhub.rpc("rpc-b", "hello rpc", IType.STRING);
|
RpcResult<String> result = zhub.rpc("rpc-b", "hello rpc", IType.STRING);
|
||||||
String result = rpcResult.getResult();
|
System.out.println("结果: " + result.getResult());
|
||||||
System.out.println("rpc result:" + result);
|
```
|
||||||
|
|
||||||
|
### 类型化 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());
|
||||||
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,6 @@
|
|||||||
"position": 3,
|
"position": 3,
|
||||||
"link": {
|
"link": {
|
||||||
"type": "generated-index",
|
"type": "generated-index",
|
||||||
"description": "分布式系统常用组件"
|
"description": "ZHub 高级功能配置,包含权限管理、性能优化、安全实践等"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
148
docs/tutorial-extras/api-reference.md
Normal file
148
docs/tutorial-extras/api-reference.md
Normal 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 | 认证失败 |
|
||||||
191
docs/tutorial-extras/auth-config.md
Normal file
191
docs/tutorial-extras/auth-config.md
Normal 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
|
||||||
169
docs/tutorial-extras/docker-deployment.md
Normal file
169
docs/tutorial-extras/docker-deployment.md
Normal 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
497
docs/tutorial-extras/faq.md
Normal 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
|
||||||
@@ -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. 性能指标
|
||||||
|
|
||||||
|
- 锁获取成功率
|
||||||
|
- 锁平均持有时间
|
||||||
|
- 锁等待时间
|
||||||
|
- 锁竞争频率
|
||||||
|
|||||||
132
docs/tutorial-extras/security-best-practices.md
Normal file
132
docs/tutorial-extras/security-best-practices.md
Normal 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`)
|
||||||
|
- [ ] 配置最小权限原则
|
||||||
|
- [ ] 实施网络隔离
|
||||||
|
- [ ] 启用访问日志
|
||||||
|
- [ ] 定期安全审计
|
||||||
|
|
||||||
|
### 定期维护
|
||||||
|
|
||||||
|
- 定期检查权限配置
|
||||||
|
- 定期更新认证令牌
|
||||||
|
- 监控服务状态和连接情况
|
||||||
@@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
421
docs/tutorial-extras/troubleshooting.md
Normal file
421
docs/tutorial-extras/troubleshooting.md
Normal 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)。
|
||||||
278
docs/tutorial-extras/zhub-log.md
Normal file
278
docs/tutorial-extras/zhub-log.md
Normal 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级别
|
||||||
@@ -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
11
static/robots.txt
Normal 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/
|
||||||
Reference in New Issue
Block a user