diff --git a/back/redkale/getting-started.md b/back/redkale/getting-started.md deleted file mode 100644 index 2ee07ee..0000000 --- a/back/redkale/getting-started.md +++ /dev/null @@ -1,77 +0,0 @@ ---- -sidebar_position: 1 ---- - -# 快速开始 - -import Tabs from '@theme/Tabs'; -import TabItem from '@theme/TabItem'; - - - - - - This is an apple 🍎 - - - This is an orange 🍊 - - - This is a banana 🍌 - - - -好的,以下是对应的文件名和目录结构: - -- 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 进行整理编写。另外,如有需要,您还可以进一步细分和拓展目录结构,以适应实际需求。 \ No newline at end of file diff --git a/back/redkale/getting-started/_category_.json b/back/redkale/getting-started/_category_.json deleted file mode 100644 index 3538283..0000000 --- a/back/redkale/getting-started/_category_.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "label": "快速开始", - "position": 1, - "link": { - "type": "generated-index" - } -} diff --git a/docs/admin-apis/_category_.json b/docs/admin-apis/_category_.json new file mode 100644 index 0000000..d2af360 --- /dev/null +++ b/docs/admin-apis/_category_.json @@ -0,0 +1,8 @@ +{ + "label": "管理接口 API", + "position": 2, + "link": { + "type": "generated-index", + "description": "ZHub 服务管理接口详细说明,包括服务监控、配置重载、资源清理等功能。" + } +} diff --git a/docs/admin-apis/auth-reload-api.md b/docs/admin-apis/auth-reload-api.md new file mode 100644 index 0000000..d207b02 --- /dev/null +++ b/docs/admin-apis/auth-reload-api.md @@ -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. **访问日志**: 记录权限相关的访问日志 diff --git a/docs/admin-apis/cleanup-api.md b/docs/admin-apis/cleanup-api.md new file mode 100644 index 0000000..4829576 --- /dev/null +++ b/docs/admin-apis/cleanup-api.md @@ -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. **资源回收**: 清理不再使用的主题和消息 + diff --git a/docs/admin-apis/info-api.md b/docs/admin-apis/info-api.md new file mode 100644 index 0000000..87b90cd --- /dev/null +++ b/docs/admin-apis/info-api.md @@ -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. **运维管理**: 评估服务负载和资源使用情况 + +## 注意事项 + +- 该接口为只读操作,不会修改服务状态 +- 返回的信息实时反映当前服务状态 diff --git a/docs/admin-apis/other-apis.md b/docs/admin-apis/other-apis.md new file mode 100644 index 0000000..ce65912 --- /dev/null +++ b/docs/admin-apis/other-apis.md @@ -0,0 +1,34 @@ +--- +sidebar_position: 5 +title: 其他管理接口 +description: ZHub 其他管理接口说明 +--- + +# 其他管理接口 + +除了核心的管理接口外,ZHub 还提供了其他有用的管理接口,用于版本查询、消息发送和延时消息管理等功能。 + +--- + +## 版本信息接口 + +### 接口说明 + +- **路径**: `GET /_/version` +- **功能**: 查看服务版本信息 +- **用途**: 确认服务版本,进行版本管理 + +### 使用示例 + +```bash +# 查看服务版本 +curl http://127.0.0.1:711/_/version +``` + +### 返回信息 + +返回当前 ZHub 服务的版本信息,包括: + +- 服务版本号 +- 构建时间 +--- diff --git a/docs/admin-apis/overview.md b/docs/admin-apis/overview.md new file mode 100644 index 0000000..901a00d --- /dev/null +++ b/docs/admin-apis/overview.md @@ -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 接口 diff --git a/docs/admin-apis/timer-reload-api.md b/docs/admin-apis/timer-reload-api.md new file mode 100644 index 0000000..8a841c6 --- /dev/null +++ b/docs/admin-apis/timer-reload-api.md @@ -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 重要提醒 +- 重载操作会立即生效,请确保配置正确 +::: \ No newline at end of file diff --git a/docs/intro.md b/docs/intro.md index 29ee71e..c5deec4 100644 --- a/docs/intro.md +++ b/docs/intro.md @@ -1,90 +1,121 @@ --- +title: 快速上手 +description: ZHub 轻量级消息中间件快速入门指南,包含安装配置、基础使用和功能特性介绍 sidebar_position: 1 --- # ZHub 快速上手 ## 概述 -> zhub是⼀个⾼性能事件发布订阅服务组件,功能丰富,包含发布-订阅、⼴播消息、延时消息、 -Rpc调⽤、分布式定时调度、分布式锁,运⾏包仅有1M+;低服务资源消费,初始启动内存 10M-。 +ZHub 是一个轻量级消息中间件,支持发布订阅、广播消息、延时消息、RPC调用等功能。运行包仅1M+,启动内存10M-。 + +**核心特性**: +- 消息顺序保证:单个主题内严格按发送顺序处理 +- 高性能:内存处理,支持高并发 +- 轻量级:运行包1M+,启动内存10M- ![zhub-fun.png](https://img.1216.top/docs/zhub/zhub-fun.png) --- -## 开始 搭建 zhub 服务 -> 让我们在 **5到10分钟内完成 zhub 中间件安装、集成、测试**. +## 搭建 ZHub 服务 ### 下载软件包 -- [zhub.zip (点击下载)](https://img.1216.top/docs/zhub/zhub.zip) 包含以下内容: - - `zhub-client-0.1.1.dev.jar` 常规Java 项目驱动包 - - `zhub-client-spring-0.1.1.jar` springboot 项目驱动包 - - `zhub.exe` Window 运行包 - - `zhub.sh` Linux 运行包 - - `zhub` Mac 运行包 - - `app.ini` 配置文件 - ![zhub-zip.png](https://img.1216.top/docs/zhub/dist-zip.png) +**下载地址**: [https://zhub.dev/release/latest/](https://zhub.dev/release/latest/) + +**支持平台**: +- `zhub-linux-amd64.tar` - Linux AMD64 +- `zhub-linux-arm64.tar` - Linux ARM64 +- `zhub-win-amd64.tar` - Windows AMD64 + +**目录结构**: +``` +zhub/ +├── zhub.sh # 可执行文件 +├── app.ini # 服务配置 +└── auth.yml # 权限配置(可选) +``` ### 配置 app.ini -```bash -# app.ini +```ini [service] -watch=0.0.0.0:711 # 服务管理端口 +watch=0.0.0.0:711 # 管理端口 addr=0.0.0.0:1216 # 服务端口 -auth=0 # 是否开启连接授权 0不开启、1开启 +auth=0 # 权限验证 0关闭/1开启 [data] dir=./data # 数据目录 [log] -handlers=console # console|file -level=debug # info|debug|error -file=zhub.log - -[ztimer] # ztimer 配置 (可选,如果不使用定时调度则可不配置) -# db.addr=127.0.0.1:3306 # timer 使用的MySql数据库配置 -# db.user=root -# db.password=123456 -# db.database=zhub +handlers=console # 日志输出 +level=debug # 日志级别 ``` +**重要**: +- 客户端 `appid` 必须唯一 +- 生产环境建议开启权限验证 + +**性能注意事项**: +- 服务端通道容量500条,满时消息会被丢弃 +- 定期执行内存清理:`curl http://127.0.0.1:711/_/cleanup` +- 监控服务状态:`curl http://127.0.0.1:711/_/info` + --- -### 初始化 ztimer 数据库 (可选,如果不使用定时调度则不需要配置) +### 初始化数据库(可选, 定时调度调度任务配置) +**MySQL**: ```sql CREATE DATABASE zhub; CREATE TABLE `zhub`.`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; -# 初始化 四个定时任务配置, 订阅名称分别为 T:A、T:B、T:C、T:D -INSERT INTO `zhub`.`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); + `timerid` varchar(64) NOT NULL DEFAULT '' PRIMARY KEY COMMENT '任务ID', + `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停用' +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='定时任务表'; +``` + +**PostgreSQL**: +```sql +CREATE DATABASE zhub; +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 +); + +-- 添加表和字段注释 +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 -# window -./zhub.exe -# linux (添加执行权限 chmod +x ./zhub.sh) -./zhub.sh +# Linux/Mac +chmod +x ./zhub.sh && ./zhub.sh + +# Windows +# 解压后直接运行 ``` + +**端口**:管理端口 711,服务端口 1216 --- ## 连接使用 -### 导入连接驱动 (根据不同的项目选择不同的导入方式) +### 导入依赖 import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem'; @@ -93,7 +124,7 @@ import TabItem from '@theme/TabItem'; ```xml - + maven-nexus @@ -105,9 +136,9 @@ import TabItem from '@theme/TabItem'; - net.tccn + dev.zhub zhub-client - 0.1.1.dev + 0.1.0424.dev ``` @@ -116,7 +147,7 @@ import TabItem from '@theme/TabItem'; ```xml - + maven-nexus @@ -126,11 +157,11 @@ import TabItem from '@theme/TabItem'; - + - net.tccn + dev.zhub zhub-client-spring - 0.1.1.dev + 0.1.0424.dev ``` @@ -139,7 +170,7 @@ import TabItem from '@theme/TabItem'; ```xml - + maven-nexus @@ -149,11 +180,11 @@ import TabItem from '@theme/TabItem'; - + - net.tccn + dev.zhub zhub-client-redkale - 0.1.1.dev + 0.1.0424.dev ``` @@ -167,19 +198,20 @@ import TabItem from '@theme/TabItem'; ``` // 参数说明:①连接地址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"); ``` -```yml +```yaml # application.yml zhub: - addr: 47.107.112.45:1216 + addr: 127.0.0.1:1216 groupid: groupid-x appid: zhub_demo_1 - # auth: token-12345 # 启用 auth情况下接入验权配置 + auth: token-12345 # 开启权限验证时配置授权码 ``` ```java // 自动注入连接对象 @@ -189,10 +221,10 @@ zhub: -```yaml +```properties # source.properties 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].appid = zhub_demo_1 # (无需配置,取 redklae 配置的 appname) ``` @@ -206,68 +238,52 @@ redkale.cluster.zhub[zhub].groupid = zcore-zhub --- -### 使用 zhub 收发消息 -> 通过上面的操作,我们已经得到了一个 zhub 的连接实例,下面来看看具体的使用 -> +### 快速体验 -1、消息的发布-订阅 +#### 1. 消息发布订阅 ```java - zhub.subscribe("topic-a", x -> { - System.out.println("接收到 a 事件:" + x); - }); +// 订阅消息 +zhub.subscribe("topic-a", x -> { + System.out.println("接收到消息:" + x); +}); + +// 发布消息 +zhub.publish("topic-a", "Hello ZHub!"); ``` + +#### 2. RPC 远程调用 ```java - zhub.publish("topic-a", "123"); +// 服务端:提供 RPC 服务 +zhub.rpcSubscribe("user.getInfo", IType.STRING, request -> { + String userId = request.getValue(); + return request.render("用户信息: " + userId); +}); + +// 客户端:调用 RPC 服务 +RpcResult result = zhub.rpc("user.getInfo", "user123", IType.STRING); +System.out.println("RPC 结果: " + result.getResult()); ``` -2、rpc的订阅-调用 + +#### 3. 其他功能 ```java - zhub.rpcSubscribe("rpc-b", IType.STRING, r -> { - String str = r.getValue(); - System.out.println("接收到 b 事件:" + str); - return r.render("接收到 b 事件:" + str); - }); -``` -```java - RpcResult rpcResult = zhub.rpc("rpc-b", "hello rpc", IType.STRING); - String result = rpcResult.getResult(); - System.out.println("rpc result:" + result); -``` -3、广播消息 -```java - zhub.broadcast("topic-a", "123"); -``` -4、延时消息 -```java - zhub.delay("topic-a", "123", 1000 * 60 * 5); -``` -5、定时调度 -```java - zhub.timer("T:A", () -> { - System.out.println("收到定时调度事件:T:A"); - }); -``` -6、分布式锁 -```java - // 获取锁,直到索取到锁后返回 - Lock lock = zhub.lock("lock-a", 5); - try { - System.out.println("获取到锁"); - } finally { - lock.unLock(); - } -``` -```java - // 尝试获取锁,立即返回 - Lock lock = zhub.tryLock("lock-a", 5); - if (!lock.success()) { - System.out.println("未获取到锁"); - return; - } - - // 获取到锁 - try { - System.out.println("获取到锁"); - } finally { - lock.unLock(); - } +// 广播消息 +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) \ No newline at end of file diff --git a/docs/oth/_category_.json b/docs/oth/_category_.json index 75118bc..536944e 100644 --- a/docs/oth/_category_.json +++ b/docs/oth/_category_.json @@ -3,6 +3,6 @@ "position": 5, "link": { "type": "generated-index", - "description": "这里存放了各种常用的工具。" + "description": "ZHub 相关工具和概念,包含类型令牌、微服务架构等" } } diff --git a/docs/oth/a.md b/docs/oth/a.md deleted file mode 100644 index 201ba4a..0000000 --- a/docs/oth/a.md +++ /dev/null @@ -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 # 启动(服务模式) - -``` diff --git a/docs/oth/type-token.md b/docs/oth/type-token.md index 5650ca6..54670ab 100644 --- a/docs/oth/type-token.md +++ b/docs/oth/type-token.md @@ -1,10 +1,14 @@ --- sidebar_position: 1 +title: IType 类型定义 +description: ZHub 客户端 IType 接口类型定义 --- -# IType +# IType 类型定义 -> IType 中实现的 TypeToken +IType 接口提供了 ZHub 客户端中常用的类型定义,用于 RPC 调用和消息订阅时的类型安全。 + +## 接口定义 ```java package dev.zhub; @@ -24,6 +28,49 @@ public interface IType { } ``` +## 使用示例 + +### RPC 调用 +```java +// 字符串类型 RPC +RpcResult result = zhub.rpc("user.getInfo", "user123", IType.STRING); + +// 整数类型 RPC +RpcResult count = zhub.rpc("user.getCount", "group1", IType.INT); + +// Map 类型 RPC +RpcResult> 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(){}` 构建 +- 字符串消息默认类型`new TypeToken(){}`,无需显式声明 diff --git a/docs/oth/微服务.md b/docs/oth/微服务.md index e937273..b6c1bfa 100644 --- a/docs/oth/微服务.md +++ b/docs/oth/微服务.md @@ -1,14 +1,41 @@ --- -sidebar_position: 1 +sidebar_position: 2 +title: ZHub 与微服务 +description: ZHub 在微服务架构中的应用场景 --- + # ZHub 与微服务 -- 服务注册与发现: -> 在分布式系统中,服务注册与发现是确保系统能够找到并调用正确服务的关键机制。ZHub 作为一个服务注册中心或服务发现机制的一部分,它负责维护服务列表(service-topic),使得其他服务能够通过它找到并调用所需的服务。 -- 负载均衡: -> 在分布式系统中,负载均衡是确保请求均匀分布到各个服务实例上的关键机制。ZHub 是一个负载均衡器,它可负责将请求分发到不同的服务实例上,以提高系统的可用性和性能。 -- 消息队列: -> 在微服务架构中,消息队列可以用于异步处理请求和解耦服务之间的通信。ZHub 是一个消息队列服务,它可负责接收、存储和分发消息,使得服务可以在需要时处理这些消息。 +## 核心功能 +- **消息通信**:支持发布订阅、RPC调用等通信模式 +- **异步处理**:解耦服务间通信,提高系统响应性 +## 架构优势 +- **服务解耦**:消息通信降低依赖,支持独立部署 +- **异步处理**:提高响应性能,支持事件驱动 +- **可靠性**:重试机制、监控管理 + +## 应用场景 + +```java +// 用户服务 +zhub.publish("user.registered", userInfo); +zhub.subscribe("user.registered", new TypeToken(){}, event -> processUserEvent(event)); + +// 订单服务 +zhub.publish("order.created", orderInfo); +zhub.subscribe("order.created", new TypeToken(){}, event -> processOrderEvent(event)); + +// 支付服务 +zhub.publish("payment.completed", paymentInfo); +zhub.subscribe("payment.completed", new TypeToken(){}, event -> processPaymentEvent(event)); +``` + +## 最佳实践 + +- **服务划分**:按业务领域划分,保持单一职责 +- **消息设计**:清晰命名规范,可扩展格式 +- **错误处理**:重试机制、死信队列、状态监控 +- **监控管理**:连接状态、处理量、延迟监控 diff --git a/docs/tutorial-basics/_category_.json b/docs/tutorial-basics/_category_.json index 02b463e..e0a1b25 100644 --- a/docs/tutorial-basics/_category_.json +++ b/docs/tutorial-basics/_category_.json @@ -3,6 +3,6 @@ "position": 2, "link": { "type": "generated-index", - "description": "完成 ZHub 服务安装后,来看看一遍就会的基础使用文档~" + "description": "ZHub 基础功能使用指南,包含连接创建、发布订阅、RPC调用等核心功能" } } diff --git a/docs/tutorial-basics/broadcast-delay.md b/docs/tutorial-basics/broadcast-delay.md new file mode 100644 index 0000000..20bff2f --- /dev/null +++ b/docs/tutorial-basics/broadcast-delay.md @@ -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(){}, 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)); +``` + +## 注意事项 + +- 延时时间不限制延迟时间 +- 重启后延时消息丢失 +- 广播消息影响所有客户端性能 diff --git a/docs/tutorial-basics/broadcast.md b/docs/tutorial-basics/broadcast.md deleted file mode 100644 index 5989f22..0000000 --- a/docs/tutorial-basics/broadcast.md +++ /dev/null @@ -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!"; - } -``` diff --git a/docs/tutorial-basics/create-connection.md b/docs/tutorial-basics/create-connection.md index 7d10403..b139c86 100644 --- a/docs/tutorial-basics/create-connection.md +++ b/docs/tutorial-basics/create-connection.md @@ -1,60 +1,177 @@ --- -sidebar_position: 0 +sidebar_position: 1 title: 创建连接 description: 初始化客户端连接对象 --- -:::tip -目前已提供三种客户端连接使用 +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; -- Java 项目 - - [普通 Java 项目](#java通用) - - [使用 Redkale 的 Java 项目](#redkale框架-项目里面使用) -- [Golang 项目](#golang-项目中使用) +## 支持的框架 -::: +普通Java、SpringBoot、Redkale、Golang ---- - -## Java通用 - -> 在Java 项目中引入 zhub-client.jar + + ```java - private ZHubClient zhub; +private ZHubClient zhub; - @Before - public void init() { - // 参数说明:① ip:端⼝, ②消费者组名称, ③项⽬实例名(名称需全局唯⼀)④授权码 - zhub = new ZHubClient("127.0.0.1:6066", "test-hub", "DEV-LOCAL", "user@pwd123"); +@Before +public void init() { + // 参数:地址、组名、appid(唯一)、token + zhub = new ZHubClient("127.0.0.1:1216", "test-hub", "DEV-LOCAL-001", "token-12345"); +} +``` + +**说明**: +- `appid` 必须唯一,RPC 消息回复使用此标识 +- `groupid` 协同消费组,同组内只有一个消费者处理消息 + + + + +**1. 依赖** +```xml + + dev.zhub + zhub-client-spring + 0.1.0424.dev + +``` + +**2. 配置 application.yml** +```yaml +zhub: + addr: 127.0.0.1:1216 + groupid: spring-boot-app + appid: spring-boot-001 # 必须唯一 + auth: token-12345 +``` + +**3. 配置类** +```java +@Configuration +public class ZHubConfig { + @Value("${zhub.addr}") private String addr; + @Value("${zhub.groupid}") private String groupId; + @Value("${zhub.appid}") private String appId; + @Value("${zhub.auth}") private String auth; + + @Bean + public ZHubClient zhubClient() { + return new ZHubClient(addr, groupId, appId, auth); } +} ``` ---- - -## Redkale框架 项目里面使用 - -> 在Java的redkale 项目中引入 zhub-rekale.jar -> 在配置文件中配置zhub组件 - +**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); + }); + } +} ``` -# source.properties 中配置 -############ ClusterSource @Resource(name="hub") ############ -redkale.cluster.zhub[hub].addr = 127.0.0.1:6066 + + + + +**配置文件**: +```properties +# source.properties +redkale.cluster.zhub[hub].addr = 127.0.0.1:1216 redkale.cluster.zhub[hub].auth = user@pwd123 redkale.cluster.zhub[hub].groupid = test-hub ``` -> 在 service 中注入组件 -> - +**使用**: ```java - @Resource(name = "hub") - protected ZHubClient zhub; +@Resource(name = "hub") +protected ZHubClient zhub; ``` -## Golang 项目中使用 + + -> 待补充 +```go +// Golang 连接示例 +// TODO: 待补充 +``` ---- + + + + + +## 使用示例 + + + + +```java +// 单个主题 +zhub.subscribe("user-login", message -> System.out.println("登录: " + message)); + +// 类型化消息(使用TypeToken) +zhub.subscribe("user-profile", new TypeToken(){}, profile -> + System.out.println("用户: " + profile.getUsername())); +``` + + + + +```java +// 逗号分隔 +zhub.subscribe("user-login,user-logout,user-register", message -> + System.out.println("用户操作: " + message)); +``` + + + + +```java +// 字符串消息 +zhub.publish("user-login", "用户ID: 12345"); + +// 类型化消息 +UserProfile profile = new UserProfile("12345", "张三", "zhangsan@example.com"); +zhub.publish("user-profile", profile); +``` + + + + +## 性能优化 + +### 异步处理 +```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); + } +}); +``` diff --git a/docs/tutorial-basics/delay.md b/docs/tutorial-basics/delay.md deleted file mode 100644 index cc5258b..0000000 --- a/docs/tutorial-basics/delay.md +++ /dev/null @@ -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!"; - } -``` diff --git a/docs/tutorial-basics/golang-connection.md b/docs/tutorial-basics/golang-connection.md new file mode 100644 index 0000000..a8b5caf --- /dev/null +++ b/docs/tutorial-basics/golang-connection.md @@ -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 请参考客户端源码文档 +::: diff --git a/docs/tutorial-basics/pub-sub.md b/docs/tutorial-basics/pub-sub.md new file mode 100644 index 0000000..8e5a607 --- /dev/null +++ b/docs/tutorial-basics/pub-sub.md @@ -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(){}, 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 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(){}, 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 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条,满时消息会被丢弃 diff --git a/docs/tutorial-basics/publish-subscribe.md b/docs/tutorial-basics/publish-subscribe.md deleted file mode 100644 index 58dd11c..0000000 --- a/docs/tutorial-basics/publish-subscribe.md +++ /dev/null @@ -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` 的消息内容 diff --git a/docs/tutorial-basics/rpc.md b/docs/tutorial-basics/rpc.md index f22ef5d..298aa69 100644 --- a/docs/tutorial-basics/rpc.md +++ b/docs/tutorial-basics/rpc.md @@ -1,36 +1,167 @@ --- sidebar_position: 4 -title: 远程调用 RPC -description: RPC 远程调用,Remote Procedure Call,RPC +title: RPC 远程调用 +description: ZHub RPC 远程调用功能详解,包含基础类型、类型化调用和多客户端示例 --- -# RPC远程调用 +# RPC 远程调用 -:::tip - -RPC 是一种通过网络将远程过程调用(Remote Procedure Call,RPC)封装成消息,并传送到远程服务器上的过程。 - -::: -![zhub-fun.png](https://img.1216.top/docs/zhub/rpc-flow.png) +![rpc-flow.png](https://img.1216.top/docs/zhub/rpc-flow.png) ## 使用场景 -> 在分布式环境下,通过 RPC 可以在两个应用之间进行消息传递,实现远程调用。 -## rpc的订阅-调用基础示例 -### 被调用端 +- **微服务间通信**:用户服务调用订单服务 +- **数据查询服务**:统一的数据查询接口 +- **业务逻辑封装**:封装复杂业务逻辑供其他模块调用 +- **第三方服务集成**:调用外部 API + +## 基础示例 + +**重要**:RPC 通讯要求每个客户端使用唯一的 appid,消息回复使用此标识。 + +### 基础类型 RPC + +**服务端**: ```java - // 订阅 rpc-b 事件, 参数类型为 String - zhub.rpcSubscribe("rpc-b", IType.STRING, r -> { - String str = r.getValue(); - System.out.println("接收到 b 事件:" + str); - return r.render("接收到 b 事件:" + str); - }); -``` -### 调用端 -```java - // 调用 rpc-b 事件, 参数类型为 String,返回类型为 String - RpcResult rpcResult = zhub.rpc("rpc-b", "hello rpc", IType.STRING); - String result = rpcResult.getResult(); - System.out.println("rpc result:" + result); +// 订阅 RPC 服务 +zhub.rpcSubscribe("rpc-b", IType.STRING, r -> { + String str = r.getValue(); + System.out.println("接收到: " + str); + return r.render("处理结果: " + str); +}); +``` + +**客户端**: +```java +// 调用 RPC 服务 +RpcResult result = zhub.rpc("rpc-b", "hello rpc", IType.STRING); +System.out.println("结果: " + result.getResult()); +``` + +### 类型化 RPC + +**定义类型**: +```java +// 请求类型 +public class UserQueryRequest { + private String userId; + private String queryType; + // getter/setter... +} + +// 响应类型 +public class UserInfoResponse { + private String userId; + private String username; + private String email; + private long lastLoginTime; + // getter/setter... +} +``` + +**服务端**: +```java +zhub.rpcSubscribe("user-get-info", new TypeToken(){}, 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 result = zhub.rpc("user-get-info", request, new TypeToken(){}); + +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(){}, 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 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 result = clientB.rpc("user-get-info", request, new TypeToken(){}); +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(){}, 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 result = zhub.rpc("order-get-details", request, new TypeToken(){}); + +if (result.isSuccess()) { + OrderResponse order = result.getResult(); + System.out.println("订单状态: " + order.getStatus()); + System.out.println("订单金额: " + order.getAmount()); +} ``` diff --git a/docs/tutorial-extras/_category_.json b/docs/tutorial-extras/_category_.json index 9812c39..0cfb4aa 100644 --- a/docs/tutorial-extras/_category_.json +++ b/docs/tutorial-extras/_category_.json @@ -3,6 +3,6 @@ "position": 3, "link": { "type": "generated-index", - "description": "分布式系统常用组件" + "description": "ZHub 高级功能配置,包含权限管理、性能优化、安全实践等" } } diff --git a/docs/tutorial-extras/api-reference.md b/docs/tutorial-extras/api-reference.md new file mode 100644 index 0000000..a80d2a5 --- /dev/null +++ b/docs/tutorial-extras/api-reference.md @@ -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 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 | 认证失败 | diff --git a/docs/tutorial-extras/auth-config.md b/docs/tutorial-extras/auth-config.md new file mode 100644 index 0000000..5a51408 --- /dev/null +++ b/docs/tutorial-extras/auth-config.md @@ -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 diff --git a/docs/tutorial-extras/docker-deployment.md b/docs/tutorial-extras/docker-deployment.md new file mode 100644 index 0000000..fbbed24 --- /dev/null +++ b/docs/tutorial-extras/docker-deployment.md @@ -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 +``` \ No newline at end of file diff --git a/docs/tutorial-extras/faq.md b/docs/tutorial-extras/faq.md new file mode 100644 index 0000000..f6ca0eb --- /dev/null +++ b/docs/tutorial-extras/faq.md @@ -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 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 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 result = zhub.rpc("rpc-topic", "data", IType.STRING, 30000); + ``` + +2. **使用异步 RPC**: + ```java + CompletableFuture> 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 \ No newline at end of file diff --git a/docs/tutorial-extras/lock.md b/docs/tutorial-extras/lock.md index 918b0e3..6f07348 100644 --- a/docs/tutorial-extras/lock.md +++ b/docs/tutorial-extras/lock.md @@ -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 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. 性能指标 + +- 锁获取成功率 +- 锁平均持有时间 +- 锁等待时间 +- 锁竞争频率 diff --git a/docs/tutorial-extras/security-best-practices.md b/docs/tutorial-extras/security-best-practices.md new file mode 100644 index 0000000..b92d433 --- /dev/null +++ b/docs/tutorial-extras/security-best-practices.md @@ -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`) +- [ ] 配置最小权限原则 +- [ ] 实施网络隔离 +- [ ] 启用访问日志 +- [ ] 定期安全审计 + +### 定期维护 + +- 定期检查权限配置 +- 定期更新认证令牌 +- 监控服务状态和连接情况 \ No newline at end of file diff --git a/docs/tutorial-extras/timer.md b/docs/tutorial-extras/timer.md index 9361ada..ad12062 100644 --- a/docs/tutorial-extras/timer.md +++ b/docs/tutorial-extras/timer.md @@ -1,5 +1,444 @@ --- sidebar_position: 2 +title: 定时调度 +description: ZHub 定时调度功能详解 --- -# 定时调度 \ No newline at end of file +# 定时调度 + +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); + } + } + } +} +``` \ No newline at end of file diff --git a/docs/tutorial-extras/troubleshooting.md b/docs/tutorial-extras/troubleshooting.md new file mode 100644 index 0000000..92f77cd --- /dev/null +++ b/docs/tutorial-extras/troubleshooting.md @@ -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 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 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)。 diff --git a/docs/tutorial-extras/zhub-log.md b/docs/tutorial-extras/zhub-log.md new file mode 100644 index 0000000..a144b92 --- /dev/null +++ b/docs/tutorial-extras/zhub-log.md @@ -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级别 diff --git a/docusaurus.config.js b/docusaurus.config.js index 3c3999e..9b2c59a 100644 --- a/docusaurus.config.js +++ b/docusaurus.config.js @@ -6,8 +6,8 @@ const darkCodeTheme = require('prism-react-renderer/themes/dracula') /** @type {import('@docusaurus/types').Config} */ const config = { - title: 'ZHub', - tagline: '轻量级消息中间件', + title: 'ZHub - 轻量级消息中间件', + tagline: '高性能、轻量级的消息中间件,支持发布订阅、RPC调用、延时消息等功能', favicon: 'img/favicon.ico', // Set the production url of your site here @@ -22,8 +22,8 @@ const config = { // GitHub pages deployment config. // If you aren't using GitHub pages, you don't need these. - organizationName: 'facebook', // Usually your GitHub org/user name. - projectName: 'docusaurus', // Usually your repo name. + organizationName: 'zhub', // Usually your GitHub org/user name. + projectName: 'zhub-docs', // Usually your repo name. onBrokenLinks: 'throw', onBrokenMarkdownLinks: 'warn', @@ -32,8 +32,8 @@ const config = { // metadata like html lang. For example, if your site is Chinese, you may want // to replace "en" with "zh-Hans". i18n: { - defaultLocale: 'en', - locales: ['en'], + defaultLocale: 'zh-Hans', + locales: ['zh-Hans'], }, presets: [ @@ -70,7 +70,7 @@ const config = { navbar: { title: 'ZHub', logo: { - alt: 'My Site Logo', + alt: 'ZHub Logo', src: 'img/logo.svg', }, items: [ @@ -113,6 +113,18 @@ const config = { darkTheme: darkCodeTheme, 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'}, + ], }), } diff --git a/static/robots.txt b/static/robots.txt new file mode 100644 index 0000000..64a67ff --- /dev/null +++ b/static/robots.txt @@ -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/