diff --git a/.codecov.yml b/.codecov.yml index 273a5e5f..8cb2470c 100644 --- a/.codecov.yml +++ b/.codecov.yml @@ -20,10 +20,11 @@ coverage: project: default: target: auto - threshold: 10% + threshold: 0% + informational: true patch: - target: auto - threshold: 10% + default: + informational: true ignore: - "hippo4j-example/.*" - "docs/.*" diff --git a/.github/workflows/reademe-contributors.yml b/.github/workflows/reademe-contributors.yml index 34583d53..34476f4b 100644 --- a/.github/workflows/reademe-contributors.yml +++ b/.github/workflows/reademe-contributors.yml @@ -21,7 +21,7 @@ on: push: branches: - - main + - develop jobs: contrib-readme-job: diff --git a/README.md b/README.md index 01ba603e..fb55d867 100644 --- a/README.md +++ b/README.md @@ -72,10 +72,10 @@ Hippo-4J 通过对 JDK 线程池增强,以及扩展三方框架底层线程池 + + + + - + - + + - + + + - + + + - + + + + + - + + + + - + + + - + + -
- - itmachen + + mageeric
- 小马哥 + 马称
@@ -107,10 +107,10 @@ Hippo-4J 通过对 JDK 线程池增强,以及扩展三方框架底层线程池 - - hippo4jbot + + pizihao
- Hippo4jbot[bot] + Pizihao
@@ -121,20 +121,27 @@ Hippo-4J 通过对 JDK 线程池增强,以及扩展三方框架底层线程池 - - BigXin0109 + + hippo4jbot
- BigXin0109 + Hippo4jbot[bot]
- - pizihao + + BigXin0109
- Pizihao + BigXin0109
+ + wulangcode +
+ WuLang +
+
Gdk666 @@ -143,17 +150,17 @@ Hippo-4J 通过对 JDK 线程池增强,以及扩展三方框架底层线程池 - - xqxyxchy + + Createsequence
- Null + 黄成兴
- - road2master + + xqxyxchy
- Lijx + Null
@@ -163,6 +170,13 @@ Hippo-4J 通过对 JDK 线程池增强,以及扩展三方框架底层线程池 Null + + road2master +
+ Lijx +
+
baymax55 @@ -183,7 +197,8 @@ Hippo-4J 通过对 JDK 线程池增强,以及扩展三方框架底层线程池
Null
-
Atmanuclear @@ -197,8 +212,7 @@ Hippo-4J 通过对 JDK 线程池增强,以及扩展三方框架底层线程池
Hippo4j
-
imyzt @@ -227,13 +241,6 @@ Hippo-4J 通过对 JDK 线程池增强,以及扩展三方框架底层线程池 Null - - wulangcode -
- WuLang -
-
gywanghai @@ -254,15 +261,15 @@ Hippo-4J 通过对 JDK 线程池增强,以及扩展三方框架底层线程池
Redick Liu
-
xiaochengxuyuan
Sean Wu
-
HKMV @@ -318,15 +325,15 @@ Hippo-4J 通过对 JDK 线程池增强,以及扩展三方框架底层线程池
Tomsun28
-
backbay2-yzg
游祖光
-
puppet4 @@ -382,15 +389,15 @@ Hippo-4J 通过对 JDK 线程池增强,以及扩展三方框架底层线程池
Dmego
-
dousp
Douspeng
-
hl1248 @@ -405,6 +412,20 @@ Hippo-4J 通过对 JDK 线程池增强,以及扩展三方框架底层线程池 Lynn + + Malcolmli +
+ Malcolm +
+
+ + PleasePerfunctory +
+ Null +
+
alexhaoxuan @@ -432,7 +453,8 @@ Hippo-4J 通过对 JDK 线程池增强,以及扩展三方框架底层线程池
Zhenye
-
dongming0920 @@ -453,8 +475,7 @@ Hippo-4J 通过对 JDK 线程池增强,以及扩展三方框架底层线程池
Guide
-
hbw1994 @@ -483,13 +504,21 @@ Hippo-4J 通过对 JDK 线程池增强,以及扩展三方框架底层线程池 Null + + w-jirong +
+ 季容 +
+
klsq94
Hui Cao
-
kongyanbo-cx @@ -517,8 +546,7 @@ Hippo-4J 通过对 JDK 线程池增强,以及扩展三方框架底层线程池
Op-lht
-
wangjie-github @@ -553,7 +581,8 @@ Hippo-4J 通过对 JDK 线程池增强,以及扩展三方框架底层线程池
Null
-
yangzhiw @@ -581,8 +610,7 @@ Hippo-4J 通过对 JDK 线程池增强,以及扩展三方框架底层线程池
Zhaojinchao
-
zj1997 @@ -590,6 +618,13 @@ Hippo-4J 通过对 JDK 线程池增强,以及扩展三方框架底层线程池 Null + + zoujin001 +
+ Null +
+
li-xiao-shuang @@ -610,13 +645,6 @@ Hippo-4J 通过对 JDK 线程池增强,以及扩展三方框架底层线程池
Xinhao
-
- - Createsequence -
- 黄成兴 -
diff --git a/dev-support/hippo4j_checkstyle_suppression.xml b/dev-support/hippo4j_checkstyle_suppression.xml index ab55dae0..e760e379 100644 --- a/dev-support/hippo4j_checkstyle_suppression.xml +++ b/dev-support/hippo4j_checkstyle_suppression.xml @@ -25,4 +25,7 @@ + + + diff --git a/docs/docs/community/_category_.json b/docs/community/_category_.json similarity index 100% rename from docs/docs/community/_category_.json rename to docs/community/_category_.json diff --git a/docs/community/contributor.md b/docs/community/contributor.md new file mode 100644 index 00000000..f40d60b1 --- /dev/null +++ b/docs/community/contributor.md @@ -0,0 +1,16 @@ +--- +id: contributor-guide +sidebar_position: 1 +title: 贡献指南 +--- + +Git Commit Log 尽量使用英文。 + +Pull Request 尽量保持单一,不同语义的代码贡献应拆分多个 Pull Request。 + +为了让您的 GitHub ID 显示在 Contributor 列表中,别忘了以下设置: + +```shell +git config --global user.name "username" +git config --global user.email "GitHub 账号邮箱" +``` diff --git a/docs/docs/community/dev_convention/_category_.json b/docs/community/dev_convention/_category_.json similarity index 100% rename from docs/docs/community/dev_convention/_category_.json rename to docs/community/dev_convention/_category_.json diff --git a/docs/i18n/zh/docusaurus-plugin-content-docs/current/community/dev_convention/code.md b/docs/community/dev_convention/code.md similarity index 88% rename from docs/i18n/zh/docusaurus-plugin-content-docs/current/community/dev_convention/code.md rename to docs/community/dev_convention/code.md index f91acdbe..ce3d6018 100644 --- a/docs/i18n/zh/docusaurus-plugin-content-docs/current/community/dev_convention/code.md +++ b/docs/community/dev_convention/code.md @@ -1,8 +1,7 @@ --- sidebar_position: 2 +title: 代码规约 --- -# 代码规约 - 1. 代码提交前,执行 `mvn spotless:apply` 保证代码格式符合规范。 2. 代码中不要出现无意义的空行。 diff --git a/docs/versioned_docs/version-1.4.2/community/dev_convention/document.md b/docs/community/dev_convention/document.md similarity index 99% rename from docs/versioned_docs/version-1.4.2/community/dev_convention/document.md rename to docs/community/dev_convention/document.md index 923ad81d..7f0d65a2 100644 --- a/docs/versioned_docs/version-1.4.2/community/dev_convention/document.md +++ b/docs/community/dev_convention/document.md @@ -1,9 +1,8 @@ --- sidebar_position: 1 +title: 文档规约 --- -# 文档规约 - 文档引用自:[中文文案排版指北](https://github.com/sparanoid/chinese-copywriting-guidelines) ## 空格 diff --git a/docs/i18n/zh/docusaurus-plugin-content-docs/current/community/sponsor.md b/docs/community/sponsor.md similarity index 85% rename from docs/i18n/zh/docusaurus-plugin-content-docs/current/community/sponsor.md rename to docs/community/sponsor.md index c73fc64a..f216fc3b 100644 --- a/docs/i18n/zh/docusaurus-plugin-content-docs/current/community/sponsor.md +++ b/docs/community/sponsor.md @@ -1,16 +1,15 @@ --- sidebar_position: 4 +title: 支持开源 --- -# 支持开源 - 如果您正在使用这个项目并感觉良好,或者是想支持我继续开发,通过以下二维码一次性捐款。 -在这里承诺将,将收到的所有赞助支持资金完全公开化,且后续资金用途仅 Hippo-4J 项目的运转。 +在这里承诺将,将收到的所有赞助支持资金完全公开化,且后续资金用途仅 Hippo4j 项目的运转。 ![](https://images-machen.oss-cn-beijing.aliyuncs.com/IMG_6719_2.jpg?x-oss-process=image/resize,h_180,w_180) -感谢给予支持的朋友,您的支持是 Hippo-4J 社区前进的动力 🎉 +感谢给予支持的朋友,您的支持是 Hippo4j 社区前进的动力 🎉 | | ID | 赞赏金额 | 时间 | 备注 | |-----|--|-------|------------|--------------------| diff --git a/docs/i18n/zh/docusaurus-plugin-content-docs/version-1.4.2/community/update-log.md b/docs/community/update-log.md similarity index 85% rename from docs/i18n/zh/docusaurus-plugin-content-docs/version-1.4.2/community/update-log.md rename to docs/community/update-log.md index aa4adc20..3985ed9c 100644 --- a/docs/i18n/zh/docusaurus-plugin-content-docs/version-1.4.2/community/update-log.md +++ b/docs/community/update-log.md @@ -1,8 +1,53 @@ --- +title: 更新日志 sidebar_position: 5 --- -# 更新日志 +## 1.4.3 (Nov 06, 2022) + +这是一个功能增强版本,修复了少量 BUG。建议按照当前版本升级。具体信息可查看 Release 标签地址:[1.4.3](https://github.com/opengoofy/hippo4j/milestone/13?closed=1) + +**Use Change** + +- 重构线程池监控,配置层级和命名改变 +- 如果使用钉钉报警,关键字【警报】修改为【告警】 + +**Feature** + +- 重构 Spring 后置处理器创建动态线程池逻辑 +- 官网开启多版本化功能 +- 官网支持国际化,en-US +- 适配线程池延迟初始化 @wulangcode +- 添加 Codecov 相关代码覆盖率指标 +- 项目优雅关闭时停止运行状态采集 + +**Refactor** + +- DynamicThreadPoolExecutor 重构,增加插件扩展逻辑 @Createsequence +- 重构线程池监控,新增容器和三方框架线程池监控 +- 重构服务端包目录,聚合 hippo4j-server 相关 module + +**Bug** + +- dubbo 线程池无法获取运行信息 @iwangjie +- 线程池检查活跃度报警取值错误 @maxisvest +- 动态线程池修改多次后队列提示信息丢失 +- docker部署 mysql启动报错H2驱动 +- docker-startup.sh的mysql配置多个“-” @Malcolmli +- 动态注册线程池队列容量赋值错误 +- 飞书超时类型告警不存在 Trace 信息时发送错误 @mageeric + +**Optimize** + +- 修改报警文案,【警报】修改为【告警】 @wulangcode +- 自动选择H2数据库的存储路径 @iwangjie +- 服务端在客户端后面启动,依旧支持长轮训 @wulangcode +- 配置未发生变更时,长轮询返回 304 @wulangcode +- discovery服务Lease类中判断过期时间需要多等一个duration @w-jirong +- 优化 ThreadPoolBuilder#maxPoolNum 核心线程不得大于最大线程 @wulangcode +- hippo4j console ui 迁移至本项目 +- 查询 Web 线程池列表添加框架标识 +- 优化 H2 初始化逻辑 ## 1.4.2 (Oct 18, 2022) diff --git a/docs/docs/community/developer.md b/docs/docs/community/developer.md deleted file mode 100644 index 89b57b88..00000000 --- a/docs/docs/community/developer.md +++ /dev/null @@ -1,89 +0,0 @@ ---- -sidebar_position: 2 ---- - -# 核心开发者 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
姓名GitHub ID博客地址联系方式
马称magegoofy小马哥的技术专栏machen@apache.org
陆宽shining-stars-lk宽仔的代码之路1031900093@qq.com
王杰iwangjie-wangchenmo1025@gmail.com
魏虎weihubeatsweihubeatsweihubeats@163.com
李剑鑫BigXin0109Only丶Big1064730540@qq.com
刘文浩pizihaopizihaohao3073liu@163.com
叶炜shanjianq-17855368071@163.com
黄成兴CreatesequenceCreatesequence's Blog841396397@qq.com
- -## 成为核心开发者 - -持续对 Hippo-4J 进行贡献, 粗略评估,完成 10 次 PR 贡献即可成为核心开发者。 其中包括完成 2 个 [good pro issue](https://github.com/opengoofy/hippo4j/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+pro+issue%22) 或以上,以及若干个 [good first issue](https://github.com/opengoofy/hippo4j/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22)。 - -:::note -会根据 PR 质量提供个性化评估,有可能一个或两个质量较高 PR 即可成为核心开发者。参考:[重构 DynamicThreadPoolExecutor 功能扩展逻辑](https://github.com/opengoofy/hippo4j/pull/854) -::: - -成为核心开发者后,会为该 GitHub 账号获取 Jetbrains 全家桶 Licenses,有效期为 1 年。不用再为破解而烦恼,感受随时升级的快乐。 - -:::note -距离到期两周前,会再次申请 Jetbrains Licenses。有点类似于无限续约的感觉,在此感谢 Jetbrains 公司对开源的支持。 -::: - -截至 `2022-10-30` 当天,已为登记的 7 位核心开发者成功申请 Licenses。 - -![](https://images-machen.oss-cn-beijing.aliyuncs.com/image-20221030134303060.png) diff --git a/docs/docs/community/powered-by.md b/docs/docs/community/powered-by.md deleted file mode 100644 index 635d9011..00000000 --- a/docs/docs/community/powered-by.md +++ /dev/null @@ -1,37 +0,0 @@ ---- -sidebar_position: 3 ---- - -# 采用公司 - -## 登记 - -欢迎采用了 Hippo4J 的公司在此登记,非常感谢大家对 Hippo4J 的关注和支持,这是我们前进最大的动力。 - -请按公司名 + 首页的格式在 [此处](https://github.com/opengoofy/hippo4j/issues/13) 登记。 - -## 谁在使用 Hippo4J - -共计 21+ 家公司生产接入 Hippo4J。按照公司登记时间排序。 - -- [身边云](https://serviceshare.com) -- [Medbanks](https://www.medbanks.cn) -- [北京智合联创科技有限公司](http://www.zhlc.com.cn) -- [神州数码](http://www.digitalchina.com) -- [payermax](https://www.payermax.com/) -- [轻松到家](http://www.uyess.com/index.html) -- [某商业银行股份有限公司](https://github.com/opengoofy/hippo4j/issues/13) -- [某国际物流信息股份有限公司](https://github.com/opengoofy/hippo4j/issues/13) -- [萨科(深圳)科技有限公司](https://www.lbdj.com/) -- [广东天枢新能源科技有限公司](https://gd-tianshu.com/) -- [FitTime](http://fittime.com/) -- [百强国际物流](https://github.com/opengoofy/hippo4j/issues/13) -- [海南某深圳分公司](https://github.com/opengoofy/hippo4j/issues/13) -- [众合云科(51社保)](https://home.101hr.com/) -- [好货云店](https://pc.haohuoyundian.com/) -- [斗象科技](https://www.tophant.com/) -- [深圳航天信息有限公司](http://sz.aisino.com/) -- [新东方教育科技集团](https://www.xdf.cn/) -- [远眺网络科技有限公司](https://www.yuantiaokj.com/) -- [浙江吉利控股集团有限公司](https://www.geely.com/) -- [三立人(深圳)科技有限公司-焦内](https://www.bananain.com/) diff --git a/docs/docs/community/sponsor.md b/docs/docs/community/sponsor.md deleted file mode 100644 index c73fc64a..00000000 --- a/docs/docs/community/sponsor.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -sidebar_position: 4 ---- - -# 支持开源 - -如果您正在使用这个项目并感觉良好,或者是想支持我继续开发,通过以下二维码一次性捐款。 - -在这里承诺将,将收到的所有赞助支持资金完全公开化,且后续资金用途仅 Hippo-4J 项目的运转。 - -![](https://images-machen.oss-cn-beijing.aliyuncs.com/IMG_6719_2.jpg?x-oss-process=image/resize,h_180,w_180) - -感谢给予支持的朋友,您的支持是 Hippo-4J 社区前进的动力 🎉 - -| | ID | 赞赏金额 | 时间 | 备注 | -|-----|--|-------|------------|--------------------| -| 1 | 六月飞雪 | 30.00 | 2021-12-30 | 代码设计很优雅的一款框架,继续加油! | -| 2 | 孙大圣 | 26.6 | 2022-03-23 | 学习一下😁😁 | -| 3 | Easy 点 | 66.00 | 2022-04-09 | 好货好技术当加赏 | -| 4 | 捷克 | 30.00 | 2022-05-21 | 非常不错的框架,点赞 | -| 5 | 吃猫的饼干 | 88.00 | 2022-08-21 | 👍 | -| 6 | 不忘初心· | 66.00 | 2022-10-28 | Nice! | -| 7 | 时刻· | 6.00 | 2022-10-30 | -! | diff --git a/docs/docs/user_docs/getting_started/config/hippo4j-config-monitor.md b/docs/docs/user_docs/getting_started/config/hippo4j-config-monitor.md index 72528638..c030dc10 100644 --- a/docs/docs/user_docs/getting_started/config/hippo4j-config-monitor.md +++ b/docs/docs/user_docs/getting_started/config/hippo4j-config-monitor.md @@ -39,7 +39,12 @@ management: spring: dynamic: thread-pool: - collect-type: micrometer + monitor: + enable: true # 是否开启采集线程池运行时数据 + collect-interval: 5000 # 采集线程池运行数据频率 + collect-types: micrometer # 采集线程池运行数据的类型。eg:log、micrometer。多个可以同时使用,默认 micrometer + initial-delay: 10000 # 项目启动后延迟多久进行采集 + thread-pool-types: dynamic # 采集线程池的类型。eg:dynamic、web、adapter。可任意配置,默认 dynamic ``` 项目启动,访问 `http://localhost:29999/actuator/prometheus` 出现 `dynamic_thread_pool_` 前缀的指标,即为成功。 diff --git a/docs/docs/user_docs/getting_started/server/hippo4j-server-config.md b/docs/docs/user_docs/getting_started/server/hippo4j-server-config.md index 24bf9a13..e1ef853f 100644 --- a/docs/docs/user_docs/getting_started/server/hippo4j-server-config.md +++ b/docs/docs/user_docs/getting_started/server/hippo4j-server-config.md @@ -1,5 +1,5 @@ --- -sidebar_position: 4 +sidebar_position: 3 --- # 服务端配置 diff --git a/docs/docs/user_docs/getting_started/server/hippo4j-server-monitor.md b/docs/docs/user_docs/getting_started/server/hippo4j-server-monitor.md new file mode 100644 index 00000000..b743c790 --- /dev/null +++ b/docs/docs/user_docs/getting_started/server/hippo4j-server-monitor.md @@ -0,0 +1,122 @@ +--- +sidebar_position: 2 +--- + +# 线程池监控 + +Server 模式默认内置线程池运行时采集和监控功能,如果想要使用 Prometheus + Grafana 的方式可以查看以下内容。 + +## 线程池监控配置 + +接下来引入 SpringBoot Actuator。Spring 2.x 一般都有版本指定,所以这里不用写版本号。 + +```xml + + io.micrometer + micrometer-registry-prometheus + + + + org.springframework.boot + spring-boot-starter-actuator + +``` + +添加动态线程池监控相关配置: + +```yaml +management: + metrics: + export: + prometheus: + enabled: true + server: + port: 29999 # 可选配置,如果不配置该 port,直接使用 ${server.port} + endpoints: + web: + exposure: + include: '*' # 测试使用,开启了所有端点,生产环境不建议 * +spring: + dynamic: + thread-pool: + monitor: + enable: true # 是否开启采集线程池运行时数据 + collect-interval: 5000 # 采集线程池运行数据频率 + collect-types: server,micrometer # 采集线程池运行数据的类型。eg:server、micrometer。多个可以同时使用,默认 server + initial-delay: 10000 # 项目启动后延迟多久进行采集 + thread-pool-types: dynamic # 采集线程池的类型。eg:dynamic、web、adapter。可任意配置,默认 dynamic +``` + +项目启动,访问 `http://localhost:29999/actuator/prometheus` 出现 `dynamic_thread_pool_` 前缀的指标,即为成功。 + +![](https://images-machen.oss-cn-beijing.aliyuncs.com/image-20220912220401016.png) + +## 配置 Prometheus + +通过 Docker 启动 Prometheus 服务。 + +```shell +docker run -d -p 9090:9090 --name prometheus prom/prometheus +``` + +添加 Prometheus 抽取数据任务。 + +```shell +# 进入 prometheus 容器内部 +docker exec -it prometheus /bin/sh +# 编辑 prometheus 配置文件 +vi /etc/prometheus/prometheus.yml +``` + +scrape_configs 节点下新添加一个 job,如果 Prometheus 是 Docker 方式部署,`{scrape_configs.static_configs.targets}` 需要写本机的 IP。 + +```yaml +scrape_configs: + - job_name: 'dynamic-thread-pool-job' + scrape_interval: 5s + metrics_path: '/actuator/prometheus' + static_configs: + - targets: [ '127.0.0.1:29999' ] +``` + +配置成功后 `exit` 退出容器,并进行 Prometheus 容器重启 `docker restart prometheus`。 + +访问 Prometheus 控制台 `http://localhost:9090/graph` 路径,能够展示相关指标即为配置成功。 + +![](https://images-machen.oss-cn-beijing.aliyuncs.com/image-20220912221237597.png) + +## 配置 Grafana + +```shell +docker run -d -p 3000:3000 --name=grafana grafana/grafana +``` + +访问 Grafana 地址,[http://localhost:3000](http://localhost:3000) 用户名密码:`admin` + +Grafana 访问 `http://localhost:3000/datasources` 导入 Prometheus 数据源。 + +![](https://images-machen.oss-cn-beijing.aliyuncs.com/image-20220912221646866.png) + +> 如果 Prometheus 为 Docker 方式部署,HTTP URL 需要为本地 IP,比如:http://192.168.1.5:9090 + +关注公众号 `龙台的技术笔记`,回复:`监控`,获取 Hippo4J Grafana DashBoard JSON 配置。 + +| 公众号 | 回复关键词 | +|:------------------------------------------------------------------------------------------------------------:|:-------------------------------------------------------------------------------------------------------------------------:| +| ![](https://images-machen.oss-cn-beijing.aliyuncs.com/43_65f6020ed111b6bb3808ec338576bd6b.png?x-oss-process=image/resize,h_300,w_400) | ![](https://images-machen.oss-cn-beijing.aliyuncs.com/image-20220327171957444.png?x-oss-process=image/resize,h_300,w_400) | + +获取到 JSON 文件后,通过 `http://localhost:3000/dashboard/import` 将 JSON 文件导入至 Grafana DashBoard。 + +![](https://images-machen.oss-cn-beijing.aliyuncs.com/image-20220912225627272.png) + +下拉框内动态选择创建好的 Prometheus 数据源,并点击 `Import`。 + +![](https://images-machen.oss-cn-beijing.aliyuncs.com/image-20220912225700200.png) + +即可使用炫酷的 Hippo-4J 动态线程池监控 DashBoard。大家伙儿也可以根据个人喜好进行定制 DashBoard,如果觉得有优化点,欢迎和我联系贡献。 + +![](https://images-machen.oss-cn-beijing.aliyuncs.com/image-20220912225813972.png) + +如果项目客户端启动多个示例,动态线程池监控效果图如下: + +![](https://images-machen.oss-cn-beijing.aliyuncs.com/20220814_hippo4j_monitor.jpg) diff --git a/docs/docs/user_docs/getting_started/server/hippo4j-server-start.md b/docs/docs/user_docs/getting_started/server/hippo4j-server-start.md index 64b94ee3..003d464f 100644 --- a/docs/docs/user_docs/getting_started/server/hippo4j-server-start.md +++ b/docs/docs/user_docs/getting_started/server/hippo4j-server-start.md @@ -1,5 +1,5 @@ --- -sidebar_position: 3 +sidebar_position: 1 --- # 接入流程 diff --git a/docs/docusaurus.config.js b/docs/docusaurus.config.js index ee1748d7..6e92cb22 100644 --- a/docs/docusaurus.config.js +++ b/docs/docusaurus.config.js @@ -62,6 +62,18 @@ const config = { }), ], ], + + plugins: [ + [ + "@docusaurus/plugin-content-docs", + { + id: "community", + path: "community", + routeBasePath: "community", + sidebarPath: require.resolve("./sidebarsCommunity.js"), + }, + ], + ], themeConfig: /** @type {import('@docusaurus/preset-classic').ThemeConfig} */ @@ -89,12 +101,13 @@ const config = { label: '文档', }, { - type: 'docSidebar', - docId: 'contributor', - position: 'left', - sidebarId: 'community', - label: '社区', + to: "/community/contributor-guide", + label: "社区", + position: "left", + activeBaseRegex: `/community/`, }, + { to: "/team", label: "团队", position: "left" }, + { to: "/users", label: "用户", position: "left" }, /*{to: '/blog', label: '博客', position: 'left'},*/ { href: 'http://console.hippo4j.cn/index.html', diff --git a/docs/i18n/zh/code.json b/docs/i18n/zh/code.json index fd6dd555..e037b95c 100644 --- a/docs/i18n/zh/code.json +++ b/docs/i18n/zh/code.json @@ -253,5 +253,8 @@ "theme.tags.tagsPageTitle": { "message": "标签", "description": "The title of the tag list page" + }, + "Community": { + "message": "社区" } } diff --git a/docs/i18n/zh/docusaurus-plugin-content-docs-community/current.json b/docs/i18n/zh/docusaurus-plugin-content-docs-community/current.json new file mode 100644 index 00000000..52732047 --- /dev/null +++ b/docs/i18n/zh/docusaurus-plugin-content-docs-community/current.json @@ -0,0 +1,94 @@ +{ + "version.label": { + "message": "Next", + "description": "The label for version current" + }, + "sidebar.tutorialSidebar.category.社区": { + "message": "社区", + "description": "The label for category 社区 in sidebar tutorialSidebar" + }, + "sidebar.tutorialSidebar.category.贡献规约": { + "message": "贡献规约", + "description": "The label for category 贡献规约 in sidebar tutorialSidebar" + }, + "sidebar.tutorialSidebar.category.user_docs": { + "message": "user_docs", + "description": "The label for category user_docs in sidebar tutorialSidebar" + }, + "sidebar.tutorialSidebar.category.用户指南": { + "message": "用户指南", + "description": "The label for category 用户指南 in sidebar tutorialSidebar" + }, + "sidebar.tutorialSidebar.category.用户指南.link.generated-index.description": { + "message": "帮助想要了解 Hippo4J 的用户快速掌握核心开发理念。", + "description": "The generated-index page description for category 用户指南 in sidebar tutorialSidebar" + }, + "sidebar.tutorialSidebar.category.快速开始": { + "message": "快速开始", + "description": "The label for category 快速开始 in sidebar tutorialSidebar" + }, + "sidebar.tutorialSidebar.category.依赖配置中心": { + "message": "依赖配置中心", + "description": "The label for category 依赖配置中心 in sidebar tutorialSidebar" + }, + "sidebar.tutorialSidebar.category.无中间件依赖": { + "message": "无中间件依赖", + "description": "The label for category 无中间件依赖 in sidebar tutorialSidebar" + }, + "sidebar.tutorialSidebar.category.运维指南": { + "message": "运维指南", + "description": "The label for category 运维指南 in sidebar tutorialSidebar" + }, + "sidebar.tutorialSidebar.category.开发者手册": { + "message": "开发者手册", + "description": "The label for category 开发者手册 in sidebar tutorialSidebar" + }, + "sidebar.tutorialSidebar.category.开发者手册.link.generated-index.description": { + "message": "Hippo4J 留给使用者能够扩展的知识点。", + "description": "The generated-index page description for category 开发者手册 in sidebar tutorialSidebar" + }, + "sidebar.tutorialSidebar.category.其它": { + "message": "其它", + "description": "The label for category 其它 in sidebar tutorialSidebar" + }, + "sidebar.user_docs.category.用户指南": { + "message": "用户指南", + "description": "The label for category 用户指南 in sidebar user_docs" + }, + "sidebar.user_docs.category.用户指南.link.generated-index.description": { + "message": "帮助想要了解 Hippo4J 的用户快速掌握核心开发理念。", + "description": "The generated-index page description for category 用户指南 in sidebar user_docs" + }, + "sidebar.user_docs.category.快速开始": { + "message": "快速开始", + "description": "The label for category 快速开始 in sidebar user_docs" + }, + "sidebar.user_docs.category.依赖配置中心": { + "message": "依赖配置中心", + "description": "The label for category 依赖配置中心 in sidebar user_docs" + }, + "sidebar.user_docs.category.无中间件依赖": { + "message": "无中间件依赖", + "description": "The label for category 无中间件依赖 in sidebar user_docs" + }, + "sidebar.user_docs.category.运维指南": { + "message": "运维指南", + "description": "The label for category 运维指南 in sidebar user_docs" + }, + "sidebar.user_docs.category.开发者手册": { + "message": "开发者手册", + "description": "The label for category 开发者手册 in sidebar user_docs" + }, + "sidebar.user_docs.category.开发者手册.link.generated-index.description": { + "message": "Hippo4J 留给使用者能够扩展的知识点。", + "description": "The generated-index page description for category 开发者手册 in sidebar user_docs" + }, + "sidebar.user_docs.category.其它": { + "message": "其它", + "description": "The label for category 其它 in sidebar user_docs" + }, + "sidebar.community.category.贡献规约": { + "message": "贡献规约", + "description": "The label for category 贡献规约 in sidebar community" + } +} diff --git a/docs/i18n/zh/docusaurus-plugin-content-docs/current/community/_category_.json b/docs/i18n/zh/docusaurus-plugin-content-docs-community/current/_category_.json similarity index 100% rename from docs/i18n/zh/docusaurus-plugin-content-docs/current/community/_category_.json rename to docs/i18n/zh/docusaurus-plugin-content-docs-community/current/_category_.json diff --git a/docs/i18n/zh/docusaurus-plugin-content-docs-community/current/contributor.md b/docs/i18n/zh/docusaurus-plugin-content-docs-community/current/contributor.md new file mode 100644 index 00000000..dd77fa3d --- /dev/null +++ b/docs/i18n/zh/docusaurus-plugin-content-docs-community/current/contributor.md @@ -0,0 +1,16 @@ +--- +id: contributor-guide +sidebar_position: 1 +title: 贡献指南 +--- + +Git Commit Log 尽量使用英文。 + +Pull Request 尽量保持单一,不同语义的代码贡献应拆分多个 Pull Request。 + +为了让您的 GitHub ID 显示在 Contributor 列表中,别忘了以下设置: + +```shell +git config --global user.name "username" +git config --global user.email "GitHub 账号邮箱" +``` \ No newline at end of file diff --git a/docs/i18n/zh/docusaurus-plugin-content-docs/current/community/dev_convention/_category_.json b/docs/i18n/zh/docusaurus-plugin-content-docs-community/current/dev_convention/_category_.json similarity index 100% rename from docs/i18n/zh/docusaurus-plugin-content-docs/current/community/dev_convention/_category_.json rename to docs/i18n/zh/docusaurus-plugin-content-docs-community/current/dev_convention/_category_.json diff --git a/docs/docs/community/dev_convention/code.md b/docs/i18n/zh/docusaurus-plugin-content-docs-community/current/dev_convention/code.md similarity index 100% rename from docs/docs/community/dev_convention/code.md rename to docs/i18n/zh/docusaurus-plugin-content-docs-community/current/dev_convention/code.md diff --git a/docs/docs/community/dev_convention/document.md b/docs/i18n/zh/docusaurus-plugin-content-docs-community/current/dev_convention/document.md similarity index 100% rename from docs/docs/community/dev_convention/document.md rename to docs/i18n/zh/docusaurus-plugin-content-docs-community/current/dev_convention/document.md diff --git a/docs/i18n/zh/docusaurus-plugin-content-docs/version-1.4.2/community/sponsor.md b/docs/i18n/zh/docusaurus-plugin-content-docs-community/current/sponsor.md similarity index 87% rename from docs/i18n/zh/docusaurus-plugin-content-docs/version-1.4.2/community/sponsor.md rename to docs/i18n/zh/docusaurus-plugin-content-docs-community/current/sponsor.md index c73fc64a..7108dc6e 100644 --- a/docs/i18n/zh/docusaurus-plugin-content-docs/version-1.4.2/community/sponsor.md +++ b/docs/i18n/zh/docusaurus-plugin-content-docs-community/current/sponsor.md @@ -6,11 +6,11 @@ sidebar_position: 4 如果您正在使用这个项目并感觉良好,或者是想支持我继续开发,通过以下二维码一次性捐款。 -在这里承诺将,将收到的所有赞助支持资金完全公开化,且后续资金用途仅 Hippo-4J 项目的运转。 +在这里承诺将,将收到的所有赞助支持资金完全公开化,且后续资金用途仅 Hippo4j 项目的运转。 ![](https://images-machen.oss-cn-beijing.aliyuncs.com/IMG_6719_2.jpg?x-oss-process=image/resize,h_180,w_180) -感谢给予支持的朋友,您的支持是 Hippo-4J 社区前进的动力 🎉 +感谢给予支持的朋友,您的支持是 Hippo4j 社区前进的动力 🎉 | | ID | 赞赏金额 | 时间 | 备注 | |-----|--|-------|------------|--------------------| diff --git a/docs/docs/community/update-log.md b/docs/i18n/zh/docusaurus-plugin-content-docs-community/current/update-log.md similarity index 85% rename from docs/docs/community/update-log.md rename to docs/i18n/zh/docusaurus-plugin-content-docs-community/current/update-log.md index aa4adc20..3985ed9c 100644 --- a/docs/docs/community/update-log.md +++ b/docs/i18n/zh/docusaurus-plugin-content-docs-community/current/update-log.md @@ -1,8 +1,53 @@ --- +title: 更新日志 sidebar_position: 5 --- -# 更新日志 +## 1.4.3 (Nov 06, 2022) + +这是一个功能增强版本,修复了少量 BUG。建议按照当前版本升级。具体信息可查看 Release 标签地址:[1.4.3](https://github.com/opengoofy/hippo4j/milestone/13?closed=1) + +**Use Change** + +- 重构线程池监控,配置层级和命名改变 +- 如果使用钉钉报警,关键字【警报】修改为【告警】 + +**Feature** + +- 重构 Spring 后置处理器创建动态线程池逻辑 +- 官网开启多版本化功能 +- 官网支持国际化,en-US +- 适配线程池延迟初始化 @wulangcode +- 添加 Codecov 相关代码覆盖率指标 +- 项目优雅关闭时停止运行状态采集 + +**Refactor** + +- DynamicThreadPoolExecutor 重构,增加插件扩展逻辑 @Createsequence +- 重构线程池监控,新增容器和三方框架线程池监控 +- 重构服务端包目录,聚合 hippo4j-server 相关 module + +**Bug** + +- dubbo 线程池无法获取运行信息 @iwangjie +- 线程池检查活跃度报警取值错误 @maxisvest +- 动态线程池修改多次后队列提示信息丢失 +- docker部署 mysql启动报错H2驱动 +- docker-startup.sh的mysql配置多个“-” @Malcolmli +- 动态注册线程池队列容量赋值错误 +- 飞书超时类型告警不存在 Trace 信息时发送错误 @mageeric + +**Optimize** + +- 修改报警文案,【警报】修改为【告警】 @wulangcode +- 自动选择H2数据库的存储路径 @iwangjie +- 服务端在客户端后面启动,依旧支持长轮训 @wulangcode +- 配置未发生变更时,长轮询返回 304 @wulangcode +- discovery服务Lease类中判断过期时间需要多等一个duration @w-jirong +- 优化 ThreadPoolBuilder#maxPoolNum 核心线程不得大于最大线程 @wulangcode +- hippo4j console ui 迁移至本项目 +- 查询 Web 线程池列表添加框架标识 +- 优化 H2 初始化逻辑 ## 1.4.2 (Oct 18, 2022) diff --git a/docs/i18n/zh/docusaurus-plugin-content-docs/current/community/contributor.md b/docs/i18n/zh/docusaurus-plugin-content-docs/current/community/contributor.md deleted file mode 100644 index f0185ad3..00000000 --- a/docs/i18n/zh/docusaurus-plugin-content-docs/current/community/contributor.md +++ /dev/null @@ -1,24 +0,0 @@ ---- -sidebar_position: 1 ---- - -# 贡献指南 - -Git Commit Log 尽量使用英文。 - -Pull Request 尽量保持单一,不同语义的代码贡献应拆分多个 Pull Request。 - -为了让您的 GitHub ID 显示在 Contributor 列表中,别忘了以下设置: - -```shell -git config --global user.name "username" -git config --global user.email "GitHub 账号邮箱" -``` - -## 贡献者列表 - -您可以在 [Hippo4J](https://github.com/opengoofy/hippo4j/graphs/contributors) 和 [Hippo4J Console](https://github.com/opengoofy/hippo4j-console) 的贡献列表中找到全部的贡献者名单。 - - - - diff --git a/docs/i18n/zh/docusaurus-plugin-content-docs/current/community/dev_convention/document.md b/docs/i18n/zh/docusaurus-plugin-content-docs/current/community/dev_convention/document.md deleted file mode 100644 index 923ad81d..00000000 --- a/docs/i18n/zh/docusaurus-plugin-content-docs/current/community/dev_convention/document.md +++ /dev/null @@ -1,227 +0,0 @@ ---- -sidebar_position: 1 ---- - -# 文档规约 - -文档引用自:[中文文案排版指北](https://github.com/sparanoid/chinese-copywriting-guidelines) - -## 空格 - -> 「有研究顯示,打字的時候不喜歡在中文和英文之間加空格的人,感情路都走得很辛苦,有七成的比例會在 34 歲的時候跟自己不愛的人結婚,而其餘三成的人最後只能把遺產留給自己的貓。畢竟愛情跟書寫都需要適時地留白。 -> -> 與大家共勉之。」——[vinta/paranoid-auto-spacing](https://github.com/vinta/pangu.js) - -### 中英文之間需要增加空格 - -正確: - -> 在 LeanCloud 上,數據儲存是圍繞 `AVObject` 進行的。 - -錯誤: - -> 在LeanCloud上,數據儲存是圍繞`AVObject`進行的。 - -> 在 LeanCloud上,數據儲存是圍繞`AVObject` 進行的。 - -完整的正確用法: - -> 在 LeanCloud 上,數據儲存是圍繞 `AVObject` 進行的。每個 `AVObject` 都包含了與 JSON 兼容的 key-value 對應的數據。數據是 schema-free 的,你不需要在每個 `AVObject` 上提前指定存在哪些键,只要直接設定對應的 key-value 即可。 - -例外:「豆瓣FM」等產品名詞,按照官方所定義的格式書寫。 - -### 中文與數字之間需要增加空格 - -正確: - -> 今天出去買菜花了 5000 元。 - -錯誤: - -> 今天出去買菜花了 5000元。 - -> 今天出去買菜花了5000元。 - -### 數字與單位之間需要增加空格 - -正確: - -> 我家的光纖入屋寬頻有 10 Gbps,SSD 一共有 20 TB。 - -錯誤: - -> 我家的光纖入屋寬頻有 10Gbps,SSD 一共有 20TB。 - -例外:度數/百分比與數字之間不需要增加空格: - -正確: - -> 角度為 90° 的角,就是直角。 - -> 新 MacBook Pro 有 15% 的 CPU 性能提升。 - -錯誤: - -> 角度為 90 ° 的角,就是直角。 - -> 新 MacBook Pro 有 15 % 的 CPU 性能提升。 - -### 全形標點與其他字符之間不加空格 - -正確: - -> 剛剛買了一部 iPhone,好開心! - -錯誤: - -> 剛剛買了一部 iPhone ,好開心! - -> 剛剛買了一部 iPhone, 好開心! - -### `text-spacing` to the rescue? - -CSS Text Module Level 4 的 [`text-spacing`](https://www.w3.org/TR/css-text-4/#text-spacing-property) 和 Microsoft 的 [`-ms-text-autospace`](https://msdn.microsoft.com/library/ms531164(v=vs.85).aspx) 可以實現自動為中英文之間增加空白。不過目前並未普及,另外在其他應用場景,例如 macOS、iOS、Windows 等用戶介面目前並不存在這個特性,所以請繼續保持隨手加空格的習慣。 - -## 標點符號 - -### 不重複使用標點符號 - -即使中國大陸的標點符號用法允許重複使用標點符號,但是這麼做會破壞句子的美觀性。 - -正確: - -> 德國隊竟然戰勝了巴西隊! - -> 她竟然對你說「喵」?! - -錯誤: - -> 德國隊竟然戰勝了巴西隊!! - -> 德國隊竟然戰勝了巴西隊!!!!!!!! - -> 她竟然對你說「喵」??!! - -> 她竟然對你說「喵」?!?!??!! - -## 全形和半形 - -不明白什麼是全形(全角)與半形(半角)符號?請查看維基百科條目『[全形和半形](https://zh.wikipedia.org/wiki/%E5%85%A8%E5%BD%A2%E5%92%8C%E5%8D%8A%E5%BD%A2)』。 - -### 使用全形中文標點 - -正確: - -> 嗨!你知道嘛?今天前台的小妹跟我說「喵」了哎! - -> 核磁共振成像(NMRI)是什麼原理都不知道?JFGI! - -錯誤: - -> 嗨! 你知道嘛? 今天前台的小妹跟我說 "喵" 了哎! - -> 嗨!你知道嘛?今天前台的小妹跟我說"喵"了哎! - -> 核磁共振成像 (NMRI) 是什麼原理都不知道? JFGI! - -> 核磁共振成像(NMRI)是什麼原理都不知道?JFGI! - -### 數字使用半形字符 - -正確: - -> 這件蛋糕只賣 1000 元。 - -錯誤: - -> 這件蛋糕只賣 1000 元。 - -例外:在設計稿、宣傳海報中如出現極少量數字的情形時,為方便文字對齊,是可以使用全形數字的。 - -### 遇到完整的英文整句、特殊名詞,其內容使用半形標點 - -正確: - -> 賈伯斯那句話是怎麼說的?「Stay hungry, stay foolish.」 - -> 推薦你閱讀《Hackers & Painters: Big Ideas from the Computer Age》,非常的有趣。 - -錯誤: - -> 賈伯斯那句話是怎麼說的?「Stay hungry,stay foolish。」 - -> 推薦你閱讀《Hackers&Painters:Big Ideas from the Computer Age》,非常的有趣。 - -## 名詞 - -### 專有名詞使用正確的大小寫 - -大小寫相關用法原屬於英文書寫範疇,不屬於本 wiki 討論內容,在這裡只對部分易錯用法進行簡述。 - -正確: - -> 使用 GitHub 登錄 - -> 我們的客戶有 GitHub、Foursquare、Microsoft Corporation、Google、Facebook, Inc.。 - -錯誤: - -> 使用 github 登錄 - -> 使用 GITHUB 登錄 - -> 使用 Github 登錄 - -> 使用 gitHub 登錄 - -> 使用 gイんĤЦ8 登錄 - -> 我們的客戶有 github、foursquare、microsoft corporation、google、facebook, inc.。 - -> 我們的客戶有 GITHUB、FOURSQUARE、MICROSOFT CORPORATION、GOOGLE、FACEBOOK, INC.。 - -> 我們的客戶有 Github、FourSquare、MicroSoft Corporation、Google、FaceBook, Inc.。 - -> 我們的客戶有 gitHub、fourSquare、microSoft Corporation、google、faceBook, Inc.。 - -> 我們的客戶有 gイんĤЦ8、キouЯƧquムгє、๓เςг๏ร๏Ŧt ς๏гק๏гคtเ๏ภn、900913、ƒ4ᄃëв๏๏к, IПᄃ.。 - -注意:當網頁中需要配合整體視覺風格而出現全部大寫/小寫的情形,HTML 中請使用標準的大小寫規範進行書寫;並通過 `text-transform: uppercase;`/`text-transform: lowercase;` 對表現形式進行定義。 - -### 不要使用不道地的縮寫 - -正確: - -> 我們需要一位熟悉 TypeScript、HTML5,至少理解一種框架(如 React、Next.js)的前端開發者。 - -錯誤: - -> 我們需要一位熟悉 Ts、h5,至少理解一種框架(如 RJS、nextjs)的 FED。 - -## 爭議 - -以下用法略帶有個人色彩,即:無論是否遵循下述規則,從語法的角度來講都是**正確**的。 - -### 超連結之間增加空格 - -用法: - -> 請 [提交一個 issue](#) 並分配给相關同事。 - -> 訪問我們網站的最新動態,請 [點擊這裡](#) 進行訂閱! - -對比用法: - -> 請[提交一個 issue](#) 並分配给相關同事。 - -> 訪問我們網站的最新動態,請[點擊這裡](#)進行訂閱! - -### 簡體中文使用直角引號 - -用法: - -> 「老师,『有条不紊』的『紊』是什么意思?」 - -對比用法: - -> “老师,‘有条不紊’的‘紊’是什么意思?” diff --git a/docs/i18n/zh/docusaurus-plugin-content-docs/current/community/developer.md b/docs/i18n/zh/docusaurus-plugin-content-docs/current/community/developer.md deleted file mode 100644 index 89b57b88..00000000 --- a/docs/i18n/zh/docusaurus-plugin-content-docs/current/community/developer.md +++ /dev/null @@ -1,89 +0,0 @@ ---- -sidebar_position: 2 ---- - -# 核心开发者 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
姓名GitHub ID博客地址联系方式
马称magegoofy小马哥的技术专栏machen@apache.org
陆宽shining-stars-lk宽仔的代码之路1031900093@qq.com
王杰iwangjie-wangchenmo1025@gmail.com
魏虎weihubeatsweihubeatsweihubeats@163.com
李剑鑫BigXin0109Only丶Big1064730540@qq.com
刘文浩pizihaopizihaohao3073liu@163.com
叶炜shanjianq-17855368071@163.com
黄成兴CreatesequenceCreatesequence's Blog841396397@qq.com
- -## 成为核心开发者 - -持续对 Hippo-4J 进行贡献, 粗略评估,完成 10 次 PR 贡献即可成为核心开发者。 其中包括完成 2 个 [good pro issue](https://github.com/opengoofy/hippo4j/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+pro+issue%22) 或以上,以及若干个 [good first issue](https://github.com/opengoofy/hippo4j/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22)。 - -:::note -会根据 PR 质量提供个性化评估,有可能一个或两个质量较高 PR 即可成为核心开发者。参考:[重构 DynamicThreadPoolExecutor 功能扩展逻辑](https://github.com/opengoofy/hippo4j/pull/854) -::: - -成为核心开发者后,会为该 GitHub 账号获取 Jetbrains 全家桶 Licenses,有效期为 1 年。不用再为破解而烦恼,感受随时升级的快乐。 - -:::note -距离到期两周前,会再次申请 Jetbrains Licenses。有点类似于无限续约的感觉,在此感谢 Jetbrains 公司对开源的支持。 -::: - -截至 `2022-10-30` 当天,已为登记的 7 位核心开发者成功申请 Licenses。 - -![](https://images-machen.oss-cn-beijing.aliyuncs.com/image-20221030134303060.png) diff --git a/docs/i18n/zh/docusaurus-plugin-content-docs/current/community/update-log.md b/docs/i18n/zh/docusaurus-plugin-content-docs/current/community/update-log.md deleted file mode 100644 index aa4adc20..00000000 --- a/docs/i18n/zh/docusaurus-plugin-content-docs/current/community/update-log.md +++ /dev/null @@ -1,299 +0,0 @@ ---- -sidebar_position: 5 ---- - -# 更新日志 - -## 1.4.2 (Oct 18, 2022) - -这是一个功能增强版本,修复了少量 BUG。建议按照当前版本升级。具体信息可查看 Release 标签地址:[1.4.2](https://github.com/opengoofy/hippo4j/milestone/12?closed=1) - -**Feature** - -- 强制指定客户端注册的 ip + port -- 支持 spring-cloud-tencent Polaris 线程池动态更新 @weihubeats -- 服务启动时加载 MySQL、H2 数据库初始化语句 -- Adapter 初始化覆盖核心参数 @pizihao -- Server 端新增是否开启认证模式 @baymax55 - -**Refactor** - -- 替换底层网络工具类 OkHttp @yanrongzhen -- 全局移除 commons-lang3 工具包依赖 @yanrongzhen -- 去除三方工具类依赖 @pizihao -- 全局移除 Guava 工具包依赖 @road2master -- DockerFile 基于 H2 数据库重新构建 @BigXin0109 - -**Bug** - -- Dubbo 2.7.15 无法获取线程池引用 @iwangjie -- 动态线程池报警参数颠倒 @jinlingmei - -**Optimize** - -- 线程池实例运行数据采集,如果线程池id不存在,且长度超长,会报异常 @Gdk666 -- 项目中动态线程池数量为空时,存在 CPU 空转情况 -- 客户端注册服务端失败,输出服务端返回信息 @wulangcode -- 调整数据库项目 id 和线程池 id 字段长度 -- 增加代码检查工具 maven-checkstyle-plugin -- 调整控制台监控图表颜色展示 - -## 1.4.1 (Sep 12, 2022) - -这是一个功能增强版本,修复了若干 BUG。建议按照当前版本升级。具体信息可查看 Release 标签地址:[1.4.1](https://github.com/opengoofy/hippo4j/milestone/11?closed=1) - -**Feature** - -- 支持 H2 数据库 @weihubeats -- 动态线程池配置变更时,支持单个、多个或全部节点变 @pizihao -- 增加线程池活跃度和容量报警可选择关闭 -- @DynamicThreadPool 线程池不存在则创建 @shanjianq -- 支持 ETCD 配置中心动态调整参数 @weihubeats -- 创建动态线程池支持 spring 线程池 @BigXin0109 -- 线程池实例变更增加执行超时时间 -- 线程池相关查询页面增加阻塞队列属性 -- 定义动态线程池时,抽象默认配置 -- 提供 ExecutorContext 封装上下文细节 @road2master -- Docker 制作服务端镜像,帮助开发者快速启动 @BigXin0109 -- RabbitMQ 适配器增加多个 MQ 数据源 @weihubeats - -**Bug** - -- 动态线程池设置关闭时启动报错 @dousp -- ExecutorTtlWrapper 类型的 Executor 不生效 @BigXin0109 -- Undertow 获取 WebServer 类型参数异常 @shining-stars-lk -- 修复线程池核心、最大线程数校验限制 -- ByteConvertUtil#getPrintSize 单位转换错误 @onesimplecoder -- 创建线程池单选框选择错误 -- ReflectUtil#getFieldsDirectly missing fields @BigXin0109 -- 本地代码中设置的 capacity 无效 @BigXin0109 -- 服务端线程池超时时间存在拆箱空指针异常 @oreoft -- 未读取服务端返回执行超时时间属性 -- ResizableCapacityLinkedBlockingQueue#put 当前元素数量大于 capacity 未阻塞 - -**Optimize** - -- 长轮询任务判断逻辑优化 @shining-stars-lk -- 线程池存在实例不允许删除线程池 @shanjianq -- 优化租户、项目列表展示排版 -- 通知报警模块项目和线程池下拉查询排序修改 -- 动态线程池拒绝策略触发,以异步的方式报警 -- 优化框架中线程池工厂产生的线程名称 @road2master - -## 1.4.0 (Aug 16, 2022) - -`hippo4j server` 兼容历史低版本,`hippo4j config` 中部分属性名进行了调整,请参考 [hippo4j config 快速开始](https://hippo4j.cn/docs/user_docs/getting-started/hippo4j-core-start)。 - -注意事项: -1. 如果是对已运行 hippo4j server 升级,执行 `/conf/sql-upgrade` 目录下对应的升级脚本。 -2. 需客户端在 1.4.0 及以上版本才可在 hippo4j server 设置线程执行超时时间属性。 - -**Feature** - -- 添加 Alibaba Dubbo 线程池监控及动态变更 -- hippo4j server 支持任务执行超时时间动态修改 -- 阿里 TTL 框架线程池适配 -- 添加动态线程池自动注册功能 -- 订阅回调线程池参数变更 -- 动态线程池监控增加 SPI 自定义功能 -- hippo4j server 支持多种线程池监控方式,例如 Prometheus -- 通知相关参数添加动态变更功能 - -**Bug** - -- 线程池变更:executeTimeOut 变更极端情况下会出现异常 -- 用户登录时候,如果输入了不存在的用户名,后台报空指针异常 -- 修复了对 spring-boot 服务中 tomcat 线程池的兼容问题 -- 排除 Tomcat Jar 使用 Undertow 启动报错 - -**Optimize** - -- hippo4j-core-spring-boot-starter 模块修改名称为 hippo4j-config-spring-boot-starter -- 拆分容器线程池子页面:Tomcat、Undertow、Jetty -- 服务端访问客户端时对 URL 转码 -- MyBatisPlus 修改全局填充方法优化 -- 控制台线程池列表下拉框默认正序 -- 控制台线程池实例菜单,对于非可修改容量队列外,不允许修改队列容量 -- 动态线程池控制台功能变更 -- 租户和项目列表分页查询按照创建时间倒序展示 -- 线程池监控页面图表 UI 优化 -- 设置 maven-gpg-plugin 插件默认不执行 -- 前端控制台相关搜索条件添加必填提示 -- hippo4j 消息通知 & 报警抽象优化 -- 配置中心未配置线程池启动报错 -- 控制台线程池报警 UI 以及功能优化 -- Web、框架线程池编辑弹框 UI 优化 -- 线程池添加、编辑页面 UI 优化 -- 线程池运行详情页前端 UI 优化 - -**Refactor** - -- 删除自定义日志组件 -- 线程池监控功能重构 -- hippo4j core 配置中心生效判断重构 -- 配置变更通知 & 报警通知重构 -- Web 容器线程池适配迁移 hippo4j-adapter - -## 1.3.1 (July 17, 2022) - -注:这是一个兼容历史版本的小范围升级。 - -**Feature** - -- 控制台新增线程池功能设置为 Admin 权限 -- 添加 Hystrix 线程池监控及动态变更 -- 添加 Netty 上传动态线程池监控数据方式 -- 添加 GitHub Actions CI 流程 -- 添加 Spring Kafka 示例项目 -- Tomcat 版本号 >= 9.0.55 线程池适配 - -**Refactor** - -- 更多线程池拆分子目录页面 - -**Optimize** - -- hippo4j core 添加 banner 打印 -- 优化可变更容量阻塞队列名称 - -**BUG** - -- Apollo 配置修改延迟了一个版本 -- Spring Boot 环境下使用 hippo4j-core 接入,配置中心使用 nacos;启动时提示 ConfigService not found - -查看 1.3.1 版本发布:https://github.com/mabaiwan/hippo4j/milestone/9 - -## 1.3.0 (June 06, 2022) - -1.3.0 发布 **适配三方框架的基础框架**。 - -目前已完成 **Dubbo、RabbitMQ、RocketMQ、RocketMQSpringCloudStream** 的线程池适配,后续还会接入 **Kafka、Hystrix** 等框架或中间件的线程池适配。 - -注:这是一个兼容历史版本的重大升级。 - -**Feature** - -- 添加 RabbitMQ 线程池监控及动态变更 -- 添加 RocketMQ 线程池监控及动态变更 -- 添加 Dubbo 线程池监控及动态变更 -- 添加 SpringCloud Stream RocketMQ 消费线程池监控及动态变更 - -**Refactor** - -- 重构容器线程池查询及修改功能 -- 优化配置中心触发监听后,所执行的数据变更逻辑 - -**Optimize** - -- 前端控制台删除无用组件 -- 服务端页面字段未显示中文 -- 控制台 UI 优化 -- 修改线程池实例后实时刷新列表参数 -- 容器线程池编辑仅限 Admin 权限 -- SpringBoot Starter 变更包路径 - -**BUG** - -- 修复 SpringBoot Nacos 动态刷新不生效 -- 报警配置 alarm=false 不配置通知报警平台和接收人报错 - -## 1.2.1 (May 07, 2022) - -**BugFix** - -- apollo 动态配置不生效 -- 修复 hippo4j-core 后置处理器创建线程池问题 -- 重构 hippo4j-core spring 后置处理器逻辑 -- 优化ThreadPoolNotifyAlarmHandler下的空指针异常 -- 修复线程池核心、最大线程数变更问题 -- startup.cmd 未正常读取 conf 配置文件 - -**Optimize** - -- 配置文件中字段歧义 -- 修改代码中历史网址 -- InstanceInfo 的 groupKey 参数重复设置 -- ConfigFileTypeEnum 枚举字段添加注释 -- 线程资源通过线程池创建,不允许自行显示创建线程 -- Guava 版本升级至 30.0-jre 及以上版本 -- SystemClock 替换 System.currentTimeMillis() -- 添加代码格式化插件 Spotless -- 修改线程池文案 - -## 1.2.0 (Mar 13, 2022) - -**Feature** - -- hippo4j-core线程池资源对接 Prometheus 监控 -- hippo4j-core 支持 Zookeeper -- hippo4j-core 支持 Apollo - -**Optimize** - -- 适配非 Web SpringBoot 项目使用 Hippo4J -- 优化报警通知 -- 修复在 JDK 小版本中的兼容性问题 - -**BugFix** - -- server 端查看容器线程池,参数为 null -- 重构线程池查看及容器线程池查看等交互 -- 修复引入 hippo4j-spring-boot-starter 后,运行单元测试报错 -- 修复可能出现的空指针异常 - -## 1.1.0 (Mar 13, 2022) - -Hippo4J 线程池框架 1.1.0 RELEASE 版本,添加了 Hippo4J-Core(依赖配置中心的动态线程池). - -**Feature** - -- 删除 DynamicThreadPoolExecutor 内代码实现,仅通过线程池扩展点进行扩展 -- 通过动态代理实现线程池拒绝策略执行次数统计 -- 抽象通知报警消息模块 -- 抽象 hippo4j 核心组件,不依赖 server 端即可完成动态调参、监控、报警等功能 -- 前端删除线程池按钮添加 Admin 权限 -- 添加线程池任务运行超长报警 -- 容器线程池支持 Undertow -- 容器线程池支持 Jetty -- 重构服务端异常体系 - -**Optimize** - -- 前端项目 Token 失效跳转登录页 -- 优化 Server 启动脚本日志输出 -- 优化前端按钮权限控制粒度 -- 优化线程池报警推送文案 -- 前端弹框样式优化 -- 适配低版本 SpringBoot Bind -- 优化消息通知模块 - -**BugFix** - -- Duplicate entry 'xxx' for key 'uk_configinfo_datagrouptenant' - -## 1.0.0 (Feb 01, 2022) - -**Feature** - -- 线程池运行堆栈查看 -- 扩展 Web 容器线程池动态调参、监控 - -**Optimize** - -- 删除高版本 SpringBoot Api -- ListableBeanFactory#findAnnotationOnBean SpringBoot 低版本适配 -- 优化客户端关闭时调用服务端钩子函数 -- 线程池实例参数弹框添加实例 ID 和线程池状态 -- 补充线程池替换 Hippo4J 文档 -- 1.5.x springboot 引入hippo4j-spring-boot-starter配置项,bean初始化失败 -- 优化线程池参数编辑合理性校验 -- BaseInstanceRegistry 读写锁重构 - -**BugFix** - -- 本地项目线程池实例缓存无法精确清理 -- 线程池实例页面多实例不同 Active 展示错误 -- 创建动态线程池逻辑判断修复 -- 创建动态线程池增强参数未设置 -- 控制消息推送报警频率的方法有并发安全的问题 -- tomcat线程池上下文获取失败 diff --git a/docs/i18n/zh/docusaurus-plugin-content-docs/current/user_docs/getting_started/config/hippo4j-config-monitor.md b/docs/i18n/zh/docusaurus-plugin-content-docs/current/user_docs/getting_started/config/hippo4j-config-monitor.md index 72528638..c030dc10 100644 --- a/docs/i18n/zh/docusaurus-plugin-content-docs/current/user_docs/getting_started/config/hippo4j-config-monitor.md +++ b/docs/i18n/zh/docusaurus-plugin-content-docs/current/user_docs/getting_started/config/hippo4j-config-monitor.md @@ -39,7 +39,12 @@ management: spring: dynamic: thread-pool: - collect-type: micrometer + monitor: + enable: true # 是否开启采集线程池运行时数据 + collect-interval: 5000 # 采集线程池运行数据频率 + collect-types: micrometer # 采集线程池运行数据的类型。eg:log、micrometer。多个可以同时使用,默认 micrometer + initial-delay: 10000 # 项目启动后延迟多久进行采集 + thread-pool-types: dynamic # 采集线程池的类型。eg:dynamic、web、adapter。可任意配置,默认 dynamic ``` 项目启动,访问 `http://localhost:29999/actuator/prometheus` 出现 `dynamic_thread_pool_` 前缀的指标,即为成功。 diff --git a/docs/i18n/zh/docusaurus-plugin-content-docs/current/user_docs/getting_started/server/hippo4j-server-config.md b/docs/i18n/zh/docusaurus-plugin-content-docs/current/user_docs/getting_started/server/hippo4j-server-config.md index 24bf9a13..e1ef853f 100644 --- a/docs/i18n/zh/docusaurus-plugin-content-docs/current/user_docs/getting_started/server/hippo4j-server-config.md +++ b/docs/i18n/zh/docusaurus-plugin-content-docs/current/user_docs/getting_started/server/hippo4j-server-config.md @@ -1,5 +1,5 @@ --- -sidebar_position: 4 +sidebar_position: 3 --- # 服务端配置 diff --git a/docs/i18n/zh/docusaurus-plugin-content-docs/current/user_docs/getting_started/server/hippo4j-server-monitor.md b/docs/i18n/zh/docusaurus-plugin-content-docs/current/user_docs/getting_started/server/hippo4j-server-monitor.md new file mode 100644 index 00000000..b743c790 --- /dev/null +++ b/docs/i18n/zh/docusaurus-plugin-content-docs/current/user_docs/getting_started/server/hippo4j-server-monitor.md @@ -0,0 +1,122 @@ +--- +sidebar_position: 2 +--- + +# 线程池监控 + +Server 模式默认内置线程池运行时采集和监控功能,如果想要使用 Prometheus + Grafana 的方式可以查看以下内容。 + +## 线程池监控配置 + +接下来引入 SpringBoot Actuator。Spring 2.x 一般都有版本指定,所以这里不用写版本号。 + +```xml + + io.micrometer + micrometer-registry-prometheus + + + + org.springframework.boot + spring-boot-starter-actuator + +``` + +添加动态线程池监控相关配置: + +```yaml +management: + metrics: + export: + prometheus: + enabled: true + server: + port: 29999 # 可选配置,如果不配置该 port,直接使用 ${server.port} + endpoints: + web: + exposure: + include: '*' # 测试使用,开启了所有端点,生产环境不建议 * +spring: + dynamic: + thread-pool: + monitor: + enable: true # 是否开启采集线程池运行时数据 + collect-interval: 5000 # 采集线程池运行数据频率 + collect-types: server,micrometer # 采集线程池运行数据的类型。eg:server、micrometer。多个可以同时使用,默认 server + initial-delay: 10000 # 项目启动后延迟多久进行采集 + thread-pool-types: dynamic # 采集线程池的类型。eg:dynamic、web、adapter。可任意配置,默认 dynamic +``` + +项目启动,访问 `http://localhost:29999/actuator/prometheus` 出现 `dynamic_thread_pool_` 前缀的指标,即为成功。 + +![](https://images-machen.oss-cn-beijing.aliyuncs.com/image-20220912220401016.png) + +## 配置 Prometheus + +通过 Docker 启动 Prometheus 服务。 + +```shell +docker run -d -p 9090:9090 --name prometheus prom/prometheus +``` + +添加 Prometheus 抽取数据任务。 + +```shell +# 进入 prometheus 容器内部 +docker exec -it prometheus /bin/sh +# 编辑 prometheus 配置文件 +vi /etc/prometheus/prometheus.yml +``` + +scrape_configs 节点下新添加一个 job,如果 Prometheus 是 Docker 方式部署,`{scrape_configs.static_configs.targets}` 需要写本机的 IP。 + +```yaml +scrape_configs: + - job_name: 'dynamic-thread-pool-job' + scrape_interval: 5s + metrics_path: '/actuator/prometheus' + static_configs: + - targets: [ '127.0.0.1:29999' ] +``` + +配置成功后 `exit` 退出容器,并进行 Prometheus 容器重启 `docker restart prometheus`。 + +访问 Prometheus 控制台 `http://localhost:9090/graph` 路径,能够展示相关指标即为配置成功。 + +![](https://images-machen.oss-cn-beijing.aliyuncs.com/image-20220912221237597.png) + +## 配置 Grafana + +```shell +docker run -d -p 3000:3000 --name=grafana grafana/grafana +``` + +访问 Grafana 地址,[http://localhost:3000](http://localhost:3000) 用户名密码:`admin` + +Grafana 访问 `http://localhost:3000/datasources` 导入 Prometheus 数据源。 + +![](https://images-machen.oss-cn-beijing.aliyuncs.com/image-20220912221646866.png) + +> 如果 Prometheus 为 Docker 方式部署,HTTP URL 需要为本地 IP,比如:http://192.168.1.5:9090 + +关注公众号 `龙台的技术笔记`,回复:`监控`,获取 Hippo4J Grafana DashBoard JSON 配置。 + +| 公众号 | 回复关键词 | +|:------------------------------------------------------------------------------------------------------------:|:-------------------------------------------------------------------------------------------------------------------------:| +| ![](https://images-machen.oss-cn-beijing.aliyuncs.com/43_65f6020ed111b6bb3808ec338576bd6b.png?x-oss-process=image/resize,h_300,w_400) | ![](https://images-machen.oss-cn-beijing.aliyuncs.com/image-20220327171957444.png?x-oss-process=image/resize,h_300,w_400) | + +获取到 JSON 文件后,通过 `http://localhost:3000/dashboard/import` 将 JSON 文件导入至 Grafana DashBoard。 + +![](https://images-machen.oss-cn-beijing.aliyuncs.com/image-20220912225627272.png) + +下拉框内动态选择创建好的 Prometheus 数据源,并点击 `Import`。 + +![](https://images-machen.oss-cn-beijing.aliyuncs.com/image-20220912225700200.png) + +即可使用炫酷的 Hippo-4J 动态线程池监控 DashBoard。大家伙儿也可以根据个人喜好进行定制 DashBoard,如果觉得有优化点,欢迎和我联系贡献。 + +![](https://images-machen.oss-cn-beijing.aliyuncs.com/image-20220912225813972.png) + +如果项目客户端启动多个示例,动态线程池监控效果图如下: + +![](https://images-machen.oss-cn-beijing.aliyuncs.com/20220814_hippo4j_monitor.jpg) diff --git a/docs/i18n/zh/docusaurus-plugin-content-docs/current/user_docs/getting_started/server/hippo4j-server-start.md b/docs/i18n/zh/docusaurus-plugin-content-docs/current/user_docs/getting_started/server/hippo4j-server-start.md index 64b94ee3..003d464f 100644 --- a/docs/i18n/zh/docusaurus-plugin-content-docs/current/user_docs/getting_started/server/hippo4j-server-start.md +++ b/docs/i18n/zh/docusaurus-plugin-content-docs/current/user_docs/getting_started/server/hippo4j-server-start.md @@ -1,5 +1,5 @@ --- -sidebar_position: 3 +sidebar_position: 1 --- # 接入流程 diff --git a/docs/i18n/zh/docusaurus-plugin-content-docs/version-1.4.2/community/contributor.md b/docs/i18n/zh/docusaurus-plugin-content-docs/version-1.4.2/community/contributor.md deleted file mode 100644 index f0185ad3..00000000 --- a/docs/i18n/zh/docusaurus-plugin-content-docs/version-1.4.2/community/contributor.md +++ /dev/null @@ -1,24 +0,0 @@ ---- -sidebar_position: 1 ---- - -# 贡献指南 - -Git Commit Log 尽量使用英文。 - -Pull Request 尽量保持单一,不同语义的代码贡献应拆分多个 Pull Request。 - -为了让您的 GitHub ID 显示在 Contributor 列表中,别忘了以下设置: - -```shell -git config --global user.name "username" -git config --global user.email "GitHub 账号邮箱" -``` - -## 贡献者列表 - -您可以在 [Hippo4J](https://github.com/opengoofy/hippo4j/graphs/contributors) 和 [Hippo4J Console](https://github.com/opengoofy/hippo4j-console) 的贡献列表中找到全部的贡献者名单。 - - - - diff --git a/docs/i18n/zh/docusaurus-plugin-content-docs/version-1.4.2/community/dev_convention/code.md b/docs/i18n/zh/docusaurus-plugin-content-docs/version-1.4.2/community/dev_convention/code.md deleted file mode 100644 index f91acdbe..00000000 --- a/docs/i18n/zh/docusaurus-plugin-content-docs/version-1.4.2/community/dev_convention/code.md +++ /dev/null @@ -1,8 +0,0 @@ ---- -sidebar_position: 2 ---- - -# 代码规约 - -1. 代码提交前,执行 `mvn spotless:apply` 保证代码格式符合规范。 -2. 代码中不要出现无意义的空行。 diff --git a/docs/i18n/zh/docusaurus-plugin-content-docs/version-1.4.2/community/dev_convention/document.md b/docs/i18n/zh/docusaurus-plugin-content-docs/version-1.4.2/community/dev_convention/document.md deleted file mode 100644 index 923ad81d..00000000 --- a/docs/i18n/zh/docusaurus-plugin-content-docs/version-1.4.2/community/dev_convention/document.md +++ /dev/null @@ -1,227 +0,0 @@ ---- -sidebar_position: 1 ---- - -# 文档规约 - -文档引用自:[中文文案排版指北](https://github.com/sparanoid/chinese-copywriting-guidelines) - -## 空格 - -> 「有研究顯示,打字的時候不喜歡在中文和英文之間加空格的人,感情路都走得很辛苦,有七成的比例會在 34 歲的時候跟自己不愛的人結婚,而其餘三成的人最後只能把遺產留給自己的貓。畢竟愛情跟書寫都需要適時地留白。 -> -> 與大家共勉之。」——[vinta/paranoid-auto-spacing](https://github.com/vinta/pangu.js) - -### 中英文之間需要增加空格 - -正確: - -> 在 LeanCloud 上,數據儲存是圍繞 `AVObject` 進行的。 - -錯誤: - -> 在LeanCloud上,數據儲存是圍繞`AVObject`進行的。 - -> 在 LeanCloud上,數據儲存是圍繞`AVObject` 進行的。 - -完整的正確用法: - -> 在 LeanCloud 上,數據儲存是圍繞 `AVObject` 進行的。每個 `AVObject` 都包含了與 JSON 兼容的 key-value 對應的數據。數據是 schema-free 的,你不需要在每個 `AVObject` 上提前指定存在哪些键,只要直接設定對應的 key-value 即可。 - -例外:「豆瓣FM」等產品名詞,按照官方所定義的格式書寫。 - -### 中文與數字之間需要增加空格 - -正確: - -> 今天出去買菜花了 5000 元。 - -錯誤: - -> 今天出去買菜花了 5000元。 - -> 今天出去買菜花了5000元。 - -### 數字與單位之間需要增加空格 - -正確: - -> 我家的光纖入屋寬頻有 10 Gbps,SSD 一共有 20 TB。 - -錯誤: - -> 我家的光纖入屋寬頻有 10Gbps,SSD 一共有 20TB。 - -例外:度數/百分比與數字之間不需要增加空格: - -正確: - -> 角度為 90° 的角,就是直角。 - -> 新 MacBook Pro 有 15% 的 CPU 性能提升。 - -錯誤: - -> 角度為 90 ° 的角,就是直角。 - -> 新 MacBook Pro 有 15 % 的 CPU 性能提升。 - -### 全形標點與其他字符之間不加空格 - -正確: - -> 剛剛買了一部 iPhone,好開心! - -錯誤: - -> 剛剛買了一部 iPhone ,好開心! - -> 剛剛買了一部 iPhone, 好開心! - -### `text-spacing` to the rescue? - -CSS Text Module Level 4 的 [`text-spacing`](https://www.w3.org/TR/css-text-4/#text-spacing-property) 和 Microsoft 的 [`-ms-text-autospace`](https://msdn.microsoft.com/library/ms531164(v=vs.85).aspx) 可以實現自動為中英文之間增加空白。不過目前並未普及,另外在其他應用場景,例如 macOS、iOS、Windows 等用戶介面目前並不存在這個特性,所以請繼續保持隨手加空格的習慣。 - -## 標點符號 - -### 不重複使用標點符號 - -即使中國大陸的標點符號用法允許重複使用標點符號,但是這麼做會破壞句子的美觀性。 - -正確: - -> 德國隊竟然戰勝了巴西隊! - -> 她竟然對你說「喵」?! - -錯誤: - -> 德國隊竟然戰勝了巴西隊!! - -> 德國隊竟然戰勝了巴西隊!!!!!!!! - -> 她竟然對你說「喵」??!! - -> 她竟然對你說「喵」?!?!??!! - -## 全形和半形 - -不明白什麼是全形(全角)與半形(半角)符號?請查看維基百科條目『[全形和半形](https://zh.wikipedia.org/wiki/%E5%85%A8%E5%BD%A2%E5%92%8C%E5%8D%8A%E5%BD%A2)』。 - -### 使用全形中文標點 - -正確: - -> 嗨!你知道嘛?今天前台的小妹跟我說「喵」了哎! - -> 核磁共振成像(NMRI)是什麼原理都不知道?JFGI! - -錯誤: - -> 嗨! 你知道嘛? 今天前台的小妹跟我說 "喵" 了哎! - -> 嗨!你知道嘛?今天前台的小妹跟我說"喵"了哎! - -> 核磁共振成像 (NMRI) 是什麼原理都不知道? JFGI! - -> 核磁共振成像(NMRI)是什麼原理都不知道?JFGI! - -### 數字使用半形字符 - -正確: - -> 這件蛋糕只賣 1000 元。 - -錯誤: - -> 這件蛋糕只賣 1000 元。 - -例外:在設計稿、宣傳海報中如出現極少量數字的情形時,為方便文字對齊,是可以使用全形數字的。 - -### 遇到完整的英文整句、特殊名詞,其內容使用半形標點 - -正確: - -> 賈伯斯那句話是怎麼說的?「Stay hungry, stay foolish.」 - -> 推薦你閱讀《Hackers & Painters: Big Ideas from the Computer Age》,非常的有趣。 - -錯誤: - -> 賈伯斯那句話是怎麼說的?「Stay hungry,stay foolish。」 - -> 推薦你閱讀《Hackers&Painters:Big Ideas from the Computer Age》,非常的有趣。 - -## 名詞 - -### 專有名詞使用正確的大小寫 - -大小寫相關用法原屬於英文書寫範疇,不屬於本 wiki 討論內容,在這裡只對部分易錯用法進行簡述。 - -正確: - -> 使用 GitHub 登錄 - -> 我們的客戶有 GitHub、Foursquare、Microsoft Corporation、Google、Facebook, Inc.。 - -錯誤: - -> 使用 github 登錄 - -> 使用 GITHUB 登錄 - -> 使用 Github 登錄 - -> 使用 gitHub 登錄 - -> 使用 gイんĤЦ8 登錄 - -> 我們的客戶有 github、foursquare、microsoft corporation、google、facebook, inc.。 - -> 我們的客戶有 GITHUB、FOURSQUARE、MICROSOFT CORPORATION、GOOGLE、FACEBOOK, INC.。 - -> 我們的客戶有 Github、FourSquare、MicroSoft Corporation、Google、FaceBook, Inc.。 - -> 我們的客戶有 gitHub、fourSquare、microSoft Corporation、google、faceBook, Inc.。 - -> 我們的客戶有 gイんĤЦ8、キouЯƧquムгє、๓เςг๏ร๏Ŧt ς๏гק๏гคtเ๏ภn、900913、ƒ4ᄃëв๏๏к, IПᄃ.。 - -注意:當網頁中需要配合整體視覺風格而出現全部大寫/小寫的情形,HTML 中請使用標準的大小寫規範進行書寫;並通過 `text-transform: uppercase;`/`text-transform: lowercase;` 對表現形式進行定義。 - -### 不要使用不道地的縮寫 - -正確: - -> 我們需要一位熟悉 TypeScript、HTML5,至少理解一種框架(如 React、Next.js)的前端開發者。 - -錯誤: - -> 我們需要一位熟悉 Ts、h5,至少理解一種框架(如 RJS、nextjs)的 FED。 - -## 爭議 - -以下用法略帶有個人色彩,即:無論是否遵循下述規則,從語法的角度來講都是**正確**的。 - -### 超連結之間增加空格 - -用法: - -> 請 [提交一個 issue](#) 並分配给相關同事。 - -> 訪問我們網站的最新動態,請 [點擊這裡](#) 進行訂閱! - -對比用法: - -> 請[提交一個 issue](#) 並分配给相關同事。 - -> 訪問我們網站的最新動態,請[點擊這裡](#)進行訂閱! - -### 簡體中文使用直角引號 - -用法: - -> 「老师,『有条不紊』的『紊』是什么意思?」 - -對比用法: - -> “老师,‘有条不紊’的‘紊’是什么意思?” diff --git a/docs/i18n/zh/docusaurus-plugin-content-docs/version-1.4.2/community/developer.md b/docs/i18n/zh/docusaurus-plugin-content-docs/version-1.4.2/community/developer.md deleted file mode 100644 index 89b57b88..00000000 --- a/docs/i18n/zh/docusaurus-plugin-content-docs/version-1.4.2/community/developer.md +++ /dev/null @@ -1,89 +0,0 @@ ---- -sidebar_position: 2 ---- - -# 核心开发者 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
姓名GitHub ID博客地址联系方式
马称magegoofy小马哥的技术专栏machen@apache.org
陆宽shining-stars-lk宽仔的代码之路1031900093@qq.com
王杰iwangjie-wangchenmo1025@gmail.com
魏虎weihubeatsweihubeatsweihubeats@163.com
李剑鑫BigXin0109Only丶Big1064730540@qq.com
刘文浩pizihaopizihaohao3073liu@163.com
叶炜shanjianq-17855368071@163.com
黄成兴CreatesequenceCreatesequence's Blog841396397@qq.com
- -## 成为核心开发者 - -持续对 Hippo-4J 进行贡献, 粗略评估,完成 10 次 PR 贡献即可成为核心开发者。 其中包括完成 2 个 [good pro issue](https://github.com/opengoofy/hippo4j/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+pro+issue%22) 或以上,以及若干个 [good first issue](https://github.com/opengoofy/hippo4j/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22)。 - -:::note -会根据 PR 质量提供个性化评估,有可能一个或两个质量较高 PR 即可成为核心开发者。参考:[重构 DynamicThreadPoolExecutor 功能扩展逻辑](https://github.com/opengoofy/hippo4j/pull/854) -::: - -成为核心开发者后,会为该 GitHub 账号获取 Jetbrains 全家桶 Licenses,有效期为 1 年。不用再为破解而烦恼,感受随时升级的快乐。 - -:::note -距离到期两周前,会再次申请 Jetbrains Licenses。有点类似于无限续约的感觉,在此感谢 Jetbrains 公司对开源的支持。 -::: - -截至 `2022-10-30` 当天,已为登记的 7 位核心开发者成功申请 Licenses。 - -![](https://images-machen.oss-cn-beijing.aliyuncs.com/image-20221030134303060.png) diff --git a/docs/i18n/zh/docusaurus-plugin-content-docs/version-1.4.3/user_docs/dev_manual/_category_.json b/docs/i18n/zh/docusaurus-plugin-content-docs/version-1.4.3/user_docs/dev_manual/_category_.json new file mode 100644 index 00000000..11f12432 --- /dev/null +++ b/docs/i18n/zh/docusaurus-plugin-content-docs/version-1.4.3/user_docs/dev_manual/_category_.json @@ -0,0 +1,8 @@ +{ + "label": "开发者手册", + "position": 5, + "link": { + "type": "generated-index", + "description": "Hippo4J 留给使用者能够扩展的知识点。" + } +} diff --git a/docs/i18n/zh/docusaurus-plugin-content-docs/version-1.4.3/user_docs/dev_manual/rejected-policy-custom.md b/docs/i18n/zh/docusaurus-plugin-content-docs/version-1.4.3/user_docs/dev_manual/rejected-policy-custom.md new file mode 100644 index 00000000..1f2cf694 --- /dev/null +++ b/docs/i18n/zh/docusaurus-plugin-content-docs/version-1.4.3/user_docs/dev_manual/rejected-policy-custom.md @@ -0,0 +1,57 @@ +--- +sidebar_position: 1 +--- + +# 拒绝策略自定义 + +Hippo4J 通过 SPI 的方式对拒绝策略进行扩展,可以让用户在 Hippo4J 中完成自定义拒绝策略实现。 + +## Hippo4J Server 拒绝策略扩展 + +自定义拒绝策略,实现 `CustomRejectedExecutionHandler` 接口,示例如下: + +```java +public class ErrorLogRejectedExecutionHandler implements CustomRejectedExecutionHandler { + + @Override + public Integer getType() { + return 12; + } + + @Override + public RejectedExecutionHandler generateRejected() { + return new CustomErrorLogRejectedExecutionHandler(); + } + + public static class CustomErrorLogRejectedExecutionHandler implements RejectedExecutionHandler { + + @Override + public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) { + Logger logger = LoggerFactory.getLogger(this.getClass()); + logger.error("线程池抛出拒绝策略"); + } + } +} +``` + +创建 `src/main/resources/META-INF/services` 目录,创建 SPI 自定义拒绝策略文件 `cn.hippo4j.common.executor.support.CustomRejectedExecutionHandler`。 + +`cn.hippo4j.common.executor.support.CustomRejectedExecutionHandler` 文件内仅放一行自定义拒绝策略全限定名即可,示例: + +```text +cn.hippo4j.example.core.handler.ErrorLogRejectedExecutionHandler +``` + +创建、修改线程池页面选择 `CustomRejectedPolicy(自定义 SPI 策略)`。 + +![](https://images-machen.oss-cn-beijing.aliyuncs.com/image-20220813173907814.png) + +拒绝策略触发时,完成上述代码效果,仅打印异常日志提示。 + +```text +2022-08-01 21:27:49.515 ERROR 48928 --- [ateHandler.test] r$CustomErrorLogRejectedExecutionHandler : 线程池抛出拒绝策略 +``` + +:::note +具体参考 `hippo4j-example/hippo4j-spring-boot-starter-example` 模块。 +::: diff --git a/docs/i18n/zh/docusaurus-plugin-content-docs/version-1.4.3/user_docs/dev_manual/rejected-policy-info.md b/docs/i18n/zh/docusaurus-plugin-content-docs/version-1.4.3/user_docs/dev_manual/rejected-policy-info.md new file mode 100644 index 00000000..d5c68138 --- /dev/null +++ b/docs/i18n/zh/docusaurus-plugin-content-docs/version-1.4.3/user_docs/dev_manual/rejected-policy-info.md @@ -0,0 +1,50 @@ +--- +sidebar_position: 0 +--- + +# 内置拒绝策略 + +内置两种拒绝策略说明: + +**RunsOldestTaskPolicy**:添加新任务并由主线程运行最早的任务。 + +```java +public class RunsOldestTaskPolicy implements RejectedExecutionHandler { + + @Override + public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) { + if (executor.isShutdown()) { + return; + } + BlockingQueue workQueue = executor.getQueue(); + Runnable firstWork = workQueue.poll(); + boolean newTaskAdd = workQueue.offer(r); + if (firstWork != null) { + firstWork.run(); + } + if (!newTaskAdd) { + executor.execute(r); + } + } +} +``` + +**SyncPutQueuePolicy**:主线程把拒绝任务以阻塞的方式添加到队列。 + +```java +@Slf4j +public class SyncPutQueuePolicy implements RejectedExecutionHandler { + + @Override + public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) { + if (executor.isShutdown()) { + return; + } + try { + executor.getQueue().put(r); + } catch (InterruptedException e) { + log.error("Adding Queue task to thread pool failed.", e); + } + } +} +``` \ No newline at end of file diff --git a/docs/i18n/zh/docusaurus-plugin-content-docs/version-1.4.2/community/dev_convention/_category_.json b/docs/i18n/zh/docusaurus-plugin-content-docs/version-1.4.3/user_docs/getting_started/_category_.json similarity index 53% rename from docs/i18n/zh/docusaurus-plugin-content-docs/version-1.4.2/community/dev_convention/_category_.json rename to docs/i18n/zh/docusaurus-plugin-content-docs/version-1.4.3/user_docs/getting_started/_category_.json index cb875453..72b1e151 100644 --- a/docs/i18n/zh/docusaurus-plugin-content-docs/version-1.4.2/community/dev_convention/_category_.json +++ b/docs/i18n/zh/docusaurus-plugin-content-docs/version-1.4.3/user_docs/getting_started/_category_.json @@ -1,6 +1,6 @@ { - "label": "贡献规约", - "position": 2, + "label": "快速开始", + "position": 3, "link": { "type": "generated-index" } diff --git a/docs/i18n/zh/docusaurus-plugin-content-docs/version-1.4.3/user_docs/getting_started/config/_category_.json b/docs/i18n/zh/docusaurus-plugin-content-docs/version-1.4.3/user_docs/getting_started/config/_category_.json new file mode 100644 index 00000000..78b3d9c4 --- /dev/null +++ b/docs/i18n/zh/docusaurus-plugin-content-docs/version-1.4.3/user_docs/getting_started/config/_category_.json @@ -0,0 +1,5 @@ +{ + "label": "依赖配置中心", + "position": 2, + "collapsed": true +} diff --git a/docs/i18n/zh/docusaurus-plugin-content-docs/version-1.4.3/user_docs/getting_started/config/hippo4j-config-default.md b/docs/i18n/zh/docusaurus-plugin-content-docs/version-1.4.3/user_docs/getting_started/config/hippo4j-config-default.md new file mode 100644 index 00000000..9c9e0fc9 --- /dev/null +++ b/docs/i18n/zh/docusaurus-plugin-content-docs/version-1.4.3/user_docs/getting_started/config/hippo4j-config-default.md @@ -0,0 +1,45 @@ +--- +sidebar_position: 4 +--- + +# 参数默认配置 + +曾有多名小伙伴反馈说,项目中线程池一多,配置文件中配置就显得很臃肿。为此 hippo4j-config 开发出了动态线程池默认配置。 + +```yaml +spring: + dynamic: + thread-pool: + default-executor: + core-pool-size: 4 + maximum-pool-size: 6 + blocking-queue: ResizableCapacityLinkedBlockingQueue + queue-capacity: 1024 + execute-time-out: 1000 + keep-alive-time: 9999 + rejected-handler: AbortPolicy + active-alarm: 90 + capacity-alarm: 85 + alarm: true + allow-core-thread-time-out: true + notify: + interval: 5 + receives: chen.ma + executors: + - thread-pool-id: message-produce + - thread-pool-id: message-consume + core-pool-size: 80 + maximum-pool-size: 100 + execute-time-out: 1000 + notify: + interval: 6 + receives: chen.ma +``` + +`spring.dynamic.thread-pool.executors` 层级下,仅需要配置 `thread-pool-id`,其余配置从 `spring.dynamic.thread-pool.default-executor` 读取。 + +如果 `spring.dynamic.thread-pool.executors` 下配置和 `spring.dynamic.thread-pool.default-executor` 冲突,以前者为主。 + +通过该自定义配置方式,可减少大量重复线程池参数配置项,提高核心配置简洁度。 + +提示:`spring.dynamic.thread-pool.default-executor` 层级下参数,不提供动态刷新功能。 diff --git a/docs/i18n/zh/docusaurus-plugin-content-docs/version-1.4.3/user_docs/getting_started/config/hippo4j-config-monitor.md b/docs/i18n/zh/docusaurus-plugin-content-docs/version-1.4.3/user_docs/getting_started/config/hippo4j-config-monitor.md new file mode 100644 index 00000000..c030dc10 --- /dev/null +++ b/docs/i18n/zh/docusaurus-plugin-content-docs/version-1.4.3/user_docs/getting_started/config/hippo4j-config-monitor.md @@ -0,0 +1,122 @@ +--- +sidebar_position: 3 +--- + +# 线程池监控 + +## 线程池监控配置 + +监控前置条件:需要先完成 hippo4j-config 的 [接入工作](/docs/user_docs/getting_started/config/hippo4j-config-start)。 + +接下来引入 SpringBoot Actuator。Spring 2.x 一般都有版本指定,所以这里不用写版本号。 + +```xml + + io.micrometer + micrometer-registry-prometheus + + + + org.springframework.boot + spring-boot-starter-actuator + +``` + +添加动态线程池监控相关配置: + +```yaml +management: + metrics: + export: + prometheus: + enabled: true + server: + port: 29999 # 可选配置,如果不配置该 port,直接使用 ${server.port} + endpoints: + web: + exposure: + include: '*' # 测试使用,开启了所有端点,生产环境不建议 * +spring: + dynamic: + thread-pool: + monitor: + enable: true # 是否开启采集线程池运行时数据 + collect-interval: 5000 # 采集线程池运行数据频率 + collect-types: micrometer # 采集线程池运行数据的类型。eg:log、micrometer。多个可以同时使用,默认 micrometer + initial-delay: 10000 # 项目启动后延迟多久进行采集 + thread-pool-types: dynamic # 采集线程池的类型。eg:dynamic、web、adapter。可任意配置,默认 dynamic +``` + +项目启动,访问 `http://localhost:29999/actuator/prometheus` 出现 `dynamic_thread_pool_` 前缀的指标,即为成功。 + +![](https://images-machen.oss-cn-beijing.aliyuncs.com/image-20220912220401016.png) + +## 配置 Prometheus + +通过 Docker 启动 Prometheus 服务。 + +```shell +docker run -d -p 9090:9090 --name prometheus prom/prometheus +``` + +添加 Prometheus 抽取数据任务。 + +```shell +# 进入 prometheus 容器内部 +docker exec -it prometheus /bin/sh +# 编辑 prometheus 配置文件 +vi /etc/prometheus/prometheus.yml +``` + +scrape_configs 节点下新添加一个 job,如果 Prometheus 是 Docker 方式部署,`{scrape_configs.static_configs.targets}` 需要写本机的 IP。 + +```yaml +scrape_configs: + - job_name: 'dynamic-thread-pool-job' + scrape_interval: 5s + metrics_path: '/actuator/prometheus' + static_configs: + - targets: [ '127.0.0.1:29999' ] +``` + +配置成功后 `exit` 退出容器,并进行 Prometheus 容器重启 `docker restart prometheus`。 + +访问 Prometheus 控制台 `http://localhost:9090/graph` 路径,能够展示相关指标即为配置成功。 + +![](https://images-machen.oss-cn-beijing.aliyuncs.com/image-20220912221237597.png) + +## 配置 Grafana + +```shell +docker run -d -p 3000:3000 --name=grafana grafana/grafana +``` + +访问 Grafana 地址,[http://localhost:3000](http://localhost:3000) 用户名密码:`admin` + +Grafana 访问 `http://localhost:3000/datasources` 导入 Prometheus 数据源。 + +![](https://images-machen.oss-cn-beijing.aliyuncs.com/image-20220912221646866.png) + +> 如果 Prometheus 为 Docker 方式部署,HTTP URL 需要为本地 IP,比如:http://192.168.1.5:9090 + +关注公众号 `龙台的技术笔记`,回复:`监控`,获取 Hippo4J Grafana DashBoard JSON 配置。 + +| 公众号 | 回复关键词 | +|:------------------------------------------------------------------------------------------------------------:|:-------------------------------------------------------------------------------------------------------------------------:| +| ![](https://images-machen.oss-cn-beijing.aliyuncs.com/43_65f6020ed111b6bb3808ec338576bd6b.png?x-oss-process=image/resize,h_300,w_400) | ![](https://images-machen.oss-cn-beijing.aliyuncs.com/image-20220327171957444.png?x-oss-process=image/resize,h_300,w_400) | + +获取到 JSON 文件后,通过 `http://localhost:3000/dashboard/import` 将 JSON 文件导入至 Grafana DashBoard。 + +![](https://images-machen.oss-cn-beijing.aliyuncs.com/image-20220912225627272.png) + +下拉框内动态选择创建好的 Prometheus 数据源,并点击 `Import`。 + +![](https://images-machen.oss-cn-beijing.aliyuncs.com/image-20220912225700200.png) + +即可使用炫酷的 Hippo-4J 动态线程池监控 DashBoard。大家伙儿也可以根据个人喜好进行定制 DashBoard,如果觉得有优化点,欢迎和我联系贡献。 + +![](https://images-machen.oss-cn-beijing.aliyuncs.com/image-20220912225813972.png) + +如果项目客户端启动多个示例,动态线程池监控效果图如下: + +![](https://images-machen.oss-cn-beijing.aliyuncs.com/20220814_hippo4j_monitor.jpg) diff --git a/docs/i18n/zh/docusaurus-plugin-content-docs/version-1.4.3/user_docs/getting_started/config/hippo4j-config-more.md b/docs/i18n/zh/docusaurus-plugin-content-docs/version-1.4.3/user_docs/getting_started/config/hippo4j-config-more.md new file mode 100644 index 00000000..2511b4f3 --- /dev/null +++ b/docs/i18n/zh/docusaurus-plugin-content-docs/version-1.4.3/user_docs/getting_started/config/hippo4j-config-more.md @@ -0,0 +1,80 @@ +--- +sidebar_position: 3 +--- + +# 个性化配置 + +以下所述特性自 hippo4j-config v1.4.2 及以上版本提供,由 hippo4j 核心开发者 [@pizihao](https://github.com/pizihao) 完成相应功能开发。 + +## 需求背景 + +**1)容器及三方框架线程池自定义启用** + +最初设计容器线程池和三方框架线程池的动态变更是和启动无关的。也就是说,启动时不会根据配置文件中相关参数去修改两者对应的线程池配置。 + +这么设计的初衷是因为,不想让 hippo4j 过多的去介入框架原有的功能。因为容器和三方框架都支持线程池参数的自定义。 + +也就造成,可能你在配置中心配置了对应的容器和三方框架线程池参数,启动时是无效的。但当修改配置文件任一配置,容器和三方框架线程池配置将生效。 + +为了更好的用户体验,决定加入启用标识来控制:是否在项目初始化启动时,对容器和三方框架线程池参数进行修改。 + +**2)客户端集群个性化配置** + +大家都知道,hippo4j-config 是依赖配置中心做线程池配置动态变更。这种模式有一种缺点:改动配置文件后,所有客户端都会变更。 + +有些小伙伴希望 hippo4j-config 能够像 hippo4j-server 一样,能够针对单独的客户端进行配置变更。 + +## 容器及三方框架线程池自定义启用 + +容器及三方框架线程池添加启用配置,为了保持统一,动态线程池配置中也有该参数配置。配置项默认开启。 + +```yaml +spring: + dynamic: + thread-pool: + tomcat: + enable: true + executors: + - thread-pool-id: message-consume + enable: false + adapter-executors: + - threadPoolKey: 'input' + enable: true +``` + +## 客户端集群个性化配置 + +分别在动态线程池、容器线程池以及三方框架线程池配置下增加 `nodes` 配置节点,通过该配置可匹配需要变更的节点。 + +```yaml +spring: + dynamic: + thread-pool: + tomcat: + nodes: 192.168.1.5:*,192.168.1.6:8080 + executors: + - thread-pool-id: message-consume + nodes: 192.168.1.5:* + adapter-executors: + - threadPoolKey: 'input' + nodes: 192.168.1.5:* +``` + +来一段代码方法中的注释,大家就基本明白如何使用了。 + +```java +/** + * Matching nodes
+ * nodes is ip + port.Get 'nodes' in the new Properties,Compare this with the ip + port of Application.
+ * support prefix pattern matching. e.g:
+ *
    + *
  • 192.168.1.5:* -- Matches all ports of 192.168.1.5
  • + *
  • 192.168.1.*:2009 -- Matches 2009 port of 192.168.1.*
  • + *
  • * -- all
  • + *
  • empty -- all
  • + *
+ * The format of ip + port is ip : port. + */ +``` + +`nodes` 可与 `enable` 同时使用。如此,基于配置中心的动态线程池实现方式,将能够更方便的支持个性化需求。 diff --git a/docs/i18n/zh/docusaurus-plugin-content-docs/version-1.4.3/user_docs/getting_started/config/hippo4j-config-springboot1x-adapter.md b/docs/i18n/zh/docusaurus-plugin-content-docs/version-1.4.3/user_docs/getting_started/config/hippo4j-config-springboot1x-adapter.md new file mode 100644 index 00000000..46311923 --- /dev/null +++ b/docs/i18n/zh/docusaurus-plugin-content-docs/version-1.4.3/user_docs/getting_started/config/hippo4j-config-springboot1x-adapter.md @@ -0,0 +1,121 @@ +--- +sidebar_position: 5 +--- + +# 适配SpringBoot1x + +目前已支持 Nacos、Apollo 配置中心适配 SpringBoot 1.5.x 版本。 + +```xml + + cn.hippo4j + hippo4j-config-spring-boot-1x-starter + 1.4.3 + +``` + +Nacos SpringBoot 配置如下: + +```yaml +spring: + cloud: + nacos: + config: + ext-config: + - data-id: hippo4j-nacos.yaml + group: DEFAULT_GROUP + refresh: true + server-addr: 127.0.0.1:8848 + dynamic: + thread-pool: + config-file-type: yml + nacos: + data-id: hippo4j-nacos.yaml + group: DEFAULT_GROUP +``` + +Apollo SpringBoot 配置如下: + +```yaml +apollo: + autoUpdateInjectedSpringProperties: true + bootstrap: + eagerLoad: + enabled: true + enabled: true + namespaces: application + meta: http://127.0.0.1:8080 +app: + id: dynamic-threadpool-example +spring: + dynamic: + thread-pool: + apollo: + namespace: application +``` + +动态线程池通用配置如下: + +```yaml +management: + context-path: /actuator + security: + enabled: false +server: + port: 8091 + servlet: + context-path: /example +spring: + application: + name: dynamic-threadpool-example + dynamic: + thread-pool: + banner: true + check-state-interval: 5 + collect-type: micrometer + config-file-type: properties + enable: true + executors: + - active-alarm: 80 + alarm: true + allow-core-thread-time-out: true + blocking-queue: LinkedBlockingQueue + capacity-alarm: 80 + core-pool-size: 1 + execute-time-out: 1000 + keep-alive-time: 6691 + maximum-pool-size: 1 + notify: + interval: 8 + receives: chen.ma + queue-capacity: 1 + rejected-handler: AbortPolicy + thread-name-prefix: message-consume + thread-pool-id: message-consume + - active-alarm: 80 + alarm: true + allow-core-thread-time-out: true + blocking-queue: LinkedBlockingQueue + capacity-alarm: 80 + core-pool-size: 1 + execute-time-out: 1000 + keep-alive-time: 6691 + maximum-pool-size: 1 + notify: + interval: 8 + receives: chen.ma + queue-capacity: 1 + rejected-handler: AbortPolicy + thread-name-prefix: message-produce + thread-pool-id: message-produce + notify-platforms: + - platform: WECHAT + token: ac0426a5-c712-474c-9bff-72b8b8f5caff + profiles: + active: dev +``` + +具体 Demo 运行请参考以下示例模块,已验证对应线程池动态变更、报警以及运行时监控功能。 + +- `/hippo4j-config-nacos-spring-boot-1x-starter-example` +- `hippo4j-example/hippo4j-config-apollo-spring-boot-1x-starter-example` diff --git a/docs/i18n/zh/docusaurus-plugin-content-docs/version-1.4.3/user_docs/getting_started/config/hippo4j-config-start.md b/docs/i18n/zh/docusaurus-plugin-content-docs/version-1.4.3/user_docs/getting_started/config/hippo4j-config-start.md new file mode 100644 index 00000000..6a326717 --- /dev/null +++ b/docs/i18n/zh/docusaurus-plugin-content-docs/version-1.4.3/user_docs/getting_started/config/hippo4j-config-start.md @@ -0,0 +1,193 @@ +--- +sidebar_position: 1 +--- + +# 接入流程 + +Nacos、Apollo、Zookeeper、ETCD、Polaris 配置中心任选其一。 + +## hippo4j 配置 + +```xml + + cn.hippo4j + hippo4j-config-spring-boot-starter + 1.4.3 + +``` + +启动类上添加注解 `@EnableDynamicThreadPool`。 + +```java +@SpringBootApplication +@EnableDynamicThreadPool +public class ExampleApplication { + public static void main(String[] args) { + SpringApplication.run(ExampleApplication.class, args); + } +} +``` + +SpringBoot 应用配置文件添加: + +```yaml +server: + port: 8090 + servlet: + context-path: /example + +spring: + profiles: + active: dev + + dynamic: + thread-pool: + # 是否开启动态线程池 + enable: true + # 是否打印 banner + banner: true + # 是否开启线程池数据采集,对接 Micrometer、ES、Log 等 + collect: true + # 检查线程池状态,是否达到报警条件,单位毫秒 + check-state-interval: 3000 + # 通知报警平台,请替换为自己创建的群机器人 + notify-platforms: + - platform: 'WECHAT' + token: xxx + - platform: 'DING' + token: xxx + secret: xxx # 加签专属 + - platform: 'LARK' + token: xxx + # Nacos、Apollo、Zookeeper、ETCD、Polaris 任选其一 + nacos: + data-id: xxx + group: xxx + apollo: + namespace: xxxx + # 配置中心文件格式 + config-file-type: yml + # tomcat、undertow、jetty 三种容器线程池,任选其一 + undertow: + core-pool-size: 100 + maximum-pool-size: 200 + keep-alive-time: 1000 + # 全局通知配置-是否报警 + alarm: true + # 活跃度报警阈值;假设线程池最大线程数 10,当线程数达到 8 发起报警 + active-alarm: 80 + # 容量报警阈值;假设阻塞队列容量 100,当容量达到 80 发起报警 + capacity-alarm: 80 + # 报警间隔,同一线程池下同一报警纬度,在 interval 时间内只会报警一次,单位秒 + alarm-interval: 8 + # 企业微信填写用户 ID(填写其它将无法达到 @ 效果)、钉钉填手机号、飞书填 ou_ 开头唯一 ID + receives: xxx + # 动态线程池列表 + executors: + - thread-pool-id: 'message-consume' + # 核心线程数 + core-pool-size: 1 + # 最大线程数 + maximum-pool-size: 1 + # 阻塞队列名称,参考 BlockingQueueTypeEnum,支持 SPI + blocking-queue: 'LinkedBlockingQueue' + # 阻塞队列大小 + queue-capacity: 1 + # 执行超时时间,超过此时间发起报警,单位毫秒 + execute-time-out: 1000 + # 拒绝策略名称,参考 RejectedPolicyTypeEnum,支持 SPI + rejected-handler: 'AbortPolicy' + # 线程存活时间,单位秒 + keep-alive-time: 1024 + # 是否允许核心线程超时 + allow-core-thread-time-out: true + # 线程工厂名称前缀 + thread-name-prefix: 'message-consume' + # 是否报警 + alarm: true + # 活跃度报警阈值;假设线程池最大线程数 10,当线程数达到 8 发起报警 + active-alarm: 80 + # 容量报警阈值;假设阻塞队列容量 100,当容量达到 80 发起报警 + capacity-alarm: 80 + # 通知配置,线程池中通知配置如果存在,则会覆盖全局通知配置 + notify: + # 报警间隔,同一线程池下同一报警纬度,在 interval 时间内只会报警一次,单位分钟 + interval: 8 + # 企业微信填写用户 ID(填写其它将无法达到 @ 效果)、钉钉填手机号、飞书填 ou_ 开头唯一 ID + receives: xxx + - thread-pool-id: 'message-produce' + core-pool-size: 1 + maximum-pool-size: 1 + queue-capacity: 1 + execute-time-out: 1000 + blocking-queue: 'LinkedBlockingQueue' + rejected-handler: 'AbortPolicy' + keep-alive-time: 1024 + allow-core-thread-time-out: true + thread-name-prefix: 'message-consume' + alarm: true + active-alarm: 80 + capacity-alarm: 80 + notify: + interval: 8 + receives: xxx +``` + +## ThreadPoolExecutor 适配 + +添加线程池配置类,通过 `@DynamicThreadPool` 注解修饰。`threadPoolId` 为服务端创建的线程池 ID。 + +```java +package cn.hippo4j.example; + +import cn.hippo4j.core.executor.DynamicThreadPool; +import cn.hippo4j.core.executor.support.ThreadPoolBuilder; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import java.util.concurrent.ThreadPoolExecutor; + +@Configuration +public class ThreadPoolConfig { + + @Bean + @DynamicThreadPool + public ThreadPoolExecutor messageConsumeDynamicExecutor() { + String threadPoolId = "message-consume"; + ThreadPoolExecutor messageConsumeDynamicExecutor = ThreadPoolBuilder.builder() + .threadFactory(threadPoolId) + .threadPoolId(threadPoolId) + .dynamicPool() + .build(); + return messageConsumeDynamicExecutor; + } + + @Bean + @DynamicThreadPool + public ThreadPoolExecutor messageProduceDynamicExecutor() { + String threadPoolId = "message-produce"; + ThreadPoolExecutor messageProduceDynamicExecutor = ThreadPoolBuilder.builder() + .threadFactory(threadPoolId) + .threadPoolId(threadPoolId) + .dynamicPool() + .build(); + return messageProduceDynamicExecutor; + } + +} +``` + +通过 ThreadPoolBuilder 构建动态线程池,只有 threadFactory、threadPoolId 为必填项,其它参数会从配置中心拉取。 + +项目中使用上述定义的动态线程池,如下所示: + +```java +@Resource +private ThreadPoolExecutor messageConsumeDynamicExecutor; + +messageConsumeDynamicExecutor.execute(() -> xxx); + +@Resource +private ThreadPoolExecutor messageProduceDynamicExecutor; + +messageProduceDynamicExecutor.execute(() -> xxx); +``` diff --git a/docs/i18n/zh/docusaurus-plugin-content-docs/version-1.4.3/user_docs/getting_started/difference.md b/docs/i18n/zh/docusaurus-plugin-content-docs/version-1.4.3/user_docs/getting_started/difference.md new file mode 100644 index 00000000..4e07d71b --- /dev/null +++ b/docs/i18n/zh/docusaurus-plugin-content-docs/version-1.4.3/user_docs/getting_started/difference.md @@ -0,0 +1,37 @@ +--- +sidebar_position: 0 +--- + +# 运行模式介绍 + +1.1.0 版本发布后,Hippo-4J 分为两种使用模式:轻量级依赖配置中心以及无中间件依赖版本。 + +![](https://images-machen.oss-cn-beijing.aliyuncs.com/image-20220319154626314.png) + +### hippo4j-config + +**轻量级动态线程池管理**,依赖 Nacos、Apollo、Zookeeper、ETCD、Polaris 等三方配置中心(任选其一)完成线程池参数动态变更,支持运行时报警、监控等功能。 + +> 监控功能配置详见:[线程池监控](/docs/user_docs/getting_started/config/hippo4j-config-monitor) + +![](https://images-machen.oss-cn-beijing.aliyuncs.com/20220814_hippo4j_monitor.jpg) + +### hippo4j-server + +**部署 hippo4j-server 服务**,通过可视化 Web 界面完成线程池的创建、变更以及查看,不依赖三方中间件。 + +相比较 hippo4j-config,功能会更强大,但同时也引入了一定的复杂性。需要部署一个 Java 服务,以及依赖 MySQL 数据库。 + +![](https://images-machen.oss-cn-beijing.aliyuncs.com/1644032018254-min.gif) + +### 使用总结 + +| | hippo4j-config | hippo4j-server | +| ---- | ---------------------------------------------------- | ------------------------------------------------------------ | +| 依赖 | Nacos、Apollo、Zookeeper、ETCD、Polaris 配置中心(任选其一) | 部署 Hippo-4J Server(内部无依赖中间件) | +| 使用 | 配置中心补充线程池相关参数 | Hippo-4J Server Web 控制台添加线程池记录 | +| 功能 | 包含基础功能:参数动态化、运行时监控、报警等 | 基础功能之外扩展控制台界面、线程池堆栈查看、线程池运行信息实时查看、历史运行信息查看、线程池配置集群个性化等 | + +使用建议:根据公司情况选择,如果基本功能可以满足使用,选择 hippo4j-config 使用即可;如果希望更多的功能,可以选择 hippo4j-server。 + +**两者在进行替换的时候,无需修改业务代码**。 diff --git a/docs/i18n/zh/docusaurus-plugin-content-docs/version-1.4.3/user_docs/getting_started/hippo4j-adapter.md b/docs/i18n/zh/docusaurus-plugin-content-docs/version-1.4.3/user_docs/getting_started/hippo4j-adapter.md new file mode 100644 index 00000000..e879fe75 --- /dev/null +++ b/docs/i18n/zh/docusaurus-plugin-content-docs/version-1.4.3/user_docs/getting_started/hippo4j-adapter.md @@ -0,0 +1,72 @@ +--- +sidebar_position: 6 +--- + +# 三方框架线程池适配 + +Hippo4J 目前已支持的三方框架线程池列表: + +- Dubbo +- Hystrix +- RabbitMQ +- RocketMQ +- AlibabaDubbo +- RocketMQSpringCloudStream +- RabbitMQSpringCloudStream + +引入 Hippo4J Server 或 Core 的 Maven Jar 坐标后,还需要引入对应的框架适配 Jar: + +```xml + + cn.hippo4j + + hippo4j-spring-boot-starter-adapter-dubbo + + hippo4j-spring-boot-starter-adapter-alibaba-dubbo + + hippo4j-spring-boot-starter-adapter-hystrix + + hippo4j-spring-boot-starter-adapter-rabbitmq + + hippo4j-spring-boot-starter-adapter-rocketmq + + hippo4j-spring-boot-starter-adapter-spring-cloud-stream-rocketmq + + hippo4j-spring-boot-starter-adapter-spring-cloud-stream-rabbitmq + 1.4.3 + +``` + +如果想省事,仅需引入一个全量包,框架底层会根据条件判断加载具体线程池适配器。 + +```xml + + cn.hippo4j + hippo4j-spring-boot-starter-adapter-all + 1.4.3 + +``` + +## Hippo4J Server + +Hippo4J Server 仅需要引入上述 Jar 包,即可在 Hippo4J Server 的控制台进行查看及修改三方框架线程池。 + +![](https://images-machen.oss-cn-beijing.aliyuncs.com/image-20220531194810047.png) + +## Hippo4J Config + +Hippo4J Config 除了依赖上述适配 Jar 包外,还需要在配置中心添加以下配置项。 + +```yaml +spring: + dynamic: + thread-pool: + # 省略其它配置 + adapter-executors: + # threadPoolKey 代表线程池标识 + - threadPoolKey: 'input' + # mark 为三方线程池框架类型,参见文初已支持框架集合 + mark: 'RocketMQSpringCloudStream' + corePoolSize: 10 + maximumPoolSize: 10 +``` diff --git a/docs/i18n/zh/docusaurus-plugin-content-docs/version-1.4.3/user_docs/getting_started/img/docsVersionDropdown.png b/docs/i18n/zh/docusaurus-plugin-content-docs/version-1.4.3/user_docs/getting_started/img/docsVersionDropdown.png new file mode 100644 index 00000000..97e41646 Binary files /dev/null and b/docs/i18n/zh/docusaurus-plugin-content-docs/version-1.4.3/user_docs/getting_started/img/docsVersionDropdown.png differ diff --git a/docs/i18n/zh/docusaurus-plugin-content-docs/version-1.4.3/user_docs/getting_started/img/grafana-monitor.jpg b/docs/i18n/zh/docusaurus-plugin-content-docs/version-1.4.3/user_docs/getting_started/img/grafana-monitor.jpg new file mode 100644 index 00000000..336bd980 Binary files /dev/null and b/docs/i18n/zh/docusaurus-plugin-content-docs/version-1.4.3/user_docs/getting_started/img/grafana-monitor.jpg differ diff --git a/docs/i18n/zh/docusaurus-plugin-content-docs/version-1.4.3/user_docs/getting_started/img/localeDropdown.png b/docs/i18n/zh/docusaurus-plugin-content-docs/version-1.4.3/user_docs/getting_started/img/localeDropdown.png new file mode 100644 index 00000000..e257edc1 Binary files /dev/null and b/docs/i18n/zh/docusaurus-plugin-content-docs/version-1.4.3/user_docs/getting_started/img/localeDropdown.png differ diff --git a/docs/i18n/zh/docusaurus-plugin-content-docs/version-1.4.3/user_docs/getting_started/server/_category_.json b/docs/i18n/zh/docusaurus-plugin-content-docs/version-1.4.3/user_docs/getting_started/server/_category_.json new file mode 100644 index 00000000..4063c17f --- /dev/null +++ b/docs/i18n/zh/docusaurus-plugin-content-docs/version-1.4.3/user_docs/getting_started/server/_category_.json @@ -0,0 +1,5 @@ +{ + "label": "无中间件依赖", + "position": 3, + "collapsed": true +} diff --git a/docs/i18n/zh/docusaurus-plugin-content-docs/version-1.4.3/user_docs/getting_started/server/hippo4j-server-config.md b/docs/i18n/zh/docusaurus-plugin-content-docs/version-1.4.3/user_docs/getting_started/server/hippo4j-server-config.md new file mode 100644 index 00000000..e1ef853f --- /dev/null +++ b/docs/i18n/zh/docusaurus-plugin-content-docs/version-1.4.3/user_docs/getting_started/server/hippo4j-server-config.md @@ -0,0 +1,19 @@ +--- +sidebar_position: 3 +--- + +# 服务端配置 + +`hippo4j.core.clean-history-data-enable` + +是否开启线程池历史数据清洗,默认开启。 + +`hippo4j.core.clean-history-data-period` + +线程池历史数据保留时间,默认值:30,单位分钟。 + +服务端会保留这个配置时间的数据,超过这个时间则会被清理。比如按照默认值 30 分钟来说,12:00 收集到的数据,12:30 就会被清理删除。 + +`hippo4j.core.monitor.report-type` + +客户端监控上报服务端类型,可选值:http、netty,默认 http。服务端开启 netty 配置后,需要在客户端对应开启才可生效。用来应对大量动态线程池监控场景。 diff --git a/docs/i18n/zh/docusaurus-plugin-content-docs/version-1.4.3/user_docs/getting_started/server/hippo4j-server-monitor.md b/docs/i18n/zh/docusaurus-plugin-content-docs/version-1.4.3/user_docs/getting_started/server/hippo4j-server-monitor.md new file mode 100644 index 00000000..b743c790 --- /dev/null +++ b/docs/i18n/zh/docusaurus-plugin-content-docs/version-1.4.3/user_docs/getting_started/server/hippo4j-server-monitor.md @@ -0,0 +1,122 @@ +--- +sidebar_position: 2 +--- + +# 线程池监控 + +Server 模式默认内置线程池运行时采集和监控功能,如果想要使用 Prometheus + Grafana 的方式可以查看以下内容。 + +## 线程池监控配置 + +接下来引入 SpringBoot Actuator。Spring 2.x 一般都有版本指定,所以这里不用写版本号。 + +```xml + + io.micrometer + micrometer-registry-prometheus + + + + org.springframework.boot + spring-boot-starter-actuator + +``` + +添加动态线程池监控相关配置: + +```yaml +management: + metrics: + export: + prometheus: + enabled: true + server: + port: 29999 # 可选配置,如果不配置该 port,直接使用 ${server.port} + endpoints: + web: + exposure: + include: '*' # 测试使用,开启了所有端点,生产环境不建议 * +spring: + dynamic: + thread-pool: + monitor: + enable: true # 是否开启采集线程池运行时数据 + collect-interval: 5000 # 采集线程池运行数据频率 + collect-types: server,micrometer # 采集线程池运行数据的类型。eg:server、micrometer。多个可以同时使用,默认 server + initial-delay: 10000 # 项目启动后延迟多久进行采集 + thread-pool-types: dynamic # 采集线程池的类型。eg:dynamic、web、adapter。可任意配置,默认 dynamic +``` + +项目启动,访问 `http://localhost:29999/actuator/prometheus` 出现 `dynamic_thread_pool_` 前缀的指标,即为成功。 + +![](https://images-machen.oss-cn-beijing.aliyuncs.com/image-20220912220401016.png) + +## 配置 Prometheus + +通过 Docker 启动 Prometheus 服务。 + +```shell +docker run -d -p 9090:9090 --name prometheus prom/prometheus +``` + +添加 Prometheus 抽取数据任务。 + +```shell +# 进入 prometheus 容器内部 +docker exec -it prometheus /bin/sh +# 编辑 prometheus 配置文件 +vi /etc/prometheus/prometheus.yml +``` + +scrape_configs 节点下新添加一个 job,如果 Prometheus 是 Docker 方式部署,`{scrape_configs.static_configs.targets}` 需要写本机的 IP。 + +```yaml +scrape_configs: + - job_name: 'dynamic-thread-pool-job' + scrape_interval: 5s + metrics_path: '/actuator/prometheus' + static_configs: + - targets: [ '127.0.0.1:29999' ] +``` + +配置成功后 `exit` 退出容器,并进行 Prometheus 容器重启 `docker restart prometheus`。 + +访问 Prometheus 控制台 `http://localhost:9090/graph` 路径,能够展示相关指标即为配置成功。 + +![](https://images-machen.oss-cn-beijing.aliyuncs.com/image-20220912221237597.png) + +## 配置 Grafana + +```shell +docker run -d -p 3000:3000 --name=grafana grafana/grafana +``` + +访问 Grafana 地址,[http://localhost:3000](http://localhost:3000) 用户名密码:`admin` + +Grafana 访问 `http://localhost:3000/datasources` 导入 Prometheus 数据源。 + +![](https://images-machen.oss-cn-beijing.aliyuncs.com/image-20220912221646866.png) + +> 如果 Prometheus 为 Docker 方式部署,HTTP URL 需要为本地 IP,比如:http://192.168.1.5:9090 + +关注公众号 `龙台的技术笔记`,回复:`监控`,获取 Hippo4J Grafana DashBoard JSON 配置。 + +| 公众号 | 回复关键词 | +|:------------------------------------------------------------------------------------------------------------:|:-------------------------------------------------------------------------------------------------------------------------:| +| ![](https://images-machen.oss-cn-beijing.aliyuncs.com/43_65f6020ed111b6bb3808ec338576bd6b.png?x-oss-process=image/resize,h_300,w_400) | ![](https://images-machen.oss-cn-beijing.aliyuncs.com/image-20220327171957444.png?x-oss-process=image/resize,h_300,w_400) | + +获取到 JSON 文件后,通过 `http://localhost:3000/dashboard/import` 将 JSON 文件导入至 Grafana DashBoard。 + +![](https://images-machen.oss-cn-beijing.aliyuncs.com/image-20220912225627272.png) + +下拉框内动态选择创建好的 Prometheus 数据源,并点击 `Import`。 + +![](https://images-machen.oss-cn-beijing.aliyuncs.com/image-20220912225700200.png) + +即可使用炫酷的 Hippo-4J 动态线程池监控 DashBoard。大家伙儿也可以根据个人喜好进行定制 DashBoard,如果觉得有优化点,欢迎和我联系贡献。 + +![](https://images-machen.oss-cn-beijing.aliyuncs.com/image-20220912225813972.png) + +如果项目客户端启动多个示例,动态线程池监控效果图如下: + +![](https://images-machen.oss-cn-beijing.aliyuncs.com/20220814_hippo4j_monitor.jpg) diff --git a/docs/i18n/zh/docusaurus-plugin-content-docs/version-1.4.3/user_docs/getting_started/server/hippo4j-server-start.md b/docs/i18n/zh/docusaurus-plugin-content-docs/version-1.4.3/user_docs/getting_started/server/hippo4j-server-start.md new file mode 100644 index 00000000..69957eb3 --- /dev/null +++ b/docs/i18n/zh/docusaurus-plugin-content-docs/version-1.4.3/user_docs/getting_started/server/hippo4j-server-start.md @@ -0,0 +1,127 @@ +--- +sidebar_position: 1 +--- + +# 接入流程 + +部署服务端,参考 [部署手册](/docs/user_docs/ops/hippo4j-server-deploy)。 + +服务端创建 [租户、项目](/docs/user_docs/other/issue#租户和项目在-hippo4j-中是什么意思) 和线程池记录。 + +需要注意,项目 ID 需要与配置文件 `{application.name}` 保持一致。 + +:::note +租户、项目、线程池 ID 如果由多个词组成,建议以 - 进行分割。比如:message-center。 +::: + +## Hippo4J 配置 + +SpringBoot Pom 引入 Hippo4j Starter Jar。 + +```xml + + cn.hippo4j + hippo4j-spring-boot-starter + 1.4.3 + +``` + +启动类上添加注解 `@EnableDynamicThreadPool`。 + +```java +@SpringBootApplication +@EnableDynamicThreadPool +public class ExampleApplication { + public static void main(String[] args) { + SpringApplication.run(ExampleApplication.class, args); + } +} +``` + +SpringBoot 应用配置文件添加: + +```yaml +spring: + profiles: + active: dev + application: + # 服务端创建的项目 id 需要与 application.name 保持一致 + name: dynamic-threadpool-example + dynamic: + thread-pool: + # 服务端地址 + server-addr: http://localhost:6691 + # 用户名 + username: admin + # 密码 + password: 123456 + # 租户 id, 对应 tenant 表 + namespace: prescription + # 项目 id, 对应 item 表 + item-id: ${spring.application.name} +``` + +## ThreadPoolExecutor 适配 + +添加线程池配置类,通过 `@DynamicThreadPool` 注解修饰。`threadPoolId` 为服务端创建的线程池 ID。 + +```java +package cn.hippo4j.example; + +import cn.hippo4j.core.executor.DynamicThreadPool; +import cn.hippo4j.core.executor.support.ThreadPoolBuilder; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import java.util.concurrent.ThreadPoolExecutor; + +@Configuration +public class ThreadPoolConfig { + + @Bean + @DynamicThreadPool + public ThreadPoolExecutor messageConsumeDynamicExecutor() { + String threadPoolId = "message-consume"; + ThreadPoolExecutor messageConsumeDynamicExecutor = ThreadPoolBuilder.builder() + .threadFactory(threadPoolId) + .threadPoolId(threadPoolId) + .dynamicPool() + .build(); + return messageConsumeDynamicExecutor; + } + + @Bean + @DynamicThreadPool + public ThreadPoolExecutor messageProduceDynamicExecutor() { + String threadPoolId = "message-produce"; + ThreadPoolExecutor messageProduceDynamicExecutor = ThreadPoolBuilder.builder() + .threadFactory(threadPoolId) + .threadPoolId(threadPoolId) + .dynamicPool() + .build(); + return messageProduceDynamicExecutor; + } + +} +``` + +通过 ThreadPoolBuilder 构建动态线程池,只有 threadFactory、threadPoolId 为必填项,其它参数会从 hippo4j-server 服务拉取。 + +:::note +创建线程池时建议填充实际的参数。如果在连接 Hippo4J Server 端失败时,会使用填充配置创建线程池。 +::: + +项目中使用上述定义的动态线程池,如下所示: + +```java +@Resource +private ThreadPoolExecutor messageConsumeDynamicExecutor; + +messageConsumeDynamicExecutor.execute(() -> xxx); + +@Resource +private ThreadPoolExecutor messageProduceDynamicExecutor; + +messageProduceDynamicExecutor.execute(() -> xxx); +``` + diff --git a/docs/docs/community/contributor.md b/docs/i18n/zh/docusaurus-plugin-content-docs/version-1.4.3/user_docs/intro.md similarity index 84% rename from docs/docs/community/contributor.md rename to docs/i18n/zh/docusaurus-plugin-content-docs/version-1.4.3/user_docs/intro.md index 5aa056a0..fd9e5dcb 100644 --- a/docs/docs/community/contributor.md +++ b/docs/i18n/zh/docusaurus-plugin-content-docs/version-1.4.3/user_docs/intro.md @@ -2,20 +2,65 @@ sidebar_position: 1 --- -# 贡献指南 +# 简介 -Git Commit Log 尽量使用英文。 +## 线程池痛点 -Pull Request 尽量保持单一,不同语义的代码贡献应拆分多个 Pull Request。 +线程池是一种基于池化思想管理线程的工具,使用线程池可以减少创建销毁线程的开销,避免线程过多导致系统资源耗尽。在高并发以及大批量的任务处理场景,线程池的使用是必不可少的。 -为了让您的 GitHub ID 显示在 Contributor 列表中,别忘了以下设置: +如果有在项目中实际使用线程池,相信你可能会遇到以下痛点: -```shell -git config --global user.name "username" -git config --global user.email "GitHub 账号邮箱" -``` +- 线程池随便定义,线程资源过多,造成服务器高负载。 -## 贡献者列表 +- 线程池参数不易评估,随着业务的并发提升,业务面临出现故障的风险。 +- 线程池任务执行时间超过平均执行周期,开发人员无法感知。 +- 线程池任务堆积,触发拒绝策略,影响既有业务正常运行。 +- 当业务出现超时、熔断等问题时,因为没有监控,无法确定是不是线程池引起。 +- 原生线程池不支持运行时变量的传递,比如 MDC 上下文遇到线程池就 GG。 +- 无法执行优雅关闭,当项目关闭时,大量正在运行的线程池任务被丢弃。 +- 线程池运行中,任务执行停止,怀疑发生死锁或执行耗时操作,但是无从下手。 + +## 什么是 Hippo-4J + +Hippo-4J 通过对 JDK 线程池增强,以及扩展三方框架底层线程池等功能,为业务系统提高线上运行保障能力。 + +提供以下功能支持: + +- 全局管控 - 管理应用线程池实例。 + +- 动态变更 - 应用运行时动态变更线程池参数,包括不限于:核心、最大线程数、阻塞队列容量、拒绝策略等。 +- 通知报警 - 内置四种报警通知策略,线程池活跃度、容量水位、拒绝策略以及任务执行时间超长。 +- 运行监控 - 实时查看线程池运行时数据,最近半小时线程池运行数据图表展示。 +- 功能扩展 - 支持线程池任务传递上下文;项目关闭时,支持等待线程池在指定时间内完成任务。 +- 多种模式 - 内置两种使用模式:[依赖配置中心](https://hippo4j.cn/docs/user_docs/getting_started/config/hippo4j-config-start) 和 [无中间件依赖](https://hippo4j.cn/docs/user_docs/getting_started/server/hippo4j-server-start)。 +- 容器管理 - Tomcat、Jetty、Undertow 容器线程池运行时查看和线程数变更。 +- 框架适配 - Dubbo、Hystrix、RabbitMQ、RocketMQ 等消费线程池运行时数据查看和线程数变更。 + +## 快速开始 + +对于本地演示目的,请参阅 [Quick start](https://hippo4j.cn/docs/user_docs/user_guide/quick-start) + +演示环境: [http://console.hippo4j.cn/index.html](http://console.hippo4j.cn/index.html) + +## 接入登记 + +更多接入的公司,欢迎在 [登记地址](https://github.com/opengoofy/hippo4j/issues/13) 登记,登记仅仅为了产品推广。 + +## 联系我 + +![](https://user-images.githubusercontent.com/77398366/185774220-c11951f9-e130-4d60-8204-afb5c51d4401.png) + +扫码添加微信,备注:hippo4j,邀您加入群聊。若图片加载不出来,访问 [官网站点](https://hippo4j.cn/docs/user_docs/other/group)。 + +## 友情链接 + +- [[ Sa-Token ]](https://github.com/dromara/sa-token):一个轻量级 java 权限认证框架,让鉴权变得简单、优雅! + +- [[ HertzBeat ]](https://github.com/dromara/hertzbeat):易用友好的云监控系统, 无需 Agent, 强大自定义监控能力。 +- [[ JavaGuide ]](https://github.com/Snailclimb/JavaGuide):一份涵盖大部分 Java 程序员所需要掌握的核心知识。 +- [[ toBeBetterJavaer ]](https://github.com/itwanger/toBeBetterJavaer):一份通俗易懂、风趣幽默的 Java 学习指南。 + +## 贡献者 感谢所有为项目作出贡献的开发者。如果有意贡献,参考 [good first issue](https://github.com/opengoofy/hippo4j/issues?q=is%3Aopen+is%3Aissue+label%3A%22good+first+issue%22)。 diff --git a/docs/versioned_docs/version-1.4.2/community/dev_convention/_category_.json b/docs/i18n/zh/docusaurus-plugin-content-docs/version-1.4.3/user_docs/ops/_category_.json similarity index 53% rename from docs/versioned_docs/version-1.4.2/community/dev_convention/_category_.json rename to docs/i18n/zh/docusaurus-plugin-content-docs/version-1.4.3/user_docs/ops/_category_.json index cb875453..d5b7d1e8 100644 --- a/docs/versioned_docs/version-1.4.2/community/dev_convention/_category_.json +++ b/docs/i18n/zh/docusaurus-plugin-content-docs/version-1.4.3/user_docs/ops/_category_.json @@ -1,6 +1,6 @@ { - "label": "贡献规约", - "position": 2, + "label": "运维指南", + "position": 4, "link": { "type": "generated-index" } diff --git a/docs/i18n/zh/docusaurus-plugin-content-docs/version-1.4.3/user_docs/ops/hippo4j-server-deploy.md b/docs/i18n/zh/docusaurus-plugin-content-docs/version-1.4.3/user_docs/ops/hippo4j-server-deploy.md new file mode 100644 index 00000000..f78457ba --- /dev/null +++ b/docs/i18n/zh/docusaurus-plugin-content-docs/version-1.4.3/user_docs/ops/hippo4j-server-deploy.md @@ -0,0 +1,45 @@ +--- +sidebar_position: 1 +--- + +# 源码包部署 + +[RELEASE](https://github.com/opengoofy/hippo4j/releases) 页面下载对应版本并进行解压。 + +## 初始化 + +修改数据库相关信息。 + +```txt +/conf/application.properties +``` + +如果是新运行 Hippo-4J,数据库执行下述 SQL 脚本即可。 + +```txt +/conf/hippo4j_manager.sql +``` + +如果是对已运行 Hippo-4J 升级,请查看 `/conf/sql-upgrade` 目录下,是否有目标版本对应的升级脚本。 + +## 直接运行 + +Mac Linux 启动执行。 + +```txt +sh ./bin/startup.sh +``` + +Windows 启动执行。 + +```txt +bin/startup.cmd +``` + +## 访问控制台 + +启动成功后,访问链接。用户名密码:admin 123456 + +```txt +localhost:6691/index.html +``` diff --git a/docs/i18n/zh/docusaurus-plugin-content-docs/version-1.4.3/user_docs/ops/server-docker.md b/docs/i18n/zh/docusaurus-plugin-content-docs/version-1.4.3/user_docs/ops/server-docker.md new file mode 100644 index 00000000..141c597a --- /dev/null +++ b/docs/i18n/zh/docusaurus-plugin-content-docs/version-1.4.3/user_docs/ops/server-docker.md @@ -0,0 +1,50 @@ +--- +sidebar_position: 2 +--- + +# Docker部署 + +## 镜像启动 + +Docker 镜像默认使用内置 H2 数据库,数据持久化到 Docker 容器存储卷中。 + +```shell +docker run -d -p 6691:6691 --name hippo4j-server hippo4j/hippo4j-server +``` + +或者,底层存储数据库切换为 MySQL。`DATASOURCE_HOST` 需要切换为本地 IP,不能使用 `127.0.0.1` 或 `localhost`。 + +```shell +docker run -d -p 6691:6691 --name hippo4j-server \ +-e DATASOURCE_MODE=mysql \ +-e DATASOURCE_HOST=xxx.xxx.xxx.xxx \ +-e DATASOURCE_PORT=3306 \ +-e DATASOURCE_DB=hippo4j_manager \ +-e DATASOURCE_USERNAME=root \ +-e DATASOURCE_PASSWORD=root \ +hippo4j/hippo4j-server +``` + +访问 Server 控制台,路径 `http://localhost:6691/index.html` ,默认用户名密码:admin / 123456 + +## 镜像构建 + +如果想要自定义镜像,可以通过以下命令快速构建 Hippo4J Server: + +方式一: + +```shell +# 进入到 hippo4j-server/hippo4j-bootstrap 工程路径下 +mvn clean package -Dskip.spotless.apply=true +# 默认打包是打包的 tag 是 latest +docker build -t hippo4j/hippo4j-server ../hippo4j-bootstrap +``` + +方式二: + +通过 `maven docker plugin` + +```shell +# 进入到 hippo4j-server 工程路径下 +mvn clean package -DskipTests -Dskip.spotless.apply=true docker:build +``` diff --git a/docs/i18n/zh/docusaurus-plugin-content-docs/version-1.4.2/community/_category_.json b/docs/i18n/zh/docusaurus-plugin-content-docs/version-1.4.3/user_docs/other/_category_.json similarity index 56% rename from docs/i18n/zh/docusaurus-plugin-content-docs/version-1.4.2/community/_category_.json rename to docs/i18n/zh/docusaurus-plugin-content-docs/version-1.4.3/user_docs/other/_category_.json index bcd256c9..a74d7432 100644 --- a/docs/i18n/zh/docusaurus-plugin-content-docs/version-1.4.2/community/_category_.json +++ b/docs/i18n/zh/docusaurus-plugin-content-docs/version-1.4.3/user_docs/other/_category_.json @@ -1,6 +1,6 @@ { - "label": "社区", - "position": 1, + "label": "其它", + "position": 6, "link": { "type": "generated-index" } diff --git a/docs/i18n/zh/docusaurus-plugin-content-docs/version-1.4.3/user_docs/other/group.md b/docs/i18n/zh/docusaurus-plugin-content-docs/version-1.4.3/user_docs/other/group.md new file mode 100644 index 00000000..e75e96be --- /dev/null +++ b/docs/i18n/zh/docusaurus-plugin-content-docs/version-1.4.3/user_docs/other/group.md @@ -0,0 +1,9 @@ +--- +sidebar_position: 1 +--- + +# 加群沟通 + +扫码添加微信,备注:`hippo4j`,邀您加入群聊。 + +![](https://images-machen.oss-cn-beijing.aliyuncs.com/185774220-c11951f9-e130-4d60-8204-afb5c51d4401.png) diff --git a/docs/i18n/zh/docusaurus-plugin-content-docs/version-1.4.3/user_docs/other/issue.md b/docs/i18n/zh/docusaurus-plugin-content-docs/version-1.4.3/user_docs/other/issue.md new file mode 100644 index 00000000..11f48a12 --- /dev/null +++ b/docs/i18n/zh/docusaurus-plugin-content-docs/version-1.4.3/user_docs/other/issue.md @@ -0,0 +1,90 @@ +--- +sidebar_position: 2 +--- + +# 常见问题 + +- 租户和项目在 Hippo4J 中是什么意思 +- 控制台线程池管理和线程池实例的区别 +- 示例项目为什么会有跨域请求 +- 更新代码后运行时服务端SQL报错 +- 生产环境如何不启用动态线程池 +- Server 端宕机会影响 Client 运行么 +- Hippo4J 的发布方式是怎样的?如何选择正确的版本 +- 群机器人接受不到通知报警 +- 设置线程池参数优先级问题 +- 线程池实例中修改队列容量参数问题 +- 控制台 SocketTimeoutException: connect timed out + +## 租户和项目在 Hippo4J 中是什么意思 + +Hippo4J 按照租户、项目、线程池的维度划分。 + +举个例子,小编在一家公司的公共组件团队,团队中负责消息、短链接网关等项目。公共组件是租户,消息或短链接就是项目。 + +## 控制台线程池管理和线程池实例的区别 + +在线程池管理中修改线程池参数,客户端并不能实时感知到并变更参数,需要重启客户端。而线程池实例中去对具体的实例修改参数时,客户端无需重启,可以实时感知到参数变化。如果二者针对同一线程 +池的参数配置不同,则在重启客户端时,客户端会去拉去线程池管理中的参数配置。 + +二者对应的定位:线程池管理中的配置是常态化配置。而线程池实例里的配置变更像是一种临时修改,比如突发的流量激增等场景,并不具备普适性。 + +## 示例项目为什么会有跨域请求 + +~~正常大家在部署时,服务端项目和客户端都在同一网络下,进行内网通信,是没有问题的。~~ + +~~因为示例项目中,服务端部署在外网,而客户端注册到服务端 IP 是内网的,所以不通。~~ + +~~涉及功能:线程池实例-查看、编辑,容器线程池。~~ + +1.2.0 版本后,服务端访问客户端已变成,浏览器访问服务端,服务端转发客户端的形式完成调用,跨域问题已解决。 + +## 更新代码后运行时服务端SQL报错 + +如果更新代码运行功能出错,大概率是因为项目新增或修改了表结构。如版本升级迭代涉及数据库表变更,会额外提供 SQL 变更文件。 + +如若第一次使用,初始化 SQL 脚本地址:[hippo4j_manager.sql](https://github.com/longtai-cn/hippo4j/blob/develop/hippo4j-server/conf/hippo4j_manager.sql)。 + +> 友情提示:每次执行数据库表或数据变更时,一定要保持提前备份的好习惯。 + +## 生产环境如何不启用动态线程池 + +测试环境已经引入 Hippo4J,暂时不打算上线生产环境。 + +生产环境指定配置 `spring.dynamic.thread-pool.enable=false`,测试环境和生产环境配置就会隔离。 + +## Server 端宕机会影响 Client 运行么 + +不会。Client 端包含对 Server 端的健康检查机制,Server 端不可用时会停止交互,检查到可用时重新建立连接交互。 + +## Hippo4J 的发布方式是怎样的?如何选择正确的版本 + +Hippo4J 发布时可能会涉及到两端发布,分别是 Server 和 Starter。如无特殊说明,**每一次的版本升级将兼容上一版本代码**。 + +- 如涉及 Server 发布,会在 [发布列表页面](https://github.com/longtai-cn/hippo4j/releases) 创建最新的发行版本; +- 如涉及 Starter 发布,将直接推送 Starter Jar 至中央仓库,Server 包版本不变。 + +## 群机器人接受不到通知报警 + +如果是钉钉机器人,需在机器人配置自定义关键字,才可发送成功。如下所示: + +![](https://images-machen.oss-cn-beijing.aliyuncs.com/image-20220530200133377.png?x-oss-process=image/resize,h_500,w_800) + +如果使用 hippo4j-server,请检查在 hippo4j-server 添加的报警通知记录,是否在客户端项目启动前,因为客户端只有在启动时会去 hippo4j-server 拉取报警通知记录。 + +重启客户端项目,会重新拉取最新报警推送配置,问题解决。 + +## 设置线程池参数优先级问题 + +- 当使用 `@DynamicThreadPool` 进行修饰的方法中和在管理界面设置中同时存在的话,则管理界面设置的优先级最高; +- 如果连接 server 端失败的话,使用 `@DynamicThreadPool` 进行修饰设置的优先级最高。 + +## 线程池实例中修改队列容量参数问题 + +在线程池管理中添加时,只有当选择队列类型为 `ResizableCapacityLinkedBlockingQueue` 时,后续再进行修改容量大小时才会实时的刷新修改成功。 + +## 控制台 SocketTimeoutException: connect timed out + +控制台中触发的某些操作涉及到 hippo4j-server 调用客户端项目。如果 hippo4j-server 部署在测试环境,而客户端项目为本地启动,则会触发该问题。 + +为什么编辑线程池参数不报错?因为线程池的动态变更是客户端主动发起连接,和服务端保持了一个长轮询,所以不存在服务端主动调用客户端行为。 diff --git a/docs/i18n/zh/docusaurus-plugin-content-docs/version-1.4.3/user_docs/other/official-ccounts.md b/docs/i18n/zh/docusaurus-plugin-content-docs/version-1.4.3/user_docs/other/official-ccounts.md new file mode 100644 index 00000000..61a1a5c6 --- /dev/null +++ b/docs/i18n/zh/docusaurus-plugin-content-docs/version-1.4.3/user_docs/other/official-ccounts.md @@ -0,0 +1,23 @@ +--- +sidebar_position: 5 +--- + +# 推荐公众号 + +## JavaGuide + +专注Java后端学习和大厂面试的公众号! + +![](https://images-machen.oss-cn-beijing.aliyuncs.com/JavaGuide.png) + +## HelloGitHub + +HelloGitHub,专注于开源社区技术和知识内容分享。 + +![](https://images-machen.oss-cn-beijing.aliyuncs.com/HelloGitHub.png) + +## macrozheng + +专注Java技术分享,解析优质开源项目。涵盖SpringBoot、SpringCloud、Docker、K8S等实用技术,作者Github开源项目mall(50K+Star)。 + +![](https://images-machen.oss-cn-beijing.aliyuncs.com/macrozheng.png) diff --git a/docs/i18n/zh/docusaurus-plugin-content-docs/version-1.4.3/user_docs/other/operation.md b/docs/i18n/zh/docusaurus-plugin-content-docs/version-1.4.3/user_docs/other/operation.md new file mode 100644 index 00000000..ba9ed7f0 --- /dev/null +++ b/docs/i18n/zh/docusaurus-plugin-content-docs/version-1.4.3/user_docs/other/operation.md @@ -0,0 +1,23 @@ +--- +sidebar_position: 6 +--- + +# 公众号合作 + +## 推荐须知 + +hippo4j 作为一款新兴动态线程池框架,开源出来的时间比较晚,目前迫切需要不同的途径进行推广。 + +如果您是公众号运营者或者开源爱好者,欢迎将 hippo4j 推荐给您的粉丝。 + +1. 您无需为 hippo4j 专门撰写文案,只需要直接导入 [推荐文章](https://mp.weixin.qq.com/s/JTTwcBEiK_MnFcPTZl3zGA) 即可。 +2. 在文章底部或内容中留下项目官网或者 GitHub 仓库链接。 +3. 文章需至少 1000+ 的阅读量。 + +作为推荐回报,hippo4j 可以为您: + +1. 在框架官方文档 [推荐公众号](/docs/user_docs/other/official-ccounts) 页面处留下您的公众号二维码。 +2. 在框架官方交流群里@全体成员推广您的公众号一次,附带介绍语。 +3. 您的公众号所有新推文章都可以将链接发送到 hippo4j 交流群中,增加阅读量。 + +如果您还有除公众号以外的其它途径可以与 hippo4j 相互推荐,欢迎 [加群沟通](/docs/user_docs/other/group)。 diff --git a/docs/i18n/zh/docusaurus-plugin-content-docs/version-1.4.3/user_docs/other/question.md b/docs/i18n/zh/docusaurus-plugin-content-docs/version-1.4.3/user_docs/other/question.md new file mode 100644 index 00000000..49fd4d77 --- /dev/null +++ b/docs/i18n/zh/docusaurus-plugin-content-docs/version-1.4.3/user_docs/other/question.md @@ -0,0 +1,246 @@ +--- +sidebar_position: 3 +--- + +# 问题提问 + +文档引用自:[提问的智慧](https://github.com/ryanhanwu/How-To-Ask-Questions-The-Smart-Way) + +## 在提问之前 + +在你准备要通过电子邮件、新闻群组或者聊天室提出技术问题前,请先做到以下事情: + +1. 尝试在你准备提问的论坛的旧文章中搜索答案。 +2. 尝试上网搜索以找到答案。 +3. 尝试阅读手册以找到答案。 +4. 尝试阅读常见问题文件(FAQ)以找到答案。 +5. 尝试自己检查或试验以找到答案。 +6. 向你身边的强者朋友打听以找到答案。 +7. 如果你是程序开发者,请尝试阅读源代码以找到答案。 + +当你提出问题的时候,请先表明你已经做了上述的努力;这将有助于树立你并不是一个不劳而获且浪费别人的时间的提问者。如果你能一并表达在做了上述努力的过程中所**学到**的东西会更好,因为我们更乐于回答那些表现出能从答案中学习的人的问题。 + +## 当你提问时 + +### 慎选提问的论坛 +小心选择你要提问的场合。如果你做了下述的事情,你很可能被忽略掉或者被看作失败者: + +* 在与主题不合的论坛上贴出你的问题。 +* 在探讨进阶技术问题的论坛张贴非常初级的问题;反之亦然。 +* 在太多的不同新闻群组上重复转贴同样的问题(cross-post)。 +* 向既非熟人也没有义务解决你问题的人发送私人电邮。 + +因此,第一步是找到对的论坛。再说一次,Google 和其它搜索引擎还是你的朋友,用它们来找到与你遭遇到困难的软硬件问题最相关的网站。通常那儿都有常见问题(FAQ)、邮件列表及相关说明文件的链接。如果你的努力(包括**阅读** FAQ)都没有结果,网站上也许还有报告 Bug(Bug-reporting)的流程或链接,如果是这样,链过去看看。 + +### 使用有意义且描述明确的标题 + +在邮件列表、新闻群组或论坛中,大约 50 字以内的标题是抓住资深专家注意力的好机会。别用喋喋不休的帮帮忙、跪求、急(更别说救命啊!!!!这样让人反感的话,用这种标题会被条件反射式地忽略)来浪费这个机会。不要妄想用你的痛苦程度来打动我们,而应该是在这点空间中使用极简单扼要的描述方式来提出问题。 + +一个好标题范例是`目标 —— 差异`式的描述,许多技术支持组织就是这样做的。在`目标`部分指出是哪一个或哪一组东西有问题,在`差异`部分则描述与期望的行为不一致的地方。 + +> 蠢问题:救命啊!我的笔记本电脑不能正常显示了! + +> 聪明问题:X.org 6.8.1 的鼠标指针会变形,某牌显卡 MV1005 芯片组。 + +> 更聪明问题:X.org 6.8.1 的鼠标指针,在某牌显卡 MV1005 芯片组环境下 - 会变形。 + +### 使用清晰、正确、精准且合乎语法的语句 + +我们从经验中发现,粗心的提问者通常也会粗心地写程序与思考(我敢打包票)。回答粗心大意者的问题很不值得,我们宁愿把时间耗在别处。 + +正确的拼写、标点符号和大小写是很重要的。一般来说,如果你觉得这样做很麻烦,不想在乎这些,那我们也觉得麻烦,不想在乎你的提问。花点额外的精力斟酌一下字句,用不着太僵硬与正式 —— 事实上,黑客文化很看重能准确地使用非正式、俚语和幽默的语句。但它**必须很**准确,而且有迹象表明你是在思考和关注问题。 + +### 精确地描述问题并言之有物 + +* 仔细、清楚地描述你的问题或 Bug 的症状。 +* 描述问题发生的环境(机器配置、操作系统、应用程序、以及相关的信息),提供经销商的发行版和版本号(如:`Fedora Core 4`、`Slackware 9.1`等)。 +* 描述在提问前你是怎样去研究和理解这个问题的。 +* 描述在提问前为确定问题而采取的诊断步骤。 +* 描述最近做过什么可能相关的硬件或软件变更。 +* 尽可能地提供一个可以`重现这个问题的可控环境`的方法。 + +尽量去揣测一个黑客会怎样反问你,在你提问之前预先将黑客们可能提出的问题回答一遍。 + +以上几点中,当你报告的是你认为可能在代码中的问题时,给黑客一个可以重现你的问题的环境尤其重要。当你这么做时,你得到有效的回答的机会和速度都会大大的提升。 + +[Simon Tatham](http://www.chiark.greenend.org.uk/~sgtatham/) 写过一篇名为《[如何有效的报告 Bug](http://www.chiark.greenend.org.uk/~sgtatham/bugs-cn.html)》的出色文章。强力推荐你也读一读。 + +### 话不在多而在精 + +你需要提供精确有内容的信息。这并不是要求你简单的把成堆的出错代码或者资料完全转录到你的提问中。如果你有庞大而复杂的测试样例能重现程序挂掉的情境,尽量将它剪裁得越小越好。 + +这样做的用处至少有三点。 +第一,表现出你为简化问题付出了努力,这可以使你得到回答的机会增加; +第二,简化问题使你更有可能得到**有用**的答案; +第三,在精炼你的 bug 报告的过程中,你很可能就自己找到了解决方法或权宜之计。 + +### 别动辄声称找到 Bug + +当你在使用软件中遇到问题,除非你非常、**非常**的有根据,不要动辄声称找到了 Bug。提示:除非你能提供解决问题的源代码补丁,或者提供回归测试来表明前一版本中行为不正确,否则你都多半不够完全确信。这同样适用在网页和文件,如果你(声称)发现了文件的`Bug`,你应该能提供相应位置的修正或替代文件。 + +请记得,还有其他许多用户没遇到你发现的问题,否则你在阅读文件或搜索网页时就应该发现了(你在抱怨前[已经做了这些,是吧](#在提问之前)?)。这也意味着很有可能是你弄错了而不是软件本身有问题。 + +编写软件的人总是非常辛苦地使它尽可能完美。如果你声称找到了 Bug,也就是在质疑他们的能力,即使你是对的,也有可能会冒犯到其中某部分人。当你在标题中嚷嚷着有`Bug`时,这尤其严重。 + +提问时,即使你私下非常确信已经发现一个真正的 Bug,最好写得像是**你**做错了什么。如果真的有 Bug,你会在回复中看到这点。这样做的话,如果真有 Bug,维护者就会向你道歉,这总比你惹恼别人然后欠别人一个道歉要好一点。 + +### 低声下气不能代替你的功课 + +有些人明白他们不该粗鲁或傲慢的提问并要求得到答复,但他们选择另一个极端 —— 低声下气:`我知道我只是个可悲的新手,一个撸瑟,但...`。这既使人困扰,也没有用,尤其是伴随着与实际问题含糊不清的描述时更令人反感。 + +别用原始灵长类动物的把戏来浪费你我的时间。取而代之的是,尽可能清楚地描述背景条件和你的问题情况。这比低声下气更好地定位了你的位置。 + +有时网页论坛会设有专为新手提问的版面,如果你真的认为遇到了初学者的问题,到那去就是了,但一样别那么低声下气。 + +### 描述问题症状而非你的猜测 + +告诉黑客们你认为问题是怎样造成的并没什么帮助。(如果你的推断如此有效,还用向别人求助吗?),因此要确信你原原本本告诉了他们问题的症状,而不是你的解释和理论;让黑客们来推测和诊断。如果你认为陈述自己的猜测很重要,清楚地说明这只是你的猜测,并描述为什么它们不起作用。 + +**蠢问题** + +> 我在编译内核时接连遇到 SIG11 错误, +> 我怀疑某条飞线搭在主板的走线上了,这种情况应该怎样检查最好? + +**聪明问题** + +> 我的组装电脑是 FIC-PA2007 主机板搭载 AMD K6/233 CPU(威盛 Apollo VP2 芯片组), +> 256MB Corsair PC133 SDRAM 内存,在编译内核时,从开机 20 分钟以后就频频产生 SIG11 错误, +> 但是在头 20 分钟内从没发生过相同的问题。重新启动也没有用,但是关机一晚上就又能工作 20 分钟。 +> 所有内存都换过了,没有效果。相关部分的标准编译记录如下… + +由于以上这点似乎让许多人觉得难以配合,这里有句话可以提醒你:`所有的诊断专家都来自密苏里州。` 美国国务院的官方座右铭则是:`让我看看`(出自国会议员 Willard D. Vandiver 在 1899 年时的讲话:`我来自一个出产玉米,棉花,牛蒡和民主党人的国家,滔滔雄辩既不能说服我,也不会让我满意。我来自密苏里州,你必须让我看看。`) 针对诊断者而言,这并不是一种怀疑,而只是一种真实而有用的需求,以便让他们看到的是与你看到的原始证据尽可能一致的东西,而不是你的猜测与归纳的结论。所以,大方的展示给我们看吧! + +### 按发生时间先后列出问题症状 + +问题发生前的一系列操作,往往就是对找出问题最有帮助的线索。因此,你的说明里应该包含你的操作步骤,以及机器和软件的反应,直到问题发生。在命令行处理的情况下,提供一段操作记录(例如运行脚本工具所生成的),并引用相关的若干行(如 20 行)记录会非常有帮助。 + +如果挂掉的程序有诊断选项(如 -v 的详述开关),试着选择这些能在记录中增加调试信息的选项。记住,`多`不等于`好`。试着选取适当的调试级别以便提供有用的信息而不是让读者淹没在垃圾中。 + +如果你的说明很长(如超过四个段落),在开头简述问题,接下来再按时间顺序详述会有所帮助。这样黑客们在读你的记录时就知道该注意哪些内容了。 + +### 描述目标而不是过程 + +如果你想弄清楚如何做某事(而不是报告一个 Bug),在开头就描述你的目标,然后才陈述重现你所卡住的特定步骤。 + +经常寻求技术帮助的人在心中有个更高层次的目标,而他们在自以为能达到目标的特定道路上被卡住了,然后跑来问该怎么走,但没有意识到这条路本身就有问题。结果要费很大的劲才能搞定。 + +**蠢问题** + +> 我怎样才能从某绘图程序的颜色选择器中取得十六进制的 RGB 值? + +**聪明问题** + +> 我正试着用替换一幅图片的色码(color table)成自己选定的色码,我现在知道的唯一方法是编辑每个色码区块(table slot), +> 但却无法从某绘图程序的颜色选择器取得十六进制的 RGB 值。 + +第二种提问法比较聪明,你可能得到像是```建议采用另一个更合适的工具```的回复。 + +### 清楚明确的表达你的问题以及需求 + +漫无边际的提问是近乎无休无止的时间黑洞。最有可能给你有用答案的人通常也正是最忙的人(他们忙是因为要亲自完成大部分工作)。这样的人对无节制的时间黑洞相当厌恶,所以他们也倾向于厌恶那些漫无边际的提问。 + +如果你明确表述需要回答者做什么(如提供指点、发送一段代码、检查你的补丁、或是其他等等),就最有可能得到有用的答案。因为这会定出一个时间和精力的上限,便于回答者能集中精力来帮你。这么做很棒。 + +要理解专家们所处的世界,请把专业技能想像为充裕的资源,而回复的时间则是稀缺的资源。你要求他们奉献的时间越少,你越有可能从真正专业而且很忙的专家那里得到解答。 + +所以,界定一下你的问题,使专家花在辨识你的问题和回答所需要付出的时间减到最少,这技巧对你有用答案相当有帮助 —— 但这技巧通常和简化问题有所区别。因此,问`我想更好地理解 X,可否指点一下哪有好一点说明?`通常比问`你能解释一下 X 吗?`更好。如果你的代码不能运作,通常请别人看看哪里有问题,比要求别人替你改正要明智得多。 + +### 礼多人不怪,而且有时还很有帮助 + +彬彬有礼,多用`请`和`谢谢您的关注`,或`谢谢你的关照`。让大家都知道你对他们花时间免费提供帮助心存感激。 + +坦白说,这一点并没有比使用清晰、正确、精准且合乎语法和避免使用专用格式重要(也不能取而代之)。黑客们一般宁可读有点唐突但技术上鲜明的 Bug 报告,而不是那种有礼但含糊的报告。(如果这点让你不解,记住我们是按问题能教给我们什么来评价问题的价值的) + +然而,如果你有一串的问题待解决,客气一点肯定会增加你得到有用回应的机会。 + +(我们注意到,自从本指南发布后,从资深黑客那里得到的唯一严重缺陷反馈,就是对预先道谢这一条。一些黑客觉得`先谢了`意味着事后就不用再感谢任何人的暗示。我们的建议是要么先说`先谢了`,**然后**事后再对回复者表示感谢,或者换种方式表达感激,譬如用`谢谢你的关注`或`谢谢你的关照`。) + +## 不该问的问题 + +以下是几个经典蠢问题,以及黑客没回答时心中所想的: + +问题:[我能在哪找到 X 程序或 X 资源?](#q1) + +问题:[我怎样用 X 做 Y?](#q2) + +问题:[我的程序/设定/SQL 语句没有用](#q3) + +问题:[我的 Windows 电脑有问题,你能帮我吗?](#q4) + +问题:[我的程序不会动了,我认为系统工具 X 有问题](#q5) + +问题:[我在安装 Linux(或者 X )时有问题,你能帮我吗?](#q6) + +问题:[我怎么才能破解 root 帐号/窃取 OP 特权/读别人的邮件呢?](#q7) + +--- + +> 问题:我能在哪找到 X 程序或 X 资源? + +回答:就在我找到它的地方啊,白痴 —— 搜索引擎的那一头。天哪!难道还有人不会用 [Google](https://www.google.com) 吗? + +> 问题:我怎样用 X 做 Y? + +回答:如果你想解决的是 Y ,提问时别给出可能并不恰当的方法。这种问题说明提问者不但对 X 完全无知,也对 Y 要解决的问题糊涂,还被特定形势禁锢了思维。最好忽略这种人,等他们把问题搞清楚了再说。 + +> 问题:我的{程序/设定/SQL 语句}没有用 + +回答:这不算是问题吧,我对要我问你二十个问题才找得出你真正问题的问题没兴趣 —— 我有更有意思的事要做呢。在看到这类问题的时候,我的反应通常不外如下三种 + +* 你还有什么要补充的吗? +* 真糟糕,希望你能搞定。 +* 这关我屁事? + +> 问题:我的 Windows 电脑有问题,你能帮我吗? + +回答:能啊,扔掉微软的垃圾,换个像 Linux 或 BSD 的开源操作系统吧。 + +注意:如果程序有官方版 Windows 或者与 Windows 有互动(如 Samba),你**可以**问与 Windows 相关的问题,只是别对问题是由 Windows 操作系统而不是程序本身造成的回复感到惊讶, 因为 Windows 一般来说实在太烂,这种说法通常都是对的。 + +> 问题:我的程序不会动了,我认为系统工具 X 有问题 + +回答:你完全有可能是第一个注意到被成千上万用户反复使用的系统调用与函数库文件有明显缺陷的人,更有可能的是你完全没有根据。不同凡响的说法需要不同凡响的证据,当你这样声称时,你必须有清楚而详尽的缺陷说明文件作后盾。 + +> 问题:我在安装 Linux(或者 X )时有问题,你能帮我吗? + +回答:不能,我只有亲自在你的电脑上动手才能找到毛病。还是去找你当地的 Linux 使用群组者寻求实际的指导吧(你能在[这儿](http://www.linux.org/groups/index.html)找到用户群组的清单)。 + +注意:如果安装问题与某 Linux 的发行版有关,在它的邮件列表、论坛或本地用户群组中提问也许是恰当的。此时,应描述问题的准确细节。在此之前,先用 `Linux` 和**所有**被怀疑的硬件作关键词仔细搜索。 + +> 问题:我怎么才能破解 root 帐号/窃取 OP 特权/读别人的邮件呢? + +回答:想要这样做,说明了你是个卑鄙小人;想找个黑客帮你,说明你是个白痴! + +## 好问题与蠢问题 + +最后,我将透过举一些例子,来说明怎样聪明的提问;同一个问题的两种问法被放在一起,一种是愚蠢的,另一种才是明智的。 + +**蠢问题**: + +> 我从 foo 项目找来的源码没法编译。它怎么这么烂? + +他觉得都是别人的错,这个傲慢自大的提问者。 + +**聪明问题**: + +> foo 项目代码在 Nulix 6.2 版下无法编译通过。我读过了 FAQ,但里面没有提到跟 Nulix 有关的问题。这是我编译过程的记录,我有什么做的不对的地方吗? + +提问者已经指明了环境,也读过了 FAQ,还列出了错误,并且他没有把问题的责任推到别人头上,他的问题值得被关注。 + +**蠢问题**: + +> 我的主机板有问题了,谁来帮我? + +某黑客对这类问题的回答通常是:`好的,还要帮你拍拍背和换尿布吗?`,然后按下删除键。 + +**聪明问题**: + +> 我在 S2464 主机板上试过了 X 、 Y 和 Z ,但没什么作用,我又试了 A 、 B 和 C 。请注意当我尝试 C 时的奇怪现象。显然 florbish 正在 grommicking,但结果出人意料。通常在 Athlon MP 主机板上引起 grommicking 的原因是什么?有谁知道接下来我该做些什么测试才能找出问题? + +## 如果得不到回答 + +如果仍得不到回答,请不要以为我们觉得无法帮助你。有时只是看到你问题的人不知道答案罢了。没有回应不代表你被忽视,虽然不可否认这种差别很难区分。 + +总的来说,简单的重复张贴问题是个很糟的点子。这将被视为无意义的喧闹。有点耐心,知道你问题答案的人可能生活在不同的时区,可能正在睡觉,也有可能你的问题一开始就没有组织好。 + +你可以通过其他渠道获得帮助,这些渠道通常更适合初学者的需要。 diff --git a/docs/i18n/zh/docusaurus-plugin-content-docs/version-1.4.3/user_docs/user_guide/_category_.json b/docs/i18n/zh/docusaurus-plugin-content-docs/version-1.4.3/user_docs/user_guide/_category_.json new file mode 100644 index 00000000..6dc10c33 --- /dev/null +++ b/docs/i18n/zh/docusaurus-plugin-content-docs/version-1.4.3/user_docs/user_guide/_category_.json @@ -0,0 +1,8 @@ +{ + "label": "用户指南", + "position": 2, + "link": { + "type": "generated-index", + "description": "帮助想要了解 Hippo4J 的用户快速掌握核心开发理念。" + } +} diff --git a/docs/i18n/zh/docusaurus-plugin-content-docs/version-1.4.3/user_docs/user_guide/frame.md b/docs/i18n/zh/docusaurus-plugin-content-docs/version-1.4.3/user_docs/user_guide/frame.md new file mode 100644 index 00000000..47f568fa --- /dev/null +++ b/docs/i18n/zh/docusaurus-plugin-content-docs/version-1.4.3/user_docs/user_guide/frame.md @@ -0,0 +1,60 @@ +--- +sidebar_position: 1 +--- + +# 为什么写 + +[美团线程池文章](https://tech.meituan.com/2020/04/02/java-pooling-pratice-in-meituan.html "美团线程池文章") 介绍中,因为业务对线程池参数没有合理配置,触发过几起生产事故,进而引发了一系列思考。最终决定封装线程池动态参数调整,扩展线程池监控以及消息报警等功能。 + +在开源平台找了挺多动态线程池项目,从功能性以及健壮性而言,个人感觉不满足企业级应用。 + +因为对动态线程池比较感兴趣,加上想写一个有意义的项目,所以决定自己来造一个轻量级的轮子。 + +想给项目起一个简单易记的名字,类似于 Eureka、Nacos、Redis;后和朋友商量,决定命名:**Hippo4J**。 + +![](https://images-machen.oss-cn-beijing.aliyuncs.com/动态线程池功能架构-1.jpg) + +## 它解决了什么问题 + +线程池在业务系统应该都有使用到,帮助业务流程提升效率以及管理线程,多数场景应用于大量的异步任务处理。 + +虽然线程池提供了我们许多便利,但也并非尽善尽美,比如下面这些问题就无法很好解决。 + +- 线程池随便定义,线程资源过多,造成服务器高负载。 + +- 线程池参数不易评估,随着业务的并发提升,业务面临出现故障的风险。 + +- 线程池任务执行时间超过平均执行周期,开发人员无法感知。 + +- 线程池任务堆积,触发拒绝策略,影响既有业务正常运行。 + +- 当业务出现超时、熔断等问题时,因为没有监控,无法确定是不是线程池引起。 + +- 原生线程池不支持运行时变量的传递,比如 MDC 上下文遇到线程池就 GG。 + +- 无法执行优雅关闭,当项目关闭时,大量正在运行的线程池任务被丢弃。 + +- 线程池运行中,任务执行停止,怀疑发生死锁或执行耗时操作,但是无从下手。 + +Hippo4J 很好解决了这些问题,它将业务中所有线程池统一管理,增强原生线程池系列功能。 + +## 它有什么特性 + +应用系统中线程池并不容易管理。参考美团的设计,Hippo4J 按照租户、项目、线程池的维度划分。再加上系统权限,让不同的开发、管理人员负责自己系统的线程池操作。 + +举个例子,小编在一家公司的公共组件团队,团队中负责消息、短链接网关等项目。公共组件是租户,消息或短链接就是项目。 + +Hippo4J 除去动态修改线程池,还包含实时查看线程池运行时指标、负载报警、配置日志管理等。 + +- `hippo4j-adapter`:适配对第三方框架中的线程池进行监控,如 Dubbo、RocketMQ、Hystrix 等; +- `hippo4j-auth`:用户、角色、权限等; +- `hippo4j-common`:多个模块公用代码实现; +- `hippo4j-config`:提供线程池准实时参数更新功能; +- `hippo4j-console`:对接前端控制台; +- `hippo4j-core`:核心的依赖,包括配置、核心包装类等; +- `hippo4j-discovery`:提供线程池项目实例注册、续约、下线等功能; +- `hippo4j-example` :示例工程; +- `hippo4j-message` :配置变更以及报警通知发送; +- `hippo4j-monitor` :线程池运行时监控; +- `hippo4j-server` :Server 端发布需要的模块聚合; +- `hippo4j-spring-boot`:SpringBoot Starter。 diff --git a/docs/i18n/zh/docusaurus-plugin-content-docs/version-1.4.3/user_docs/user_guide/framework.md b/docs/i18n/zh/docusaurus-plugin-content-docs/version-1.4.3/user_docs/user_guide/framework.md new file mode 100644 index 00000000..226ddf61 --- /dev/null +++ b/docs/i18n/zh/docusaurus-plugin-content-docs/version-1.4.3/user_docs/user_guide/framework.md @@ -0,0 +1,51 @@ +--- +sidebar_position: 2 +--- + +# 架构设计 + +简单来说,Hippo4J 从部署的角度上分为两种角色:Server 端和 Client 端。 + +Server 端是 Hippo4J 项目打包出的 Java 进程,功能包括用户权限、线程池监控以及执行持久化的动作。 + +Client 端指的是我们 SpringBoot 应用,通过引入 Hippo4J Starter Jar 包负责与 Server 端进行交互。 + +比如拉取 Server 端线程池数据、动态更新线程池配置以及采集上报线程池运行时数据等。 + +## 基础组件 + +### 配置中心(Config) + +配置中心位于 Server 端,它的主要作用是监控 Server 端线程池配置变更,实时通知到 Client 实例执行线程池变更流程。 + +代码设计基于 Nacos 1.x 版本的 **长轮询以及异步 Servlet 机制** 实现。 + +### 注册中心(Discovery) + +负责管理 Client 端(单机或集群)注册到 Server 端的实例,包括不限于**实例注册、续约、过期剔除** 等操作,代码基于 Eureka 源码实现。 + +上面的配置中心很容易理解,动态线程池参数变更的根本。但是注册中心是用来做什么的? + +注册中心管理 Client 端注册的实例,通过这些实例可以 **实时获取线程池的运行时参数信息**。 + +目前的设计是如此,不排除后续基于 Discovery 做更多的扩展。 + +### 控制台(Console) + +对接前端项目,包括不限于以下模块管理: + +![](https://images-machen.oss-cn-beijing.aliyuncs.com/image-20211107122504126.png) + +## 消息通知(Notify) + +Hippo4J 内置了很多需要通知的事件,比如:线程池参数变更通知、线程池活跃度报警、拒绝策略执行报警以及阻塞队列容量报警等。 + +目前 Notify 已经接入了钉钉、企业微信和飞书,后续持续集成邮件、短信等通知渠道;并且,Notify 模块提供了消息事件的 SPI 方案,可以接受三方自定义的推送。 + +## Hippo4j-Spring-Boot-Starter + +熟悉 SpringBoot 的小伙伴对 Starter 应该不会陌生。Hippo4J 提供以 Starter Jar 包的形式嵌套在应用内,负责与 Server 端完成交互。 + +## 功能架构 + +![](https://images-machen.oss-cn-beijing.aliyuncs.com/image-20211105230953626.png) diff --git a/docs/i18n/zh/docusaurus-plugin-content-docs/version-1.4.3/user_docs/user_guide/notify.md b/docs/i18n/zh/docusaurus-plugin-content-docs/version-1.4.3/user_docs/user_guide/notify.md new file mode 100644 index 00000000..d4ca2bfd --- /dev/null +++ b/docs/i18n/zh/docusaurus-plugin-content-docs/version-1.4.3/user_docs/user_guide/notify.md @@ -0,0 +1,75 @@ +--- +sidebar_position: 4 +--- + +# 通知报警 + +现阶段已集成钉钉、企业微信、飞书的消息推送,后续会持续接入邮箱、短信和自定义通知渠道。 + +![](https://images-machen.oss-cn-beijing.aliyuncs.com/image-20220904181527453.png) + +**通知平台** + +- DING:钉钉平台; + +- LARK:飞书平台; + +- WECHAT:企业微信。 + +**通知类型** + +- CONFIG:线程池配置变更推送; + +- ALARM:线程池运行报警推送。 + +**Token** + +获取 DING、LARK、WECHAT 机器人 Token。 + +**报警间隔** + +- CONFIG 类型通知没有报警间隔; + +- ALARM 类型设置报警间隔后,某一节点下的同一线程池指定间隔只会发送一次报警通知。 + +**接收者** + +```tex +多个接收者使用英文逗号 , 分割 (注意不要有空格) +DING:填写手机号 +WECHART:填写user_id会以@的消息发给用户,填写姓名则是普通的@,如:龙台 +LARK:填写ou_开头用户唯一标识会以@的消息发给用户,填写手机号则是普通的@ +``` + + +## 钉钉平台 + +[钉钉创建群机器人](https://www.dingtalk.com/qidian/help-detail-20781541.html) + +| 配置变更 | 报警通知 | +| :---: | :---: | +| ![](https://images-machen.oss-cn-beijing.aliyuncs.com/image-20211013122816688.png) | ![](https://images-machen.oss-cn-beijing.aliyuncs.com/image-20211013113649068.png) | + +添加钉钉机器人后,需在机器人配置自定义关键字,才可发送成功。如下所示: + +![](https://images-machen.oss-cn-beijing.aliyuncs.com/image-20220530200133377.png?x-oss-process=image/resize,h_500,w_800) + +:::tip +如果使用 1.4.3 及以上版本,`警报` 替换为 `告警`。 +::: + +## 企业微信 + +[企业微信创建群机器人](https://open.work.weixin.qq.com/help2/pc/14931?person_id=1&from=homesearch) + +| 配置变更 | 报警通知 | +| :---: | :---: | +| ![](https://images-machen.oss-cn-beijing.aliyuncs.com/image-20211203213443242.png) | ![](https://images-machen.oss-cn-beijing.aliyuncs.com/image-20211203213512019.png) | + +## 飞书平台 + +[飞书创建群机器人](https://www.feishu.cn/hc/zh-CN/articles/360024984973) + +![](https://images-machen.oss-cn-beijing.aliyuncs.com/image-20220304081729347.png) + +![](https://images-machen.oss-cn-beijing.aliyuncs.com/image-20220304081507907.png) diff --git a/docs/i18n/zh/docusaurus-plugin-content-docs/version-1.4.3/user_docs/user_guide/quick-start.md b/docs/i18n/zh/docusaurus-plugin-content-docs/version-1.4.3/user_docs/user_guide/quick-start.md new file mode 100644 index 00000000..cce9e577 --- /dev/null +++ b/docs/i18n/zh/docusaurus-plugin-content-docs/version-1.4.3/user_docs/user_guide/quick-start.md @@ -0,0 +1,40 @@ +--- +sidebar_position: 3 +--- + +# 快速开始 + +## 服务启动 + +使用 Docker 运行服务端,默认使用内置 H2 数据库,数据持久化到 Docker 容器存储卷中。 + +```shell +docker run -d -p 6691:6691 --name hippo4j-server hippo4j/hippo4j-server +``` + +> 如果没有 Docker,可以使用源码编译的方式,启动 [Hippo4J-Server/Hippo4J-Bootstrap](https://github.com/longtai-cn/hippo4j/tree/develop/hippo4j-server/hippo4j-bootstrap) 模块下 ServerApplication 应用类。 + +启动示例项目,[hippo4j-spring-boot-starter-example](https://github.com/opengoofy/hippo4j/tree/develop/hippo4j-example/hippo4j-spring-boot-starter-example) 模块下 Hippo4JServerExampleApplication 应用类。 + +访问 Server 控制台,路径 `http://localhost:6691/index.html`,默认用户名密码:admin / 123456 + +## 配置变更 + +访问控制台动态线程池菜单下线程池实例,修改动态线程池相关参数。 + +![](https://images-machen.oss-cn-beijing.aliyuncs.com/image-20220813173811668.png) + +观察 Hippo4j-Example 控制台日志输出,日志输出包括不限于此信息即为成功。 + +```tex +2022-09-10 00:23:29.783 INFO 50322 --- [change.config_0] c.h.s.s.c.ServerThreadPoolDynamicRefresh : [message-consume] Dynamic thread pool change parameter. + corePoolSize: 2 => 4 + maximumPoolSize: 6 => 12 + capacity: 1024 => 2048 + keepAliveTime: 9999 => 9999 + executeTimeOut: 800 => 3000 + rejectedType: SyncPutQueuePolicy => RunsOldestTaskPolicy + allowCoreThreadTimeOut: true => true +``` + +另外,当 Client 集群部署时,可以修改某一个实例,或选择 `全部修改` 按钮,修改所有实例线程池信息。 diff --git a/docs/i18n/zh/docusaurus-plugin-content-pages/team.md b/docs/i18n/zh/docusaurus-plugin-content-pages/team.md new file mode 100644 index 00000000..6c242062 --- /dev/null +++ b/docs/i18n/zh/docusaurus-plugin-content-pages/team.md @@ -0,0 +1,670 @@ +--- +sidebar_position: 1 +--- + +## Hippo4j 团队 + +非常感谢通过开源对 Hippo4j 贡献的开发者,项目始终保持高质量编码,以社区的力量去发展项目,并以项目反馈社区成员。我们期待对 Hippo4j 有兴趣的小伙伴加入团队,与社区共同成长。 + +## 成员 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
姓名GitHub ID博客地址联系方式
马称mageeric小马哥的技术专栏machen@apache.org
陆宽shining-stars-lk宽仔的代码之路1031900093@qq.com
王杰iwangjie-wangchenmo1025@gmail.com
魏虎weihubeatsweihubeatsweihubeats@163.com
李剑鑫BigXin0109Only丶Big1064730540@qq.com
刘文浩pizihaopizihaohao3073liu@163.com
叶炜shanjianq-17855368071@163.com
黄成兴CreatesequenceCreatesequence's Blog841396397@qq.com
+ +## 贡献者 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + mageeric +
+ 马称 +
+
+ + shining-stars-lk +
+ Lucky 8 +
+
+ + weihubeats +
+ Weihubeats +
+
+ + pirme +
+ 李金来 +
+
+ + shanjianq +
+ Shanjianq +
+
+ + pizihao +
+ Pizihao +
+
+ + iwangjie +
+ 王杰 +
+
+ + hippo4jbot +
+ Hippo4jbot[bot] +
+
+ + BigXin0109 +
+ BigXin0109 +
+
+ + Gdk666 +
+ Null +
+
+ + Createsequence +
+ 黄成兴 +
+
+ + wulangcode +
+ WuLang +
+
+ + xqxyxchy +
+ Null +
+
+ + maxisvest +
+ Null +
+
+ + road2master +
+ Lijx +
+
+ + baymax55 +
+ Baymax55 +
+
+ + zhuanghaozhe +
+ 庄昊哲 +
+
+ + liulinfei121 +
+ Null +
+
+ + Atmanuclear +
+ Null +
+
+ + hippo4j +
+ Hippo4j +
+
+ + imyzt +
+ 杨镇涛 +
+
+ + Tliutao +
+ Liutao +
+
+ + monsterxxp +
+ Null +
+
+ + voilaf +
+ Null +
+
+ + gywanghai +
+ 二师兄 +
+
+ + skyemin +
+ Null +
+
+ + Redick01 +
+ Redick Liu +
+
+ + xiaochengxuyuan +
+ Sean Wu +
+
+ + HKMV +
+ Serenity +
+
+ + gewuwo +
+ 格悟沃 +
+
+ + hushtian +
+ Null +
+
+ + jinlingmei +
+ Null +
+
+ + linlinjie +
+ Null +
+
+ + selectbook +
+ Leping Huang +
+
+ + soulmz +
+ Soulzz +
+
+ + tomsun28 +
+ Tomsun28 +
+
+ + backbay2-yzg +
+ 游祖光 +
+
+ + puppet4 +
+ Tudo +
+
+ + yanrongzhen +
+ 严荣振 +
+
+ + 2EXP +
+ Null +
+
+ + onesimplecoder +
+ Alic +
+
+ + CalebZYC +
+ Null +
+
+ + Hibernate5666 +
+ Cheng Xihong +
+
+ + smartdj +
+ DJ +
+
+ + dmego +
+ Dmego +
+
+ + dousp +
+ Douspeng +
+
+ + hl1248 +
+ Lucas +
+
+ + gentlelynn +
+ Lynn +
+
+ + Malcolmli +
+ Malcolm +
+
+ + alexhaoxuan +
+ Alexli +
+
+ + qizhongju +
+ Bug搬运工 +
+
+ + san4j +
+ San4j +
+
+ + zhenyed +
+ Zhenye +
+
+ + dongming0920 +
+ Null +
+
+ + f497196689 +
+ Fengjing +
+
+ + Snailclimb +
+ Guide +
+
+ + hbw1994 +
+ Null +
+
+ + hncboy +
+ Null +
+
+ + stronglong +
+ Itermis +
+
+ + janey668 +
+ Null +
+
+ + w-jirong +
+ 季容 +
+
+ + klsq94 +
+ Hui Cao +
+
+ + kongyanbo-cx +
+ Null +
+
+ + lishiyu +
+ Null +
+
+ + Nhxz +
+ Nhxz +
+
+ + op-lht +
+ Op-lht +
+
+ + wangjie-github +
+ Wangjie +
+
+ + wangyi123456 +
+ Null +
+
+ + Williamren97 +
+ William Ren +
+
+ + wzw8795 +
+ Null +
+
+ + huaxianchao +
+ Null +
+
+ + yangzhiw +
+ Opentanent +
+
+ + yhc777 +
+ Null +
+
+ + zhaiweij +
+ Zhaiweij +
+
+ + zhaojinchao95 +
+ Zhaojinchao +
+
+ + zj1997 +
+ Null +
+
+ + zoujin001 +
+ Null +
+
+ + li-xiao-shuang +
+ 李晓双 Li Xiao Shuang +
+
+ + oreoft +
+ 没有气的汽水 +
+
+ + wo883721 +
+ Xinhao +
+
+ +## 成为提交者 + +持续对 Hippo4j 进行贡献, 粗略评估,完成 10 次 PR 贡献即可成为核心开发者。 其中包括完成 2 +个 [good pro issue](https://github.com/opengoofy/hippo4j/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+pro+issue%22) +或以上,以及若干个 [good first issue](https://github.com/opengoofy/hippo4j/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22)。 + +:::note +会根据 PR 质量提供个性化评估,有可能一个或两个质量较高 PR +即可成为核心开发者。参考:[重构 DynamicThreadPoolExecutor 功能扩展逻辑](https://github.com/opengoofy/hippo4j/pull/854) +::: + +成为核心开发者后,会为该 GitHub 账号获取 Jetbrains 全家桶 Licenses,有效期为 1 年。不用再为破解而烦恼,感受随时升级的快乐。 + +:::note +距离到期两周前,会再次申请 Jetbrains Licenses。有点类似于无限续约的感觉,在此感谢 Jetbrains 公司对开源的支持。 +::: + +截至 `2022-10-30` 当天,已为登记的 7 位核心开发者成功申请 Licenses。 + +![](https://images-machen.oss-cn-beijing.aliyuncs.com/image-20221030134303060.png) diff --git a/docs/i18n/zh/docusaurus-plugin-content-docs/current/community/powered-by.md b/docs/i18n/zh/docusaurus-plugin-content-pages/users.md similarity index 73% rename from docs/i18n/zh/docusaurus-plugin-content-docs/current/community/powered-by.md rename to docs/i18n/zh/docusaurus-plugin-content-pages/users.md index 635d9011..0b88e264 100644 --- a/docs/i18n/zh/docusaurus-plugin-content-docs/current/community/powered-by.md +++ b/docs/i18n/zh/docusaurus-plugin-content-pages/users.md @@ -1,24 +1,17 @@ --- -sidebar_position: 3 +sidebar_position: 1 +title: 采用公司 --- -# 采用公司 +## 谁在使用 Hippo4j -## 登记 - -欢迎采用了 Hippo4J 的公司在此登记,非常感谢大家对 Hippo4J 的关注和支持,这是我们前进最大的动力。 - -请按公司名 + 首页的格式在 [此处](https://github.com/opengoofy/hippo4j/issues/13) 登记。 - -## 谁在使用 Hippo4J - -共计 21+ 家公司生产接入 Hippo4J。按照公司登记时间排序。 +共计 23+ 家公司生产接入 Hippo4j。按照公司登记时间排序。 - [身边云](https://serviceshare.com) -- [Medbanks](https://www.medbanks.cn) +- [思派健康科技](https://www.medbanks.cn) - [北京智合联创科技有限公司](http://www.zhlc.com.cn) - [神州数码](http://www.digitalchina.com) -- [payermax](https://www.payermax.com/) +- [PayerMax](https://www.payermax.com/) - [轻松到家](http://www.uyess.com/index.html) - [某商业银行股份有限公司](https://github.com/opengoofy/hippo4j/issues/13) - [某国际物流信息股份有限公司](https://github.com/opengoofy/hippo4j/issues/13) @@ -35,3 +28,11 @@ sidebar_position: 3 - [远眺网络科技有限公司](https://www.yuantiaokj.com/) - [浙江吉利控股集团有限公司](https://www.geely.com/) - [三立人(深圳)科技有限公司-焦内](https://www.bananain.com/) +- [上海天猫好房添玑网络服务有限公司](http://www.eju.com/) +- [郑州力通水务](http://www.zzltsw.com/) + +## 登记 + +欢迎采用了 Hippo4j 的公司在此登记,非常感谢大家对 Hippo4j 的关注和支持,这是我们前进最大的动力。 + +请按公司名 + 首页的格式在 [此处](https://github.com/opengoofy/hippo4j/issues/13) 登记。 diff --git a/docs/sidebars.js b/docs/sidebars.js index 112da355..a22fc6a3 100644 --- a/docs/sidebars.js +++ b/docs/sidebars.js @@ -22,12 +22,12 @@ const sidebars = { dirName: 'user_docs', }, ], - community: [ + /*community: [ { type: 'autogenerated', dirName: 'community', }, - ], + ],*/ sponsor: [ { diff --git a/docs/sidebarsCommunity.js b/docs/sidebarsCommunity.js new file mode 100755 index 00000000..676888c2 --- /dev/null +++ b/docs/sidebarsCommunity.js @@ -0,0 +1,15 @@ +/* + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +module.exports = { + community: [ + { + type: 'autogenerated', + dirName: '.', + }, + ], +}; diff --git a/docs/src/pages/team.md b/docs/src/pages/team.md new file mode 100644 index 00000000..65609fba --- /dev/null +++ b/docs/src/pages/team.md @@ -0,0 +1,677 @@ +--- +sidebar_position: 1 +--- + +## Hippo4j 团队 + +非常感谢通过开源对 Hippo4j 贡献的开发者,项目始终保持高质量编码,以社区的力量去发展项目,并以项目反馈社区成员。我们期待对 Hippo4j 有兴趣的小伙伴加入团队,与社区共同成长。 + +## 成员 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
姓名GitHub ID博客地址联系方式
马称mageeric小马哥的技术专栏machen@apache.org
陆宽shining-stars-lk宽仔的代码之路1031900093@qq.com
王杰iwangjie-wangchenmo1025@gmail.com
魏虎weihubeatsweihubeatsweihubeats@163.com
李剑鑫BigXin0109Only丶Big1064730540@qq.com
刘文浩pizihaopizihaohao3073liu@163.com
叶炜shanjianq-17855368071@163.com
黄成兴CreatesequenceCreatesequence's Blog841396397@qq.com
吴浪wulangcode-sanliangitch@foxmail.com
+ +## 贡献者 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + mageeric +
+ 马称 +
+
+ + shining-stars-lk +
+ Lucky 8 +
+
+ + weihubeats +
+ Weihubeats +
+
+ + pirme +
+ 李金来 +
+
+ + shanjianq +
+ Shanjianq +
+
+ + pizihao +
+ Pizihao +
+
+ + iwangjie +
+ 王杰 +
+
+ + hippo4jbot +
+ Hippo4jbot[bot] +
+
+ + BigXin0109 +
+ BigXin0109 +
+
+ + Gdk666 +
+ Null +
+
+ + Createsequence +
+ 黄成兴 +
+
+ + wulangcode +
+ WuLang +
+
+ + xqxyxchy +
+ Null +
+
+ + maxisvest +
+ Null +
+
+ + road2master +
+ Lijx +
+
+ + baymax55 +
+ Baymax55 +
+
+ + zhuanghaozhe +
+ 庄昊哲 +
+
+ + liulinfei121 +
+ Null +
+
+ + Atmanuclear +
+ Null +
+
+ + hippo4j +
+ Hippo4j +
+
+ + imyzt +
+ 杨镇涛 +
+
+ + Tliutao +
+ Liutao +
+
+ + monsterxxp +
+ Null +
+
+ + voilaf +
+ Null +
+
+ + gywanghai +
+ 二师兄 +
+
+ + skyemin +
+ Null +
+
+ + Redick01 +
+ Redick Liu +
+
+ + xiaochengxuyuan +
+ Sean Wu +
+
+ + HKMV +
+ Serenity +
+
+ + gewuwo +
+ 格悟沃 +
+
+ + hushtian +
+ Null +
+
+ + jinlingmei +
+ Null +
+
+ + linlinjie +
+ Null +
+
+ + selectbook +
+ Leping Huang +
+
+ + soulmz +
+ Soulzz +
+
+ + tomsun28 +
+ Tomsun28 +
+
+ + backbay2-yzg +
+ 游祖光 +
+
+ + puppet4 +
+ Tudo +
+
+ + yanrongzhen +
+ 严荣振 +
+
+ + 2EXP +
+ Null +
+
+ + onesimplecoder +
+ Alic +
+
+ + CalebZYC +
+ Null +
+
+ + Hibernate5666 +
+ Cheng Xihong +
+
+ + smartdj +
+ DJ +
+
+ + dmego +
+ Dmego +
+
+ + dousp +
+ Douspeng +
+
+ + hl1248 +
+ Lucas +
+
+ + gentlelynn +
+ Lynn +
+
+ + Malcolmli +
+ Malcolm +
+
+ + alexhaoxuan +
+ Alexli +
+
+ + qizhongju +
+ Bug搬运工 +
+
+ + san4j +
+ San4j +
+
+ + zhenyed +
+ Zhenye +
+
+ + dongming0920 +
+ Null +
+
+ + f497196689 +
+ Fengjing +
+
+ + Snailclimb +
+ Guide +
+
+ + hbw1994 +
+ Null +
+
+ + hncboy +
+ Null +
+
+ + stronglong +
+ Itermis +
+
+ + janey668 +
+ Null +
+
+ + w-jirong +
+ 季容 +
+
+ + klsq94 +
+ Hui Cao +
+
+ + kongyanbo-cx +
+ Null +
+
+ + lishiyu +
+ Null +
+
+ + Nhxz +
+ Nhxz +
+
+ + op-lht +
+ Op-lht +
+
+ + wangjie-github +
+ Wangjie +
+
+ + wangyi123456 +
+ Null +
+
+ + Williamren97 +
+ William Ren +
+
+ + wzw8795 +
+ Null +
+
+ + huaxianchao +
+ Null +
+
+ + yangzhiw +
+ Opentanent +
+
+ + yhc777 +
+ Null +
+
+ + zhaiweij +
+ Zhaiweij +
+
+ + zhaojinchao95 +
+ Zhaojinchao +
+
+ + zj1997 +
+ Null +
+
+ + zoujin001 +
+ Null +
+
+ + li-xiao-shuang +
+ 李晓双 Li Xiao Shuang +
+
+ + oreoft +
+ 没有气的汽水 +
+
+ + wo883721 +
+ Xinhao +
+
+ +## 成为提交者 + +持续对 Hippo4j 进行贡献, 粗略评估,完成 10 次 PR 贡献即可成为核心开发者。 其中包括完成 2 +个 [good pro issue](https://github.com/opengoofy/hippo4j/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+pro+issue%22) +或以上,以及若干个 [good first issue](https://github.com/opengoofy/hippo4j/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22)。 + +:::note +会根据 PR 质量提供个性化评估,有可能一个或两个质量较高 PR +即可成为核心开发者。参考:[重构 DynamicThreadPoolExecutor 功能扩展逻辑](https://github.com/opengoofy/hippo4j/pull/854) +::: + +成为核心开发者后,会为该 GitHub 账号获取 Jetbrains 全家桶 Licenses,有效期为 1 年。不用再为破解而烦恼,感受随时升级的快乐。 + +:::note +距离到期两周前,会再次申请 Jetbrains Licenses。有点类似于无限续约的感觉,在此感谢 Jetbrains 公司对开源的支持。 +::: + +截至 `2022-10-30` 当天,已为登记的 7 位核心开发者成功申请 Licenses。 + +![](https://images-machen.oss-cn-beijing.aliyuncs.com/image-20221030134303060.png) diff --git a/docs/i18n/zh/docusaurus-plugin-content-docs/version-1.4.2/community/powered-by.md b/docs/src/pages/users.md similarity index 73% rename from docs/i18n/zh/docusaurus-plugin-content-docs/version-1.4.2/community/powered-by.md rename to docs/src/pages/users.md index 635d9011..0b88e264 100644 --- a/docs/i18n/zh/docusaurus-plugin-content-docs/version-1.4.2/community/powered-by.md +++ b/docs/src/pages/users.md @@ -1,24 +1,17 @@ --- -sidebar_position: 3 +sidebar_position: 1 +title: 采用公司 --- -# 采用公司 +## 谁在使用 Hippo4j -## 登记 - -欢迎采用了 Hippo4J 的公司在此登记,非常感谢大家对 Hippo4J 的关注和支持,这是我们前进最大的动力。 - -请按公司名 + 首页的格式在 [此处](https://github.com/opengoofy/hippo4j/issues/13) 登记。 - -## 谁在使用 Hippo4J - -共计 21+ 家公司生产接入 Hippo4J。按照公司登记时间排序。 +共计 23+ 家公司生产接入 Hippo4j。按照公司登记时间排序。 - [身边云](https://serviceshare.com) -- [Medbanks](https://www.medbanks.cn) +- [思派健康科技](https://www.medbanks.cn) - [北京智合联创科技有限公司](http://www.zhlc.com.cn) - [神州数码](http://www.digitalchina.com) -- [payermax](https://www.payermax.com/) +- [PayerMax](https://www.payermax.com/) - [轻松到家](http://www.uyess.com/index.html) - [某商业银行股份有限公司](https://github.com/opengoofy/hippo4j/issues/13) - [某国际物流信息股份有限公司](https://github.com/opengoofy/hippo4j/issues/13) @@ -35,3 +28,11 @@ sidebar_position: 3 - [远眺网络科技有限公司](https://www.yuantiaokj.com/) - [浙江吉利控股集团有限公司](https://www.geely.com/) - [三立人(深圳)科技有限公司-焦内](https://www.bananain.com/) +- [上海天猫好房添玑网络服务有限公司](http://www.eju.com/) +- [郑州力通水务](http://www.zzltsw.com/) + +## 登记 + +欢迎采用了 Hippo4j 的公司在此登记,非常感谢大家对 Hippo4j 的关注和支持,这是我们前进最大的动力。 + +请按公司名 + 首页的格式在 [此处](https://github.com/opengoofy/hippo4j/issues/13) 登记。 diff --git a/docs/versioned_docs/version-1.4.2/community/contributor.md b/docs/versioned_docs/version-1.4.2/community/contributor.md deleted file mode 100644 index f0185ad3..00000000 --- a/docs/versioned_docs/version-1.4.2/community/contributor.md +++ /dev/null @@ -1,24 +0,0 @@ ---- -sidebar_position: 1 ---- - -# 贡献指南 - -Git Commit Log 尽量使用英文。 - -Pull Request 尽量保持单一,不同语义的代码贡献应拆分多个 Pull Request。 - -为了让您的 GitHub ID 显示在 Contributor 列表中,别忘了以下设置: - -```shell -git config --global user.name "username" -git config --global user.email "GitHub 账号邮箱" -``` - -## 贡献者列表 - -您可以在 [Hippo4J](https://github.com/opengoofy/hippo4j/graphs/contributors) 和 [Hippo4J Console](https://github.com/opengoofy/hippo4j-console) 的贡献列表中找到全部的贡献者名单。 - - - - diff --git a/docs/versioned_docs/version-1.4.2/community/dev_convention/code.md b/docs/versioned_docs/version-1.4.2/community/dev_convention/code.md deleted file mode 100644 index f91acdbe..00000000 --- a/docs/versioned_docs/version-1.4.2/community/dev_convention/code.md +++ /dev/null @@ -1,8 +0,0 @@ ---- -sidebar_position: 2 ---- - -# 代码规约 - -1. 代码提交前,执行 `mvn spotless:apply` 保证代码格式符合规范。 -2. 代码中不要出现无意义的空行。 diff --git a/docs/versioned_docs/version-1.4.2/community/developer.md b/docs/versioned_docs/version-1.4.2/community/developer.md deleted file mode 100644 index 89b57b88..00000000 --- a/docs/versioned_docs/version-1.4.2/community/developer.md +++ /dev/null @@ -1,89 +0,0 @@ ---- -sidebar_position: 2 ---- - -# 核心开发者 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
姓名GitHub ID博客地址联系方式
马称magegoofy小马哥的技术专栏machen@apache.org
陆宽shining-stars-lk宽仔的代码之路1031900093@qq.com
王杰iwangjie-wangchenmo1025@gmail.com
魏虎weihubeatsweihubeatsweihubeats@163.com
李剑鑫BigXin0109Only丶Big1064730540@qq.com
刘文浩pizihaopizihaohao3073liu@163.com
叶炜shanjianq-17855368071@163.com
黄成兴CreatesequenceCreatesequence's Blog841396397@qq.com
- -## 成为核心开发者 - -持续对 Hippo-4J 进行贡献, 粗略评估,完成 10 次 PR 贡献即可成为核心开发者。 其中包括完成 2 个 [good pro issue](https://github.com/opengoofy/hippo4j/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+pro+issue%22) 或以上,以及若干个 [good first issue](https://github.com/opengoofy/hippo4j/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22)。 - -:::note -会根据 PR 质量提供个性化评估,有可能一个或两个质量较高 PR 即可成为核心开发者。参考:[重构 DynamicThreadPoolExecutor 功能扩展逻辑](https://github.com/opengoofy/hippo4j/pull/854) -::: - -成为核心开发者后,会为该 GitHub 账号获取 Jetbrains 全家桶 Licenses,有效期为 1 年。不用再为破解而烦恼,感受随时升级的快乐。 - -:::note -距离到期两周前,会再次申请 Jetbrains Licenses。有点类似于无限续约的感觉,在此感谢 Jetbrains 公司对开源的支持。 -::: - -截至 `2022-10-30` 当天,已为登记的 7 位核心开发者成功申请 Licenses。 - -![](https://images-machen.oss-cn-beijing.aliyuncs.com/image-20221030134303060.png) diff --git a/docs/versioned_docs/version-1.4.2/community/powered-by.md b/docs/versioned_docs/version-1.4.2/community/powered-by.md deleted file mode 100644 index 635d9011..00000000 --- a/docs/versioned_docs/version-1.4.2/community/powered-by.md +++ /dev/null @@ -1,37 +0,0 @@ ---- -sidebar_position: 3 ---- - -# 采用公司 - -## 登记 - -欢迎采用了 Hippo4J 的公司在此登记,非常感谢大家对 Hippo4J 的关注和支持,这是我们前进最大的动力。 - -请按公司名 + 首页的格式在 [此处](https://github.com/opengoofy/hippo4j/issues/13) 登记。 - -## 谁在使用 Hippo4J - -共计 21+ 家公司生产接入 Hippo4J。按照公司登记时间排序。 - -- [身边云](https://serviceshare.com) -- [Medbanks](https://www.medbanks.cn) -- [北京智合联创科技有限公司](http://www.zhlc.com.cn) -- [神州数码](http://www.digitalchina.com) -- [payermax](https://www.payermax.com/) -- [轻松到家](http://www.uyess.com/index.html) -- [某商业银行股份有限公司](https://github.com/opengoofy/hippo4j/issues/13) -- [某国际物流信息股份有限公司](https://github.com/opengoofy/hippo4j/issues/13) -- [萨科(深圳)科技有限公司](https://www.lbdj.com/) -- [广东天枢新能源科技有限公司](https://gd-tianshu.com/) -- [FitTime](http://fittime.com/) -- [百强国际物流](https://github.com/opengoofy/hippo4j/issues/13) -- [海南某深圳分公司](https://github.com/opengoofy/hippo4j/issues/13) -- [众合云科(51社保)](https://home.101hr.com/) -- [好货云店](https://pc.haohuoyundian.com/) -- [斗象科技](https://www.tophant.com/) -- [深圳航天信息有限公司](http://sz.aisino.com/) -- [新东方教育科技集团](https://www.xdf.cn/) -- [远眺网络科技有限公司](https://www.yuantiaokj.com/) -- [浙江吉利控股集团有限公司](https://www.geely.com/) -- [三立人(深圳)科技有限公司-焦内](https://www.bananain.com/) diff --git a/docs/versioned_docs/version-1.4.2/community/sponsor.md b/docs/versioned_docs/version-1.4.2/community/sponsor.md deleted file mode 100644 index c73fc64a..00000000 --- a/docs/versioned_docs/version-1.4.2/community/sponsor.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -sidebar_position: 4 ---- - -# 支持开源 - -如果您正在使用这个项目并感觉良好,或者是想支持我继续开发,通过以下二维码一次性捐款。 - -在这里承诺将,将收到的所有赞助支持资金完全公开化,且后续资金用途仅 Hippo-4J 项目的运转。 - -![](https://images-machen.oss-cn-beijing.aliyuncs.com/IMG_6719_2.jpg?x-oss-process=image/resize,h_180,w_180) - -感谢给予支持的朋友,您的支持是 Hippo-4J 社区前进的动力 🎉 - -| | ID | 赞赏金额 | 时间 | 备注 | -|-----|--|-------|------------|--------------------| -| 1 | 六月飞雪 | 30.00 | 2021-12-30 | 代码设计很优雅的一款框架,继续加油! | -| 2 | 孙大圣 | 26.6 | 2022-03-23 | 学习一下😁😁 | -| 3 | Easy 点 | 66.00 | 2022-04-09 | 好货好技术当加赏 | -| 4 | 捷克 | 30.00 | 2022-05-21 | 非常不错的框架,点赞 | -| 5 | 吃猫的饼干 | 88.00 | 2022-08-21 | 👍 | -| 6 | 不忘初心· | 66.00 | 2022-10-28 | Nice! | -| 7 | 时刻· | 6.00 | 2022-10-30 | -! | diff --git a/docs/versioned_docs/version-1.4.2/community/update-log.md b/docs/versioned_docs/version-1.4.2/community/update-log.md deleted file mode 100644 index aa4adc20..00000000 --- a/docs/versioned_docs/version-1.4.2/community/update-log.md +++ /dev/null @@ -1,299 +0,0 @@ ---- -sidebar_position: 5 ---- - -# 更新日志 - -## 1.4.2 (Oct 18, 2022) - -这是一个功能增强版本,修复了少量 BUG。建议按照当前版本升级。具体信息可查看 Release 标签地址:[1.4.2](https://github.com/opengoofy/hippo4j/milestone/12?closed=1) - -**Feature** - -- 强制指定客户端注册的 ip + port -- 支持 spring-cloud-tencent Polaris 线程池动态更新 @weihubeats -- 服务启动时加载 MySQL、H2 数据库初始化语句 -- Adapter 初始化覆盖核心参数 @pizihao -- Server 端新增是否开启认证模式 @baymax55 - -**Refactor** - -- 替换底层网络工具类 OkHttp @yanrongzhen -- 全局移除 commons-lang3 工具包依赖 @yanrongzhen -- 去除三方工具类依赖 @pizihao -- 全局移除 Guava 工具包依赖 @road2master -- DockerFile 基于 H2 数据库重新构建 @BigXin0109 - -**Bug** - -- Dubbo 2.7.15 无法获取线程池引用 @iwangjie -- 动态线程池报警参数颠倒 @jinlingmei - -**Optimize** - -- 线程池实例运行数据采集,如果线程池id不存在,且长度超长,会报异常 @Gdk666 -- 项目中动态线程池数量为空时,存在 CPU 空转情况 -- 客户端注册服务端失败,输出服务端返回信息 @wulangcode -- 调整数据库项目 id 和线程池 id 字段长度 -- 增加代码检查工具 maven-checkstyle-plugin -- 调整控制台监控图表颜色展示 - -## 1.4.1 (Sep 12, 2022) - -这是一个功能增强版本,修复了若干 BUG。建议按照当前版本升级。具体信息可查看 Release 标签地址:[1.4.1](https://github.com/opengoofy/hippo4j/milestone/11?closed=1) - -**Feature** - -- 支持 H2 数据库 @weihubeats -- 动态线程池配置变更时,支持单个、多个或全部节点变 @pizihao -- 增加线程池活跃度和容量报警可选择关闭 -- @DynamicThreadPool 线程池不存在则创建 @shanjianq -- 支持 ETCD 配置中心动态调整参数 @weihubeats -- 创建动态线程池支持 spring 线程池 @BigXin0109 -- 线程池实例变更增加执行超时时间 -- 线程池相关查询页面增加阻塞队列属性 -- 定义动态线程池时,抽象默认配置 -- 提供 ExecutorContext 封装上下文细节 @road2master -- Docker 制作服务端镜像,帮助开发者快速启动 @BigXin0109 -- RabbitMQ 适配器增加多个 MQ 数据源 @weihubeats - -**Bug** - -- 动态线程池设置关闭时启动报错 @dousp -- ExecutorTtlWrapper 类型的 Executor 不生效 @BigXin0109 -- Undertow 获取 WebServer 类型参数异常 @shining-stars-lk -- 修复线程池核心、最大线程数校验限制 -- ByteConvertUtil#getPrintSize 单位转换错误 @onesimplecoder -- 创建线程池单选框选择错误 -- ReflectUtil#getFieldsDirectly missing fields @BigXin0109 -- 本地代码中设置的 capacity 无效 @BigXin0109 -- 服务端线程池超时时间存在拆箱空指针异常 @oreoft -- 未读取服务端返回执行超时时间属性 -- ResizableCapacityLinkedBlockingQueue#put 当前元素数量大于 capacity 未阻塞 - -**Optimize** - -- 长轮询任务判断逻辑优化 @shining-stars-lk -- 线程池存在实例不允许删除线程池 @shanjianq -- 优化租户、项目列表展示排版 -- 通知报警模块项目和线程池下拉查询排序修改 -- 动态线程池拒绝策略触发,以异步的方式报警 -- 优化框架中线程池工厂产生的线程名称 @road2master - -## 1.4.0 (Aug 16, 2022) - -`hippo4j server` 兼容历史低版本,`hippo4j config` 中部分属性名进行了调整,请参考 [hippo4j config 快速开始](https://hippo4j.cn/docs/user_docs/getting-started/hippo4j-core-start)。 - -注意事项: -1. 如果是对已运行 hippo4j server 升级,执行 `/conf/sql-upgrade` 目录下对应的升级脚本。 -2. 需客户端在 1.4.0 及以上版本才可在 hippo4j server 设置线程执行超时时间属性。 - -**Feature** - -- 添加 Alibaba Dubbo 线程池监控及动态变更 -- hippo4j server 支持任务执行超时时间动态修改 -- 阿里 TTL 框架线程池适配 -- 添加动态线程池自动注册功能 -- 订阅回调线程池参数变更 -- 动态线程池监控增加 SPI 自定义功能 -- hippo4j server 支持多种线程池监控方式,例如 Prometheus -- 通知相关参数添加动态变更功能 - -**Bug** - -- 线程池变更:executeTimeOut 变更极端情况下会出现异常 -- 用户登录时候,如果输入了不存在的用户名,后台报空指针异常 -- 修复了对 spring-boot 服务中 tomcat 线程池的兼容问题 -- 排除 Tomcat Jar 使用 Undertow 启动报错 - -**Optimize** - -- hippo4j-core-spring-boot-starter 模块修改名称为 hippo4j-config-spring-boot-starter -- 拆分容器线程池子页面:Tomcat、Undertow、Jetty -- 服务端访问客户端时对 URL 转码 -- MyBatisPlus 修改全局填充方法优化 -- 控制台线程池列表下拉框默认正序 -- 控制台线程池实例菜单,对于非可修改容量队列外,不允许修改队列容量 -- 动态线程池控制台功能变更 -- 租户和项目列表分页查询按照创建时间倒序展示 -- 线程池监控页面图表 UI 优化 -- 设置 maven-gpg-plugin 插件默认不执行 -- 前端控制台相关搜索条件添加必填提示 -- hippo4j 消息通知 & 报警抽象优化 -- 配置中心未配置线程池启动报错 -- 控制台线程池报警 UI 以及功能优化 -- Web、框架线程池编辑弹框 UI 优化 -- 线程池添加、编辑页面 UI 优化 -- 线程池运行详情页前端 UI 优化 - -**Refactor** - -- 删除自定义日志组件 -- 线程池监控功能重构 -- hippo4j core 配置中心生效判断重构 -- 配置变更通知 & 报警通知重构 -- Web 容器线程池适配迁移 hippo4j-adapter - -## 1.3.1 (July 17, 2022) - -注:这是一个兼容历史版本的小范围升级。 - -**Feature** - -- 控制台新增线程池功能设置为 Admin 权限 -- 添加 Hystrix 线程池监控及动态变更 -- 添加 Netty 上传动态线程池监控数据方式 -- 添加 GitHub Actions CI 流程 -- 添加 Spring Kafka 示例项目 -- Tomcat 版本号 >= 9.0.55 线程池适配 - -**Refactor** - -- 更多线程池拆分子目录页面 - -**Optimize** - -- hippo4j core 添加 banner 打印 -- 优化可变更容量阻塞队列名称 - -**BUG** - -- Apollo 配置修改延迟了一个版本 -- Spring Boot 环境下使用 hippo4j-core 接入,配置中心使用 nacos;启动时提示 ConfigService not found - -查看 1.3.1 版本发布:https://github.com/mabaiwan/hippo4j/milestone/9 - -## 1.3.0 (June 06, 2022) - -1.3.0 发布 **适配三方框架的基础框架**。 - -目前已完成 **Dubbo、RabbitMQ、RocketMQ、RocketMQSpringCloudStream** 的线程池适配,后续还会接入 **Kafka、Hystrix** 等框架或中间件的线程池适配。 - -注:这是一个兼容历史版本的重大升级。 - -**Feature** - -- 添加 RabbitMQ 线程池监控及动态变更 -- 添加 RocketMQ 线程池监控及动态变更 -- 添加 Dubbo 线程池监控及动态变更 -- 添加 SpringCloud Stream RocketMQ 消费线程池监控及动态变更 - -**Refactor** - -- 重构容器线程池查询及修改功能 -- 优化配置中心触发监听后,所执行的数据变更逻辑 - -**Optimize** - -- 前端控制台删除无用组件 -- 服务端页面字段未显示中文 -- 控制台 UI 优化 -- 修改线程池实例后实时刷新列表参数 -- 容器线程池编辑仅限 Admin 权限 -- SpringBoot Starter 变更包路径 - -**BUG** - -- 修复 SpringBoot Nacos 动态刷新不生效 -- 报警配置 alarm=false 不配置通知报警平台和接收人报错 - -## 1.2.1 (May 07, 2022) - -**BugFix** - -- apollo 动态配置不生效 -- 修复 hippo4j-core 后置处理器创建线程池问题 -- 重构 hippo4j-core spring 后置处理器逻辑 -- 优化ThreadPoolNotifyAlarmHandler下的空指针异常 -- 修复线程池核心、最大线程数变更问题 -- startup.cmd 未正常读取 conf 配置文件 - -**Optimize** - -- 配置文件中字段歧义 -- 修改代码中历史网址 -- InstanceInfo 的 groupKey 参数重复设置 -- ConfigFileTypeEnum 枚举字段添加注释 -- 线程资源通过线程池创建,不允许自行显示创建线程 -- Guava 版本升级至 30.0-jre 及以上版本 -- SystemClock 替换 System.currentTimeMillis() -- 添加代码格式化插件 Spotless -- 修改线程池文案 - -## 1.2.0 (Mar 13, 2022) - -**Feature** - -- hippo4j-core线程池资源对接 Prometheus 监控 -- hippo4j-core 支持 Zookeeper -- hippo4j-core 支持 Apollo - -**Optimize** - -- 适配非 Web SpringBoot 项目使用 Hippo4J -- 优化报警通知 -- 修复在 JDK 小版本中的兼容性问题 - -**BugFix** - -- server 端查看容器线程池,参数为 null -- 重构线程池查看及容器线程池查看等交互 -- 修复引入 hippo4j-spring-boot-starter 后,运行单元测试报错 -- 修复可能出现的空指针异常 - -## 1.1.0 (Mar 13, 2022) - -Hippo4J 线程池框架 1.1.0 RELEASE 版本,添加了 Hippo4J-Core(依赖配置中心的动态线程池). - -**Feature** - -- 删除 DynamicThreadPoolExecutor 内代码实现,仅通过线程池扩展点进行扩展 -- 通过动态代理实现线程池拒绝策略执行次数统计 -- 抽象通知报警消息模块 -- 抽象 hippo4j 核心组件,不依赖 server 端即可完成动态调参、监控、报警等功能 -- 前端删除线程池按钮添加 Admin 权限 -- 添加线程池任务运行超长报警 -- 容器线程池支持 Undertow -- 容器线程池支持 Jetty -- 重构服务端异常体系 - -**Optimize** - -- 前端项目 Token 失效跳转登录页 -- 优化 Server 启动脚本日志输出 -- 优化前端按钮权限控制粒度 -- 优化线程池报警推送文案 -- 前端弹框样式优化 -- 适配低版本 SpringBoot Bind -- 优化消息通知模块 - -**BugFix** - -- Duplicate entry 'xxx' for key 'uk_configinfo_datagrouptenant' - -## 1.0.0 (Feb 01, 2022) - -**Feature** - -- 线程池运行堆栈查看 -- 扩展 Web 容器线程池动态调参、监控 - -**Optimize** - -- 删除高版本 SpringBoot Api -- ListableBeanFactory#findAnnotationOnBean SpringBoot 低版本适配 -- 优化客户端关闭时调用服务端钩子函数 -- 线程池实例参数弹框添加实例 ID 和线程池状态 -- 补充线程池替换 Hippo4J 文档 -- 1.5.x springboot 引入hippo4j-spring-boot-starter配置项,bean初始化失败 -- 优化线程池参数编辑合理性校验 -- BaseInstanceRegistry 读写锁重构 - -**BugFix** - -- 本地项目线程池实例缓存无法精确清理 -- 线程池实例页面多实例不同 Active 展示错误 -- 创建动态线程池逻辑判断修复 -- 创建动态线程池增强参数未设置 -- 控制消息推送报警频率的方法有并发安全的问题 -- tomcat线程池上下文获取失败 diff --git a/docs/versioned_docs/version-1.4.3/user_docs/dev_manual/_category_.json b/docs/versioned_docs/version-1.4.3/user_docs/dev_manual/_category_.json new file mode 100644 index 00000000..11f12432 --- /dev/null +++ b/docs/versioned_docs/version-1.4.3/user_docs/dev_manual/_category_.json @@ -0,0 +1,8 @@ +{ + "label": "开发者手册", + "position": 5, + "link": { + "type": "generated-index", + "description": "Hippo4J 留给使用者能够扩展的知识点。" + } +} diff --git a/docs/versioned_docs/version-1.4.3/user_docs/dev_manual/rejected-policy-custom.md b/docs/versioned_docs/version-1.4.3/user_docs/dev_manual/rejected-policy-custom.md new file mode 100644 index 00000000..1f2cf694 --- /dev/null +++ b/docs/versioned_docs/version-1.4.3/user_docs/dev_manual/rejected-policy-custom.md @@ -0,0 +1,57 @@ +--- +sidebar_position: 1 +--- + +# 拒绝策略自定义 + +Hippo4J 通过 SPI 的方式对拒绝策略进行扩展,可以让用户在 Hippo4J 中完成自定义拒绝策略实现。 + +## Hippo4J Server 拒绝策略扩展 + +自定义拒绝策略,实现 `CustomRejectedExecutionHandler` 接口,示例如下: + +```java +public class ErrorLogRejectedExecutionHandler implements CustomRejectedExecutionHandler { + + @Override + public Integer getType() { + return 12; + } + + @Override + public RejectedExecutionHandler generateRejected() { + return new CustomErrorLogRejectedExecutionHandler(); + } + + public static class CustomErrorLogRejectedExecutionHandler implements RejectedExecutionHandler { + + @Override + public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) { + Logger logger = LoggerFactory.getLogger(this.getClass()); + logger.error("线程池抛出拒绝策略"); + } + } +} +``` + +创建 `src/main/resources/META-INF/services` 目录,创建 SPI 自定义拒绝策略文件 `cn.hippo4j.common.executor.support.CustomRejectedExecutionHandler`。 + +`cn.hippo4j.common.executor.support.CustomRejectedExecutionHandler` 文件内仅放一行自定义拒绝策略全限定名即可,示例: + +```text +cn.hippo4j.example.core.handler.ErrorLogRejectedExecutionHandler +``` + +创建、修改线程池页面选择 `CustomRejectedPolicy(自定义 SPI 策略)`。 + +![](https://images-machen.oss-cn-beijing.aliyuncs.com/image-20220813173907814.png) + +拒绝策略触发时,完成上述代码效果,仅打印异常日志提示。 + +```text +2022-08-01 21:27:49.515 ERROR 48928 --- [ateHandler.test] r$CustomErrorLogRejectedExecutionHandler : 线程池抛出拒绝策略 +``` + +:::note +具体参考 `hippo4j-example/hippo4j-spring-boot-starter-example` 模块。 +::: diff --git a/docs/versioned_docs/version-1.4.3/user_docs/dev_manual/rejected-policy-info.md b/docs/versioned_docs/version-1.4.3/user_docs/dev_manual/rejected-policy-info.md new file mode 100644 index 00000000..d5c68138 --- /dev/null +++ b/docs/versioned_docs/version-1.4.3/user_docs/dev_manual/rejected-policy-info.md @@ -0,0 +1,50 @@ +--- +sidebar_position: 0 +--- + +# 内置拒绝策略 + +内置两种拒绝策略说明: + +**RunsOldestTaskPolicy**:添加新任务并由主线程运行最早的任务。 + +```java +public class RunsOldestTaskPolicy implements RejectedExecutionHandler { + + @Override + public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) { + if (executor.isShutdown()) { + return; + } + BlockingQueue workQueue = executor.getQueue(); + Runnable firstWork = workQueue.poll(); + boolean newTaskAdd = workQueue.offer(r); + if (firstWork != null) { + firstWork.run(); + } + if (!newTaskAdd) { + executor.execute(r); + } + } +} +``` + +**SyncPutQueuePolicy**:主线程把拒绝任务以阻塞的方式添加到队列。 + +```java +@Slf4j +public class SyncPutQueuePolicy implements RejectedExecutionHandler { + + @Override + public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) { + if (executor.isShutdown()) { + return; + } + try { + executor.getQueue().put(r); + } catch (InterruptedException e) { + log.error("Adding Queue task to thread pool failed.", e); + } + } +} +``` \ No newline at end of file diff --git a/docs/versioned_docs/version-1.4.3/user_docs/getting_started/_category_.json b/docs/versioned_docs/version-1.4.3/user_docs/getting_started/_category_.json new file mode 100644 index 00000000..72b1e151 --- /dev/null +++ b/docs/versioned_docs/version-1.4.3/user_docs/getting_started/_category_.json @@ -0,0 +1,7 @@ +{ + "label": "快速开始", + "position": 3, + "link": { + "type": "generated-index" + } +} diff --git a/docs/versioned_docs/version-1.4.3/user_docs/getting_started/config/_category_.json b/docs/versioned_docs/version-1.4.3/user_docs/getting_started/config/_category_.json new file mode 100644 index 00000000..78b3d9c4 --- /dev/null +++ b/docs/versioned_docs/version-1.4.3/user_docs/getting_started/config/_category_.json @@ -0,0 +1,5 @@ +{ + "label": "依赖配置中心", + "position": 2, + "collapsed": true +} diff --git a/docs/versioned_docs/version-1.4.3/user_docs/getting_started/config/hippo4j-config-default.md b/docs/versioned_docs/version-1.4.3/user_docs/getting_started/config/hippo4j-config-default.md new file mode 100644 index 00000000..9c9e0fc9 --- /dev/null +++ b/docs/versioned_docs/version-1.4.3/user_docs/getting_started/config/hippo4j-config-default.md @@ -0,0 +1,45 @@ +--- +sidebar_position: 4 +--- + +# 参数默认配置 + +曾有多名小伙伴反馈说,项目中线程池一多,配置文件中配置就显得很臃肿。为此 hippo4j-config 开发出了动态线程池默认配置。 + +```yaml +spring: + dynamic: + thread-pool: + default-executor: + core-pool-size: 4 + maximum-pool-size: 6 + blocking-queue: ResizableCapacityLinkedBlockingQueue + queue-capacity: 1024 + execute-time-out: 1000 + keep-alive-time: 9999 + rejected-handler: AbortPolicy + active-alarm: 90 + capacity-alarm: 85 + alarm: true + allow-core-thread-time-out: true + notify: + interval: 5 + receives: chen.ma + executors: + - thread-pool-id: message-produce + - thread-pool-id: message-consume + core-pool-size: 80 + maximum-pool-size: 100 + execute-time-out: 1000 + notify: + interval: 6 + receives: chen.ma +``` + +`spring.dynamic.thread-pool.executors` 层级下,仅需要配置 `thread-pool-id`,其余配置从 `spring.dynamic.thread-pool.default-executor` 读取。 + +如果 `spring.dynamic.thread-pool.executors` 下配置和 `spring.dynamic.thread-pool.default-executor` 冲突,以前者为主。 + +通过该自定义配置方式,可减少大量重复线程池参数配置项,提高核心配置简洁度。 + +提示:`spring.dynamic.thread-pool.default-executor` 层级下参数,不提供动态刷新功能。 diff --git a/docs/versioned_docs/version-1.4.3/user_docs/getting_started/config/hippo4j-config-monitor.md b/docs/versioned_docs/version-1.4.3/user_docs/getting_started/config/hippo4j-config-monitor.md new file mode 100644 index 00000000..c030dc10 --- /dev/null +++ b/docs/versioned_docs/version-1.4.3/user_docs/getting_started/config/hippo4j-config-monitor.md @@ -0,0 +1,122 @@ +--- +sidebar_position: 3 +--- + +# 线程池监控 + +## 线程池监控配置 + +监控前置条件:需要先完成 hippo4j-config 的 [接入工作](/docs/user_docs/getting_started/config/hippo4j-config-start)。 + +接下来引入 SpringBoot Actuator。Spring 2.x 一般都有版本指定,所以这里不用写版本号。 + +```xml + + io.micrometer + micrometer-registry-prometheus + + + + org.springframework.boot + spring-boot-starter-actuator + +``` + +添加动态线程池监控相关配置: + +```yaml +management: + metrics: + export: + prometheus: + enabled: true + server: + port: 29999 # 可选配置,如果不配置该 port,直接使用 ${server.port} + endpoints: + web: + exposure: + include: '*' # 测试使用,开启了所有端点,生产环境不建议 * +spring: + dynamic: + thread-pool: + monitor: + enable: true # 是否开启采集线程池运行时数据 + collect-interval: 5000 # 采集线程池运行数据频率 + collect-types: micrometer # 采集线程池运行数据的类型。eg:log、micrometer。多个可以同时使用,默认 micrometer + initial-delay: 10000 # 项目启动后延迟多久进行采集 + thread-pool-types: dynamic # 采集线程池的类型。eg:dynamic、web、adapter。可任意配置,默认 dynamic +``` + +项目启动,访问 `http://localhost:29999/actuator/prometheus` 出现 `dynamic_thread_pool_` 前缀的指标,即为成功。 + +![](https://images-machen.oss-cn-beijing.aliyuncs.com/image-20220912220401016.png) + +## 配置 Prometheus + +通过 Docker 启动 Prometheus 服务。 + +```shell +docker run -d -p 9090:9090 --name prometheus prom/prometheus +``` + +添加 Prometheus 抽取数据任务。 + +```shell +# 进入 prometheus 容器内部 +docker exec -it prometheus /bin/sh +# 编辑 prometheus 配置文件 +vi /etc/prometheus/prometheus.yml +``` + +scrape_configs 节点下新添加一个 job,如果 Prometheus 是 Docker 方式部署,`{scrape_configs.static_configs.targets}` 需要写本机的 IP。 + +```yaml +scrape_configs: + - job_name: 'dynamic-thread-pool-job' + scrape_interval: 5s + metrics_path: '/actuator/prometheus' + static_configs: + - targets: [ '127.0.0.1:29999' ] +``` + +配置成功后 `exit` 退出容器,并进行 Prometheus 容器重启 `docker restart prometheus`。 + +访问 Prometheus 控制台 `http://localhost:9090/graph` 路径,能够展示相关指标即为配置成功。 + +![](https://images-machen.oss-cn-beijing.aliyuncs.com/image-20220912221237597.png) + +## 配置 Grafana + +```shell +docker run -d -p 3000:3000 --name=grafana grafana/grafana +``` + +访问 Grafana 地址,[http://localhost:3000](http://localhost:3000) 用户名密码:`admin` + +Grafana 访问 `http://localhost:3000/datasources` 导入 Prometheus 数据源。 + +![](https://images-machen.oss-cn-beijing.aliyuncs.com/image-20220912221646866.png) + +> 如果 Prometheus 为 Docker 方式部署,HTTP URL 需要为本地 IP,比如:http://192.168.1.5:9090 + +关注公众号 `龙台的技术笔记`,回复:`监控`,获取 Hippo4J Grafana DashBoard JSON 配置。 + +| 公众号 | 回复关键词 | +|:------------------------------------------------------------------------------------------------------------:|:-------------------------------------------------------------------------------------------------------------------------:| +| ![](https://images-machen.oss-cn-beijing.aliyuncs.com/43_65f6020ed111b6bb3808ec338576bd6b.png?x-oss-process=image/resize,h_300,w_400) | ![](https://images-machen.oss-cn-beijing.aliyuncs.com/image-20220327171957444.png?x-oss-process=image/resize,h_300,w_400) | + +获取到 JSON 文件后,通过 `http://localhost:3000/dashboard/import` 将 JSON 文件导入至 Grafana DashBoard。 + +![](https://images-machen.oss-cn-beijing.aliyuncs.com/image-20220912225627272.png) + +下拉框内动态选择创建好的 Prometheus 数据源,并点击 `Import`。 + +![](https://images-machen.oss-cn-beijing.aliyuncs.com/image-20220912225700200.png) + +即可使用炫酷的 Hippo-4J 动态线程池监控 DashBoard。大家伙儿也可以根据个人喜好进行定制 DashBoard,如果觉得有优化点,欢迎和我联系贡献。 + +![](https://images-machen.oss-cn-beijing.aliyuncs.com/image-20220912225813972.png) + +如果项目客户端启动多个示例,动态线程池监控效果图如下: + +![](https://images-machen.oss-cn-beijing.aliyuncs.com/20220814_hippo4j_monitor.jpg) diff --git a/docs/versioned_docs/version-1.4.3/user_docs/getting_started/config/hippo4j-config-more.md b/docs/versioned_docs/version-1.4.3/user_docs/getting_started/config/hippo4j-config-more.md new file mode 100644 index 00000000..2511b4f3 --- /dev/null +++ b/docs/versioned_docs/version-1.4.3/user_docs/getting_started/config/hippo4j-config-more.md @@ -0,0 +1,80 @@ +--- +sidebar_position: 3 +--- + +# 个性化配置 + +以下所述特性自 hippo4j-config v1.4.2 及以上版本提供,由 hippo4j 核心开发者 [@pizihao](https://github.com/pizihao) 完成相应功能开发。 + +## 需求背景 + +**1)容器及三方框架线程池自定义启用** + +最初设计容器线程池和三方框架线程池的动态变更是和启动无关的。也就是说,启动时不会根据配置文件中相关参数去修改两者对应的线程池配置。 + +这么设计的初衷是因为,不想让 hippo4j 过多的去介入框架原有的功能。因为容器和三方框架都支持线程池参数的自定义。 + +也就造成,可能你在配置中心配置了对应的容器和三方框架线程池参数,启动时是无效的。但当修改配置文件任一配置,容器和三方框架线程池配置将生效。 + +为了更好的用户体验,决定加入启用标识来控制:是否在项目初始化启动时,对容器和三方框架线程池参数进行修改。 + +**2)客户端集群个性化配置** + +大家都知道,hippo4j-config 是依赖配置中心做线程池配置动态变更。这种模式有一种缺点:改动配置文件后,所有客户端都会变更。 + +有些小伙伴希望 hippo4j-config 能够像 hippo4j-server 一样,能够针对单独的客户端进行配置变更。 + +## 容器及三方框架线程池自定义启用 + +容器及三方框架线程池添加启用配置,为了保持统一,动态线程池配置中也有该参数配置。配置项默认开启。 + +```yaml +spring: + dynamic: + thread-pool: + tomcat: + enable: true + executors: + - thread-pool-id: message-consume + enable: false + adapter-executors: + - threadPoolKey: 'input' + enable: true +``` + +## 客户端集群个性化配置 + +分别在动态线程池、容器线程池以及三方框架线程池配置下增加 `nodes` 配置节点,通过该配置可匹配需要变更的节点。 + +```yaml +spring: + dynamic: + thread-pool: + tomcat: + nodes: 192.168.1.5:*,192.168.1.6:8080 + executors: + - thread-pool-id: message-consume + nodes: 192.168.1.5:* + adapter-executors: + - threadPoolKey: 'input' + nodes: 192.168.1.5:* +``` + +来一段代码方法中的注释,大家就基本明白如何使用了。 + +```java +/** + * Matching nodes
+ * nodes is ip + port.Get 'nodes' in the new Properties,Compare this with the ip + port of Application.
+ * support prefix pattern matching. e.g:
+ *
    + *
  • 192.168.1.5:* -- Matches all ports of 192.168.1.5
  • + *
  • 192.168.1.*:2009 -- Matches 2009 port of 192.168.1.*
  • + *
  • * -- all
  • + *
  • empty -- all
  • + *
+ * The format of ip + port is ip : port. + */ +``` + +`nodes` 可与 `enable` 同时使用。如此,基于配置中心的动态线程池实现方式,将能够更方便的支持个性化需求。 diff --git a/docs/versioned_docs/version-1.4.3/user_docs/getting_started/config/hippo4j-config-springboot1x-adapter.md b/docs/versioned_docs/version-1.4.3/user_docs/getting_started/config/hippo4j-config-springboot1x-adapter.md new file mode 100644 index 00000000..46311923 --- /dev/null +++ b/docs/versioned_docs/version-1.4.3/user_docs/getting_started/config/hippo4j-config-springboot1x-adapter.md @@ -0,0 +1,121 @@ +--- +sidebar_position: 5 +--- + +# 适配SpringBoot1x + +目前已支持 Nacos、Apollo 配置中心适配 SpringBoot 1.5.x 版本。 + +```xml + + cn.hippo4j + hippo4j-config-spring-boot-1x-starter + 1.4.3 + +``` + +Nacos SpringBoot 配置如下: + +```yaml +spring: + cloud: + nacos: + config: + ext-config: + - data-id: hippo4j-nacos.yaml + group: DEFAULT_GROUP + refresh: true + server-addr: 127.0.0.1:8848 + dynamic: + thread-pool: + config-file-type: yml + nacos: + data-id: hippo4j-nacos.yaml + group: DEFAULT_GROUP +``` + +Apollo SpringBoot 配置如下: + +```yaml +apollo: + autoUpdateInjectedSpringProperties: true + bootstrap: + eagerLoad: + enabled: true + enabled: true + namespaces: application + meta: http://127.0.0.1:8080 +app: + id: dynamic-threadpool-example +spring: + dynamic: + thread-pool: + apollo: + namespace: application +``` + +动态线程池通用配置如下: + +```yaml +management: + context-path: /actuator + security: + enabled: false +server: + port: 8091 + servlet: + context-path: /example +spring: + application: + name: dynamic-threadpool-example + dynamic: + thread-pool: + banner: true + check-state-interval: 5 + collect-type: micrometer + config-file-type: properties + enable: true + executors: + - active-alarm: 80 + alarm: true + allow-core-thread-time-out: true + blocking-queue: LinkedBlockingQueue + capacity-alarm: 80 + core-pool-size: 1 + execute-time-out: 1000 + keep-alive-time: 6691 + maximum-pool-size: 1 + notify: + interval: 8 + receives: chen.ma + queue-capacity: 1 + rejected-handler: AbortPolicy + thread-name-prefix: message-consume + thread-pool-id: message-consume + - active-alarm: 80 + alarm: true + allow-core-thread-time-out: true + blocking-queue: LinkedBlockingQueue + capacity-alarm: 80 + core-pool-size: 1 + execute-time-out: 1000 + keep-alive-time: 6691 + maximum-pool-size: 1 + notify: + interval: 8 + receives: chen.ma + queue-capacity: 1 + rejected-handler: AbortPolicy + thread-name-prefix: message-produce + thread-pool-id: message-produce + notify-platforms: + - platform: WECHAT + token: ac0426a5-c712-474c-9bff-72b8b8f5caff + profiles: + active: dev +``` + +具体 Demo 运行请参考以下示例模块,已验证对应线程池动态变更、报警以及运行时监控功能。 + +- `/hippo4j-config-nacos-spring-boot-1x-starter-example` +- `hippo4j-example/hippo4j-config-apollo-spring-boot-1x-starter-example` diff --git a/docs/versioned_docs/version-1.4.3/user_docs/getting_started/config/hippo4j-config-start.md b/docs/versioned_docs/version-1.4.3/user_docs/getting_started/config/hippo4j-config-start.md new file mode 100644 index 00000000..6a326717 --- /dev/null +++ b/docs/versioned_docs/version-1.4.3/user_docs/getting_started/config/hippo4j-config-start.md @@ -0,0 +1,193 @@ +--- +sidebar_position: 1 +--- + +# 接入流程 + +Nacos、Apollo、Zookeeper、ETCD、Polaris 配置中心任选其一。 + +## hippo4j 配置 + +```xml + + cn.hippo4j + hippo4j-config-spring-boot-starter + 1.4.3 + +``` + +启动类上添加注解 `@EnableDynamicThreadPool`。 + +```java +@SpringBootApplication +@EnableDynamicThreadPool +public class ExampleApplication { + public static void main(String[] args) { + SpringApplication.run(ExampleApplication.class, args); + } +} +``` + +SpringBoot 应用配置文件添加: + +```yaml +server: + port: 8090 + servlet: + context-path: /example + +spring: + profiles: + active: dev + + dynamic: + thread-pool: + # 是否开启动态线程池 + enable: true + # 是否打印 banner + banner: true + # 是否开启线程池数据采集,对接 Micrometer、ES、Log 等 + collect: true + # 检查线程池状态,是否达到报警条件,单位毫秒 + check-state-interval: 3000 + # 通知报警平台,请替换为自己创建的群机器人 + notify-platforms: + - platform: 'WECHAT' + token: xxx + - platform: 'DING' + token: xxx + secret: xxx # 加签专属 + - platform: 'LARK' + token: xxx + # Nacos、Apollo、Zookeeper、ETCD、Polaris 任选其一 + nacos: + data-id: xxx + group: xxx + apollo: + namespace: xxxx + # 配置中心文件格式 + config-file-type: yml + # tomcat、undertow、jetty 三种容器线程池,任选其一 + undertow: + core-pool-size: 100 + maximum-pool-size: 200 + keep-alive-time: 1000 + # 全局通知配置-是否报警 + alarm: true + # 活跃度报警阈值;假设线程池最大线程数 10,当线程数达到 8 发起报警 + active-alarm: 80 + # 容量报警阈值;假设阻塞队列容量 100,当容量达到 80 发起报警 + capacity-alarm: 80 + # 报警间隔,同一线程池下同一报警纬度,在 interval 时间内只会报警一次,单位秒 + alarm-interval: 8 + # 企业微信填写用户 ID(填写其它将无法达到 @ 效果)、钉钉填手机号、飞书填 ou_ 开头唯一 ID + receives: xxx + # 动态线程池列表 + executors: + - thread-pool-id: 'message-consume' + # 核心线程数 + core-pool-size: 1 + # 最大线程数 + maximum-pool-size: 1 + # 阻塞队列名称,参考 BlockingQueueTypeEnum,支持 SPI + blocking-queue: 'LinkedBlockingQueue' + # 阻塞队列大小 + queue-capacity: 1 + # 执行超时时间,超过此时间发起报警,单位毫秒 + execute-time-out: 1000 + # 拒绝策略名称,参考 RejectedPolicyTypeEnum,支持 SPI + rejected-handler: 'AbortPolicy' + # 线程存活时间,单位秒 + keep-alive-time: 1024 + # 是否允许核心线程超时 + allow-core-thread-time-out: true + # 线程工厂名称前缀 + thread-name-prefix: 'message-consume' + # 是否报警 + alarm: true + # 活跃度报警阈值;假设线程池最大线程数 10,当线程数达到 8 发起报警 + active-alarm: 80 + # 容量报警阈值;假设阻塞队列容量 100,当容量达到 80 发起报警 + capacity-alarm: 80 + # 通知配置,线程池中通知配置如果存在,则会覆盖全局通知配置 + notify: + # 报警间隔,同一线程池下同一报警纬度,在 interval 时间内只会报警一次,单位分钟 + interval: 8 + # 企业微信填写用户 ID(填写其它将无法达到 @ 效果)、钉钉填手机号、飞书填 ou_ 开头唯一 ID + receives: xxx + - thread-pool-id: 'message-produce' + core-pool-size: 1 + maximum-pool-size: 1 + queue-capacity: 1 + execute-time-out: 1000 + blocking-queue: 'LinkedBlockingQueue' + rejected-handler: 'AbortPolicy' + keep-alive-time: 1024 + allow-core-thread-time-out: true + thread-name-prefix: 'message-consume' + alarm: true + active-alarm: 80 + capacity-alarm: 80 + notify: + interval: 8 + receives: xxx +``` + +## ThreadPoolExecutor 适配 + +添加线程池配置类,通过 `@DynamicThreadPool` 注解修饰。`threadPoolId` 为服务端创建的线程池 ID。 + +```java +package cn.hippo4j.example; + +import cn.hippo4j.core.executor.DynamicThreadPool; +import cn.hippo4j.core.executor.support.ThreadPoolBuilder; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import java.util.concurrent.ThreadPoolExecutor; + +@Configuration +public class ThreadPoolConfig { + + @Bean + @DynamicThreadPool + public ThreadPoolExecutor messageConsumeDynamicExecutor() { + String threadPoolId = "message-consume"; + ThreadPoolExecutor messageConsumeDynamicExecutor = ThreadPoolBuilder.builder() + .threadFactory(threadPoolId) + .threadPoolId(threadPoolId) + .dynamicPool() + .build(); + return messageConsumeDynamicExecutor; + } + + @Bean + @DynamicThreadPool + public ThreadPoolExecutor messageProduceDynamicExecutor() { + String threadPoolId = "message-produce"; + ThreadPoolExecutor messageProduceDynamicExecutor = ThreadPoolBuilder.builder() + .threadFactory(threadPoolId) + .threadPoolId(threadPoolId) + .dynamicPool() + .build(); + return messageProduceDynamicExecutor; + } + +} +``` + +通过 ThreadPoolBuilder 构建动态线程池,只有 threadFactory、threadPoolId 为必填项,其它参数会从配置中心拉取。 + +项目中使用上述定义的动态线程池,如下所示: + +```java +@Resource +private ThreadPoolExecutor messageConsumeDynamicExecutor; + +messageConsumeDynamicExecutor.execute(() -> xxx); + +@Resource +private ThreadPoolExecutor messageProduceDynamicExecutor; + +messageProduceDynamicExecutor.execute(() -> xxx); +``` diff --git a/docs/versioned_docs/version-1.4.3/user_docs/getting_started/difference.md b/docs/versioned_docs/version-1.4.3/user_docs/getting_started/difference.md new file mode 100644 index 00000000..4e07d71b --- /dev/null +++ b/docs/versioned_docs/version-1.4.3/user_docs/getting_started/difference.md @@ -0,0 +1,37 @@ +--- +sidebar_position: 0 +--- + +# 运行模式介绍 + +1.1.0 版本发布后,Hippo-4J 分为两种使用模式:轻量级依赖配置中心以及无中间件依赖版本。 + +![](https://images-machen.oss-cn-beijing.aliyuncs.com/image-20220319154626314.png) + +### hippo4j-config + +**轻量级动态线程池管理**,依赖 Nacos、Apollo、Zookeeper、ETCD、Polaris 等三方配置中心(任选其一)完成线程池参数动态变更,支持运行时报警、监控等功能。 + +> 监控功能配置详见:[线程池监控](/docs/user_docs/getting_started/config/hippo4j-config-monitor) + +![](https://images-machen.oss-cn-beijing.aliyuncs.com/20220814_hippo4j_monitor.jpg) + +### hippo4j-server + +**部署 hippo4j-server 服务**,通过可视化 Web 界面完成线程池的创建、变更以及查看,不依赖三方中间件。 + +相比较 hippo4j-config,功能会更强大,但同时也引入了一定的复杂性。需要部署一个 Java 服务,以及依赖 MySQL 数据库。 + +![](https://images-machen.oss-cn-beijing.aliyuncs.com/1644032018254-min.gif) + +### 使用总结 + +| | hippo4j-config | hippo4j-server | +| ---- | ---------------------------------------------------- | ------------------------------------------------------------ | +| 依赖 | Nacos、Apollo、Zookeeper、ETCD、Polaris 配置中心(任选其一) | 部署 Hippo-4J Server(内部无依赖中间件) | +| 使用 | 配置中心补充线程池相关参数 | Hippo-4J Server Web 控制台添加线程池记录 | +| 功能 | 包含基础功能:参数动态化、运行时监控、报警等 | 基础功能之外扩展控制台界面、线程池堆栈查看、线程池运行信息实时查看、历史运行信息查看、线程池配置集群个性化等 | + +使用建议:根据公司情况选择,如果基本功能可以满足使用,选择 hippo4j-config 使用即可;如果希望更多的功能,可以选择 hippo4j-server。 + +**两者在进行替换的时候,无需修改业务代码**。 diff --git a/docs/versioned_docs/version-1.4.3/user_docs/getting_started/hippo4j-adapter.md b/docs/versioned_docs/version-1.4.3/user_docs/getting_started/hippo4j-adapter.md new file mode 100644 index 00000000..e879fe75 --- /dev/null +++ b/docs/versioned_docs/version-1.4.3/user_docs/getting_started/hippo4j-adapter.md @@ -0,0 +1,72 @@ +--- +sidebar_position: 6 +--- + +# 三方框架线程池适配 + +Hippo4J 目前已支持的三方框架线程池列表: + +- Dubbo +- Hystrix +- RabbitMQ +- RocketMQ +- AlibabaDubbo +- RocketMQSpringCloudStream +- RabbitMQSpringCloudStream + +引入 Hippo4J Server 或 Core 的 Maven Jar 坐标后,还需要引入对应的框架适配 Jar: + +```xml + + cn.hippo4j + + hippo4j-spring-boot-starter-adapter-dubbo + + hippo4j-spring-boot-starter-adapter-alibaba-dubbo + + hippo4j-spring-boot-starter-adapter-hystrix + + hippo4j-spring-boot-starter-adapter-rabbitmq + + hippo4j-spring-boot-starter-adapter-rocketmq + + hippo4j-spring-boot-starter-adapter-spring-cloud-stream-rocketmq + + hippo4j-spring-boot-starter-adapter-spring-cloud-stream-rabbitmq + 1.4.3 + +``` + +如果想省事,仅需引入一个全量包,框架底层会根据条件判断加载具体线程池适配器。 + +```xml + + cn.hippo4j + hippo4j-spring-boot-starter-adapter-all + 1.4.3 + +``` + +## Hippo4J Server + +Hippo4J Server 仅需要引入上述 Jar 包,即可在 Hippo4J Server 的控制台进行查看及修改三方框架线程池。 + +![](https://images-machen.oss-cn-beijing.aliyuncs.com/image-20220531194810047.png) + +## Hippo4J Config + +Hippo4J Config 除了依赖上述适配 Jar 包外,还需要在配置中心添加以下配置项。 + +```yaml +spring: + dynamic: + thread-pool: + # 省略其它配置 + adapter-executors: + # threadPoolKey 代表线程池标识 + - threadPoolKey: 'input' + # mark 为三方线程池框架类型,参见文初已支持框架集合 + mark: 'RocketMQSpringCloudStream' + corePoolSize: 10 + maximumPoolSize: 10 +``` diff --git a/docs/versioned_docs/version-1.4.3/user_docs/getting_started/img/docsVersionDropdown.png b/docs/versioned_docs/version-1.4.3/user_docs/getting_started/img/docsVersionDropdown.png new file mode 100644 index 00000000..97e41646 Binary files /dev/null and b/docs/versioned_docs/version-1.4.3/user_docs/getting_started/img/docsVersionDropdown.png differ diff --git a/docs/versioned_docs/version-1.4.3/user_docs/getting_started/img/grafana-monitor.jpg b/docs/versioned_docs/version-1.4.3/user_docs/getting_started/img/grafana-monitor.jpg new file mode 100644 index 00000000..336bd980 Binary files /dev/null and b/docs/versioned_docs/version-1.4.3/user_docs/getting_started/img/grafana-monitor.jpg differ diff --git a/docs/versioned_docs/version-1.4.3/user_docs/getting_started/img/localeDropdown.png b/docs/versioned_docs/version-1.4.3/user_docs/getting_started/img/localeDropdown.png new file mode 100644 index 00000000..e257edc1 Binary files /dev/null and b/docs/versioned_docs/version-1.4.3/user_docs/getting_started/img/localeDropdown.png differ diff --git a/docs/versioned_docs/version-1.4.3/user_docs/getting_started/server/_category_.json b/docs/versioned_docs/version-1.4.3/user_docs/getting_started/server/_category_.json new file mode 100644 index 00000000..4063c17f --- /dev/null +++ b/docs/versioned_docs/version-1.4.3/user_docs/getting_started/server/_category_.json @@ -0,0 +1,5 @@ +{ + "label": "无中间件依赖", + "position": 3, + "collapsed": true +} diff --git a/docs/versioned_docs/version-1.4.3/user_docs/getting_started/server/hippo4j-server-config.md b/docs/versioned_docs/version-1.4.3/user_docs/getting_started/server/hippo4j-server-config.md new file mode 100644 index 00000000..e1ef853f --- /dev/null +++ b/docs/versioned_docs/version-1.4.3/user_docs/getting_started/server/hippo4j-server-config.md @@ -0,0 +1,19 @@ +--- +sidebar_position: 3 +--- + +# 服务端配置 + +`hippo4j.core.clean-history-data-enable` + +是否开启线程池历史数据清洗,默认开启。 + +`hippo4j.core.clean-history-data-period` + +线程池历史数据保留时间,默认值:30,单位分钟。 + +服务端会保留这个配置时间的数据,超过这个时间则会被清理。比如按照默认值 30 分钟来说,12:00 收集到的数据,12:30 就会被清理删除。 + +`hippo4j.core.monitor.report-type` + +客户端监控上报服务端类型,可选值:http、netty,默认 http。服务端开启 netty 配置后,需要在客户端对应开启才可生效。用来应对大量动态线程池监控场景。 diff --git a/docs/versioned_docs/version-1.4.3/user_docs/getting_started/server/hippo4j-server-monitor.md b/docs/versioned_docs/version-1.4.3/user_docs/getting_started/server/hippo4j-server-monitor.md new file mode 100644 index 00000000..b743c790 --- /dev/null +++ b/docs/versioned_docs/version-1.4.3/user_docs/getting_started/server/hippo4j-server-monitor.md @@ -0,0 +1,122 @@ +--- +sidebar_position: 2 +--- + +# 线程池监控 + +Server 模式默认内置线程池运行时采集和监控功能,如果想要使用 Prometheus + Grafana 的方式可以查看以下内容。 + +## 线程池监控配置 + +接下来引入 SpringBoot Actuator。Spring 2.x 一般都有版本指定,所以这里不用写版本号。 + +```xml + + io.micrometer + micrometer-registry-prometheus + + + + org.springframework.boot + spring-boot-starter-actuator + +``` + +添加动态线程池监控相关配置: + +```yaml +management: + metrics: + export: + prometheus: + enabled: true + server: + port: 29999 # 可选配置,如果不配置该 port,直接使用 ${server.port} + endpoints: + web: + exposure: + include: '*' # 测试使用,开启了所有端点,生产环境不建议 * +spring: + dynamic: + thread-pool: + monitor: + enable: true # 是否开启采集线程池运行时数据 + collect-interval: 5000 # 采集线程池运行数据频率 + collect-types: server,micrometer # 采集线程池运行数据的类型。eg:server、micrometer。多个可以同时使用,默认 server + initial-delay: 10000 # 项目启动后延迟多久进行采集 + thread-pool-types: dynamic # 采集线程池的类型。eg:dynamic、web、adapter。可任意配置,默认 dynamic +``` + +项目启动,访问 `http://localhost:29999/actuator/prometheus` 出现 `dynamic_thread_pool_` 前缀的指标,即为成功。 + +![](https://images-machen.oss-cn-beijing.aliyuncs.com/image-20220912220401016.png) + +## 配置 Prometheus + +通过 Docker 启动 Prometheus 服务。 + +```shell +docker run -d -p 9090:9090 --name prometheus prom/prometheus +``` + +添加 Prometheus 抽取数据任务。 + +```shell +# 进入 prometheus 容器内部 +docker exec -it prometheus /bin/sh +# 编辑 prometheus 配置文件 +vi /etc/prometheus/prometheus.yml +``` + +scrape_configs 节点下新添加一个 job,如果 Prometheus 是 Docker 方式部署,`{scrape_configs.static_configs.targets}` 需要写本机的 IP。 + +```yaml +scrape_configs: + - job_name: 'dynamic-thread-pool-job' + scrape_interval: 5s + metrics_path: '/actuator/prometheus' + static_configs: + - targets: [ '127.0.0.1:29999' ] +``` + +配置成功后 `exit` 退出容器,并进行 Prometheus 容器重启 `docker restart prometheus`。 + +访问 Prometheus 控制台 `http://localhost:9090/graph` 路径,能够展示相关指标即为配置成功。 + +![](https://images-machen.oss-cn-beijing.aliyuncs.com/image-20220912221237597.png) + +## 配置 Grafana + +```shell +docker run -d -p 3000:3000 --name=grafana grafana/grafana +``` + +访问 Grafana 地址,[http://localhost:3000](http://localhost:3000) 用户名密码:`admin` + +Grafana 访问 `http://localhost:3000/datasources` 导入 Prometheus 数据源。 + +![](https://images-machen.oss-cn-beijing.aliyuncs.com/image-20220912221646866.png) + +> 如果 Prometheus 为 Docker 方式部署,HTTP URL 需要为本地 IP,比如:http://192.168.1.5:9090 + +关注公众号 `龙台的技术笔记`,回复:`监控`,获取 Hippo4J Grafana DashBoard JSON 配置。 + +| 公众号 | 回复关键词 | +|:------------------------------------------------------------------------------------------------------------:|:-------------------------------------------------------------------------------------------------------------------------:| +| ![](https://images-machen.oss-cn-beijing.aliyuncs.com/43_65f6020ed111b6bb3808ec338576bd6b.png?x-oss-process=image/resize,h_300,w_400) | ![](https://images-machen.oss-cn-beijing.aliyuncs.com/image-20220327171957444.png?x-oss-process=image/resize,h_300,w_400) | + +获取到 JSON 文件后,通过 `http://localhost:3000/dashboard/import` 将 JSON 文件导入至 Grafana DashBoard。 + +![](https://images-machen.oss-cn-beijing.aliyuncs.com/image-20220912225627272.png) + +下拉框内动态选择创建好的 Prometheus 数据源,并点击 `Import`。 + +![](https://images-machen.oss-cn-beijing.aliyuncs.com/image-20220912225700200.png) + +即可使用炫酷的 Hippo-4J 动态线程池监控 DashBoard。大家伙儿也可以根据个人喜好进行定制 DashBoard,如果觉得有优化点,欢迎和我联系贡献。 + +![](https://images-machen.oss-cn-beijing.aliyuncs.com/image-20220912225813972.png) + +如果项目客户端启动多个示例,动态线程池监控效果图如下: + +![](https://images-machen.oss-cn-beijing.aliyuncs.com/20220814_hippo4j_monitor.jpg) diff --git a/docs/versioned_docs/version-1.4.3/user_docs/getting_started/server/hippo4j-server-start.md b/docs/versioned_docs/version-1.4.3/user_docs/getting_started/server/hippo4j-server-start.md new file mode 100644 index 00000000..69957eb3 --- /dev/null +++ b/docs/versioned_docs/version-1.4.3/user_docs/getting_started/server/hippo4j-server-start.md @@ -0,0 +1,127 @@ +--- +sidebar_position: 1 +--- + +# 接入流程 + +部署服务端,参考 [部署手册](/docs/user_docs/ops/hippo4j-server-deploy)。 + +服务端创建 [租户、项目](/docs/user_docs/other/issue#租户和项目在-hippo4j-中是什么意思) 和线程池记录。 + +需要注意,项目 ID 需要与配置文件 `{application.name}` 保持一致。 + +:::note +租户、项目、线程池 ID 如果由多个词组成,建议以 - 进行分割。比如:message-center。 +::: + +## Hippo4J 配置 + +SpringBoot Pom 引入 Hippo4j Starter Jar。 + +```xml + + cn.hippo4j + hippo4j-spring-boot-starter + 1.4.3 + +``` + +启动类上添加注解 `@EnableDynamicThreadPool`。 + +```java +@SpringBootApplication +@EnableDynamicThreadPool +public class ExampleApplication { + public static void main(String[] args) { + SpringApplication.run(ExampleApplication.class, args); + } +} +``` + +SpringBoot 应用配置文件添加: + +```yaml +spring: + profiles: + active: dev + application: + # 服务端创建的项目 id 需要与 application.name 保持一致 + name: dynamic-threadpool-example + dynamic: + thread-pool: + # 服务端地址 + server-addr: http://localhost:6691 + # 用户名 + username: admin + # 密码 + password: 123456 + # 租户 id, 对应 tenant 表 + namespace: prescription + # 项目 id, 对应 item 表 + item-id: ${spring.application.name} +``` + +## ThreadPoolExecutor 适配 + +添加线程池配置类,通过 `@DynamicThreadPool` 注解修饰。`threadPoolId` 为服务端创建的线程池 ID。 + +```java +package cn.hippo4j.example; + +import cn.hippo4j.core.executor.DynamicThreadPool; +import cn.hippo4j.core.executor.support.ThreadPoolBuilder; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import java.util.concurrent.ThreadPoolExecutor; + +@Configuration +public class ThreadPoolConfig { + + @Bean + @DynamicThreadPool + public ThreadPoolExecutor messageConsumeDynamicExecutor() { + String threadPoolId = "message-consume"; + ThreadPoolExecutor messageConsumeDynamicExecutor = ThreadPoolBuilder.builder() + .threadFactory(threadPoolId) + .threadPoolId(threadPoolId) + .dynamicPool() + .build(); + return messageConsumeDynamicExecutor; + } + + @Bean + @DynamicThreadPool + public ThreadPoolExecutor messageProduceDynamicExecutor() { + String threadPoolId = "message-produce"; + ThreadPoolExecutor messageProduceDynamicExecutor = ThreadPoolBuilder.builder() + .threadFactory(threadPoolId) + .threadPoolId(threadPoolId) + .dynamicPool() + .build(); + return messageProduceDynamicExecutor; + } + +} +``` + +通过 ThreadPoolBuilder 构建动态线程池,只有 threadFactory、threadPoolId 为必填项,其它参数会从 hippo4j-server 服务拉取。 + +:::note +创建线程池时建议填充实际的参数。如果在连接 Hippo4J Server 端失败时,会使用填充配置创建线程池。 +::: + +项目中使用上述定义的动态线程池,如下所示: + +```java +@Resource +private ThreadPoolExecutor messageConsumeDynamicExecutor; + +messageConsumeDynamicExecutor.execute(() -> xxx); + +@Resource +private ThreadPoolExecutor messageProduceDynamicExecutor; + +messageProduceDynamicExecutor.execute(() -> xxx); +``` + diff --git a/docs/versioned_docs/version-1.4.3/user_docs/intro.md b/docs/versioned_docs/version-1.4.3/user_docs/intro.md new file mode 100644 index 00000000..fd9e5dcb --- /dev/null +++ b/docs/versioned_docs/version-1.4.3/user_docs/intro.md @@ -0,0 +1,616 @@ +--- +sidebar_position: 1 +--- + +# 简介 + +## 线程池痛点 + +线程池是一种基于池化思想管理线程的工具,使用线程池可以减少创建销毁线程的开销,避免线程过多导致系统资源耗尽。在高并发以及大批量的任务处理场景,线程池的使用是必不可少的。 + +如果有在项目中实际使用线程池,相信你可能会遇到以下痛点: + +- 线程池随便定义,线程资源过多,造成服务器高负载。 + +- 线程池参数不易评估,随着业务的并发提升,业务面临出现故障的风险。 +- 线程池任务执行时间超过平均执行周期,开发人员无法感知。 +- 线程池任务堆积,触发拒绝策略,影响既有业务正常运行。 +- 当业务出现超时、熔断等问题时,因为没有监控,无法确定是不是线程池引起。 +- 原生线程池不支持运行时变量的传递,比如 MDC 上下文遇到线程池就 GG。 +- 无法执行优雅关闭,当项目关闭时,大量正在运行的线程池任务被丢弃。 +- 线程池运行中,任务执行停止,怀疑发生死锁或执行耗时操作,但是无从下手。 + +## 什么是 Hippo-4J + +Hippo-4J 通过对 JDK 线程池增强,以及扩展三方框架底层线程池等功能,为业务系统提高线上运行保障能力。 + +提供以下功能支持: + +- 全局管控 - 管理应用线程池实例。 + +- 动态变更 - 应用运行时动态变更线程池参数,包括不限于:核心、最大线程数、阻塞队列容量、拒绝策略等。 +- 通知报警 - 内置四种报警通知策略,线程池活跃度、容量水位、拒绝策略以及任务执行时间超长。 +- 运行监控 - 实时查看线程池运行时数据,最近半小时线程池运行数据图表展示。 +- 功能扩展 - 支持线程池任务传递上下文;项目关闭时,支持等待线程池在指定时间内完成任务。 +- 多种模式 - 内置两种使用模式:[依赖配置中心](https://hippo4j.cn/docs/user_docs/getting_started/config/hippo4j-config-start) 和 [无中间件依赖](https://hippo4j.cn/docs/user_docs/getting_started/server/hippo4j-server-start)。 +- 容器管理 - Tomcat、Jetty、Undertow 容器线程池运行时查看和线程数变更。 +- 框架适配 - Dubbo、Hystrix、RabbitMQ、RocketMQ 等消费线程池运行时数据查看和线程数变更。 + +## 快速开始 + +对于本地演示目的,请参阅 [Quick start](https://hippo4j.cn/docs/user_docs/user_guide/quick-start) + +演示环境: [http://console.hippo4j.cn/index.html](http://console.hippo4j.cn/index.html) + +## 接入登记 + +更多接入的公司,欢迎在 [登记地址](https://github.com/opengoofy/hippo4j/issues/13) 登记,登记仅仅为了产品推广。 + +## 联系我 + +![](https://user-images.githubusercontent.com/77398366/185774220-c11951f9-e130-4d60-8204-afb5c51d4401.png) + +扫码添加微信,备注:hippo4j,邀您加入群聊。若图片加载不出来,访问 [官网站点](https://hippo4j.cn/docs/user_docs/other/group)。 + +## 友情链接 + +- [[ Sa-Token ]](https://github.com/dromara/sa-token):一个轻量级 java 权限认证框架,让鉴权变得简单、优雅! + +- [[ HertzBeat ]](https://github.com/dromara/hertzbeat):易用友好的云监控系统, 无需 Agent, 强大自定义监控能力。 +- [[ JavaGuide ]](https://github.com/Snailclimb/JavaGuide):一份涵盖大部分 Java 程序员所需要掌握的核心知识。 +- [[ toBeBetterJavaer ]](https://github.com/itwanger/toBeBetterJavaer):一份通俗易懂、风趣幽默的 Java 学习指南。 + +## 贡献者 + +感谢所有为项目作出贡献的开发者。如果有意贡献,参考 [good first issue](https://github.com/opengoofy/hippo4j/issues?q=is%3Aopen+is%3Aissue+label%3A%22good+first+issue%22)。 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + itmachen +
+ 小马哥 +
+
+ + shining-stars-lk +
+ Lucky 8 +
+
+ + weihubeats +
+ Weihubeats +
+
+ + pirme +
+ 李金来 +
+
+ + shanjianq +
+ Shanjianq +
+
+ + hippo4jbot +
+ Hippo4jbot[bot] +
+
+ + iwangjie +
+ 王杰 +
+
+ + BigXin0109 +
+ BigXin0109 +
+
+ + pizihao +
+ Pizihao +
+
+ + Gdk666 +
+ Null +
+
+ + xqxyxchy +
+ Null +
+
+ + road2master +
+ Lijx +
+
+ + maxisvest +
+ Null +
+
+ + baymax55 +
+ Baymax55 +
+
+ + zhuanghaozhe +
+ 庄昊哲 +
+
+ + liulinfei121 +
+ Null +
+
+ + Atmanuclear +
+ Null +
+
+ + hippo4j +
+ Hippo4j +
+
+ + imyzt +
+ 杨镇涛 +
+
+ + Tliutao +
+ Liutao +
+
+ + monsterxxp +
+ Null +
+
+ + voilaf +
+ Null +
+
+ + wulangcode +
+ WuLang +
+
+ + gywanghai +
+ 二师兄 +
+
+ + skyemin +
+ Null +
+
+ + Redick01 +
+ Redick Liu +
+
+ + xiaochengxuyuan +
+ Sean Wu +
+
+ + HKMV +
+ Serenity +
+
+ + gewuwo +
+ 格悟沃 +
+
+ + hushtian +
+ Null +
+
+ + jinlingmei +
+ Null +
+
+ + linlinjie +
+ Null +
+
+ + selectbook +
+ Leping Huang +
+
+ + soulmz +
+ Soulzz +
+
+ + tomsun28 +
+ Tomsun28 +
+
+ + backbay2-yzg +
+ 游祖光 +
+
+ + puppet4 +
+ Tudo +
+
+ + yanrongzhen +
+ 严荣振 +
+
+ + 2EXP +
+ Null +
+
+ + onesimplecoder +
+ Alic +
+
+ + CalebZYC +
+ Null +
+
+ + Hibernate5666 +
+ Cheng Xihong +
+
+ + smartdj +
+ DJ +
+
+ + dmego +
+ Dmego +
+
+ + dousp +
+ Douspeng +
+
+ + hl1248 +
+ Lucas +
+
+ + gentlelynn +
+ Lynn +
+
+ + alexhaoxuan +
+ Alexli +
+
+ + qizhongju +
+ Bug搬运工 +
+
+ + san4j +
+ San4j +
+
+ + zhenyed +
+ Zhenye +
+
+ + dongming0920 +
+ Null +
+
+ + f497196689 +
+ Fengjing +
+
+ + Snailclimb +
+ Guide +
+
+ + hbw1994 +
+ Null +
+
+ + hncboy +
+ Null +
+
+ + stronglong +
+ Itermis +
+
+ + janey668 +
+ Null +
+
+ + klsq94 +
+ Hui Cao +
+
+ + kongyanbo-cx +
+ Null +
+
+ + lishiyu +
+ Null +
+
+ + Nhxz +
+ Nhxz +
+
+ + op-lht +
+ Op-lht +
+
+ + wangjie-github +
+ Wangjie +
+
+ + wangyi123456 +
+ Null +
+
+ + Williamren97 +
+ William Ren +
+
+ + wzw8795 +
+ Null +
+
+ + huaxianchao +
+ Null +
+
+ + yangzhiw +
+ Opentanent +
+
+ + yhc777 +
+ Null +
+
+ + zhaiweij +
+ Zhaiweij +
+
+ + zhaojinchao95 +
+ Zhaojinchao +
+
+ + zj1997 +
+ Null +
+
+ + li-xiao-shuang +
+ 李晓双 Li Xiao Shuang +
+
+ + oreoft +
+ 没有气的汽水 +
+
+ + wo883721 +
+ Xinhao +
+
+ + Createsequence +
+ 黄成兴 +
+
diff --git a/docs/versioned_docs/version-1.4.3/user_docs/ops/_category_.json b/docs/versioned_docs/version-1.4.3/user_docs/ops/_category_.json new file mode 100644 index 00000000..d5b7d1e8 --- /dev/null +++ b/docs/versioned_docs/version-1.4.3/user_docs/ops/_category_.json @@ -0,0 +1,7 @@ +{ + "label": "运维指南", + "position": 4, + "link": { + "type": "generated-index" + } +} diff --git a/docs/versioned_docs/version-1.4.3/user_docs/ops/hippo4j-server-deploy.md b/docs/versioned_docs/version-1.4.3/user_docs/ops/hippo4j-server-deploy.md new file mode 100644 index 00000000..f78457ba --- /dev/null +++ b/docs/versioned_docs/version-1.4.3/user_docs/ops/hippo4j-server-deploy.md @@ -0,0 +1,45 @@ +--- +sidebar_position: 1 +--- + +# 源码包部署 + +[RELEASE](https://github.com/opengoofy/hippo4j/releases) 页面下载对应版本并进行解压。 + +## 初始化 + +修改数据库相关信息。 + +```txt +/conf/application.properties +``` + +如果是新运行 Hippo-4J,数据库执行下述 SQL 脚本即可。 + +```txt +/conf/hippo4j_manager.sql +``` + +如果是对已运行 Hippo-4J 升级,请查看 `/conf/sql-upgrade` 目录下,是否有目标版本对应的升级脚本。 + +## 直接运行 + +Mac Linux 启动执行。 + +```txt +sh ./bin/startup.sh +``` + +Windows 启动执行。 + +```txt +bin/startup.cmd +``` + +## 访问控制台 + +启动成功后,访问链接。用户名密码:admin 123456 + +```txt +localhost:6691/index.html +``` diff --git a/docs/versioned_docs/version-1.4.3/user_docs/ops/server-docker.md b/docs/versioned_docs/version-1.4.3/user_docs/ops/server-docker.md new file mode 100644 index 00000000..141c597a --- /dev/null +++ b/docs/versioned_docs/version-1.4.3/user_docs/ops/server-docker.md @@ -0,0 +1,50 @@ +--- +sidebar_position: 2 +--- + +# Docker部署 + +## 镜像启动 + +Docker 镜像默认使用内置 H2 数据库,数据持久化到 Docker 容器存储卷中。 + +```shell +docker run -d -p 6691:6691 --name hippo4j-server hippo4j/hippo4j-server +``` + +或者,底层存储数据库切换为 MySQL。`DATASOURCE_HOST` 需要切换为本地 IP,不能使用 `127.0.0.1` 或 `localhost`。 + +```shell +docker run -d -p 6691:6691 --name hippo4j-server \ +-e DATASOURCE_MODE=mysql \ +-e DATASOURCE_HOST=xxx.xxx.xxx.xxx \ +-e DATASOURCE_PORT=3306 \ +-e DATASOURCE_DB=hippo4j_manager \ +-e DATASOURCE_USERNAME=root \ +-e DATASOURCE_PASSWORD=root \ +hippo4j/hippo4j-server +``` + +访问 Server 控制台,路径 `http://localhost:6691/index.html` ,默认用户名密码:admin / 123456 + +## 镜像构建 + +如果想要自定义镜像,可以通过以下命令快速构建 Hippo4J Server: + +方式一: + +```shell +# 进入到 hippo4j-server/hippo4j-bootstrap 工程路径下 +mvn clean package -Dskip.spotless.apply=true +# 默认打包是打包的 tag 是 latest +docker build -t hippo4j/hippo4j-server ../hippo4j-bootstrap +``` + +方式二: + +通过 `maven docker plugin` + +```shell +# 进入到 hippo4j-server 工程路径下 +mvn clean package -DskipTests -Dskip.spotless.apply=true docker:build +``` diff --git a/docs/versioned_docs/version-1.4.2/community/_category_.json b/docs/versioned_docs/version-1.4.3/user_docs/other/_category_.json similarity index 56% rename from docs/versioned_docs/version-1.4.2/community/_category_.json rename to docs/versioned_docs/version-1.4.3/user_docs/other/_category_.json index bcd256c9..a74d7432 100644 --- a/docs/versioned_docs/version-1.4.2/community/_category_.json +++ b/docs/versioned_docs/version-1.4.3/user_docs/other/_category_.json @@ -1,6 +1,6 @@ { - "label": "社区", - "position": 1, + "label": "其它", + "position": 6, "link": { "type": "generated-index" } diff --git a/docs/versioned_docs/version-1.4.3/user_docs/other/group.md b/docs/versioned_docs/version-1.4.3/user_docs/other/group.md new file mode 100644 index 00000000..e75e96be --- /dev/null +++ b/docs/versioned_docs/version-1.4.3/user_docs/other/group.md @@ -0,0 +1,9 @@ +--- +sidebar_position: 1 +--- + +# 加群沟通 + +扫码添加微信,备注:`hippo4j`,邀您加入群聊。 + +![](https://images-machen.oss-cn-beijing.aliyuncs.com/185774220-c11951f9-e130-4d60-8204-afb5c51d4401.png) diff --git a/docs/versioned_docs/version-1.4.3/user_docs/other/issue.md b/docs/versioned_docs/version-1.4.3/user_docs/other/issue.md new file mode 100644 index 00000000..11f48a12 --- /dev/null +++ b/docs/versioned_docs/version-1.4.3/user_docs/other/issue.md @@ -0,0 +1,90 @@ +--- +sidebar_position: 2 +--- + +# 常见问题 + +- 租户和项目在 Hippo4J 中是什么意思 +- 控制台线程池管理和线程池实例的区别 +- 示例项目为什么会有跨域请求 +- 更新代码后运行时服务端SQL报错 +- 生产环境如何不启用动态线程池 +- Server 端宕机会影响 Client 运行么 +- Hippo4J 的发布方式是怎样的?如何选择正确的版本 +- 群机器人接受不到通知报警 +- 设置线程池参数优先级问题 +- 线程池实例中修改队列容量参数问题 +- 控制台 SocketTimeoutException: connect timed out + +## 租户和项目在 Hippo4J 中是什么意思 + +Hippo4J 按照租户、项目、线程池的维度划分。 + +举个例子,小编在一家公司的公共组件团队,团队中负责消息、短链接网关等项目。公共组件是租户,消息或短链接就是项目。 + +## 控制台线程池管理和线程池实例的区别 + +在线程池管理中修改线程池参数,客户端并不能实时感知到并变更参数,需要重启客户端。而线程池实例中去对具体的实例修改参数时,客户端无需重启,可以实时感知到参数变化。如果二者针对同一线程 +池的参数配置不同,则在重启客户端时,客户端会去拉去线程池管理中的参数配置。 + +二者对应的定位:线程池管理中的配置是常态化配置。而线程池实例里的配置变更像是一种临时修改,比如突发的流量激增等场景,并不具备普适性。 + +## 示例项目为什么会有跨域请求 + +~~正常大家在部署时,服务端项目和客户端都在同一网络下,进行内网通信,是没有问题的。~~ + +~~因为示例项目中,服务端部署在外网,而客户端注册到服务端 IP 是内网的,所以不通。~~ + +~~涉及功能:线程池实例-查看、编辑,容器线程池。~~ + +1.2.0 版本后,服务端访问客户端已变成,浏览器访问服务端,服务端转发客户端的形式完成调用,跨域问题已解决。 + +## 更新代码后运行时服务端SQL报错 + +如果更新代码运行功能出错,大概率是因为项目新增或修改了表结构。如版本升级迭代涉及数据库表变更,会额外提供 SQL 变更文件。 + +如若第一次使用,初始化 SQL 脚本地址:[hippo4j_manager.sql](https://github.com/longtai-cn/hippo4j/blob/develop/hippo4j-server/conf/hippo4j_manager.sql)。 + +> 友情提示:每次执行数据库表或数据变更时,一定要保持提前备份的好习惯。 + +## 生产环境如何不启用动态线程池 + +测试环境已经引入 Hippo4J,暂时不打算上线生产环境。 + +生产环境指定配置 `spring.dynamic.thread-pool.enable=false`,测试环境和生产环境配置就会隔离。 + +## Server 端宕机会影响 Client 运行么 + +不会。Client 端包含对 Server 端的健康检查机制,Server 端不可用时会停止交互,检查到可用时重新建立连接交互。 + +## Hippo4J 的发布方式是怎样的?如何选择正确的版本 + +Hippo4J 发布时可能会涉及到两端发布,分别是 Server 和 Starter。如无特殊说明,**每一次的版本升级将兼容上一版本代码**。 + +- 如涉及 Server 发布,会在 [发布列表页面](https://github.com/longtai-cn/hippo4j/releases) 创建最新的发行版本; +- 如涉及 Starter 发布,将直接推送 Starter Jar 至中央仓库,Server 包版本不变。 + +## 群机器人接受不到通知报警 + +如果是钉钉机器人,需在机器人配置自定义关键字,才可发送成功。如下所示: + +![](https://images-machen.oss-cn-beijing.aliyuncs.com/image-20220530200133377.png?x-oss-process=image/resize,h_500,w_800) + +如果使用 hippo4j-server,请检查在 hippo4j-server 添加的报警通知记录,是否在客户端项目启动前,因为客户端只有在启动时会去 hippo4j-server 拉取报警通知记录。 + +重启客户端项目,会重新拉取最新报警推送配置,问题解决。 + +## 设置线程池参数优先级问题 + +- 当使用 `@DynamicThreadPool` 进行修饰的方法中和在管理界面设置中同时存在的话,则管理界面设置的优先级最高; +- 如果连接 server 端失败的话,使用 `@DynamicThreadPool` 进行修饰设置的优先级最高。 + +## 线程池实例中修改队列容量参数问题 + +在线程池管理中添加时,只有当选择队列类型为 `ResizableCapacityLinkedBlockingQueue` 时,后续再进行修改容量大小时才会实时的刷新修改成功。 + +## 控制台 SocketTimeoutException: connect timed out + +控制台中触发的某些操作涉及到 hippo4j-server 调用客户端项目。如果 hippo4j-server 部署在测试环境,而客户端项目为本地启动,则会触发该问题。 + +为什么编辑线程池参数不报错?因为线程池的动态变更是客户端主动发起连接,和服务端保持了一个长轮询,所以不存在服务端主动调用客户端行为。 diff --git a/docs/versioned_docs/version-1.4.3/user_docs/other/official-ccounts.md b/docs/versioned_docs/version-1.4.3/user_docs/other/official-ccounts.md new file mode 100644 index 00000000..61a1a5c6 --- /dev/null +++ b/docs/versioned_docs/version-1.4.3/user_docs/other/official-ccounts.md @@ -0,0 +1,23 @@ +--- +sidebar_position: 5 +--- + +# 推荐公众号 + +## JavaGuide + +专注Java后端学习和大厂面试的公众号! + +![](https://images-machen.oss-cn-beijing.aliyuncs.com/JavaGuide.png) + +## HelloGitHub + +HelloGitHub,专注于开源社区技术和知识内容分享。 + +![](https://images-machen.oss-cn-beijing.aliyuncs.com/HelloGitHub.png) + +## macrozheng + +专注Java技术分享,解析优质开源项目。涵盖SpringBoot、SpringCloud、Docker、K8S等实用技术,作者Github开源项目mall(50K+Star)。 + +![](https://images-machen.oss-cn-beijing.aliyuncs.com/macrozheng.png) diff --git a/docs/versioned_docs/version-1.4.3/user_docs/other/operation.md b/docs/versioned_docs/version-1.4.3/user_docs/other/operation.md new file mode 100644 index 00000000..ba9ed7f0 --- /dev/null +++ b/docs/versioned_docs/version-1.4.3/user_docs/other/operation.md @@ -0,0 +1,23 @@ +--- +sidebar_position: 6 +--- + +# 公众号合作 + +## 推荐须知 + +hippo4j 作为一款新兴动态线程池框架,开源出来的时间比较晚,目前迫切需要不同的途径进行推广。 + +如果您是公众号运营者或者开源爱好者,欢迎将 hippo4j 推荐给您的粉丝。 + +1. 您无需为 hippo4j 专门撰写文案,只需要直接导入 [推荐文章](https://mp.weixin.qq.com/s/JTTwcBEiK_MnFcPTZl3zGA) 即可。 +2. 在文章底部或内容中留下项目官网或者 GitHub 仓库链接。 +3. 文章需至少 1000+ 的阅读量。 + +作为推荐回报,hippo4j 可以为您: + +1. 在框架官方文档 [推荐公众号](/docs/user_docs/other/official-ccounts) 页面处留下您的公众号二维码。 +2. 在框架官方交流群里@全体成员推广您的公众号一次,附带介绍语。 +3. 您的公众号所有新推文章都可以将链接发送到 hippo4j 交流群中,增加阅读量。 + +如果您还有除公众号以外的其它途径可以与 hippo4j 相互推荐,欢迎 [加群沟通](/docs/user_docs/other/group)。 diff --git a/docs/versioned_docs/version-1.4.3/user_docs/other/question.md b/docs/versioned_docs/version-1.4.3/user_docs/other/question.md new file mode 100644 index 00000000..49fd4d77 --- /dev/null +++ b/docs/versioned_docs/version-1.4.3/user_docs/other/question.md @@ -0,0 +1,246 @@ +--- +sidebar_position: 3 +--- + +# 问题提问 + +文档引用自:[提问的智慧](https://github.com/ryanhanwu/How-To-Ask-Questions-The-Smart-Way) + +## 在提问之前 + +在你准备要通过电子邮件、新闻群组或者聊天室提出技术问题前,请先做到以下事情: + +1. 尝试在你准备提问的论坛的旧文章中搜索答案。 +2. 尝试上网搜索以找到答案。 +3. 尝试阅读手册以找到答案。 +4. 尝试阅读常见问题文件(FAQ)以找到答案。 +5. 尝试自己检查或试验以找到答案。 +6. 向你身边的强者朋友打听以找到答案。 +7. 如果你是程序开发者,请尝试阅读源代码以找到答案。 + +当你提出问题的时候,请先表明你已经做了上述的努力;这将有助于树立你并不是一个不劳而获且浪费别人的时间的提问者。如果你能一并表达在做了上述努力的过程中所**学到**的东西会更好,因为我们更乐于回答那些表现出能从答案中学习的人的问题。 + +## 当你提问时 + +### 慎选提问的论坛 +小心选择你要提问的场合。如果你做了下述的事情,你很可能被忽略掉或者被看作失败者: + +* 在与主题不合的论坛上贴出你的问题。 +* 在探讨进阶技术问题的论坛张贴非常初级的问题;反之亦然。 +* 在太多的不同新闻群组上重复转贴同样的问题(cross-post)。 +* 向既非熟人也没有义务解决你问题的人发送私人电邮。 + +因此,第一步是找到对的论坛。再说一次,Google 和其它搜索引擎还是你的朋友,用它们来找到与你遭遇到困难的软硬件问题最相关的网站。通常那儿都有常见问题(FAQ)、邮件列表及相关说明文件的链接。如果你的努力(包括**阅读** FAQ)都没有结果,网站上也许还有报告 Bug(Bug-reporting)的流程或链接,如果是这样,链过去看看。 + +### 使用有意义且描述明确的标题 + +在邮件列表、新闻群组或论坛中,大约 50 字以内的标题是抓住资深专家注意力的好机会。别用喋喋不休的帮帮忙、跪求、急(更别说救命啊!!!!这样让人反感的话,用这种标题会被条件反射式地忽略)来浪费这个机会。不要妄想用你的痛苦程度来打动我们,而应该是在这点空间中使用极简单扼要的描述方式来提出问题。 + +一个好标题范例是`目标 —— 差异`式的描述,许多技术支持组织就是这样做的。在`目标`部分指出是哪一个或哪一组东西有问题,在`差异`部分则描述与期望的行为不一致的地方。 + +> 蠢问题:救命啊!我的笔记本电脑不能正常显示了! + +> 聪明问题:X.org 6.8.1 的鼠标指针会变形,某牌显卡 MV1005 芯片组。 + +> 更聪明问题:X.org 6.8.1 的鼠标指针,在某牌显卡 MV1005 芯片组环境下 - 会变形。 + +### 使用清晰、正确、精准且合乎语法的语句 + +我们从经验中发现,粗心的提问者通常也会粗心地写程序与思考(我敢打包票)。回答粗心大意者的问题很不值得,我们宁愿把时间耗在别处。 + +正确的拼写、标点符号和大小写是很重要的。一般来说,如果你觉得这样做很麻烦,不想在乎这些,那我们也觉得麻烦,不想在乎你的提问。花点额外的精力斟酌一下字句,用不着太僵硬与正式 —— 事实上,黑客文化很看重能准确地使用非正式、俚语和幽默的语句。但它**必须很**准确,而且有迹象表明你是在思考和关注问题。 + +### 精确地描述问题并言之有物 + +* 仔细、清楚地描述你的问题或 Bug 的症状。 +* 描述问题发生的环境(机器配置、操作系统、应用程序、以及相关的信息),提供经销商的发行版和版本号(如:`Fedora Core 4`、`Slackware 9.1`等)。 +* 描述在提问前你是怎样去研究和理解这个问题的。 +* 描述在提问前为确定问题而采取的诊断步骤。 +* 描述最近做过什么可能相关的硬件或软件变更。 +* 尽可能地提供一个可以`重现这个问题的可控环境`的方法。 + +尽量去揣测一个黑客会怎样反问你,在你提问之前预先将黑客们可能提出的问题回答一遍。 + +以上几点中,当你报告的是你认为可能在代码中的问题时,给黑客一个可以重现你的问题的环境尤其重要。当你这么做时,你得到有效的回答的机会和速度都会大大的提升。 + +[Simon Tatham](http://www.chiark.greenend.org.uk/~sgtatham/) 写过一篇名为《[如何有效的报告 Bug](http://www.chiark.greenend.org.uk/~sgtatham/bugs-cn.html)》的出色文章。强力推荐你也读一读。 + +### 话不在多而在精 + +你需要提供精确有内容的信息。这并不是要求你简单的把成堆的出错代码或者资料完全转录到你的提问中。如果你有庞大而复杂的测试样例能重现程序挂掉的情境,尽量将它剪裁得越小越好。 + +这样做的用处至少有三点。 +第一,表现出你为简化问题付出了努力,这可以使你得到回答的机会增加; +第二,简化问题使你更有可能得到**有用**的答案; +第三,在精炼你的 bug 报告的过程中,你很可能就自己找到了解决方法或权宜之计。 + +### 别动辄声称找到 Bug + +当你在使用软件中遇到问题,除非你非常、**非常**的有根据,不要动辄声称找到了 Bug。提示:除非你能提供解决问题的源代码补丁,或者提供回归测试来表明前一版本中行为不正确,否则你都多半不够完全确信。这同样适用在网页和文件,如果你(声称)发现了文件的`Bug`,你应该能提供相应位置的修正或替代文件。 + +请记得,还有其他许多用户没遇到你发现的问题,否则你在阅读文件或搜索网页时就应该发现了(你在抱怨前[已经做了这些,是吧](#在提问之前)?)。这也意味着很有可能是你弄错了而不是软件本身有问题。 + +编写软件的人总是非常辛苦地使它尽可能完美。如果你声称找到了 Bug,也就是在质疑他们的能力,即使你是对的,也有可能会冒犯到其中某部分人。当你在标题中嚷嚷着有`Bug`时,这尤其严重。 + +提问时,即使你私下非常确信已经发现一个真正的 Bug,最好写得像是**你**做错了什么。如果真的有 Bug,你会在回复中看到这点。这样做的话,如果真有 Bug,维护者就会向你道歉,这总比你惹恼别人然后欠别人一个道歉要好一点。 + +### 低声下气不能代替你的功课 + +有些人明白他们不该粗鲁或傲慢的提问并要求得到答复,但他们选择另一个极端 —— 低声下气:`我知道我只是个可悲的新手,一个撸瑟,但...`。这既使人困扰,也没有用,尤其是伴随着与实际问题含糊不清的描述时更令人反感。 + +别用原始灵长类动物的把戏来浪费你我的时间。取而代之的是,尽可能清楚地描述背景条件和你的问题情况。这比低声下气更好地定位了你的位置。 + +有时网页论坛会设有专为新手提问的版面,如果你真的认为遇到了初学者的问题,到那去就是了,但一样别那么低声下气。 + +### 描述问题症状而非你的猜测 + +告诉黑客们你认为问题是怎样造成的并没什么帮助。(如果你的推断如此有效,还用向别人求助吗?),因此要确信你原原本本告诉了他们问题的症状,而不是你的解释和理论;让黑客们来推测和诊断。如果你认为陈述自己的猜测很重要,清楚地说明这只是你的猜测,并描述为什么它们不起作用。 + +**蠢问题** + +> 我在编译内核时接连遇到 SIG11 错误, +> 我怀疑某条飞线搭在主板的走线上了,这种情况应该怎样检查最好? + +**聪明问题** + +> 我的组装电脑是 FIC-PA2007 主机板搭载 AMD K6/233 CPU(威盛 Apollo VP2 芯片组), +> 256MB Corsair PC133 SDRAM 内存,在编译内核时,从开机 20 分钟以后就频频产生 SIG11 错误, +> 但是在头 20 分钟内从没发生过相同的问题。重新启动也没有用,但是关机一晚上就又能工作 20 分钟。 +> 所有内存都换过了,没有效果。相关部分的标准编译记录如下… + +由于以上这点似乎让许多人觉得难以配合,这里有句话可以提醒你:`所有的诊断专家都来自密苏里州。` 美国国务院的官方座右铭则是:`让我看看`(出自国会议员 Willard D. Vandiver 在 1899 年时的讲话:`我来自一个出产玉米,棉花,牛蒡和民主党人的国家,滔滔雄辩既不能说服我,也不会让我满意。我来自密苏里州,你必须让我看看。`) 针对诊断者而言,这并不是一种怀疑,而只是一种真实而有用的需求,以便让他们看到的是与你看到的原始证据尽可能一致的东西,而不是你的猜测与归纳的结论。所以,大方的展示给我们看吧! + +### 按发生时间先后列出问题症状 + +问题发生前的一系列操作,往往就是对找出问题最有帮助的线索。因此,你的说明里应该包含你的操作步骤,以及机器和软件的反应,直到问题发生。在命令行处理的情况下,提供一段操作记录(例如运行脚本工具所生成的),并引用相关的若干行(如 20 行)记录会非常有帮助。 + +如果挂掉的程序有诊断选项(如 -v 的详述开关),试着选择这些能在记录中增加调试信息的选项。记住,`多`不等于`好`。试着选取适当的调试级别以便提供有用的信息而不是让读者淹没在垃圾中。 + +如果你的说明很长(如超过四个段落),在开头简述问题,接下来再按时间顺序详述会有所帮助。这样黑客们在读你的记录时就知道该注意哪些内容了。 + +### 描述目标而不是过程 + +如果你想弄清楚如何做某事(而不是报告一个 Bug),在开头就描述你的目标,然后才陈述重现你所卡住的特定步骤。 + +经常寻求技术帮助的人在心中有个更高层次的目标,而他们在自以为能达到目标的特定道路上被卡住了,然后跑来问该怎么走,但没有意识到这条路本身就有问题。结果要费很大的劲才能搞定。 + +**蠢问题** + +> 我怎样才能从某绘图程序的颜色选择器中取得十六进制的 RGB 值? + +**聪明问题** + +> 我正试着用替换一幅图片的色码(color table)成自己选定的色码,我现在知道的唯一方法是编辑每个色码区块(table slot), +> 但却无法从某绘图程序的颜色选择器取得十六进制的 RGB 值。 + +第二种提问法比较聪明,你可能得到像是```建议采用另一个更合适的工具```的回复。 + +### 清楚明确的表达你的问题以及需求 + +漫无边际的提问是近乎无休无止的时间黑洞。最有可能给你有用答案的人通常也正是最忙的人(他们忙是因为要亲自完成大部分工作)。这样的人对无节制的时间黑洞相当厌恶,所以他们也倾向于厌恶那些漫无边际的提问。 + +如果你明确表述需要回答者做什么(如提供指点、发送一段代码、检查你的补丁、或是其他等等),就最有可能得到有用的答案。因为这会定出一个时间和精力的上限,便于回答者能集中精力来帮你。这么做很棒。 + +要理解专家们所处的世界,请把专业技能想像为充裕的资源,而回复的时间则是稀缺的资源。你要求他们奉献的时间越少,你越有可能从真正专业而且很忙的专家那里得到解答。 + +所以,界定一下你的问题,使专家花在辨识你的问题和回答所需要付出的时间减到最少,这技巧对你有用答案相当有帮助 —— 但这技巧通常和简化问题有所区别。因此,问`我想更好地理解 X,可否指点一下哪有好一点说明?`通常比问`你能解释一下 X 吗?`更好。如果你的代码不能运作,通常请别人看看哪里有问题,比要求别人替你改正要明智得多。 + +### 礼多人不怪,而且有时还很有帮助 + +彬彬有礼,多用`请`和`谢谢您的关注`,或`谢谢你的关照`。让大家都知道你对他们花时间免费提供帮助心存感激。 + +坦白说,这一点并没有比使用清晰、正确、精准且合乎语法和避免使用专用格式重要(也不能取而代之)。黑客们一般宁可读有点唐突但技术上鲜明的 Bug 报告,而不是那种有礼但含糊的报告。(如果这点让你不解,记住我们是按问题能教给我们什么来评价问题的价值的) + +然而,如果你有一串的问题待解决,客气一点肯定会增加你得到有用回应的机会。 + +(我们注意到,自从本指南发布后,从资深黑客那里得到的唯一严重缺陷反馈,就是对预先道谢这一条。一些黑客觉得`先谢了`意味着事后就不用再感谢任何人的暗示。我们的建议是要么先说`先谢了`,**然后**事后再对回复者表示感谢,或者换种方式表达感激,譬如用`谢谢你的关注`或`谢谢你的关照`。) + +## 不该问的问题 + +以下是几个经典蠢问题,以及黑客没回答时心中所想的: + +问题:[我能在哪找到 X 程序或 X 资源?](#q1) + +问题:[我怎样用 X 做 Y?](#q2) + +问题:[我的程序/设定/SQL 语句没有用](#q3) + +问题:[我的 Windows 电脑有问题,你能帮我吗?](#q4) + +问题:[我的程序不会动了,我认为系统工具 X 有问题](#q5) + +问题:[我在安装 Linux(或者 X )时有问题,你能帮我吗?](#q6) + +问题:[我怎么才能破解 root 帐号/窃取 OP 特权/读别人的邮件呢?](#q7) + +--- + +> 问题:我能在哪找到 X 程序或 X 资源? + +回答:就在我找到它的地方啊,白痴 —— 搜索引擎的那一头。天哪!难道还有人不会用 [Google](https://www.google.com) 吗? + +> 问题:我怎样用 X 做 Y? + +回答:如果你想解决的是 Y ,提问时别给出可能并不恰当的方法。这种问题说明提问者不但对 X 完全无知,也对 Y 要解决的问题糊涂,还被特定形势禁锢了思维。最好忽略这种人,等他们把问题搞清楚了再说。 + +> 问题:我的{程序/设定/SQL 语句}没有用 + +回答:这不算是问题吧,我对要我问你二十个问题才找得出你真正问题的问题没兴趣 —— 我有更有意思的事要做呢。在看到这类问题的时候,我的反应通常不外如下三种 + +* 你还有什么要补充的吗? +* 真糟糕,希望你能搞定。 +* 这关我屁事? + +> 问题:我的 Windows 电脑有问题,你能帮我吗? + +回答:能啊,扔掉微软的垃圾,换个像 Linux 或 BSD 的开源操作系统吧。 + +注意:如果程序有官方版 Windows 或者与 Windows 有互动(如 Samba),你**可以**问与 Windows 相关的问题,只是别对问题是由 Windows 操作系统而不是程序本身造成的回复感到惊讶, 因为 Windows 一般来说实在太烂,这种说法通常都是对的。 + +> 问题:我的程序不会动了,我认为系统工具 X 有问题 + +回答:你完全有可能是第一个注意到被成千上万用户反复使用的系统调用与函数库文件有明显缺陷的人,更有可能的是你完全没有根据。不同凡响的说法需要不同凡响的证据,当你这样声称时,你必须有清楚而详尽的缺陷说明文件作后盾。 + +> 问题:我在安装 Linux(或者 X )时有问题,你能帮我吗? + +回答:不能,我只有亲自在你的电脑上动手才能找到毛病。还是去找你当地的 Linux 使用群组者寻求实际的指导吧(你能在[这儿](http://www.linux.org/groups/index.html)找到用户群组的清单)。 + +注意:如果安装问题与某 Linux 的发行版有关,在它的邮件列表、论坛或本地用户群组中提问也许是恰当的。此时,应描述问题的准确细节。在此之前,先用 `Linux` 和**所有**被怀疑的硬件作关键词仔细搜索。 + +> 问题:我怎么才能破解 root 帐号/窃取 OP 特权/读别人的邮件呢? + +回答:想要这样做,说明了你是个卑鄙小人;想找个黑客帮你,说明你是个白痴! + +## 好问题与蠢问题 + +最后,我将透过举一些例子,来说明怎样聪明的提问;同一个问题的两种问法被放在一起,一种是愚蠢的,另一种才是明智的。 + +**蠢问题**: + +> 我从 foo 项目找来的源码没法编译。它怎么这么烂? + +他觉得都是别人的错,这个傲慢自大的提问者。 + +**聪明问题**: + +> foo 项目代码在 Nulix 6.2 版下无法编译通过。我读过了 FAQ,但里面没有提到跟 Nulix 有关的问题。这是我编译过程的记录,我有什么做的不对的地方吗? + +提问者已经指明了环境,也读过了 FAQ,还列出了错误,并且他没有把问题的责任推到别人头上,他的问题值得被关注。 + +**蠢问题**: + +> 我的主机板有问题了,谁来帮我? + +某黑客对这类问题的回答通常是:`好的,还要帮你拍拍背和换尿布吗?`,然后按下删除键。 + +**聪明问题**: + +> 我在 S2464 主机板上试过了 X 、 Y 和 Z ,但没什么作用,我又试了 A 、 B 和 C 。请注意当我尝试 C 时的奇怪现象。显然 florbish 正在 grommicking,但结果出人意料。通常在 Athlon MP 主机板上引起 grommicking 的原因是什么?有谁知道接下来我该做些什么测试才能找出问题? + +## 如果得不到回答 + +如果仍得不到回答,请不要以为我们觉得无法帮助你。有时只是看到你问题的人不知道答案罢了。没有回应不代表你被忽视,虽然不可否认这种差别很难区分。 + +总的来说,简单的重复张贴问题是个很糟的点子。这将被视为无意义的喧闹。有点耐心,知道你问题答案的人可能生活在不同的时区,可能正在睡觉,也有可能你的问题一开始就没有组织好。 + +你可以通过其他渠道获得帮助,这些渠道通常更适合初学者的需要。 diff --git a/docs/versioned_docs/version-1.4.3/user_docs/user_guide/_category_.json b/docs/versioned_docs/version-1.4.3/user_docs/user_guide/_category_.json new file mode 100644 index 00000000..6dc10c33 --- /dev/null +++ b/docs/versioned_docs/version-1.4.3/user_docs/user_guide/_category_.json @@ -0,0 +1,8 @@ +{ + "label": "用户指南", + "position": 2, + "link": { + "type": "generated-index", + "description": "帮助想要了解 Hippo4J 的用户快速掌握核心开发理念。" + } +} diff --git a/docs/versioned_docs/version-1.4.3/user_docs/user_guide/frame.md b/docs/versioned_docs/version-1.4.3/user_docs/user_guide/frame.md new file mode 100644 index 00000000..47f568fa --- /dev/null +++ b/docs/versioned_docs/version-1.4.3/user_docs/user_guide/frame.md @@ -0,0 +1,60 @@ +--- +sidebar_position: 1 +--- + +# 为什么写 + +[美团线程池文章](https://tech.meituan.com/2020/04/02/java-pooling-pratice-in-meituan.html "美团线程池文章") 介绍中,因为业务对线程池参数没有合理配置,触发过几起生产事故,进而引发了一系列思考。最终决定封装线程池动态参数调整,扩展线程池监控以及消息报警等功能。 + +在开源平台找了挺多动态线程池项目,从功能性以及健壮性而言,个人感觉不满足企业级应用。 + +因为对动态线程池比较感兴趣,加上想写一个有意义的项目,所以决定自己来造一个轻量级的轮子。 + +想给项目起一个简单易记的名字,类似于 Eureka、Nacos、Redis;后和朋友商量,决定命名:**Hippo4J**。 + +![](https://images-machen.oss-cn-beijing.aliyuncs.com/动态线程池功能架构-1.jpg) + +## 它解决了什么问题 + +线程池在业务系统应该都有使用到,帮助业务流程提升效率以及管理线程,多数场景应用于大量的异步任务处理。 + +虽然线程池提供了我们许多便利,但也并非尽善尽美,比如下面这些问题就无法很好解决。 + +- 线程池随便定义,线程资源过多,造成服务器高负载。 + +- 线程池参数不易评估,随着业务的并发提升,业务面临出现故障的风险。 + +- 线程池任务执行时间超过平均执行周期,开发人员无法感知。 + +- 线程池任务堆积,触发拒绝策略,影响既有业务正常运行。 + +- 当业务出现超时、熔断等问题时,因为没有监控,无法确定是不是线程池引起。 + +- 原生线程池不支持运行时变量的传递,比如 MDC 上下文遇到线程池就 GG。 + +- 无法执行优雅关闭,当项目关闭时,大量正在运行的线程池任务被丢弃。 + +- 线程池运行中,任务执行停止,怀疑发生死锁或执行耗时操作,但是无从下手。 + +Hippo4J 很好解决了这些问题,它将业务中所有线程池统一管理,增强原生线程池系列功能。 + +## 它有什么特性 + +应用系统中线程池并不容易管理。参考美团的设计,Hippo4J 按照租户、项目、线程池的维度划分。再加上系统权限,让不同的开发、管理人员负责自己系统的线程池操作。 + +举个例子,小编在一家公司的公共组件团队,团队中负责消息、短链接网关等项目。公共组件是租户,消息或短链接就是项目。 + +Hippo4J 除去动态修改线程池,还包含实时查看线程池运行时指标、负载报警、配置日志管理等。 + +- `hippo4j-adapter`:适配对第三方框架中的线程池进行监控,如 Dubbo、RocketMQ、Hystrix 等; +- `hippo4j-auth`:用户、角色、权限等; +- `hippo4j-common`:多个模块公用代码实现; +- `hippo4j-config`:提供线程池准实时参数更新功能; +- `hippo4j-console`:对接前端控制台; +- `hippo4j-core`:核心的依赖,包括配置、核心包装类等; +- `hippo4j-discovery`:提供线程池项目实例注册、续约、下线等功能; +- `hippo4j-example` :示例工程; +- `hippo4j-message` :配置变更以及报警通知发送; +- `hippo4j-monitor` :线程池运行时监控; +- `hippo4j-server` :Server 端发布需要的模块聚合; +- `hippo4j-spring-boot`:SpringBoot Starter。 diff --git a/docs/versioned_docs/version-1.4.3/user_docs/user_guide/framework.md b/docs/versioned_docs/version-1.4.3/user_docs/user_guide/framework.md new file mode 100644 index 00000000..226ddf61 --- /dev/null +++ b/docs/versioned_docs/version-1.4.3/user_docs/user_guide/framework.md @@ -0,0 +1,51 @@ +--- +sidebar_position: 2 +--- + +# 架构设计 + +简单来说,Hippo4J 从部署的角度上分为两种角色:Server 端和 Client 端。 + +Server 端是 Hippo4J 项目打包出的 Java 进程,功能包括用户权限、线程池监控以及执行持久化的动作。 + +Client 端指的是我们 SpringBoot 应用,通过引入 Hippo4J Starter Jar 包负责与 Server 端进行交互。 + +比如拉取 Server 端线程池数据、动态更新线程池配置以及采集上报线程池运行时数据等。 + +## 基础组件 + +### 配置中心(Config) + +配置中心位于 Server 端,它的主要作用是监控 Server 端线程池配置变更,实时通知到 Client 实例执行线程池变更流程。 + +代码设计基于 Nacos 1.x 版本的 **长轮询以及异步 Servlet 机制** 实现。 + +### 注册中心(Discovery) + +负责管理 Client 端(单机或集群)注册到 Server 端的实例,包括不限于**实例注册、续约、过期剔除** 等操作,代码基于 Eureka 源码实现。 + +上面的配置中心很容易理解,动态线程池参数变更的根本。但是注册中心是用来做什么的? + +注册中心管理 Client 端注册的实例,通过这些实例可以 **实时获取线程池的运行时参数信息**。 + +目前的设计是如此,不排除后续基于 Discovery 做更多的扩展。 + +### 控制台(Console) + +对接前端项目,包括不限于以下模块管理: + +![](https://images-machen.oss-cn-beijing.aliyuncs.com/image-20211107122504126.png) + +## 消息通知(Notify) + +Hippo4J 内置了很多需要通知的事件,比如:线程池参数变更通知、线程池活跃度报警、拒绝策略执行报警以及阻塞队列容量报警等。 + +目前 Notify 已经接入了钉钉、企业微信和飞书,后续持续集成邮件、短信等通知渠道;并且,Notify 模块提供了消息事件的 SPI 方案,可以接受三方自定义的推送。 + +## Hippo4j-Spring-Boot-Starter + +熟悉 SpringBoot 的小伙伴对 Starter 应该不会陌生。Hippo4J 提供以 Starter Jar 包的形式嵌套在应用内,负责与 Server 端完成交互。 + +## 功能架构 + +![](https://images-machen.oss-cn-beijing.aliyuncs.com/image-20211105230953626.png) diff --git a/docs/versioned_docs/version-1.4.3/user_docs/user_guide/notify.md b/docs/versioned_docs/version-1.4.3/user_docs/user_guide/notify.md new file mode 100644 index 00000000..924d5a7e --- /dev/null +++ b/docs/versioned_docs/version-1.4.3/user_docs/user_guide/notify.md @@ -0,0 +1,74 @@ +--- +sidebar_position: 4 +--- + +# 通知报警 + +现阶段已集成钉钉、企业微信、飞书的消息推送,后续会持续接入邮箱、短信和自定义通知渠道。 + +![](https://images-machen.oss-cn-beijing.aliyuncs.com/image-20220904181527453.png) + +**通知平台** + +- DING:钉钉平台; + +- LARK:飞书平台; + +- WECHAT:企业微信。 + +**通知类型** + +- CONFIG:线程池配置变更推送; + +- ALARM:线程池运行报警推送。 + +**Token** + +获取 DING、LARK、WECHAT 机器人 Token。 + +**报警间隔** + +- CONFIG 类型通知没有报警间隔; + +- ALARM 类型设置报警间隔后,某一节点下的同一线程池指定间隔只会发送一次报警通知。 + +**接收者** + +```tex +多个接收者使用英文逗号 , 分割 (注意不要有空格) +DING:填写手机号 +WECHART:填写user_id会以@的消息发给用户,填写姓名则是普通的@,如:龙台 +LARK:填写ou_开头用户唯一标识会以@的消息发给用户,填写手机号则是普通的@ +``` + +## 钉钉平台 + +[钉钉创建群机器人](https://www.dingtalk.com/qidian/help-detail-20781541.html) + +| 配置变更 | 报警通知 | +| :---: | :---: | +| ![](https://images-machen.oss-cn-beijing.aliyuncs.com/image-20211013122816688.png) | ![](https://images-machen.oss-cn-beijing.aliyuncs.com/image-20211013113649068.png) | + +添加钉钉机器人后,需在机器人配置自定义关键字,才可发送成功。如下所示: + +![](https://images-machen.oss-cn-beijing.aliyuncs.com/image-20220530200133377.png?x-oss-process=image/resize,h_500,w_800) + +:::tip +如果使用 1.4.3 及以上版本,`警报` 替换为 `告警`。 +::: + +## 企业微信 + +[企业微信创建群机器人](https://open.work.weixin.qq.com/help2/pc/14931?person_id=1&from=homesearch) + +| 配置变更 | 报警通知 | +| :---: | :---: | +| ![](https://images-machen.oss-cn-beijing.aliyuncs.com/image-20211203213443242.png) | ![](https://images-machen.oss-cn-beijing.aliyuncs.com/image-20211203213512019.png) | + +## 飞书平台 + +[飞书创建群机器人](https://www.feishu.cn/hc/zh-CN/articles/360024984973) + +![](https://images-machen.oss-cn-beijing.aliyuncs.com/image-20220304081729347.png) + +![](https://images-machen.oss-cn-beijing.aliyuncs.com/image-20220304081507907.png) diff --git a/docs/versioned_docs/version-1.4.3/user_docs/user_guide/quick-start.md b/docs/versioned_docs/version-1.4.3/user_docs/user_guide/quick-start.md new file mode 100644 index 00000000..cce9e577 --- /dev/null +++ b/docs/versioned_docs/version-1.4.3/user_docs/user_guide/quick-start.md @@ -0,0 +1,40 @@ +--- +sidebar_position: 3 +--- + +# 快速开始 + +## 服务启动 + +使用 Docker 运行服务端,默认使用内置 H2 数据库,数据持久化到 Docker 容器存储卷中。 + +```shell +docker run -d -p 6691:6691 --name hippo4j-server hippo4j/hippo4j-server +``` + +> 如果没有 Docker,可以使用源码编译的方式,启动 [Hippo4J-Server/Hippo4J-Bootstrap](https://github.com/longtai-cn/hippo4j/tree/develop/hippo4j-server/hippo4j-bootstrap) 模块下 ServerApplication 应用类。 + +启动示例项目,[hippo4j-spring-boot-starter-example](https://github.com/opengoofy/hippo4j/tree/develop/hippo4j-example/hippo4j-spring-boot-starter-example) 模块下 Hippo4JServerExampleApplication 应用类。 + +访问 Server 控制台,路径 `http://localhost:6691/index.html`,默认用户名密码:admin / 123456 + +## 配置变更 + +访问控制台动态线程池菜单下线程池实例,修改动态线程池相关参数。 + +![](https://images-machen.oss-cn-beijing.aliyuncs.com/image-20220813173811668.png) + +观察 Hippo4j-Example 控制台日志输出,日志输出包括不限于此信息即为成功。 + +```tex +2022-09-10 00:23:29.783 INFO 50322 --- [change.config_0] c.h.s.s.c.ServerThreadPoolDynamicRefresh : [message-consume] Dynamic thread pool change parameter. + corePoolSize: 2 => 4 + maximumPoolSize: 6 => 12 + capacity: 1024 => 2048 + keepAliveTime: 9999 => 9999 + executeTimeOut: 800 => 3000 + rejectedType: SyncPutQueuePolicy => RunsOldestTaskPolicy + allowCoreThreadTimeOut: true => true +``` + +另外,当 Client 集群部署时,可以修改某一个实例,或选择 `全部修改` 按钮,修改所有实例线程池信息。 diff --git a/docs/versioned_sidebars/version-1.4.3-sidebars.json b/docs/versioned_sidebars/version-1.4.3-sidebars.json new file mode 100644 index 00000000..98d1c255 --- /dev/null +++ b/docs/versioned_sidebars/version-1.4.3-sidebars.json @@ -0,0 +1,26 @@ +{ + "tutorialSidebar": [ + { + "type": "autogenerated", + "dirName": "." + } + ], + "user_docs": [ + { + "type": "autogenerated", + "dirName": "user_docs" + } + ], + "community": [ + { + "type": "autogenerated", + "dirName": "community" + } + ], + "sponsor": [ + { + "type": "autogenerated", + "dirName": "sponsor" + } + ] +} diff --git a/docs/versions.json b/docs/versions.json index 4c34c760..91c99418 100644 --- a/docs/versions.json +++ b/docs/versions.json @@ -1,3 +1,4 @@ [ + "1.4.3", "1.4.2" ] diff --git a/hippo4j-adapter/hippo4j-adapter-alibaba-dubbo/pom.xml b/hippo4j-adapter/hippo4j-adapter-alibaba-dubbo/pom.xml index e2413208..5ffcc442 100644 --- a/hippo4j-adapter/hippo4j-adapter-alibaba-dubbo/pom.xml +++ b/hippo4j-adapter/hippo4j-adapter-alibaba-dubbo/pom.xml @@ -9,19 +9,17 @@ hippo4j-adapter-alibaba-dubbo - - 2.6.12 - - cn.hippo4j hippo4j-adapter-base + ${revision} com.alibaba dubbo ${alibaba-dubbo.version} + true diff --git a/hippo4j-adapter/hippo4j-adapter-base/src/main/java/cn/hippo4j/adapter/base/ThreadPoolAdapterBeanContainer.java b/hippo4j-adapter/hippo4j-adapter-base/src/main/java/cn/hippo4j/adapter/base/ThreadPoolAdapterBeanContainer.java index 92d555f2..a87b4743 100644 --- a/hippo4j-adapter/hippo4j-adapter-base/src/main/java/cn/hippo4j/adapter/base/ThreadPoolAdapterBeanContainer.java +++ b/hippo4j-adapter/hippo4j-adapter-base/src/main/java/cn/hippo4j/adapter/base/ThreadPoolAdapterBeanContainer.java @@ -29,7 +29,7 @@ import java.util.concurrent.ConcurrentHashMap; public class ThreadPoolAdapterBeanContainer implements InitializingBean { /** - * Store three-party thread pool framework bean instances. + * Store three-party thread pool framework bean instances */ public static final Map THREAD_POOL_ADAPTER_BEAN_CONTAINER = new ConcurrentHashMap<>(); diff --git a/hippo4j-adapter/hippo4j-adapter-base/src/main/java/cn/hippo4j/adapter/base/ThreadPoolAdapterRegisterAction.java b/hippo4j-adapter/hippo4j-adapter-base/src/main/java/cn/hippo4j/adapter/base/ThreadPoolAdapterRegisterAction.java index 0d380f15..0dda7fa3 100644 --- a/hippo4j-adapter/hippo4j-adapter-base/src/main/java/cn/hippo4j/adapter/base/ThreadPoolAdapterRegisterAction.java +++ b/hippo4j-adapter/hippo4j-adapter-base/src/main/java/cn/hippo4j/adapter/base/ThreadPoolAdapterRegisterAction.java @@ -28,7 +28,7 @@ public interface ThreadPoolAdapterRegisterAction { /** * Get thread pool adapter cache configs. * - * @param threadPoolAdapterMap + * @param threadPoolAdapterMap thread-pool adapter map * @return List */ List getThreadPoolAdapterCacheConfigs(Map threadPoolAdapterMap); @@ -36,8 +36,7 @@ public interface ThreadPoolAdapterRegisterAction { /** * Do register. * - * @param cacheConfigList - * @return + * @param cacheConfigList cache config list */ void doRegister(List cacheConfigList); } diff --git a/hippo4j-adapter/hippo4j-adapter-dubbo/pom.xml b/hippo4j-adapter/hippo4j-adapter-dubbo/pom.xml index 1b975be4..62bd25f2 100644 --- a/hippo4j-adapter/hippo4j-adapter-dubbo/pom.xml +++ b/hippo4j-adapter/hippo4j-adapter-dubbo/pom.xml @@ -9,14 +9,11 @@ hippo4j-adapter-dubbo - - 3.0.5 - - cn.hippo4j hippo4j-adapter-base + ${revision} org.apache.dubbo diff --git a/hippo4j-adapter/hippo4j-adapter-hystrix/pom.xml b/hippo4j-adapter/hippo4j-adapter-hystrix/pom.xml index 8da68229..128e1ccb 100644 --- a/hippo4j-adapter/hippo4j-adapter-hystrix/pom.xml +++ b/hippo4j-adapter/hippo4j-adapter-hystrix/pom.xml @@ -13,11 +13,13 @@ cn.hippo4j hippo4j-adapter-base + ${revision} org.springframework.cloud spring-cloud-starter-netflix-hystrix ${spring-cloud-starter-netflix-hystrix.version} + true diff --git a/hippo4j-adapter/hippo4j-adapter-hystrix/src/main/java/cn/hippo4j/adapter/hystrix/HystrixThreadPoolAdapter.java b/hippo4j-adapter/hippo4j-adapter-hystrix/src/main/java/cn/hippo4j/adapter/hystrix/HystrixThreadPoolAdapter.java index ef5002f7..78a50765 100644 --- a/hippo4j-adapter/hippo4j-adapter-hystrix/src/main/java/cn/hippo4j/adapter/hystrix/HystrixThreadPoolAdapter.java +++ b/hippo4j-adapter/hippo4j-adapter-hystrix/src/main/java/cn/hippo4j/adapter/hystrix/HystrixThreadPoolAdapter.java @@ -17,7 +17,11 @@ package cn.hippo4j.adapter.hystrix; -import cn.hippo4j.adapter.base.*; +import cn.hippo4j.adapter.base.ThreadPoolAdapter; +import cn.hippo4j.adapter.base.ThreadPoolAdapterCacheConfig; +import cn.hippo4j.adapter.base.ThreadPoolAdapterParameter; +import cn.hippo4j.adapter.base.ThreadPoolAdapterRegisterAction; +import cn.hippo4j.adapter.base.ThreadPoolAdapterState; import cn.hippo4j.common.config.ApplicationContextHolder; import cn.hippo4j.common.toolkit.CollectionUtil; import com.netflix.hystrix.HystrixThreadPool; @@ -48,9 +52,9 @@ public class HystrixThreadPoolAdapter implements ThreadPoolAdapter, ApplicationL private static final String THREAD_POOLS_FIELD = "threadPools"; - private final Map HYSTRIX_CONSUME_EXECUTOR = new HashMap<>(); + private final Map hystrixConsumeExecutor = new HashMap<>(); - private ThreadPoolAdapterScheduler threadPoolAdapterScheduler; + private final ThreadPoolAdapterScheduler threadPoolAdapterScheduler; public HystrixThreadPoolAdapter(ThreadPoolAdapterScheduler threadPoolAdapterScheduler) { this.threadPoolAdapterScheduler = threadPoolAdapterScheduler; @@ -64,7 +68,7 @@ public class HystrixThreadPoolAdapter implements ThreadPoolAdapter, ApplicationL @Override public ThreadPoolAdapterState getThreadPoolState(String identify) { ThreadPoolAdapterState result = new ThreadPoolAdapterState(); - ThreadPoolExecutor threadPoolExecutor = HYSTRIX_CONSUME_EXECUTOR.get(identify); + ThreadPoolExecutor threadPoolExecutor = hystrixConsumeExecutor.get(identify); if (threadPoolExecutor != null) { result.setThreadPoolKey(identify); result.setCoreSize(threadPoolExecutor.getCorePoolSize()); @@ -78,14 +82,14 @@ public class HystrixThreadPoolAdapter implements ThreadPoolAdapter, ApplicationL @Override public List getThreadPoolStates() { List threadPoolAdapterStates = new ArrayList<>(); - HYSTRIX_CONSUME_EXECUTOR.forEach((kel, val) -> threadPoolAdapterStates.add(getThreadPoolState(kel))); + hystrixConsumeExecutor.forEach((kel, val) -> threadPoolAdapterStates.add(getThreadPoolState(kel))); return threadPoolAdapterStates; } @Override public boolean updateThreadPool(ThreadPoolAdapterParameter threadPoolAdapterParameter) { String threadPoolKey = threadPoolAdapterParameter.getThreadPoolKey(); - ThreadPoolExecutor threadPoolExecutor = HYSTRIX_CONSUME_EXECUTOR.get(threadPoolKey); + ThreadPoolExecutor threadPoolExecutor = hystrixConsumeExecutor.get(threadPoolKey); if (threadPoolExecutor == null) { log.warn("[{}] Hystrix thread pool not found.", threadPoolKey); return false; @@ -135,7 +139,7 @@ public class HystrixThreadPoolAdapter implements ThreadPoolAdapter, ApplicationL threadPoolField.setAccessible(true); ThreadPoolExecutor threadPoolExecutor = (ThreadPoolExecutor) threadPoolField.get(hystrixThreadPoolDefault); - HYSTRIX_CONSUME_EXECUTOR.put(key, threadPoolExecutor); + hystrixConsumeExecutor.put(key, threadPoolExecutor); } } } @@ -179,7 +183,7 @@ public class HystrixThreadPoolAdapter implements ThreadPoolAdapter, ApplicationL private int taskIntervalSeconds; - public HystrixThreadPoolRefreshTask(ScheduledExecutorService scheduler, int taskIntervalSeconds) { + HystrixThreadPoolRefreshTask(ScheduledExecutorService scheduler, int taskIntervalSeconds) { this.scheduler = scheduler; this.taskIntervalSeconds = taskIntervalSeconds; } @@ -196,6 +200,9 @@ public class HystrixThreadPoolAdapter implements ThreadPoolAdapter, ApplicationL } } + /** + * Thread Pool Adapter Register Task + */ class ThreadPoolAdapterRegisterTask implements Runnable { private ScheduledExecutorService scheduler; @@ -208,9 +215,9 @@ public class HystrixThreadPoolAdapter implements ThreadPoolAdapter, ApplicationL private List cacheConfigList = new ArrayList<>(); - public ThreadPoolAdapterRegisterTask(ScheduledExecutorService scheduler, int taskIntervalSeconds, - Map threadPoolAdapterMap, - ThreadPoolAdapterRegisterAction threadPoolAdapterRegisterAction) { + ThreadPoolAdapterRegisterTask(ScheduledExecutorService scheduler, int taskIntervalSeconds, + Map threadPoolAdapterMap, + ThreadPoolAdapterRegisterAction threadPoolAdapterRegisterAction) { this.scheduler = scheduler; this.taskIntervalSeconds = taskIntervalSeconds; this.threadPoolAdapterMap = threadPoolAdapterMap; diff --git a/hippo4j-adapter/hippo4j-adapter-hystrix/src/main/java/cn/hippo4j/adapter/hystrix/ThreadPoolAdapterScheduler.java b/hippo4j-adapter/hippo4j-adapter-hystrix/src/main/java/cn/hippo4j/adapter/hystrix/ThreadPoolAdapterScheduler.java index d71cf267..143b285e 100644 --- a/hippo4j-adapter/hippo4j-adapter-hystrix/src/main/java/cn/hippo4j/adapter/hystrix/ThreadPoolAdapterScheduler.java +++ b/hippo4j-adapter/hippo4j-adapter-hystrix/src/main/java/cn/hippo4j/adapter/hystrix/ThreadPoolAdapterScheduler.java @@ -18,6 +18,7 @@ package cn.hippo4j.adapter.hystrix; import cn.hippo4j.common.design.builder.ThreadFactoryBuilder; +import lombok.Getter; import lombok.extern.slf4j.Slf4j; import java.util.concurrent.ScheduledExecutorService; @@ -31,6 +32,7 @@ public class ThreadPoolAdapterScheduler { private static final int TASK_INTERVAL_SECONDS = 10; + @Getter private final ScheduledExecutorService scheduler; public ThreadPoolAdapterScheduler() { @@ -41,10 +43,11 @@ public class ThreadPoolAdapterScheduler { .build()); } - public ScheduledExecutorService getScheduler() { - return scheduler; - } - + /** + * Gt task interval seconds. + * + * @return task interval seconds + */ public int getTaskIntervalSeconds() { return TASK_INTERVAL_SECONDS; } diff --git a/hippo4j-adapter/hippo4j-adapter-kafka/pom.xml b/hippo4j-adapter/hippo4j-adapter-kafka/pom.xml deleted file mode 100644 index f193cc75..00000000 --- a/hippo4j-adapter/hippo4j-adapter-kafka/pom.xml +++ /dev/null @@ -1,18 +0,0 @@ - - - 4.0.0 - - cn.hippo4j - hippo4j-adapter - ${revision} - - hippo4j-adapter-kafka - - - - cn.hippo4j - hippo4j-adapter-base - - - diff --git a/hippo4j-adapter/hippo4j-adapter-kafka/src/main/java/cn/hippo4j/adapter/kafka/KafkaThreadPoolAdapter.java b/hippo4j-adapter/hippo4j-adapter-kafka/src/main/java/cn/hippo4j/adapter/kafka/KafkaThreadPoolAdapter.java deleted file mode 100644 index e27ced8a..00000000 --- a/hippo4j-adapter/hippo4j-adapter-kafka/src/main/java/cn/hippo4j/adapter/kafka/KafkaThreadPoolAdapter.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package cn.hippo4j.adapter.kafka; - -import cn.hippo4j.adapter.base.ThreadPoolAdapter; -import cn.hippo4j.adapter.base.ThreadPoolAdapterParameter; -import cn.hippo4j.adapter.base.ThreadPoolAdapterState; -import lombok.extern.slf4j.Slf4j; -import org.springframework.boot.context.event.ApplicationStartedEvent; -import org.springframework.context.ApplicationListener; - -/** - * Kafka thread-pool adapter. - */ -@Slf4j -public class KafkaThreadPoolAdapter implements ThreadPoolAdapter, ApplicationListener { - - @Override - public String mark() { - return "Kafka"; - } - - @Override - public ThreadPoolAdapterState getThreadPoolState(String identify) { - return null; - } - - @Override - public boolean updateThreadPool(ThreadPoolAdapterParameter threadPoolAdapterParameter) { - return false; - } - - @Override - public void onApplicationEvent(ApplicationStartedEvent event) { - - } -} diff --git a/hippo4j-adapter/hippo4j-adapter-rabbitmq/pom.xml b/hippo4j-adapter/hippo4j-adapter-rabbitmq/pom.xml index d477e026..2d54fe82 100644 --- a/hippo4j-adapter/hippo4j-adapter-rabbitmq/pom.xml +++ b/hippo4j-adapter/hippo4j-adapter-rabbitmq/pom.xml @@ -13,10 +13,12 @@ cn.hippo4j hippo4j-adapter-base + ${revision} org.springframework.boot spring-boot-starter-amqp + true diff --git a/hippo4j-adapter/hippo4j-adapter-rabbitmq/src/main/java/cn/hippo4j/adapter/rabbitmq/RabbitMQThreadPoolAdapter.java b/hippo4j-adapter/hippo4j-adapter-rabbitmq/src/main/java/cn/hippo4j/adapter/rabbitmq/RabbitMQThreadPoolAdapter.java index ccaab2b1..86b34f7e 100644 --- a/hippo4j-adapter/hippo4j-adapter-rabbitmq/src/main/java/cn/hippo4j/adapter/rabbitmq/RabbitMQThreadPoolAdapter.java +++ b/hippo4j-adapter/hippo4j-adapter-rabbitmq/src/main/java/cn/hippo4j/adapter/rabbitmq/RabbitMQThreadPoolAdapter.java @@ -27,7 +27,11 @@ import org.springframework.amqp.rabbit.connection.AbstractConnectionFactory; import org.springframework.boot.context.event.ApplicationStartedEvent; import org.springframework.context.ApplicationListener; -import java.util.*; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; import java.util.concurrent.ExecutorService; import java.util.concurrent.ThreadPoolExecutor; @@ -42,11 +46,11 @@ public class RabbitMQThreadPoolAdapter implements ThreadPoolAdapter, Application private static final String RABBITMQ = "RabbitMQ"; - private static final String FiledName = "executorService"; + private static final String FILED_NAME = "executorService"; private final Map abstractConnectionFactoryMap; - private final Map RABBITMQ_THREAD_POOL_TASK_EXECUTOR = new HashMap<>(); + private final Map rabbitmqThreadPoolTaskExecutor = new HashMap<>(); @Override public String mark() { @@ -56,7 +60,7 @@ public class RabbitMQThreadPoolAdapter implements ThreadPoolAdapter, Application @Override public ThreadPoolAdapterState getThreadPoolState(String identify) { ThreadPoolAdapterState threadPoolAdapterState = new ThreadPoolAdapterState(); - ThreadPoolExecutor threadPoolTaskExecutor = RABBITMQ_THREAD_POOL_TASK_EXECUTOR.get(identify); + ThreadPoolExecutor threadPoolTaskExecutor = rabbitmqThreadPoolTaskExecutor.get(identify); threadPoolAdapterState.setThreadPoolKey(identify); if (Objects.nonNull(threadPoolTaskExecutor)) { threadPoolAdapterState.setCoreSize(threadPoolTaskExecutor.getCorePoolSize()); @@ -68,7 +72,7 @@ public class RabbitMQThreadPoolAdapter implements ThreadPoolAdapter, Application @Override public List getThreadPoolStates() { List adapterStateList = new ArrayList<>(); - RABBITMQ_THREAD_POOL_TASK_EXECUTOR.forEach( + rabbitmqThreadPoolTaskExecutor.forEach( (key, val) -> adapterStateList.add(getThreadPoolState(key))); return adapterStateList; } @@ -76,7 +80,7 @@ public class RabbitMQThreadPoolAdapter implements ThreadPoolAdapter, Application @Override public boolean updateThreadPool(ThreadPoolAdapterParameter threadPoolAdapterParameter) { String threadPoolKey = threadPoolAdapterParameter.getThreadPoolKey(); - ThreadPoolExecutor threadPoolTaskExecutor = RABBITMQ_THREAD_POOL_TASK_EXECUTOR.get(threadPoolKey); + ThreadPoolExecutor threadPoolTaskExecutor = rabbitmqThreadPoolTaskExecutor.get(threadPoolKey); if (Objects.nonNull(threadPoolTaskExecutor)) { int originalCoreSize = threadPoolTaskExecutor.getCorePoolSize(); int originalMaximumPoolSize = threadPoolTaskExecutor.getMaximumPoolSize(); @@ -95,17 +99,16 @@ public class RabbitMQThreadPoolAdapter implements ThreadPoolAdapter, Application @Override public void onApplicationEvent(ApplicationStartedEvent event) { abstractConnectionFactoryMap.forEach((beanName, abstractConnectionFactor) -> { - ExecutorService executor = (ExecutorService) ReflectUtil.getFieldValue(abstractConnectionFactor, FiledName); + ExecutorService executor = (ExecutorService) ReflectUtil.getFieldValue(abstractConnectionFactor, FILED_NAME); if (Objects.nonNull(executor)) { if (executor instanceof ThreadPoolExecutor) { ThreadPoolExecutor threadPoolTaskExecutor = (ThreadPoolExecutor) executor; - RABBITMQ_THREAD_POOL_TASK_EXECUTOR.put(beanName, threadPoolTaskExecutor); + rabbitmqThreadPoolTaskExecutor.put(beanName, threadPoolTaskExecutor); log.info("Rabbitmq executor name {}", beanName); } else { log.warn("Custom thread pools only support ThreadPoolExecutor"); } } - }); } } diff --git a/hippo4j-adapter/hippo4j-adapter-rocketmq/pom.xml b/hippo4j-adapter/hippo4j-adapter-rocketmq/pom.xml index 5b9451b3..bf046e13 100644 --- a/hippo4j-adapter/hippo4j-adapter-rocketmq/pom.xml +++ b/hippo4j-adapter/hippo4j-adapter-rocketmq/pom.xml @@ -13,11 +13,13 @@ cn.hippo4j hippo4j-adapter-base + ${revision} org.apache.rocketmq rocketmq-spring-boot-starter ${rocketmq.version} + true diff --git a/hippo4j-adapter/hippo4j-adapter-rocketmq/src/main/java/cn/hippo4j/adapter/rocketmq/RocketMQThreadPoolAdapter.java b/hippo4j-adapter/hippo4j-adapter-rocketmq/src/main/java/cn/hippo4j/adapter/rocketmq/RocketMQThreadPoolAdapter.java index 88e2a869..e5541703 100644 --- a/hippo4j-adapter/hippo4j-adapter-rocketmq/src/main/java/cn/hippo4j/adapter/rocketmq/RocketMQThreadPoolAdapter.java +++ b/hippo4j-adapter/hippo4j-adapter-rocketmq/src/main/java/cn/hippo4j/adapter/rocketmq/RocketMQThreadPoolAdapter.java @@ -43,7 +43,7 @@ import static cn.hippo4j.common.constant.ChangeThreadPoolConstants.CHANGE_DELIMI @Slf4j public class RocketMQThreadPoolAdapter implements ThreadPoolAdapter, ApplicationListener { - private final Map ROCKET_MQ_CONSUME_EXECUTOR = new HashMap<>(); + private final Map rocketmqConsumeExecutor = new HashMap<>(); @Override public String mark() { @@ -53,7 +53,7 @@ public class RocketMQThreadPoolAdapter implements ThreadPoolAdapter, Application @Override public ThreadPoolAdapterState getThreadPoolState(String identify) { ThreadPoolAdapterState result = new ThreadPoolAdapterState(); - ThreadPoolExecutor rocketMQConsumeExecutor = ROCKET_MQ_CONSUME_EXECUTOR.get(identify); + ThreadPoolExecutor rocketMQConsumeExecutor = rocketmqConsumeExecutor.get(identify); if (rocketMQConsumeExecutor != null) { result.setThreadPoolKey(identify); result.setCoreSize(rocketMQConsumeExecutor.getCorePoolSize()); @@ -67,7 +67,7 @@ public class RocketMQThreadPoolAdapter implements ThreadPoolAdapter, Application @Override public List getThreadPoolStates() { List adapterStateList = new ArrayList<>(); - ROCKET_MQ_CONSUME_EXECUTOR.forEach( + rocketmqConsumeExecutor.forEach( (key, val) -> adapterStateList.add(getThreadPoolState(key))); return adapterStateList; } @@ -75,7 +75,7 @@ public class RocketMQThreadPoolAdapter implements ThreadPoolAdapter, Application @Override public boolean updateThreadPool(ThreadPoolAdapterParameter threadPoolAdapterParameter) { String threadPoolKey = threadPoolAdapterParameter.getThreadPoolKey(); - ThreadPoolExecutor rocketMQConsumeExecutor = ROCKET_MQ_CONSUME_EXECUTOR.get(threadPoolKey); + ThreadPoolExecutor rocketMQConsumeExecutor = rocketmqConsumeExecutor.get(threadPoolKey); if (rocketMQConsumeExecutor != null) { int originalCoreSize = rocketMQConsumeExecutor.getCorePoolSize(); int originalMaximumPoolSize = rocketMQConsumeExecutor.getMaximumPoolSize(); @@ -101,7 +101,7 @@ public class RocketMQThreadPoolAdapter implements ThreadPoolAdapter, Application if (defaultMQPushConsumer != null) { ConsumeMessageService consumeMessageService = defaultMQPushConsumer.getDefaultMQPushConsumerImpl().getConsumeMessageService(); ThreadPoolExecutor consumeExecutor = (ThreadPoolExecutor) ReflectUtil.getFieldValue(consumeMessageService, "consumeExecutor"); - ROCKET_MQ_CONSUME_EXECUTOR.put(container.getConsumerGroup(), consumeExecutor); + rocketmqConsumeExecutor.put(container.getConsumerGroup(), consumeExecutor); } } } catch (Exception ex) { diff --git a/hippo4j-adapter/hippo4j-adapter-spring-cloud-stream-kafka/pom.xml b/hippo4j-adapter/hippo4j-adapter-spring-cloud-stream-kafka/pom.xml deleted file mode 100644 index 25be8e39..00000000 --- a/hippo4j-adapter/hippo4j-adapter-spring-cloud-stream-kafka/pom.xml +++ /dev/null @@ -1,18 +0,0 @@ - - - 4.0.0 - - cn.hippo4j - hippo4j-adapter - ${revision} - - hippo4j-adapter-spring-cloud-stream-kafka - - - - cn.hippo4j - hippo4j-adapter-base - - - diff --git a/hippo4j-adapter/hippo4j-adapter-spring-cloud-stream-kafka/src/main/java/cn/hippo4j/adapter/springcloud/stream/kafka/SpringCloudStreamKafkaThreadPoolAdapter.java b/hippo4j-adapter/hippo4j-adapter-spring-cloud-stream-kafka/src/main/java/cn/hippo4j/adapter/springcloud/stream/kafka/SpringCloudStreamKafkaThreadPoolAdapter.java deleted file mode 100644 index 4cc49356..00000000 --- a/hippo4j-adapter/hippo4j-adapter-spring-cloud-stream-kafka/src/main/java/cn/hippo4j/adapter/springcloud/stream/kafka/SpringCloudStreamKafkaThreadPoolAdapter.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package cn.hippo4j.adapter.springcloud.stream.kafka; - -import cn.hippo4j.adapter.base.ThreadPoolAdapter; -import cn.hippo4j.adapter.base.ThreadPoolAdapterParameter; -import cn.hippo4j.adapter.base.ThreadPoolAdapterState; -import lombok.extern.slf4j.Slf4j; -import org.springframework.boot.context.event.ApplicationStartedEvent; -import org.springframework.context.ApplicationListener; - -import java.util.List; - -/** - * Spring cloud stream kafka thread-pool adapter. - */ -@Slf4j -public class SpringCloudStreamKafkaThreadPoolAdapter implements ThreadPoolAdapter, ApplicationListener { - - @Override - public String mark() { - return "KafkaSpringCloudStream"; - } - - @Override - public ThreadPoolAdapterState getThreadPoolState(String identify) { - return null; - } - - @Override - public List getThreadPoolStates() { - return null; - } - - @Override - public boolean updateThreadPool(ThreadPoolAdapterParameter threadPoolAdapterParameter) { - return false; - } - - @Override - public void onApplicationEvent(ApplicationStartedEvent event) { - - } -} diff --git a/hippo4j-adapter/hippo4j-adapter-spring-cloud-stream-rabbitmq/pom.xml b/hippo4j-adapter/hippo4j-adapter-spring-cloud-stream-rabbitmq/pom.xml index ffce64e8..c0a96526 100644 --- a/hippo4j-adapter/hippo4j-adapter-spring-cloud-stream-rabbitmq/pom.xml +++ b/hippo4j-adapter/hippo4j-adapter-spring-cloud-stream-rabbitmq/pom.xml @@ -13,11 +13,13 @@ cn.hippo4j hippo4j-adapter-base + ${revision} org.springframework.cloud spring-cloud-starter-stream-rabbit ${spring-cloud-starter-stream-rabbitmq.version} + true diff --git a/hippo4j-adapter/hippo4j-adapter-spring-cloud-stream-rabbitmq/src/main/java/cn/hippo4j/adapter/springcloud/stream/rabbitmq/SpringCloudStreamRabbitMQThreadPoolAdapter.java b/hippo4j-adapter/hippo4j-adapter-spring-cloud-stream-rabbitmq/src/main/java/cn/hippo4j/adapter/springcloud/stream/rabbitmq/SpringCloudStreamRabbitMQThreadPoolAdapter.java index cb04cf6b..d5b3326c 100644 --- a/hippo4j-adapter/hippo4j-adapter-spring-cloud-stream-rabbitmq/src/main/java/cn/hippo4j/adapter/springcloud/stream/rabbitmq/SpringCloudStreamRabbitMQThreadPoolAdapter.java +++ b/hippo4j-adapter/hippo4j-adapter-spring-cloud-stream-rabbitmq/src/main/java/cn/hippo4j/adapter/springcloud/stream/rabbitmq/SpringCloudStreamRabbitMQThreadPoolAdapter.java @@ -34,17 +34,22 @@ import org.springframework.cloud.stream.binding.InputBindingLifecycle; import org.springframework.context.ApplicationListener; import org.springframework.integration.amqp.inbound.AmqpInboundChannelAdapter; -import java.util.*; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Optional; import static cn.hippo4j.common.constant.ChangeThreadPoolConstants.CHANGE_DELIMITER; /** - * Spring cloud stream rabbimq thread-pool adapter. + * Spring cloud stream rabbit-mq thread-pool adapter. */ @Slf4j public class SpringCloudStreamRabbitMQThreadPoolAdapter implements ThreadPoolAdapter, ApplicationListener { - private final Map ROCKET_MQ_SPRING_CLOUD_STREAM_CONSUME_EXECUTOR = new HashMap<>(); + private final Map rocketMqSpringCloudStreamConsumeExecutor = new HashMap<>(); @Override public String mark() { @@ -54,7 +59,7 @@ public class SpringCloudStreamRabbitMQThreadPoolAdapter implements ThreadPoolAda @Override public ThreadPoolAdapterState getThreadPoolState(String identify) { ThreadPoolAdapterState result = new ThreadPoolAdapterState(); - AbstractMessageListenerContainer messageListenerContainer = ROCKET_MQ_SPRING_CLOUD_STREAM_CONSUME_EXECUTOR.get(identify); + AbstractMessageListenerContainer messageListenerContainer = rocketMqSpringCloudStreamConsumeExecutor.get(identify); if (messageListenerContainer != null) { result.setThreadPoolKey(identify); if (messageListenerContainer instanceof SimpleMessageListenerContainer) { @@ -80,7 +85,7 @@ public class SpringCloudStreamRabbitMQThreadPoolAdapter implements ThreadPoolAda @Override public List getThreadPoolStates() { List adapterStateList = new ArrayList<>(); - ROCKET_MQ_SPRING_CLOUD_STREAM_CONSUME_EXECUTOR.forEach( + rocketMqSpringCloudStreamConsumeExecutor.forEach( (key, val) -> adapterStateList.add(getThreadPoolState(key))); return adapterStateList; } @@ -88,9 +93,9 @@ public class SpringCloudStreamRabbitMQThreadPoolAdapter implements ThreadPoolAda @Override public boolean updateThreadPool(ThreadPoolAdapterParameter threadPoolAdapterParameter) { String threadPoolKey = threadPoolAdapterParameter.getThreadPoolKey(); - AbstractMessageListenerContainer messageListenerContainer = ROCKET_MQ_SPRING_CLOUD_STREAM_CONSUME_EXECUTOR.get(threadPoolKey); + AbstractMessageListenerContainer messageListenerContainer = rocketMqSpringCloudStreamConsumeExecutor.get(threadPoolKey); if (messageListenerContainer != null) { - synchronized (ROCKET_MQ_SPRING_CLOUD_STREAM_CONSUME_EXECUTOR) { + synchronized (rocketMqSpringCloudStreamConsumeExecutor) { Integer corePoolSize = threadPoolAdapterParameter.getCorePoolSize(); Integer maximumPoolSize = threadPoolAdapterParameter.getMaximumPoolSize(); if (messageListenerContainer instanceof SimpleMessageListenerContainer) { @@ -148,7 +153,7 @@ public class SpringCloudStreamRabbitMQThreadPoolAdapter implements ThreadPoolAda Object lifecycle = ReflectUtil.getFieldValue(defaultBinding, "lifecycle"); if (lifecycle instanceof AmqpInboundChannelAdapter) { AbstractMessageListenerContainer rabbitMQListenerContainer = (AbstractMessageListenerContainer) ReflectUtil.getFieldValue(lifecycle, "messageListenerContainer"); - ROCKET_MQ_SPRING_CLOUD_STREAM_CONSUME_EXECUTOR.put(bindingName, rabbitMQListenerContainer); + rocketMqSpringCloudStreamConsumeExecutor.put(bindingName, rabbitMQListenerContainer); } } } catch (Exception ex) { diff --git a/hippo4j-adapter/hippo4j-adapter-spring-cloud-stream-rocketmq/pom.xml b/hippo4j-adapter/hippo4j-adapter-spring-cloud-stream-rocketmq/pom.xml index 1227e7bf..b8c524fa 100644 --- a/hippo4j-adapter/hippo4j-adapter-spring-cloud-stream-rocketmq/pom.xml +++ b/hippo4j-adapter/hippo4j-adapter-spring-cloud-stream-rocketmq/pom.xml @@ -13,11 +13,13 @@ cn.hippo4j hippo4j-adapter-base + ${revision} com.alibaba.cloud spring-cloud-starter-stream-rocketmq ${spring-cloud-starter-stream-rocketmq.version} + true diff --git a/hippo4j-adapter/hippo4j-adapter-spring-cloud-stream-rocketmq/src/main/java/cn/hippo4j/adapter/springcloud/stream/rocketmq/SpringCloudStreamRocketMQThreadPoolAdapter.java b/hippo4j-adapter/hippo4j-adapter-spring-cloud-stream-rocketmq/src/main/java/cn/hippo4j/adapter/springcloud/stream/rocketmq/SpringCloudStreamRocketMQThreadPoolAdapter.java index b71d7aac..60d35416 100644 --- a/hippo4j-adapter/hippo4j-adapter-spring-cloud-stream-rocketmq/src/main/java/cn/hippo4j/adapter/springcloud/stream/rocketmq/SpringCloudStreamRocketMQThreadPoolAdapter.java +++ b/hippo4j-adapter/hippo4j-adapter-spring-cloud-stream-rocketmq/src/main/java/cn/hippo4j/adapter/springcloud/stream/rocketmq/SpringCloudStreamRocketMQThreadPoolAdapter.java @@ -35,7 +35,12 @@ import org.springframework.cloud.stream.binder.DefaultBinding; import org.springframework.cloud.stream.binding.InputBindingLifecycle; import org.springframework.context.ApplicationListener; -import java.util.*; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Optional; import java.util.concurrent.ThreadPoolExecutor; import static cn.hippo4j.common.constant.ChangeThreadPoolConstants.CHANGE_DELIMITER; @@ -46,7 +51,7 @@ import static cn.hippo4j.common.constant.ChangeThreadPoolConstants.CHANGE_DELIMI @Slf4j public class SpringCloudStreamRocketMQThreadPoolAdapter implements ThreadPoolAdapter, ApplicationListener { - private final Map ROCKET_MQ_SPRING_CLOUD_STREAM_CONSUME_EXECUTOR = new HashMap<>(); + private final Map rocketMqSpringCloudStreamConsumeExecutor = new HashMap<>(); @Override public String mark() { @@ -56,7 +61,7 @@ public class SpringCloudStreamRocketMQThreadPoolAdapter implements ThreadPoolAda @Override public ThreadPoolAdapterState getThreadPoolState(String identify) { ThreadPoolAdapterState result = new ThreadPoolAdapterState(); - ThreadPoolExecutor rocketMQConsumeExecutor = ROCKET_MQ_SPRING_CLOUD_STREAM_CONSUME_EXECUTOR.get(identify); + ThreadPoolExecutor rocketMQConsumeExecutor = rocketMqSpringCloudStreamConsumeExecutor.get(identify); if (rocketMQConsumeExecutor != null) { result.setThreadPoolKey(identify); result.setCoreSize(rocketMQConsumeExecutor.getCorePoolSize()); @@ -70,7 +75,7 @@ public class SpringCloudStreamRocketMQThreadPoolAdapter implements ThreadPoolAda @Override public List getThreadPoolStates() { List adapterStateList = new ArrayList<>(); - ROCKET_MQ_SPRING_CLOUD_STREAM_CONSUME_EXECUTOR.forEach( + rocketMqSpringCloudStreamConsumeExecutor.forEach( (key, val) -> adapterStateList.add(getThreadPoolState(key))); return adapterStateList; } @@ -78,7 +83,7 @@ public class SpringCloudStreamRocketMQThreadPoolAdapter implements ThreadPoolAda @Override public boolean updateThreadPool(ThreadPoolAdapterParameter threadPoolAdapterParameter) { String threadPoolKey = threadPoolAdapterParameter.getThreadPoolKey(); - ThreadPoolExecutor rocketMQConsumeExecutor = ROCKET_MQ_SPRING_CLOUD_STREAM_CONSUME_EXECUTOR.get(threadPoolKey); + ThreadPoolExecutor rocketMQConsumeExecutor = rocketMqSpringCloudStreamConsumeExecutor.get(threadPoolKey); if (rocketMQConsumeExecutor != null) { int originalCoreSize = rocketMQConsumeExecutor.getCorePoolSize(); int originalMaximumPoolSize = rocketMQConsumeExecutor.getMaximumPoolSize(); @@ -111,7 +116,7 @@ public class SpringCloudStreamRocketMQThreadPoolAdapter implements ThreadPoolAda DefaultMQPushConsumerImpl defaultMQPushConsumerImpl = consumer.getDefaultMQPushConsumerImpl(); ConsumeMessageConcurrentlyService consumeMessageService = (ConsumeMessageConcurrentlyService) defaultMQPushConsumerImpl.getConsumeMessageService(); ThreadPoolExecutor consumeExecutor = (ThreadPoolExecutor) ReflectUtil.getFieldValue(consumeMessageService, "consumeExecutor"); - ROCKET_MQ_SPRING_CLOUD_STREAM_CONSUME_EXECUTOR.put(bindingName, consumeExecutor); + rocketMqSpringCloudStreamConsumeExecutor.put(bindingName, consumeExecutor); } } catch (Exception ex) { log.error("Failed to get input-bindings thread pool.", ex); diff --git a/hippo4j-adapter/hippo4j-adapter-web/pom.xml b/hippo4j-adapter/hippo4j-adapter-web/pom.xml index 8563db72..62ab8998 100644 --- a/hippo4j-adapter/hippo4j-adapter-web/pom.xml +++ b/hippo4j-adapter/hippo4j-adapter-web/pom.xml @@ -31,10 +31,6 @@ spring-boot-starter-undertow true - - org.projectlombok - lombok - org.springframework.boot spring-boot-starter @@ -42,6 +38,7 @@ cn.hippo4j hippo4j-core + ${revision} diff --git a/hippo4j-adapter/hippo4j-adapter-web/src/main/java/cn/hippo4j/adapter/web/AbstractWebThreadPoolService.java b/hippo4j-adapter/hippo4j-adapter-web/src/main/java/cn/hippo4j/adapter/web/AbstractWebThreadPoolService.java index 771d6699..bafdf678 100644 --- a/hippo4j-adapter/hippo4j-adapter-web/src/main/java/cn/hippo4j/adapter/web/AbstractWebThreadPoolService.java +++ b/hippo4j-adapter/hippo4j-adapter-web/src/main/java/cn/hippo4j/adapter/web/AbstractWebThreadPoolService.java @@ -34,12 +34,12 @@ import java.util.concurrent.Executor; public abstract class AbstractWebThreadPoolService implements WebThreadPoolService, ApplicationRunner { /** - * Thread pool executor. + * Thread pool executor */ protected volatile Executor executor; /** - * Get web thread pool by server. + * Get web thread pool by server * * @param webServer * @return diff --git a/hippo4j-adapter/hippo4j-adapter-web/src/main/java/cn/hippo4j/adapter/web/TomcatWebThreadPoolHandler.java b/hippo4j-adapter/hippo4j-adapter-web/src/main/java/cn/hippo4j/adapter/web/TomcatWebThreadPoolHandler.java index c15cf7a6..33a4d626 100644 --- a/hippo4j-adapter/hippo4j-adapter-web/src/main/java/cn/hippo4j/adapter/web/TomcatWebThreadPoolHandler.java +++ b/hippo4j-adapter/hippo4j-adapter-web/src/main/java/cn/hippo4j/adapter/web/TomcatWebThreadPoolHandler.java @@ -31,7 +31,6 @@ import org.springframework.boot.web.server.WebServer; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; -import java.util.Date; import java.util.concurrent.BlockingQueue; import java.util.concurrent.Executor; import java.util.concurrent.ThreadPoolExecutor; @@ -47,14 +46,14 @@ public class TomcatWebThreadPoolHandler extends AbstractWebThreadPoolService { private final AtomicBoolean cacheFlag = new AtomicBoolean(Boolean.FALSE); - private static String EXCEPTION_MESSAGE; + private static String exceptionMessage; private final AbstractThreadPoolRuntime webThreadPoolRunStateHandler; @Override protected Executor getWebThreadPoolByServer(WebServer webServer) { if (cacheFlag.get()) { - log.warn("Exception getting Tomcat thread pool. Exception message: {}", EXCEPTION_MESSAGE); + log.warn("Exception getting Tomcat thread pool. Exception message: {}", exceptionMessage); return null; } Executor tomcatExecutor = null; @@ -62,8 +61,8 @@ public class TomcatWebThreadPoolHandler extends AbstractWebThreadPoolService { tomcatExecutor = ((TomcatWebServer) webServer).getTomcat().getConnector().getProtocolHandler().getExecutor(); } catch (Exception ex) { cacheFlag.set(Boolean.TRUE); - EXCEPTION_MESSAGE = ex.getMessage(); - log.error("Failed to get Tomcat thread pool. Message: {}", EXCEPTION_MESSAGE); + exceptionMessage = ex.getMessage(); + log.error("Failed to get Tomcat thread pool. Message: {}", exceptionMessage); } return tomcatExecutor; } diff --git a/hippo4j-adapter/hippo4j-adapter-web/src/main/java/cn/hippo4j/adapter/web/WebIpAndPortHolder.java b/hippo4j-adapter/hippo4j-adapter-web/src/main/java/cn/hippo4j/adapter/web/WebIpAndPortHolder.java index 04de2355..01d85d22 100644 --- a/hippo4j-adapter/hippo4j-adapter-web/src/main/java/cn/hippo4j/adapter/web/WebIpAndPortHolder.java +++ b/hippo4j-adapter/hippo4j-adapter-web/src/main/java/cn/hippo4j/adapter/web/WebIpAndPortHolder.java @@ -35,12 +35,12 @@ import java.util.concurrent.atomic.AtomicReference; @NoArgsConstructor(access = lombok.AccessLevel.PRIVATE) public class WebIpAndPortHolder { - private static boolean SUPPORT_VERSION = false; + private static boolean supportVersion = false; static { try { Class.forName("org.springframework.boot.web.server.WebServer"); - SUPPORT_VERSION = true; + supportVersion = true; } catch (Exception ignored) { } } @@ -48,17 +48,17 @@ public class WebIpAndPortHolder { /** * Application ip and application post */ - protected static AtomicReference WEB_IP_AND_PORT = new AtomicReference<>(); + protected static AtomicReference webIpAndPort = new AtomicReference<>(); public static final String ALL = "*"; protected static final String SEPARATOR = ","; protected static void initIpAndPort() { - if (!SUPPORT_VERSION) { + if (!supportVersion) { return; } - WEB_IP_AND_PORT.compareAndSet(null, getWebIpAndPortInfo()); + webIpAndPort.compareAndSet(null, getWebIpAndPortInfo()); } private static WebIpAndPortInfo getWebIpAndPortInfo() { @@ -80,10 +80,10 @@ public class WebIpAndPortHolder { * @return Web ip and port info */ public static WebIpAndPortInfo getWebIpAndPort() { - if (WEB_IP_AND_PORT.get() == null) { + if (webIpAndPort.get() == null) { initIpAndPort(); } - return WebIpAndPortHolder.WEB_IP_AND_PORT.get(); + return WebIpAndPortHolder.webIpAndPort.get(); } /** @@ -104,4 +104,4 @@ public class WebIpAndPortHolder { .filter(Objects::nonNull) .anyMatch(each -> each.check(webIpAndPort.getIpSegment(), webIpAndPort.getPort())); } -} \ No newline at end of file +} diff --git a/hippo4j-adapter/hippo4j-adapter-web/src/main/java/cn/hippo4j/adapter/web/WebThreadPoolHandlerChoose.java b/hippo4j-adapter/hippo4j-adapter-web/src/main/java/cn/hippo4j/adapter/web/WebThreadPoolHandlerChoose.java index f88f4d54..1d94d379 100644 --- a/hippo4j-adapter/hippo4j-adapter-web/src/main/java/cn/hippo4j/adapter/web/WebThreadPoolHandlerChoose.java +++ b/hippo4j-adapter/hippo4j-adapter-web/src/main/java/cn/hippo4j/adapter/web/WebThreadPoolHandlerChoose.java @@ -30,7 +30,7 @@ public class WebThreadPoolHandlerChoose { /** * Choose the web thread pool service bean. * - * @return + * @return web thread pool service bean */ public WebThreadPoolService choose() { WebThreadPoolService webThreadPoolService; diff --git a/hippo4j-adapter/hippo4j-adapter-web/src/main/java/cn/hippo4j/adapter/web/WebThreadPoolRunStateHandler.java b/hippo4j-adapter/hippo4j-adapter-web/src/main/java/cn/hippo4j/adapter/web/WebThreadPoolRunStateHandler.java index 2727e52c..a30c16c8 100644 --- a/hippo4j-adapter/hippo4j-adapter-web/src/main/java/cn/hippo4j/adapter/web/WebThreadPoolRunStateHandler.java +++ b/hippo4j-adapter/hippo4j-adapter-web/src/main/java/cn/hippo4j/adapter/web/WebThreadPoolRunStateHandler.java @@ -35,9 +35,9 @@ public class WebThreadPoolRunStateHandler extends AbstractThreadPoolRuntime { long used = MemoryUtil.heapMemoryUsed(); long max = MemoryUtil.heapMemoryMax(); String memoryProportion = StringUtil.newBuilder( - "已分配: ", + "Allocation: ", ByteConvertUtil.getPrintSize(used), - " / 最大可用: ", + " / Maximum available: ", ByteConvertUtil.getPrintSize(max)); poolRunStateInfo.setCurrentLoad(poolRunStateInfo.getCurrentLoad() + "%"); poolRunStateInfo.setPeakLoad(poolRunStateInfo.getPeakLoad() + "%"); diff --git a/hippo4j-adapter/pom.xml b/hippo4j-adapter/pom.xml index d1c0624a..1993176c 100644 --- a/hippo4j-adapter/pom.xml +++ b/hippo4j-adapter/pom.xml @@ -14,12 +14,10 @@ hippo4j-adapter-base hippo4j-adapter-dubbo hippo4j-adapter-alibaba-dubbo - hippo4j-adapter-kafka hippo4j-adapter-rabbitmq hippo4j-adapter-rocketmq hippo4j-adapter-hystrix hippo4j-adapter-spring-cloud-stream-rocketmq - hippo4j-adapter-spring-cloud-stream-kafka hippo4j-adapter-spring-cloud-stream-rabbitmq hippo4j-adapter-web diff --git a/hippo4j-common/pom.xml b/hippo4j-common/pom.xml index 5f036d55..5f56c500 100644 --- a/hippo4j-common/pom.xml +++ b/hippo4j-common/pom.xml @@ -57,6 +57,7 @@ com.github.ben-manes.caffeine caffeine + ${caffeine.version} com.github.dozermapper diff --git a/hippo4j-message/src/main/java/cn/hippo4j/message/request/base/NotifyRequest.java b/hippo4j-common/src/main/java/cn/hippo4j/common/api/NotifyRequest.java similarity index 95% rename from hippo4j-message/src/main/java/cn/hippo4j/message/request/base/NotifyRequest.java rename to hippo4j-common/src/main/java/cn/hippo4j/common/api/NotifyRequest.java index 13e0da92..9b2b71ee 100644 --- a/hippo4j-message/src/main/java/cn/hippo4j/message/request/base/NotifyRequest.java +++ b/hippo4j-common/src/main/java/cn/hippo4j/common/api/NotifyRequest.java @@ -15,7 +15,7 @@ * limitations under the License. */ -package cn.hippo4j.message.request.base; +package cn.hippo4j.common.api; /** * Notify request. diff --git a/hippo4j-common/src/main/java/cn/hippo4j/common/api/ThreadPoolCheckAlarm.java b/hippo4j-common/src/main/java/cn/hippo4j/common/api/ThreadPoolCheckAlarm.java new file mode 100644 index 00000000..6d4b0768 --- /dev/null +++ b/hippo4j-common/src/main/java/cn/hippo4j/common/api/ThreadPoolCheckAlarm.java @@ -0,0 +1,64 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.hippo4j.common.api; + +import org.springframework.boot.CommandLineRunner; + +import java.util.concurrent.ThreadPoolExecutor; + +/** + * Thread-pol check alarm. + * + *

Dynamic thread pool check and send logic wait for refactoring, + * Try not to rely on this component for custom extensions, because it is undefined. + */ +public interface ThreadPoolCheckAlarm extends CommandLineRunner { + + /** + * Check pool capacity alarm. + * + * @param threadPoolId thread-pool id + * @param threadPoolExecutor thread-pool executor + */ + void checkPoolCapacityAlarm(String threadPoolId, ThreadPoolExecutor threadPoolExecutor); + + /** + * Check pool activity alarm. + * + * @param threadPoolId thread-pool id + * @param threadPoolExecutor thread-pool executor + */ + void checkPoolActivityAlarm(String threadPoolId, ThreadPoolExecutor threadPoolExecutor); + + /** + * Async send rejected alarm. + * + * @param threadPoolId thread-pool id + */ + void asyncSendRejectedAlarm(String threadPoolId); + + /** + * Async send execute time-out alarm. + * + * @param threadPoolId thread-pool id + * @param executeTime execute time + * @param executeTimeOut execute time-out + * @param threadPoolExecutor thread-pool executor + */ + void asyncSendExecuteTimeOutAlarm(String threadPoolId, long executeTime, long executeTimeOut, ThreadPoolExecutor threadPoolExecutor); +} diff --git a/hippo4j-server/hippo4j-config/src/main/java/cn/hippo4j/config/rpc/handler/Connection.java b/hippo4j-common/src/main/java/cn/hippo4j/common/api/ThreadPoolConfigChange.java similarity index 75% rename from hippo4j-server/hippo4j-config/src/main/java/cn/hippo4j/config/rpc/handler/Connection.java rename to hippo4j-common/src/main/java/cn/hippo4j/common/api/ThreadPoolConfigChange.java index b3b69d57..8086240e 100644 --- a/hippo4j-server/hippo4j-config/src/main/java/cn/hippo4j/config/rpc/handler/Connection.java +++ b/hippo4j-common/src/main/java/cn/hippo4j/common/api/ThreadPoolConfigChange.java @@ -15,13 +15,17 @@ * limitations under the License. */ -package cn.hippo4j.config.rpc.handler; - -import java.io.Closeable; +package cn.hippo4j.common.api; /** - * Represents a network request connection and provides IO layer support + * Thread-pool config change. */ -public interface Connection extends Closeable { +public interface ThreadPoolConfigChange { + /** + * Send pool config change. + * + * @param requestParam request param + */ + void sendPoolConfigChange(T requestParam); } diff --git a/hippo4j-common/src/main/java/cn/hippo4j/common/constant/ConfigModifyTypeConstants.java b/hippo4j-common/src/main/java/cn/hippo4j/common/constant/ConfigModifyTypeConstants.java index 84a8bf61..deb4465c 100644 --- a/hippo4j-common/src/main/java/cn/hippo4j/common/constant/ConfigModifyTypeConstants.java +++ b/hippo4j-common/src/main/java/cn/hippo4j/common/constant/ConfigModifyTypeConstants.java @@ -17,6 +17,9 @@ package cn.hippo4j.common.constant; +/** + * Config modify type constants. + */ public class ConfigModifyTypeConstants { /** diff --git a/hippo4j-common/src/main/java/cn/hippo4j/common/executor/ThreadPoolManager.java b/hippo4j-common/src/main/java/cn/hippo4j/common/executor/ThreadPoolManager.java index b38d104f..aa3be5bd 100644 --- a/hippo4j-common/src/main/java/cn/hippo4j/common/executor/ThreadPoolManager.java +++ b/hippo4j-common/src/main/java/cn/hippo4j/common/executor/ThreadPoolManager.java @@ -23,12 +23,11 @@ import java.util.Map; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ExecutorService; -import java.util.concurrent.atomic.AtomicBoolean; /** * Thread-pool manager. */ -public class ThreadPoolManager { +public final class ThreadPoolManager { private Map>> resourcesManager; @@ -36,8 +35,6 @@ public class ThreadPoolManager { private static final ThreadPoolManager INSTANCE = new ThreadPoolManager(); - private static final AtomicBoolean CLOSED = new AtomicBoolean(false); - public static ThreadPoolManager getInstance() { return INSTANCE; } diff --git a/hippo4j-common/src/main/java/cn/hippo4j/common/model/register/DynamicThreadPoolRegisterWrapper.java b/hippo4j-common/src/main/java/cn/hippo4j/common/model/register/DynamicThreadPoolRegisterWrapper.java index a543223e..a14fbc53 100644 --- a/hippo4j-common/src/main/java/cn/hippo4j/common/model/register/DynamicThreadPoolRegisterWrapper.java +++ b/hippo4j-common/src/main/java/cn/hippo4j/common/model/register/DynamicThreadPoolRegisterWrapper.java @@ -38,7 +38,7 @@ public class DynamicThreadPoolRegisterWrapper { /** * Dynamic thread-pool register parameter */ - private DynamicThreadPoolRegisterParameter dynamicThreadPoolRegisterParameter; + private DynamicThreadPoolRegisterParameter parameter; // Hippo4j server ---------------------------------------------------------------------- @@ -65,12 +65,12 @@ public class DynamicThreadPoolRegisterWrapper { /** * Dynamic thread-pool server notify parameter */ - private DynamicThreadPoolRegisterServerNotifyParameter dynamicThreadPoolRegisterServerNotifyParameter; + private DynamicThreadPoolRegisterServerNotifyParameter serverNotify; // Hippo4j core ---------------------------------------------------------------------- /** - * Dynamic thread-pool core notify parameter + * Dynamic thread-pool config notify parameter */ - private DynamicThreadPoolRegisterCoreNotifyParameter dynamicThreadPoolRegisterCoreNotifyParameter; + private DynamicThreadPoolRegisterCoreNotifyParameter configNotify; } diff --git a/hippo4j-common/src/main/java/cn/hippo4j/common/toolkit/ContentUtil.java b/hippo4j-common/src/main/java/cn/hippo4j/common/toolkit/ContentUtil.java index 68e19378..ae5b6dfe 100644 --- a/hippo4j-common/src/main/java/cn/hippo4j/common/toolkit/ContentUtil.java +++ b/hippo4j-common/src/main/java/cn/hippo4j/common/toolkit/ContentUtil.java @@ -21,13 +21,17 @@ import cn.hippo4j.common.constant.Constants; import cn.hippo4j.common.model.ThreadPoolParameter; import cn.hippo4j.common.model.ThreadPoolParameterInfo; -import java.util.Objects; - /** * Content util. */ public class ContentUtil { + /** + * Get pool content. + * + * @param parameter thread-pool parameter + * @return dynamic thread-pool content str + */ public static String getPoolContent(ThreadPoolParameter parameter) { ThreadPoolParameterInfo threadPoolParameterInfo = new ThreadPoolParameterInfo(); threadPoolParameterInfo.setTenantId(parameter.getTenantId()) @@ -47,6 +51,12 @@ public class ContentUtil { return JSONUtil.toJSONString(threadPoolParameterInfo); } + /** + * Get group key. + * + * @param parameter thread-pool parameter + * @return group key + */ public static String getGroupKey(ThreadPoolParameter parameter) { return StringUtil.createBuilder() .append(parameter.getTpId()) @@ -57,6 +67,12 @@ public class ContentUtil { .toString(); } + /** + * Get group key. + * + * @param parameters thread-pool parameters + * @return group key + */ public static String getGroupKey(String... parameters) { StringBuilder stringBuilder = new StringBuilder(); for (int i = 0; i < parameters.length; i++) { diff --git a/hippo4j-common/src/main/java/cn/hippo4j/common/toolkit/Joiner.java b/hippo4j-common/src/main/java/cn/hippo4j/common/toolkit/Joiner.java index de798647..b6130d94 100644 --- a/hippo4j-common/src/main/java/cn/hippo4j/common/toolkit/Joiner.java +++ b/hippo4j-common/src/main/java/cn/hippo4j/common/toolkit/Joiner.java @@ -26,7 +26,7 @@ import java.util.Objects; * reference google guava
* com.google.common.base.Joiner */ -public class Joiner { +public final class Joiner { private final String separator; @@ -45,11 +45,11 @@ public class Joiner { * Returns a string containing the string representation of each of {@code parts}, using the * previously configured separator between each. */ - public final String join(Object[] parts) { + public String join(Object[] parts) { return join(Arrays.asList(parts)); } - public final String join(Iterable parts) { + public String join(Iterable parts) { return join(parts.iterator()); } @@ -57,11 +57,11 @@ public class Joiner { * Returns a string containing the string representation of each of {@code parts}, using the * previously configured separator between each. */ - public final String join(Iterator parts) { + public String join(Iterator parts) { return appendTo(new StringBuilder(), parts).toString(); } - public final StringBuilder appendTo(StringBuilder builder, Iterator parts) { + public StringBuilder appendTo(StringBuilder builder, Iterator parts) { try { appendTo((Appendable) builder, parts); } catch (IOException impossible) { diff --git a/hippo4j-core/pom.xml b/hippo4j-core/pom.xml index e9e05f10..ae43fb91 100644 --- a/hippo4j-core/pom.xml +++ b/hippo4j-core/pom.xml @@ -10,34 +10,15 @@ hippo4j-core - - org.springframework.boot - spring-boot-starter-test - test - - - org.projectlombok - lombok - cn.hippo4j hippo4j-common ${revision} - cn.hippo4j - hippo4j-message - - - com.aliyun - alibaba-dingtalk-service-sdk - - - - log4j - log4j - - + org.springframework.boot + spring-boot-starter-test + test diff --git a/hippo4j-core/src/main/java/cn/hippo4j/core/executor/DynamicThreadPoolExecutor.java b/hippo4j-core/src/main/java/cn/hippo4j/core/executor/DynamicThreadPoolExecutor.java index e4feda74..6790a374 100644 --- a/hippo4j-core/src/main/java/cn/hippo4j/core/executor/DynamicThreadPoolExecutor.java +++ b/hippo4j-core/src/main/java/cn/hippo4j/core/executor/DynamicThreadPoolExecutor.java @@ -80,13 +80,13 @@ public class DynamicThreadPoolExecutor extends ExtensibleThreadPoolExecutor impl * or {@code threadFactory} or {@code handler} is null */ public DynamicThreadPoolExecutor( - int corePoolSize, int maximumPoolSize, - long keepAliveTime, TimeUnit unit, - long executeTimeOut, boolean waitForTasksToCompleteOnShutdown, long awaitTerminationMillis, - @NonNull BlockingQueue blockingQueue, - @NonNull String threadPoolId, - @NonNull ThreadFactory threadFactory, - @NonNull RejectedExecutionHandler rejectedExecutionHandler) { + int corePoolSize, int maximumPoolSize, + long keepAliveTime, TimeUnit unit, + long executeTimeOut, boolean waitForTasksToCompleteOnShutdown, long awaitTerminationMillis, + @NonNull BlockingQueue blockingQueue, + @NonNull String threadPoolId, + @NonNull ThreadFactory threadFactory, + @NonNull RejectedExecutionHandler rejectedExecutionHandler) { super( threadPoolId, new DefaultThreadPoolPluginManager(), corePoolSize, maximumPoolSize, keepAliveTime, unit, diff --git a/hippo4j-core/src/main/java/cn/hippo4j/core/executor/ExtensibleThreadPoolExecutor.java b/hippo4j-core/src/main/java/cn/hippo4j/core/executor/ExtensibleThreadPoolExecutor.java index 95c8dc8c..87386a28 100644 --- a/hippo4j-core/src/main/java/cn/hippo4j/core/executor/ExtensibleThreadPoolExecutor.java +++ b/hippo4j-core/src/main/java/cn/hippo4j/core/executor/ExtensibleThreadPoolExecutor.java @@ -88,13 +88,13 @@ public class ExtensibleThreadPoolExecutor extends ThreadPoolExecutor implements * or {@code threadFactory} or {@code handler} is null */ public ExtensibleThreadPoolExecutor( - @NonNull String threadPoolId, - @NonNull ThreadPoolPluginManager threadPoolPluginManager, - int corePoolSize, int maximumPoolSize, - long keepAliveTime, TimeUnit unit, - @NonNull BlockingQueue workQueue, - @NonNull ThreadFactory threadFactory, - @NonNull RejectedExecutionHandler handler) { + @NonNull String threadPoolId, + @NonNull ThreadPoolPluginManager threadPoolPluginManager, + int corePoolSize, int maximumPoolSize, + long keepAliveTime, TimeUnit unit, + @NonNull BlockingQueue workQueue, + @NonNull ThreadFactory threadFactory, + @NonNull RejectedExecutionHandler handler) { super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, threadFactory, handler); // Pool extended info. this.threadPoolId = threadPoolId; diff --git a/hippo4j-core/src/main/java/cn/hippo4j/core/plugin/impl/TaskRejectNotifyAlarmPlugin.java b/hippo4j-core/src/main/java/cn/hippo4j/core/plugin/impl/TaskRejectNotifyAlarmPlugin.java index 6b865642..85229374 100644 --- a/hippo4j-core/src/main/java/cn/hippo4j/core/plugin/impl/TaskRejectNotifyAlarmPlugin.java +++ b/hippo4j-core/src/main/java/cn/hippo4j/core/plugin/impl/TaskRejectNotifyAlarmPlugin.java @@ -17,9 +17,9 @@ package cn.hippo4j.core.plugin.impl; +import cn.hippo4j.common.api.ThreadPoolCheckAlarm; import cn.hippo4j.common.config.ApplicationContextHolder; import cn.hippo4j.core.executor.ExtensibleThreadPoolExecutor; -import cn.hippo4j.core.executor.ThreadPoolNotifyAlarmHandler; import cn.hippo4j.core.plugin.RejectedAwarePlugin; import java.util.Optional; @@ -55,7 +55,7 @@ public class TaskRejectNotifyAlarmPlugin implements RejectedAwarePlugin { } String threadPoolId = ((ExtensibleThreadPoolExecutor) executor).getThreadPoolId(); Optional.ofNullable(ApplicationContextHolder.getInstance()) - .map(context -> context.getBean(ThreadPoolNotifyAlarmHandler.class)) + .map(context -> context.getBean(ThreadPoolCheckAlarm.class)) .ifPresent(handler -> handler.asyncSendRejectedAlarm(threadPoolId)); } } diff --git a/hippo4j-core/src/main/java/cn/hippo4j/core/plugin/impl/TaskTimeoutNotifyAlarmPlugin.java b/hippo4j-core/src/main/java/cn/hippo4j/core/plugin/impl/TaskTimeoutNotifyAlarmPlugin.java index d828cc6d..bdc6787e 100644 --- a/hippo4j-core/src/main/java/cn/hippo4j/core/plugin/impl/TaskTimeoutNotifyAlarmPlugin.java +++ b/hippo4j-core/src/main/java/cn/hippo4j/core/plugin/impl/TaskTimeoutNotifyAlarmPlugin.java @@ -17,8 +17,8 @@ package cn.hippo4j.core.plugin.impl; +import cn.hippo4j.common.api.ThreadPoolCheckAlarm; import cn.hippo4j.common.config.ApplicationContextHolder; -import cn.hippo4j.core.executor.ThreadPoolNotifyAlarmHandler; import lombok.AllArgsConstructor; import lombok.Getter; import lombok.Setter; @@ -73,7 +73,7 @@ public class TaskTimeoutNotifyAlarmPlugin extends AbstractTaskTimerPlugin { return; } Optional.ofNullable(ApplicationContextHolder.getInstance()) - .map(context -> context.getBean(ThreadPoolNotifyAlarmHandler.class)) + .map(context -> context.getBean(ThreadPoolCheckAlarm.class)) .ifPresent(handler -> handler.asyncSendExecuteTimeOutAlarm( threadPoolId, taskExecuteTime, executeTimeOut, threadPoolExecutor)); } diff --git a/hippo4j-core/src/main/java/cn/hippo4j/core/plugin/manager/DefaultGlobalThreadPoolPluginManager.java b/hippo4j-core/src/main/java/cn/hippo4j/core/plugin/manager/DefaultGlobalThreadPoolPluginManager.java new file mode 100644 index 00000000..77246371 --- /dev/null +++ b/hippo4j-core/src/main/java/cn/hippo4j/core/plugin/manager/DefaultGlobalThreadPoolPluginManager.java @@ -0,0 +1,195 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.hippo4j.core.plugin.manager; + +import cn.hippo4j.core.plugin.ThreadPoolPlugin; +import lombok.NonNull; +import org.checkerframework.checker.nullness.qual.Nullable; + +import java.util.Collection; +import java.util.Map; +import java.util.Objects; +import java.util.concurrent.ConcurrentHashMap; + +/** + * Default implementation of {@link GlobalThreadPoolPluginManager}. + */ +public class DefaultGlobalThreadPoolPluginManager implements GlobalThreadPoolPluginManager { + + /** + * enable thread pool plugins + */ + private final Map enableThreadPoolPlugins = new ConcurrentHashMap<>(8); + + /** + * enable thread pool plugin registrars + */ + private final Map enableThreadPoolPluginRegistrars = new ConcurrentHashMap<>(8); + + /** + * registered supports + */ + private final Map managedThreadPoolPluginSupports = new ConcurrentHashMap<>(32); + + /** + * Synchronize all enabled plugins and registrars in the current manager to the {@link ThreadPoolPluginSupport} + * whether the support has been managed by the current manager. + * After that, the support will not be synchronized with the plug-in and registrar states in the manager. + * + * @param support thread pool plugin manager delegate + * @see #registerThreadPoolPluginSupport + */ + @Override + public void doRegister(@NonNull ThreadPoolPluginSupport support) { + enableThreadPoolPluginRegistrars.values().forEach(registrar -> registrar.doRegister(support)); + enableThreadPoolPlugins.values().forEach(support::tryRegister); + } + + /** + * Synchronize all enabled plugins and registrars + * in the current manager to the {@link ThreadPoolPluginSupport} if the support has not been managed before, + * After that, this support will be synchronized with the plug-in and registrar status in the manager. + * + * @param support thread pool plugin manager support + * @return true if the support has not been managed before, false otherwise + * @see #doRegister + */ + @Override + public boolean registerThreadPoolPluginSupport(@NonNull ThreadPoolPluginSupport support) { + if (!managedThreadPoolPluginSupports.containsKey(support.getThreadPoolId())) { + enableThreadPoolPluginRegistrars.values().forEach(registrar -> registrar.doRegister(support)); + enableThreadPoolPlugins.values().forEach(support::tryRegister); + managedThreadPoolPluginSupports.put(support.getThreadPoolId(), support); + return true; + } + return false; + } + + /** + * Cancel the management of the specified {@link ThreadPoolPluginSupport}. + * + * @param threadPoolId thread pool id + * @return {@link ThreadPoolPluginSupport} + */ + @Override + public ThreadPoolPluginSupport cancelManagement(String threadPoolId) { + return managedThreadPoolPluginSupports.remove(threadPoolId); + } + + /** + * Get registered {@link ThreadPoolPluginSupport}. + * + * @param threadPoolId thread-pool id + * @return cn.hippo4j.core.plugin.manager.ThreadPoolPluginManager + */ + @Nullable + @Override + public ThreadPoolPluginSupport getManagedThreadPoolPluginSupport(String threadPoolId) { + return managedThreadPoolPluginSupports.get(threadPoolId); + } + + /** + * Get all registered {@link ThreadPoolPluginSupport} + * + * @return all registered {@link ThreadPoolPluginSupport} + */ + @Override + public Collection getAllManagedThreadPoolPluginSupports() { + return managedThreadPoolPluginSupports.values(); + } + + /** + * Enable plugin for all {@link ThreadPoolPluginSupport}, + * after action, newly registered support will also get this plugin. + * + * @param plugin plugin + * @return true if the plugin has not been enabled before, false otherwise + */ + @Override + public boolean enableThreadPoolPlugin(@NonNull ThreadPoolPlugin plugin) { + if (Objects.isNull(enableThreadPoolPlugins.put(plugin.getId(), plugin))) { + managedThreadPoolPluginSupports.values().forEach(support -> support.register(plugin)); + return true; + } + return false; + } + + /** + * Get all enable {@link ThreadPoolPlugin}. + * + * @return all published {@link ThreadPoolPlugin} + */ + @Override + public Collection getAllEnableThreadPoolPlugins() { + return enableThreadPoolPlugins.values(); + } + + /** + * Disable {@link ThreadPoolPlugin} for all {@link ThreadPoolPluginSupport}, + * after action, newly registered support will not get this registrar. + * + * @param pluginId plugin id + * @return {@link ThreadPoolPlugin} if enable, null otherwise + */ + @Override + public ThreadPoolPlugin disableThreadPoolPlugin(String pluginId) { + ThreadPoolPlugin removed = enableThreadPoolPlugins.remove(pluginId); + if (Objects.nonNull(removed)) { + managedThreadPoolPluginSupports.values().forEach(support -> support.unregister(pluginId)); + } + return removed; + } + + /** + * Enable registrar, then apply to all registered {@link ThreadPoolPluginSupport}, + * after action, newly registered support will also get this registrar. + * + * @param registrar registrar + * @return true if the registrar has not been enabled before, false otherwise + */ + @Override + public boolean enableThreadPoolPluginRegistrar(@NonNull ThreadPoolPluginRegistrar registrar) { + if (Objects.isNull(enableThreadPoolPluginRegistrars.put(registrar.getId(), registrar))) { + managedThreadPoolPluginSupports.values().forEach(registrar::doRegister); + return true; + } + return false; + } + + /** + * Get all enable {@link ThreadPoolPluginRegistrar}. + * + * @return all {@link ThreadPoolPluginRegistrar}. + */ + @Override + public Collection getAllEnableThreadPoolPluginRegistrar() { + return enableThreadPoolPluginRegistrars.values(); + } + + /** + * Unable {@link ThreadPoolPluginRegistrar}, newly registered support will not get this registrar. + * + * @param registrarId registrar id + * @return {@link ThreadPoolPluginRegistrar} if enable, null otherwise + */ + @Override + public ThreadPoolPluginRegistrar disableThreadPoolPluginRegistrar(String registrarId) { + return enableThreadPoolPluginRegistrars.remove(registrarId); + } + +} diff --git a/hippo4j-core/src/main/java/cn/hippo4j/core/plugin/manager/DefaultThreadPoolPluginRegistrar.java b/hippo4j-core/src/main/java/cn/hippo4j/core/plugin/manager/DefaultThreadPoolPluginRegistrar.java index be9b91e4..356782ee 100644 --- a/hippo4j-core/src/main/java/cn/hippo4j/core/plugin/manager/DefaultThreadPoolPluginRegistrar.java +++ b/hippo4j-core/src/main/java/cn/hippo4j/core/plugin/manager/DefaultThreadPoolPluginRegistrar.java @@ -18,7 +18,11 @@ package cn.hippo4j.core.plugin.manager; import cn.hippo4j.core.plugin.ThreadPoolPlugin; -import cn.hippo4j.core.plugin.impl.*; +import cn.hippo4j.core.plugin.impl.TaskDecoratorPlugin; +import cn.hippo4j.core.plugin.impl.TaskRejectCountRecordPlugin; +import cn.hippo4j.core.plugin.impl.TaskRejectNotifyAlarmPlugin; +import cn.hippo4j.core.plugin.impl.TaskTimeoutNotifyAlarmPlugin; +import cn.hippo4j.core.plugin.impl.ThreadPoolExecutorShutdownPlugin; import lombok.AllArgsConstructor; import lombok.NoArgsConstructor; @@ -35,8 +39,6 @@ import lombok.NoArgsConstructor; @AllArgsConstructor public class DefaultThreadPoolPluginRegistrar implements ThreadPoolPluginRegistrar { - public static final String REGISTRAR_NAME = "DefaultThreadPoolPluginRegistrar"; - /** * Execute time out */ @@ -47,16 +49,6 @@ public class DefaultThreadPoolPluginRegistrar implements ThreadPoolPluginRegistr */ private long awaitTerminationMillis; - /** - * Get id. - * - * @return id - */ - @Override - public String getId() { - return REGISTRAR_NAME; - } - /** * Create and register plugin for the specified thread-pool instance. * diff --git a/hippo4j-core/src/main/java/cn/hippo4j/core/plugin/manager/GlobalThreadPoolPluginManager.java b/hippo4j-core/src/main/java/cn/hippo4j/core/plugin/manager/GlobalThreadPoolPluginManager.java new file mode 100644 index 00000000..62d2085d --- /dev/null +++ b/hippo4j-core/src/main/java/cn/hippo4j/core/plugin/manager/GlobalThreadPoolPluginManager.java @@ -0,0 +1,179 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.hippo4j.core.plugin.manager; + +import cn.hippo4j.core.plugin.ThreadPoolPlugin; + +import java.util.Collection; +import java.util.Optional; +import java.util.stream.Collectors; + +/** + * A globally {@link ThreadPoolPluginManager}. + * It is used to manage {@link ThreadPoolPluginSupport} in the global, + * so that all managed {@link ThreadPoolPluginSupport} can be registered incrementally. + */ +public interface GlobalThreadPoolPluginManager extends ThreadPoolPluginRegistrar { + + /** + * Synchronize all enabled plugins and registrars + * in the current manager to the {@link ThreadPoolPluginSupport}. + * After that, the support will not be synchronized with the plug-in and registrar states in the manager. + * + * @param support thread pool plugin manager delegate + * @see #registerThreadPoolPluginSupport + */ + @Override + void doRegister(ThreadPoolPluginSupport support); + + /** + * Synchronize all enabled plugins and registrars + * in the current manager to the {@link ThreadPoolPluginSupport}, + * After that, this support will be synchronized with the plug-in and registrar status in the manager. + * + * @param support thread pool plugin manager support + * @return true if the support has not been managed before, false otherwise + * @see #doRegister + */ + boolean registerThreadPoolPluginSupport(ThreadPoolPluginSupport support); + + /** + * Cancel the management of the specified {@link ThreadPoolPluginSupport}. + * + * @param threadPoolId thread pool id + * @return {@link ThreadPoolPluginSupport} if managed, null otherwise + */ + ThreadPoolPluginSupport cancelManagement(String threadPoolId); + + /** + * Get registered {@link ThreadPoolPluginSupport}. + * + * @param threadPoolId thread-pool id + * @return {@link ThreadPoolPluginSupport} if managed, null otherwise + */ + ThreadPoolPluginSupport getManagedThreadPoolPluginSupport(String threadPoolId); + + /** + * Get all registered {@link ThreadPoolPluginSupport} + * + * @return all registered {@link ThreadPoolPluginSupport} + */ + Collection getAllManagedThreadPoolPluginSupports(); + + // ===================== plugin ===================== + + /** + * Enable plugin for all {@link ThreadPoolPluginSupport}, + * after action, newly registered support will also get this plugin. + * + * @param plugin plugin + * @return true if the plugin has not been enabled before, false otherwise + */ + boolean enableThreadPoolPlugin(ThreadPoolPlugin plugin); + + /** + * Get all enable {@link ThreadPoolPlugin}. + * + * @return all published {@link ThreadPoolPlugin} + */ + Collection getAllEnableThreadPoolPlugins(); + + /** + * Disable {@link ThreadPoolPlugin} for all {@link ThreadPoolPluginSupport}, + * after action, newly registered support will not get this registrar. + * + * @param pluginId plugin id + * @return {@link ThreadPoolPlugin} if enable, null otherwise + */ + ThreadPoolPlugin disableThreadPoolPlugin(String pluginId); + + /** + * Get all plugins from registered {@link ThreadPoolPluginSupport}. + * + * @return plugins + */ + default Collection getAllPluginsFromManagers() { + return getAllManagedThreadPoolPluginSupports().stream() + .map(ThreadPoolPluginSupport::getAllPlugins) + .flatMap(Collection::stream) + .collect(Collectors.toList()); + } + + /** + * Get plugins of type from registered {@link ThreadPoolPluginSupport}. + * + * @param pluginType plugin type + * @return plugins + */ + default Collection getPluginsOfTypeFromManagers(Class pluginType) { + return getAllPluginsFromManagers().stream() + .filter(pluginType::isInstance) + .map(pluginType::cast) + .collect(Collectors.toList()); + } + + /** + * Get plugins by id from registered {@link ThreadPoolPluginSupport}. + * + * @param pluginId plugin id + * @return plugins + */ + default Collection getPluginsFromManagers(String pluginId) { + return getAllManagedThreadPoolPluginSupports().stream() + .map(manager -> manager.getPlugin(pluginId)) + .filter(Optional::isPresent) + .map(Optional::get) + .collect(Collectors.toList()); + } + + /** + * Unregister for all registered Managers + * + * @param pluginId plugin id + */ + default void unregisterForAllManagers(String pluginId) { + getAllManagedThreadPoolPluginSupports().forEach(s -> s.unregister(pluginId)); + } + + // ===================== registrar ===================== + + /** + * Enable registrar, then apply to all registered {@link ThreadPoolPluginSupport}, + * after action, newly registered support will also get this registrar. + * + * @param registrar registrar + * @return true if the registrar has not been enabled before, false otherwise + */ + boolean enableThreadPoolPluginRegistrar(ThreadPoolPluginRegistrar registrar); + + /** + * Get all enable {@link ThreadPoolPluginRegistrar}. + * + * @return all {@link ThreadPoolPluginRegistrar}. + */ + Collection getAllEnableThreadPoolPluginRegistrar(); + + /** + * Unable {@link ThreadPoolPluginRegistrar}, newly registered support will not get this registrar. + * + * @param registrarId registrar id + * @return {@link ThreadPoolPluginRegistrar} if enable, null otherwise + */ + ThreadPoolPluginRegistrar disableThreadPoolPluginRegistrar(String registrarId); + +} diff --git a/hippo4j-core/src/main/java/cn/hippo4j/core/plugin/manager/ThreadPoolPluginRegistrar.java b/hippo4j-core/src/main/java/cn/hippo4j/core/plugin/manager/ThreadPoolPluginRegistrar.java index f6aa6dd9..5ba3e57c 100644 --- a/hippo4j-core/src/main/java/cn/hippo4j/core/plugin/manager/ThreadPoolPluginRegistrar.java +++ b/hippo4j-core/src/main/java/cn/hippo4j/core/plugin/manager/ThreadPoolPluginRegistrar.java @@ -25,12 +25,13 @@ import cn.hippo4j.core.plugin.ThreadPoolPlugin; public interface ThreadPoolPluginRegistrar { /** - * Get id. - * In spring container, the obtained id will be used as the alias of the bean name. + * Get id * * @return id */ - String getId(); + default String getId() { + return this.getClass().getSimpleName(); + } /** * Create and register plugin for the specified thread-pool instance. diff --git a/hippo4j-core/src/main/java/cn/hippo4j/core/proxy/RejectedProxyInvocationHandler.java b/hippo4j-core/src/main/java/cn/hippo4j/core/proxy/RejectedProxyInvocationHandler.java index 2b029e54..263cbcc3 100644 --- a/hippo4j-core/src/main/java/cn/hippo4j/core/proxy/RejectedProxyInvocationHandler.java +++ b/hippo4j-core/src/main/java/cn/hippo4j/core/proxy/RejectedProxyInvocationHandler.java @@ -17,8 +17,8 @@ package cn.hippo4j.core.proxy; +import cn.hippo4j.common.api.ThreadPoolCheckAlarm; import cn.hippo4j.common.config.ApplicationContextHolder; -import cn.hippo4j.core.executor.ThreadPoolNotifyAlarmHandler; import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; @@ -54,7 +54,7 @@ public class RejectedProxyInvocationHandler implements InvocationHandler { rejectCount.incrementAndGet(); if (ApplicationContextHolder.getInstance() != null) { try { - ThreadPoolNotifyAlarmHandler alarmHandler = ApplicationContextHolder.getBean(ThreadPoolNotifyAlarmHandler.class); + ThreadPoolCheckAlarm alarmHandler = ApplicationContextHolder.getBean(ThreadPoolCheckAlarm.class); alarmHandler.asyncSendRejectedAlarm(threadPoolId); } catch (Throwable ex) { log.error("Failed to send rejection policy alert.", ex); diff --git a/hippo4j-core/src/main/java/cn/hippo4j/core/toolkit/ExecutorTraceContextUtil.java b/hippo4j-core/src/main/java/cn/hippo4j/core/toolkit/ExecutorTraceContextUtil.java index dbb7f02e..0a9596ce 100644 --- a/hippo4j-core/src/main/java/cn/hippo4j/core/toolkit/ExecutorTraceContextUtil.java +++ b/hippo4j-core/src/main/java/cn/hippo4j/core/toolkit/ExecutorTraceContextUtil.java @@ -43,20 +43,20 @@ public class ExecutorTraceContextUtil { } /** - * Put execute timeout trace. + * Put timeout trace. * * @param trace trace */ - public static void putExecuteTimeoutTrace(String trace) { + public static void putTimeoutTrace(String trace) { MDC.put(EXECUTE_TIMEOUT_TRACE, trace); } /** - * Set execute timeout trace key. + * Set timeout trace key. * * @param key trace key */ - public static void setExecuteTimeoutTraceKey(String key) { + public static void setTimeoutTraceKey(String key) { EXECUTE_TIMEOUT_TRACE_KEY = key; } } diff --git a/hippo4j-core/src/main/java/cn/hippo4j/core/toolkit/inet/InetUtils.java b/hippo4j-core/src/main/java/cn/hippo4j/core/toolkit/inet/InetUtils.java index 6d78ec83..5b933523 100644 --- a/hippo4j-core/src/main/java/cn/hippo4j/core/toolkit/inet/InetUtils.java +++ b/hippo4j-core/src/main/java/cn/hippo4j/core/toolkit/inet/InetUtils.java @@ -75,7 +75,7 @@ public class InetUtils implements Closeable { try { int lowest = Integer.MAX_VALUE; for (Enumeration nics = NetworkInterface - .getNetworkInterfaces(); nics.hasMoreElements(); ) { + .getNetworkInterfaces(); nics.hasMoreElements();) { NetworkInterface ifc = nics.nextElement(); if (ifc.isUp()) { this.log.trace("Testing interface: " + ifc.getDisplayName()); @@ -86,7 +86,7 @@ public class InetUtils implements Closeable { } if (!ignoreInterface(ifc.getDisplayName())) { for (Enumeration addrs = ifc - .getInetAddresses(); addrs.hasMoreElements(); ) { + .getInetAddresses(); addrs.hasMoreElements();) { InetAddress address = addrs.nextElement(); if (address instanceof Inet4Address && !address.isLoopbackAddress() diff --git a/hippo4j-example/hippo4j-spring-boot-starter-adapter-kafka-example/src/main/java/cn/hippo4j/springboot/starter/adapter/kafka/example/ServerAdapterKafkaExampleApplication.java b/hippo4j-core/src/test/java/cn/hippo4j/core/handler/DynamicThreadPoolBannerHandlerTest.java similarity index 63% rename from hippo4j-example/hippo4j-spring-boot-starter-adapter-kafka-example/src/main/java/cn/hippo4j/springboot/starter/adapter/kafka/example/ServerAdapterKafkaExampleApplication.java rename to hippo4j-core/src/test/java/cn/hippo4j/core/handler/DynamicThreadPoolBannerHandlerTest.java index 89b8c40b..78357d1d 100644 --- a/hippo4j-example/hippo4j-spring-boot-starter-adapter-kafka-example/src/main/java/cn/hippo4j/springboot/starter/adapter/kafka/example/ServerAdapterKafkaExampleApplication.java +++ b/hippo4j-core/src/test/java/cn/hippo4j/core/handler/DynamicThreadPoolBannerHandlerTest.java @@ -15,17 +15,16 @@ * limitations under the License. */ -package cn.hippo4j.springboot.starter.adapter.kafka.example; +package cn.hippo4j.core.handler; -import cn.hippo4j.core.enable.EnableDynamicThreadPool; -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; +import cn.hippo4j.common.toolkit.StringUtil; +import org.junit.Assert; +import org.junit.Test; -@SpringBootApplication -@EnableDynamicThreadPool -public class ServerAdapterKafkaExampleApplication { +public final class DynamicThreadPoolBannerHandlerTest { - public static void main(String[] args) { - SpringApplication.run(ServerAdapterKafkaExampleApplication.class, args); + @Test + public void assertGetVersion() { + Assert.assertTrue(StringUtil.isEmpty(DynamicThreadPoolBannerHandler.getVersion())); } } diff --git a/hippo4j-core/src/test/java/cn/hippo4j/core/plugin/manager/DefaultGlobalThreadPoolPluginManagerTest.java b/hippo4j-core/src/test/java/cn/hippo4j/core/plugin/manager/DefaultGlobalThreadPoolPluginManagerTest.java new file mode 100644 index 00000000..834d0922 --- /dev/null +++ b/hippo4j-core/src/test/java/cn/hippo4j/core/plugin/manager/DefaultGlobalThreadPoolPluginManagerTest.java @@ -0,0 +1,237 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.hippo4j.core.plugin.manager; + +import cn.hippo4j.core.plugin.ThreadPoolPlugin; +import lombok.Getter; +import lombok.RequiredArgsConstructor; +import org.junit.Assert; +import org.junit.Test; + +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; + +/** + * test for {@link DefaultGlobalThreadPoolPluginManager} + */ +public class DefaultGlobalThreadPoolPluginManagerTest { + + @Test + public void testDoRegister() { + GlobalThreadPoolPluginManager manager = new DefaultGlobalThreadPoolPluginManager(); + manager.enableThreadPoolPlugin(new TestPlugin("1")); + manager.enableThreadPoolPlugin(new TestPlugin("2")); + manager.enableThreadPoolPluginRegistrar(new TestRegistrar("1")); + + TestSupport support = new TestSupport("1"); + manager.doRegister(support); + Assert.assertEquals(3, support.getAllPlugins().size()); + } + + @Test + public void testRegisterThreadPoolPluginSupport() { + GlobalThreadPoolPluginManager manager = new DefaultGlobalThreadPoolPluginManager(); + Assert.assertTrue(manager.enableThreadPoolPlugin(new TestPlugin("1"))); + + TestSupport support = new TestSupport("1"); + Assert.assertTrue(manager.registerThreadPoolPluginSupport(support)); + Assert.assertFalse(manager.registerThreadPoolPluginSupport(support)); + Assert.assertEquals(1, support.getAllPlugins().size()); + + // incremental update + manager.enableThreadPoolPlugin(new TestPlugin("2")); + manager.enableThreadPoolPluginRegistrar(new TestRegistrar("1")); + Assert.assertEquals(3, support.getAllPlugins().size()); + } + + @Test + public void testCancelManagement() { + GlobalThreadPoolPluginManager manager = new DefaultGlobalThreadPoolPluginManager(); + manager.enableThreadPoolPlugin(new TestPlugin("1")); + + TestSupport support = new TestSupport("1"); + manager.registerThreadPoolPluginSupport(support); + Assert.assertEquals(1, support.getAllPlugins().size()); + + manager.cancelManagement(support.getThreadPoolId()); + manager.enableThreadPoolPlugin(new TestPlugin("2")); + Assert.assertEquals(1, support.getAllPlugins().size()); + } + + @Test + public void testGetManagedThreadPoolPluginSupport() { + GlobalThreadPoolPluginManager manager = new DefaultGlobalThreadPoolPluginManager(); + + TestSupport support = new TestSupport("1"); + manager.registerThreadPoolPluginSupport(support); + Assert.assertSame(support, manager.getManagedThreadPoolPluginSupport(support.getThreadPoolId())); + + support = new TestSupport("2"); + manager.registerThreadPoolPluginSupport(support); + Assert.assertSame(support, manager.getManagedThreadPoolPluginSupport(support.getThreadPoolId())); + } + + @Test + public void testGetAllManagedThreadPoolPluginSupports() { + GlobalThreadPoolPluginManager manager = new DefaultGlobalThreadPoolPluginManager(); + manager.registerThreadPoolPluginSupport(new TestSupport("1")); + manager.registerThreadPoolPluginSupport(new TestSupport("2")); + Assert.assertEquals(2, manager.getAllManagedThreadPoolPluginSupports().size()); + } + + @Test + public void testEnableThreadPoolPlugin() { + GlobalThreadPoolPluginManager manager = new DefaultGlobalThreadPoolPluginManager(); + TestSupport support1 = new TestSupport("1"); + manager.registerThreadPoolPluginSupport(support1); + TestSupport support2 = new TestSupport("2"); + manager.registerThreadPoolPluginSupport(support2); + + Assert.assertTrue(manager.enableThreadPoolPlugin(new TestPlugin("1"))); + Assert.assertFalse(manager.enableThreadPoolPlugin(new TestPlugin("1"))); + Assert.assertEquals(1, support1.getAllPlugins().size()); + } + + @Test + public void testGetAllEnableThreadPoolPlugins() { + GlobalThreadPoolPluginManager manager = new DefaultGlobalThreadPoolPluginManager(); + manager.enableThreadPoolPlugin(new TestPlugin("1")); + manager.enableThreadPoolPlugin(new TestPlugin("2")); + Assert.assertEquals(2, manager.getAllEnableThreadPoolPlugins().size()); + } + + @Test + public void testDisableThreadPoolPlugin() { + GlobalThreadPoolPluginManager manager = new DefaultGlobalThreadPoolPluginManager(); + manager.enableThreadPoolPlugin(new TestPlugin("1")); + manager.enableThreadPoolPlugin(new TestPlugin("2")); + manager.disableThreadPoolPlugin("2"); + Assert.assertEquals(1, manager.getAllEnableThreadPoolPlugins().size()); + } + + @Test + public void testEnableThreadPoolPluginRegistrar() { + GlobalThreadPoolPluginManager manager = new DefaultGlobalThreadPoolPluginManager(); + Assert.assertTrue(manager.enableThreadPoolPluginRegistrar(new TestRegistrar("1"))); + Assert.assertFalse(manager.enableThreadPoolPluginRegistrar(new TestRegistrar("1"))); + Assert.assertEquals(1, manager.getAllEnableThreadPoolPluginRegistrar().size()); + } + + @Test + public void testGetAllEnableThreadPoolPluginRegistrar() { + GlobalThreadPoolPluginManager manager = new DefaultGlobalThreadPoolPluginManager(); + manager.enableThreadPoolPluginRegistrar(new TestRegistrar("1")); + manager.enableThreadPoolPluginRegistrar(new TestRegistrar("2")); + Assert.assertEquals(2, manager.getAllEnableThreadPoolPluginRegistrar().size()); + } + + @Test + public void testDisableThreadPoolPluginRegistrar() { + GlobalThreadPoolPluginManager manager = new DefaultGlobalThreadPoolPluginManager(); + manager.enableThreadPoolPluginRegistrar(new TestRegistrar("1")); + manager.enableThreadPoolPluginRegistrar(new TestRegistrar("2")); + manager.disableThreadPoolPluginRegistrar("2"); + Assert.assertEquals(1, manager.getAllEnableThreadPoolPluginRegistrar().size()); + } + + @Test + public void testGetAllPluginsFromManagers() { + GlobalThreadPoolPluginManager manager = new DefaultGlobalThreadPoolPluginManager(); + manager.enableThreadPoolPluginRegistrar(new TestRegistrar("1")); + manager.enableThreadPoolPlugin(new TestPlugin("1")); + + TestSupport support1 = new TestSupport("1"); + manager.registerThreadPoolPluginSupport(support1); + TestSupport support2 = new TestSupport("2"); + manager.registerThreadPoolPluginSupport(support2); + + Assert.assertEquals(4, manager.getAllPluginsFromManagers().size()); + } + + @Test + public void testGetPluginsOfTypeFromManagers() { + GlobalThreadPoolPluginManager manager = new DefaultGlobalThreadPoolPluginManager(); + manager.enableThreadPoolPluginRegistrar(new TestRegistrar("1")); + manager.enableThreadPoolPlugin(new TestPlugin("1")); + + TestSupport support1 = new TestSupport("1"); + manager.registerThreadPoolPluginSupport(support1); + TestSupport support2 = new TestSupport("2"); + manager.registerThreadPoolPluginSupport(support2); + + Assert.assertEquals(4, manager.getPluginsOfTypeFromManagers(TestPlugin.class).size()); + } + + @Test + public void testGetPluginsFromManagers() { + GlobalThreadPoolPluginManager manager = new DefaultGlobalThreadPoolPluginManager(); + manager.enableThreadPoolPluginRegistrar(new TestRegistrar("1")); + manager.enableThreadPoolPlugin(new TestPlugin("1")); + + TestSupport support1 = new TestSupport("1"); + manager.registerThreadPoolPluginSupport(support1); + TestSupport support2 = new TestSupport("2"); + manager.registerThreadPoolPluginSupport(support2); + + Assert.assertEquals(2, manager.getPluginsFromManagers("1").size()); + } + + @Test + public void testUnregisterForAllManagers() { + GlobalThreadPoolPluginManager manager = new DefaultGlobalThreadPoolPluginManager(); + manager.enableThreadPoolPluginRegistrar(new TestRegistrar("1")); + manager.enableThreadPoolPlugin(new TestPlugin("1")); + + TestSupport support1 = new TestSupport("1"); + manager.registerThreadPoolPluginSupport(support1); + TestSupport support2 = new TestSupport("2"); + manager.registerThreadPoolPluginSupport(support2); + + manager.unregisterForAllManagers("1"); + Assert.assertEquals(2, manager.getAllPluginsFromManagers().size()); + } + + @RequiredArgsConstructor + @Getter + private static class TestSupport implements ThreadPoolPluginSupport { + + private final String threadPoolId; + private final ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue()); + private final ThreadPoolPluginManager threadPoolPluginManager = new DefaultThreadPoolPluginManager(); + } + + @Getter + @RequiredArgsConstructor + private static class TestRegistrar implements ThreadPoolPluginRegistrar { + + private final String id; + @Override + public void doRegister(ThreadPoolPluginSupport support) { + support.register(new TestPlugin("TestRegistrar")); + } + } + + @Getter + @RequiredArgsConstructor + private static class TestPlugin implements ThreadPoolPlugin { + + private final String id; + } + +} diff --git a/hippo4j-example/hippo4j-example-core/pom.xml b/hippo4j-example/hippo4j-example-core/pom.xml index 2628dbd6..86d8c24b 100644 --- a/hippo4j-example/hippo4j-example-core/pom.xml +++ b/hippo4j-example/hippo4j-example-core/pom.xml @@ -11,6 +11,7 @@ true + 2.12.1 @@ -18,36 +19,32 @@ org.springframework.boot spring-boot-starter - org.springframework.boot spring-boot-starter-test test - cn.hippo4j - hippo4j-core + hippo4j-message + ${revision} - com.alibaba transmittable-thread-local + ${transmittable-thread-local.version} - org.openjdk.jmh jmh-core 1.23 test - org.openjdk.jmh jmh-generator-annprocess 1.23 test - diff --git a/hippo4j-example/hippo4j-example-core/src/main/java/cn/hippo4j/example/core/handler/TaskTraceBuilderHandler.java b/hippo4j-example/hippo4j-example-core/src/main/java/cn/hippo4j/example/core/handler/TaskTraceBuilderHandler.java index e557fe8f..5098a8f2 100644 --- a/hippo4j-example/hippo4j-example-core/src/main/java/cn/hippo4j/example/core/handler/TaskTraceBuilderHandler.java +++ b/hippo4j-example/hippo4j-example-core/src/main/java/cn/hippo4j/example/core/handler/TaskTraceBuilderHandler.java @@ -34,7 +34,7 @@ public final class TaskTraceBuilderHandler implements TaskDecorator { String executeTimeoutTrace = MDC.get(EXECUTE_TIMEOUT_TRACE); Runnable taskRun = () -> { if (StringUtil.isNotBlank(executeTimeoutTrace)) { - ExecutorTraceContextUtil.putExecuteTimeoutTrace(executeTimeoutTrace); + ExecutorTraceContextUtil.putTimeoutTrace(executeTimeoutTrace); } runnable.run(); // There is no need to clean up here, and it will be cleaned up after the thread task is executed. diff --git a/hippo4j-example/hippo4j-example-core/src/main/java/cn/hippo4j/example/core/inittest/RegisterDynamicThreadPoolTest.java b/hippo4j-example/hippo4j-example-core/src/main/java/cn/hippo4j/example/core/inittest/RegisterDynamicThreadPoolTest.java index d081f092..5699a205 100644 --- a/hippo4j-example/hippo4j-example-core/src/main/java/cn/hippo4j/example/core/inittest/RegisterDynamicThreadPoolTest.java +++ b/hippo4j-example/hippo4j-example-core/src/main/java/cn/hippo4j/example/core/inittest/RegisterDynamicThreadPoolTest.java @@ -17,14 +17,14 @@ package cn.hippo4j.example.core.inittest; +import cn.hippo4j.common.executor.support.BlockingQueueTypeEnum; +import cn.hippo4j.common.executor.support.RejectedPolicyTypeEnum; import cn.hippo4j.common.model.register.DynamicThreadPoolRegisterParameter; import cn.hippo4j.common.model.register.DynamicThreadPoolRegisterWrapper; import cn.hippo4j.common.model.register.notify.DynamicThreadPoolRegisterCoreNotifyParameter; import cn.hippo4j.common.model.register.notify.DynamicThreadPoolRegisterServerNotifyParameter; import cn.hippo4j.common.toolkit.JSONUtil; import cn.hippo4j.core.executor.manage.GlobalThreadPoolManage; -import cn.hippo4j.common.executor.support.BlockingQueueTypeEnum; -import cn.hippo4j.common.executor.support.RejectedPolicyTypeEnum; import cn.hippo4j.message.enums.NotifyPlatformEnum; import lombok.extern.slf4j.Slf4j; @@ -68,9 +68,9 @@ public class RegisterDynamicThreadPoolTest { DynamicThreadPoolRegisterWrapper registerWrapper = DynamicThreadPoolRegisterWrapper.builder() .updateIfExists(true) .notifyUpdateIfExists(true) - .dynamicThreadPoolRegisterParameter(parameterInfo) - .dynamicThreadPoolRegisterCoreNotifyParameter(coreNotifyParameter) - .dynamicThreadPoolRegisterServerNotifyParameter(serverNotifyParameter) + .parameter(parameterInfo) + .configNotify(coreNotifyParameter) + .serverNotify(serverNotifyParameter) .build(); ThreadPoolExecutor dynamicThreadPool = GlobalThreadPoolManage.dynamicRegister(registerWrapper); log.info("Dynamic registration thread pool parameter details: {}", JSONUtil.toJSONString(dynamicThreadPool)); diff --git a/hippo4j-example/hippo4j-example-core/src/main/java/cn/hippo4j/example/core/inittest/RunStateHandlerTest.java b/hippo4j-example/hippo4j-example-core/src/main/java/cn/hippo4j/example/core/inittest/RunStateHandlerTest.java index 00c3ed2f..dc5747fb 100644 --- a/hippo4j-example/hippo4j-example-core/src/main/java/cn/hippo4j/example/core/inittest/RunStateHandlerTest.java +++ b/hippo4j-example/hippo4j-example-core/src/main/java/cn/hippo4j/example/core/inittest/RunStateHandlerTest.java @@ -18,6 +18,7 @@ package cn.hippo4j.example.core.inittest; import lombok.extern.slf4j.Slf4j; +import org.slf4j.MDC; import org.springframework.stereotype.Component; import javax.annotation.PostConstruct; @@ -28,6 +29,8 @@ import java.util.concurrent.SynchronousQueue; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; +import static cn.hippo4j.common.constant.Constants.EXECUTE_TIMEOUT_TRACE; + /** * Run state handler test. */ @@ -44,7 +47,6 @@ public class RunStateHandlerTest { /* * @Resource private ThreadPoolTaskExecutor testSpringThreadPoolTaskExecutor; */ - private final ThreadPoolExecutor runStateHandlerTestExecutor = new ThreadPoolExecutor( 4, 4, @@ -78,7 +80,7 @@ public class RunStateHandlerTest { /** * When the execution of the thread pool task times out, the Trace flag is put into the MDC, and it is printed out when an alarm occurs. */ - // MDC.put(EXECUTE_TIMEOUT_TRACE, "39948722194639841.251.16612352194691531"); + MDC.put(EXECUTE_TIMEOUT_TRACE, "39948722194639841.251.16612352194691531"); try { Thread.sleep(5000); } catch (InterruptedException e) { diff --git a/hippo4j-example/hippo4j-spring-boot-starter-adapter-kafka-example/pom.xml b/hippo4j-example/hippo4j-spring-boot-starter-adapter-kafka-example/pom.xml deleted file mode 100644 index 40bcca10..00000000 --- a/hippo4j-example/hippo4j-spring-boot-starter-adapter-kafka-example/pom.xml +++ /dev/null @@ -1,56 +0,0 @@ - - - 4.0.0 - - cn.hippo4j - hippo4j-example - ${revision} - - hippo4j-spring-boot-starter-adapter-kafka-example - - - - org.springframework.boot - spring-boot-starter - - - - org.springframework.boot - spring-boot-starter-web - - - - org.springframework.boot - spring-boot-starter-json - - - - org.projectlombok - lombok - - - - cn.hippo4j - hippo4j-spring-boot-starter-adapter-kafka - ${project.version} - - - - cn.hippo4j - hippo4j-spring-boot-starter - ${project.version} - - - - cn.hippo4j - hippo4j-example-core - ${revision} - - - - org.springframework.kafka - spring-kafka - - - diff --git a/hippo4j-example/hippo4j-spring-boot-starter-adapter-kafka-example/src/main/java/cn/hippo4j/springboot/starter/adapter/kafka/example/consumer/KafkaMessageConsumer.java b/hippo4j-example/hippo4j-spring-boot-starter-adapter-kafka-example/src/main/java/cn/hippo4j/springboot/starter/adapter/kafka/example/consumer/KafkaMessageConsumer.java deleted file mode 100644 index 43087cc9..00000000 --- a/hippo4j-example/hippo4j-spring-boot-starter-adapter-kafka-example/src/main/java/cn/hippo4j/springboot/starter/adapter/kafka/example/consumer/KafkaMessageConsumer.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package cn.hippo4j.springboot.starter.adapter.kafka.example.consumer; - -import lombok.extern.slf4j.Slf4j; -import org.apache.kafka.clients.consumer.ConsumerRecord; -import org.springframework.kafka.annotation.KafkaListener; -import org.springframework.kafka.support.Acknowledgment; -import org.springframework.kafka.support.KafkaHeaders; -import org.springframework.messaging.handler.annotation.Header; -import org.springframework.stereotype.Component; - -import java.util.Optional; - -/** - * Kafka message consumer. - */ -@Slf4j -@Component -public class KafkaMessageConsumer { - - @KafkaListener(topics = "kafka_message_hippo4j", groupId = "hippo4j") - public void onMessage(ConsumerRecord record, Acknowledgment ack, @Header(KafkaHeaders.RECEIVED_TOPIC) String topic) { - Optional message = Optional.ofNullable(record.value()); - message.ifPresent(each -> log.info(each.toString())); - ack.acknowledge(); - } -} diff --git a/hippo4j-example/hippo4j-spring-boot-starter-adapter-kafka-example/src/main/java/cn/hippo4j/springboot/starter/adapter/kafka/example/produce/KafkaMessageProduce.java b/hippo4j-example/hippo4j-spring-boot-starter-adapter-kafka-example/src/main/java/cn/hippo4j/springboot/starter/adapter/kafka/example/produce/KafkaMessageProduce.java deleted file mode 100644 index 9cfbddbd..00000000 --- a/hippo4j-example/hippo4j-spring-boot-starter-adapter-kafka-example/src/main/java/cn/hippo4j/springboot/starter/adapter/kafka/example/produce/KafkaMessageProduce.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package cn.hippo4j.springboot.starter.adapter.kafka.example.produce; - -import cn.hippo4j.common.toolkit.IdUtil; -import cn.hippo4j.common.toolkit.JSONUtil; -import cn.hippo4j.example.core.dto.SendMessageDTO; -import lombok.AllArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.springframework.kafka.core.KafkaTemplate; -import org.springframework.stereotype.Component; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RestController; - -/** - * Kafka message produce. - */ -@Slf4j -@Component -@RestController -@AllArgsConstructor -public class KafkaMessageProduce { - - private final KafkaTemplate kafkaTemplate; - - private final String TOPIC = "kafka_message_hippo4j"; - - @GetMapping("/message/send") - public String sendMessage(Integer count) { - for (int i = 0; i < count; i++) { - String keys = IdUtil.randomUUID(); - SendMessageDTO payload = SendMessageDTO.builder() - .receiver("156011xxx91") - .uid(keys) - .build(); - kafkaTemplate.send(TOPIC, JSONUtil.toJSONString(payload)); - } - return "success"; - } -} diff --git a/hippo4j-example/hippo4j-spring-boot-starter-adapter-kafka-example/src/main/resources/application.properties b/hippo4j-example/hippo4j-spring-boot-starter-adapter-kafka-example/src/main/resources/application.properties deleted file mode 100644 index fe298e76..00000000 --- a/hippo4j-example/hippo4j-spring-boot-starter-adapter-kafka-example/src/main/resources/application.properties +++ /dev/null @@ -1,23 +0,0 @@ -server.port=8092 - -spring.profiles.active=dev -spring.dynamic.thread-pool.server-addr=http://localhost:6691 -spring.dynamic.thread-pool.namespace=prescription -spring.dynamic.thread-pool.item-id=dynamic-threadpool-example -spring.dynamic.thread-pool.username=admin -spring.dynamic.thread-pool.password=123456 - -spring.kafka.bootstrap-servers=127.0.0.1:9092 -spring.kafka.producer.retries=0 -spring.kafka.producer.batch-size=16384 -spring.kafka.producer.buffer-memory=33554432 -spring.kafka.producer.key-serializer=org.apache.kafka.common.serialization.StringSerializer -spring.kafka.producer.value-serializer=org.apache.kafka.common.serialization.StringSerializer -spring.kafka.producer.acks=1 -spring.kafka.consumer.auto-offset-reset=latest -spring.kafka.consumer.enable-auto-commit=false -spring.kafka.consumer.key-deserializer=org.apache.kafka.common.serialization.StringDeserializer -spring.kafka.consumer.value-deserializer=org.apache.kafka.common.serialization.StringDeserializer -spring.kafka.listener.concurrency=2 -spring.kafka.listener.ack-mode=manual_immediate -spring.kafka.listener.missing-topics-fatal=false diff --git a/hippo4j-example/hippo4j-spring-boot-starter-adapter-rabbitmq-example/pom.xml b/hippo4j-example/hippo4j-spring-boot-starter-adapter-rabbitmq-example/pom.xml index ab8e038d..d94e8b62 100644 --- a/hippo4j-example/hippo4j-spring-boot-starter-adapter-rabbitmq-example/pom.xml +++ b/hippo4j-example/hippo4j-spring-boot-starter-adapter-rabbitmq-example/pom.xml @@ -18,40 +18,29 @@ org.springframework.boot spring-boot-starter - org.springframework.boot spring-boot-starter-web - - - org.springframework.boot - spring-boot-starter-json - - org.projectlombok lombok - cn.hippo4j hippo4j-spring-boot-starter-adapter-rabbitmq ${project.version} - cn.hippo4j hippo4j-spring-boot-starter ${project.version} - cn.hippo4j hippo4j-example-core ${revision} - org.springframework.boot spring-boot-starter-amqp diff --git a/hippo4j-example/hippo4j-spring-boot-starter-adapter-rocketmq-example/pom.xml b/hippo4j-example/hippo4j-spring-boot-starter-adapter-rocketmq-example/pom.xml index cbabedf9..ba28fe22 100644 --- a/hippo4j-example/hippo4j-spring-boot-starter-adapter-rocketmq-example/pom.xml +++ b/hippo4j-example/hippo4j-spring-boot-starter-adapter-rocketmq-example/pom.xml @@ -18,38 +18,33 @@ org.springframework.boot spring-boot-starter - org.springframework.boot spring-boot-starter-web - - - org.springframework.boot - spring-boot-starter-json - - org.projectlombok lombok - cn.hippo4j hippo4j-spring-boot-starter-adapter-rocketmq ${project.version} - cn.hippo4j hippo4j-spring-boot-starter ${project.version} - cn.hippo4j hippo4j-example-core ${revision} + + org.apache.rocketmq + rocketmq-spring-boot-starter + ${rocketmq.version} + diff --git a/hippo4j-example/hippo4j-spring-boot-starter-adapter-spring-cloud-stream-rabbitmq-example/pom.xml b/hippo4j-example/hippo4j-spring-boot-starter-adapter-spring-cloud-stream-rabbitmq-example/pom.xml index 389906cb..17c7ad72 100644 --- a/hippo4j-example/hippo4j-spring-boot-starter-adapter-spring-cloud-stream-rabbitmq-example/pom.xml +++ b/hippo4j-example/hippo4j-spring-boot-starter-adapter-spring-cloud-stream-rabbitmq-example/pom.xml @@ -18,39 +18,34 @@ org.springframework.boot spring-boot-starter - org.springframework.boot spring-boot-starter-web - - - org.springframework.boot - spring-boot-starter-json - - org.projectlombok lombok - cn.hippo4j hippo4j-spring-boot-starter-adapter-spring-cloud-stream-rabbitmq ${project.version} - cn.hippo4j hippo4j-spring-boot-starter ${project.version} - cn.hippo4j hippo4j-example-core ${revision} + + org.springframework.cloud + spring-cloud-starter-stream-rabbit + ${spring-cloud-starter-stream-rabbitmq.version} + diff --git a/hippo4j-example/hippo4j-spring-boot-starter-adapter-spring-cloud-stream-rocketmq-example/pom.xml b/hippo4j-example/hippo4j-spring-boot-starter-adapter-spring-cloud-stream-rocketmq-example/pom.xml index 37faf900..0dc3f119 100644 --- a/hippo4j-example/hippo4j-spring-boot-starter-adapter-spring-cloud-stream-rocketmq-example/pom.xml +++ b/hippo4j-example/hippo4j-spring-boot-starter-adapter-spring-cloud-stream-rocketmq-example/pom.xml @@ -19,40 +19,29 @@ org.springframework.boot spring-boot-starter - org.springframework.boot spring-boot-starter-web - com.alibaba.cloud spring-cloud-starter-stream-rocketmq ${spring-cloud-starter-stream-rocketmq.version} - - - org.springframework.boot - spring-boot-starter-json - - org.projectlombok lombok - cn.hippo4j hippo4j-spring-boot-starter-adapter-spring-cloud-stream-rocketmq ${project.version} - cn.hippo4j hippo4j-spring-boot-starter ${project.version} - cn.hippo4j hippo4j-example-core diff --git a/hippo4j-example/pom.xml b/hippo4j-example/pom.xml index 8672119d..80999ea3 100644 --- a/hippo4j-example/pom.xml +++ b/hippo4j-example/pom.xml @@ -21,7 +21,6 @@ hippo4j-config-nacos-spring-boot-starter-example hippo4j-config-apollo-spring-boot-starter-example hippo4j-config-zookeeper-spring-boot-starter-example - hippo4j-spring-boot-starter-adapter-kafka-example hippo4j-spring-boot-starter-adapter-rabbitmq-example hippo4j-spring-boot-starter-adapter-spring-cloud-stream-rabbitmq-example hippo4j-spring-boot-starter-adapter-spring-cloud-stream-rocketmq-example diff --git a/hippo4j-message/pom.xml b/hippo4j-message/pom.xml index b32e2992..09fed8e6 100644 --- a/hippo4j-message/pom.xml +++ b/hippo4j-message/pom.xml @@ -12,17 +12,13 @@ cn.hippo4j - hippo4j-common + hippo4j-core ${revision} - - org.projectlombok - lombok - com.aliyun alibaba-dingtalk-service-sdk - true + ${dingtalk-sdk.version} diff --git a/hippo4j-message/src/main/java/cn/hippo4j/message/dto/AlarmControlDTO.java b/hippo4j-message/src/main/java/cn/hippo4j/message/dto/AlarmControlDTO.java index 11c5128f..73cb7314 100644 --- a/hippo4j-message/src/main/java/cn/hippo4j/message/dto/AlarmControlDTO.java +++ b/hippo4j-message/src/main/java/cn/hippo4j/message/dto/AlarmControlDTO.java @@ -18,7 +18,9 @@ package cn.hippo4j.message.dto; import cn.hippo4j.message.enums.NotifyTypeEnum; -import lombok.*; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; /** * Alarm control DTO. diff --git a/hippo4j-message/src/main/java/cn/hippo4j/message/platform/WeChatSendMessageHandler.java b/hippo4j-message/src/main/java/cn/hippo4j/message/platform/WeChatSendMessageHandler.java index 68dcbed5..b4fb42bf 100644 --- a/hippo4j-message/src/main/java/cn/hippo4j/message/platform/WeChatSendMessageHandler.java +++ b/hippo4j-message/src/main/java/cn/hippo4j/message/platform/WeChatSendMessageHandler.java @@ -70,6 +70,9 @@ public class WeChatSendMessageHandler extends AbstractRobotSendMessageHandler { } } + /** + * WeChat + */ @Data @Accessors(chain = true) public static class WeChatReqDTO { @@ -79,6 +82,9 @@ public class WeChatSendMessageHandler extends AbstractRobotSendMessageHandler { private Markdown markdown; } + /** + * Markdown + */ @Data public static class Markdown { diff --git a/hippo4j-message/src/main/java/cn/hippo4j/message/platform/base/AbstractRobotSendMessageHandler.java b/hippo4j-message/src/main/java/cn/hippo4j/message/platform/base/AbstractRobotSendMessageHandler.java index 209c2db9..f8acca94 100644 --- a/hippo4j-message/src/main/java/cn/hippo4j/message/platform/base/AbstractRobotSendMessageHandler.java +++ b/hippo4j-message/src/main/java/cn/hippo4j/message/platform/base/AbstractRobotSendMessageHandler.java @@ -72,7 +72,7 @@ public abstract class AbstractRobotSendMessageHandler implements SendMessageHand } else { replaceTxt = ""; } - alarmContentTxt = StringUtil.replace(alarmContentTxt, "${timout-content}", replaceTxt); + alarmContentTxt = StringUtil.replace(alarmContentTxt, "${timeout-content}", replaceTxt); String text = String.format( alarmContentTxt, alarmNotifyRequest.getActive(), diff --git a/hippo4j-message/src/main/java/cn/hippo4j/message/platform/constant/DingAlarmConstants.java b/hippo4j-message/src/main/java/cn/hippo4j/message/platform/constant/DingAlarmConstants.java index f8505403..f4bb2285 100644 --- a/hippo4j-message/src/main/java/cn/hippo4j/message/platform/constant/DingAlarmConstants.java +++ b/hippo4j-message/src/main/java/cn/hippo4j/message/platform/constant/DingAlarmConstants.java @@ -46,8 +46,8 @@ public class DingAlarmConstants { * Replace task timeout template */ public static final String DING_ALARM_TIMEOUT_REPLACE_TXT = - "任务执行时间:%d / ms \n\n " + - "超时时间:%d / ms \n\n " + - DING_ALARM_TIMEOUT_TRACE_REPLACE_TXT + - " --- \n\n "; + "任务执行时间:%d / ms \n\n " + + "超时时间:%d / ms \n\n " + + DING_ALARM_TIMEOUT_TRACE_REPLACE_TXT + + " --- \n\n "; } diff --git a/hippo4j-message/src/main/java/cn/hippo4j/message/platform/constant/WeChatAlarmConstants.java b/hippo4j-message/src/main/java/cn/hippo4j/message/platform/constant/WeChatAlarmConstants.java index 8d4f56f8..8b6001fc 100644 --- a/hippo4j-message/src/main/java/cn/hippo4j/message/platform/constant/WeChatAlarmConstants.java +++ b/hippo4j-message/src/main/java/cn/hippo4j/message/platform/constant/WeChatAlarmConstants.java @@ -36,7 +36,7 @@ public class WeChatAlarmConstants { * Replace task timeout template */ public static final String WE_CHAT_ALARM_TIMOUT_REPLACE_TXT = - "\n> 任务执行时间:%s / ms \n" + - "> 超时时间:%s / ms " + - WE_CHAT_ALARM_TIMOUT_TRACE_REPLACE_TXT; + "\n> 任务执行时间:%s / ms \n" + + "> 超时时间:%s / ms " + + WE_CHAT_ALARM_TIMOUT_TRACE_REPLACE_TXT; } diff --git a/hippo4j-message/src/main/java/cn/hippo4j/message/request/base/BaseNotifyRequest.java b/hippo4j-message/src/main/java/cn/hippo4j/message/request/base/BaseNotifyRequest.java index 5c96e994..5db9a63c 100644 --- a/hippo4j-message/src/main/java/cn/hippo4j/message/request/base/BaseNotifyRequest.java +++ b/hippo4j-message/src/main/java/cn/hippo4j/message/request/base/BaseNotifyRequest.java @@ -17,6 +17,7 @@ package cn.hippo4j.message.request.base; +import cn.hippo4j.common.api.NotifyRequest; import lombok.Data; /** diff --git a/hippo4j-message/src/main/java/cn/hippo4j/message/service/AlarmControlHandler.java b/hippo4j-message/src/main/java/cn/hippo4j/message/service/AlarmControlHandler.java index ea86e0f2..4d94b6bc 100644 --- a/hippo4j-message/src/main/java/cn/hippo4j/message/service/AlarmControlHandler.java +++ b/hippo4j-message/src/main/java/cn/hippo4j/message/service/AlarmControlHandler.java @@ -18,7 +18,6 @@ package cn.hippo4j.message.service; import cn.hippo4j.common.constant.Constants; -import cn.hippo4j.common.toolkit.IdUtil; import cn.hippo4j.common.toolkit.StringUtil; import cn.hippo4j.message.dto.AlarmControlDTO; import com.github.benmanes.caffeine.cache.Cache; @@ -58,8 +57,7 @@ public class AlarmControlHandler { try { pkId = cache.getIfPresent(alarmControl.getTypeEnum().name()); if (StringUtil.isBlank(pkId)) { - // Val meaningless. - cache.put(alarmControl.getTypeEnum().name(), IdUtil.simpleUUID()); + cache.put(alarmControl.getTypeEnum().name(), "-"); return true; } } finally { diff --git a/hippo4j-core/src/main/java/cn/hippo4j/core/executor/ThreadPoolNotifyAlarmHandler.java b/hippo4j-message/src/main/java/cn/hippo4j/message/service/DefaultThreadPoolCheckAlarmHandler.java similarity index 87% rename from hippo4j-core/src/main/java/cn/hippo4j/core/executor/ThreadPoolNotifyAlarmHandler.java rename to hippo4j-message/src/main/java/cn/hippo4j/message/service/DefaultThreadPoolCheckAlarmHandler.java index 62c8bf53..de770758 100644 --- a/hippo4j-core/src/main/java/cn/hippo4j/core/executor/ThreadPoolNotifyAlarmHandler.java +++ b/hippo4j-message/src/main/java/cn/hippo4j/message/service/DefaultThreadPoolCheckAlarmHandler.java @@ -15,24 +15,22 @@ * limitations under the License. */ -package cn.hippo4j.core.executor; +package cn.hippo4j.message.service; +import cn.hippo4j.common.api.ThreadPoolCheckAlarm; import cn.hippo4j.common.toolkit.CalculateUtil; import cn.hippo4j.common.toolkit.StringUtil; -import cn.hippo4j.core.executor.manage.GlobalNotifyAlarmManage; +import cn.hippo4j.core.executor.DynamicThreadPoolExecutor; +import cn.hippo4j.core.executor.DynamicThreadPoolWrapper; import cn.hippo4j.core.executor.manage.GlobalThreadPoolManage; import cn.hippo4j.core.executor.support.ThreadPoolBuilder; import cn.hippo4j.core.toolkit.ExecutorTraceContextUtil; import cn.hippo4j.core.toolkit.IdentifyUtil; import cn.hippo4j.message.enums.NotifyTypeEnum; import cn.hippo4j.message.request.AlarmNotifyRequest; -import cn.hippo4j.message.request.ChangeParameterNotifyRequest; -import cn.hippo4j.message.service.Hippo4jSendMessageService; -import cn.hippo4j.message.service.ThreadPoolNotifyAlarm; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Value; -import org.springframework.boot.CommandLineRunner; import java.util.List; import java.util.Objects; @@ -46,11 +44,11 @@ import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; /** - * Thread-pool notify alarm handler. + * Default thread-pool check alarm handler. */ @Slf4j @RequiredArgsConstructor -public class ThreadPoolNotifyAlarmHandler implements Runnable, CommandLineRunner { +public class DefaultThreadPoolCheckAlarmHandler implements Runnable, ThreadPoolCheckAlarm { private final Hippo4jSendMessageService hippo4jSendMessageService; @@ -66,11 +64,11 @@ public class ThreadPoolNotifyAlarmHandler implements Runnable, CommandLineRunner @Value("${spring.dynamic.thread-pool.check-state-interval:5}") private Integer checkStateInterval; - private final ScheduledExecutorService ALARM_NOTIFY_EXECUTOR = new ScheduledThreadPoolExecutor( + private final ScheduledExecutorService alarmNotifyExecutor = new ScheduledThreadPoolExecutor( 1, r -> new Thread(r, "client.alarm.notify")); - private final ExecutorService ASYNC_ALARM_NOTIFY_EXECUTOR = ThreadPoolBuilder.builder() + private final ExecutorService asyncAlarmNotifyExecutor = ThreadPoolBuilder.builder() .poolThreadSize(2, 4) .threadFactory("client.execute.timeout.alarm") .allowCoreThreadTimeOut(true) @@ -81,7 +79,7 @@ public class ThreadPoolNotifyAlarmHandler implements Runnable, CommandLineRunner @Override public void run(String... args) throws Exception { - ALARM_NOTIFY_EXECUTOR.scheduleWithFixedDelay(this, 0, checkStateInterval, TimeUnit.SECONDS); + alarmNotifyExecutor.scheduleWithFixedDelay(this, 0, checkStateInterval, TimeUnit.SECONDS); } @Override @@ -104,6 +102,7 @@ public class ThreadPoolNotifyAlarmHandler implements Runnable, CommandLineRunner * @param threadPoolId thread-pool id * @param threadPoolExecutor thread-pool executor */ + @Override public void checkPoolCapacityAlarm(String threadPoolId, ThreadPoolExecutor threadPoolExecutor) { ThreadPoolNotifyAlarm alarmConfig = GlobalNotifyAlarmManage.get(threadPoolId); if (Objects.isNull(alarmConfig) || !alarmConfig.getAlarm() || alarmConfig.getCapacityAlarm() <= 0) { @@ -127,6 +126,7 @@ public class ThreadPoolNotifyAlarmHandler implements Runnable, CommandLineRunner * @param threadPoolId thread-pool id * @param threadPoolExecutor thread-pool executor */ + @Override public void checkPoolActivityAlarm(String threadPoolId, ThreadPoolExecutor threadPoolExecutor) { ThreadPoolNotifyAlarm alarmConfig = GlobalNotifyAlarmManage.get(threadPoolId); if (Objects.isNull(alarmConfig) || !alarmConfig.getAlarm() || alarmConfig.getActiveAlarm() <= 0) { @@ -148,6 +148,7 @@ public class ThreadPoolNotifyAlarmHandler implements Runnable, CommandLineRunner * * @param threadPoolId thread-pool id */ + @Override public void asyncSendRejectedAlarm(String threadPoolId) { Runnable checkPoolRejectedAlarmTask = () -> { ThreadPoolNotifyAlarm alarmConfig = GlobalNotifyAlarmManage.get(threadPoolId); @@ -161,7 +162,7 @@ public class ThreadPoolNotifyAlarmHandler implements Runnable, CommandLineRunner hippo4jSendMessageService.sendAlarmMessage(NotifyTypeEnum.REJECT, alarmNotifyRequest); } }; - ASYNC_ALARM_NOTIFY_EXECUTOR.execute(checkPoolRejectedAlarmTask); + asyncAlarmNotifyExecutor.execute(checkPoolRejectedAlarmTask); } /** @@ -172,6 +173,7 @@ public class ThreadPoolNotifyAlarmHandler implements Runnable, CommandLineRunner * @param executeTimeOut execute time-out * @param threadPoolExecutor thread-pool executor */ + @Override public void asyncSendExecuteTimeOutAlarm(String threadPoolId, long executeTime, long executeTimeOut, ThreadPoolExecutor threadPoolExecutor) { ThreadPoolNotifyAlarm alarmConfig = GlobalNotifyAlarmManage.get(threadPoolId); if (Objects.isNull(alarmConfig) || !alarmConfig.getAlarm()) { @@ -188,26 +190,13 @@ public class ThreadPoolNotifyAlarmHandler implements Runnable, CommandLineRunner alarmNotifyRequest.setExecuteTimeoutTrace(executeTimeoutTrace); } Runnable task = () -> hippo4jSendMessageService.sendAlarmMessage(NotifyTypeEnum.TIMEOUT, alarmNotifyRequest); - ASYNC_ALARM_NOTIFY_EXECUTOR.execute(task); + asyncAlarmNotifyExecutor.execute(task); } catch (Throwable ex) { log.error("Send thread pool execution timeout alarm error.", ex); } } } - /** - * Send pool config change. - * - * @param request change parameter notify request - */ - public void sendPoolConfigChange(ChangeParameterNotifyRequest request) { - request.setActive(active.toUpperCase()); - String appName = StringUtil.isBlank(itemId) ? applicationName : itemId; - request.setAppName(appName); - request.setIdentify(IdentifyUtil.getIdentify()); - hippo4jSendMessageService.sendChangeMessage(request); - } - /** * Build alarm notify request. * diff --git a/hippo4j-message/src/main/java/cn/hippo4j/message/service/DefaultThreadPoolConfigChangeHandler.java b/hippo4j-message/src/main/java/cn/hippo4j/message/service/DefaultThreadPoolConfigChangeHandler.java new file mode 100644 index 00000000..730edd81 --- /dev/null +++ b/hippo4j-message/src/main/java/cn/hippo4j/message/service/DefaultThreadPoolConfigChangeHandler.java @@ -0,0 +1,57 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.hippo4j.message.service; + +import cn.hippo4j.common.api.ThreadPoolConfigChange; +import cn.hippo4j.common.toolkit.StringUtil; +import cn.hippo4j.core.toolkit.IdentifyUtil; +import cn.hippo4j.message.request.ChangeParameterNotifyRequest; +import lombok.RequiredArgsConstructor; +import org.springframework.beans.factory.annotation.Value; + +/** + * Default thread-pool config change handler. + */ +@RequiredArgsConstructor +public class DefaultThreadPoolConfigChangeHandler implements ThreadPoolConfigChange { + + @Value("${spring.profiles.active:UNKNOWN}") + private String active; + + @Value("${spring.dynamic.thread-pool.item-id:}") + private String itemId; + + @Value("${spring.application.name:UNKNOWN}") + private String applicationName; + + private final Hippo4jSendMessageService hippo4jSendMessageService; + + /** + * Send pool config change. + * + * @param requestParam change parameter notify request + */ + @Override + public void sendPoolConfigChange(ChangeParameterNotifyRequest requestParam) { + requestParam.setActive(active.toUpperCase()); + String appName = StringUtil.isBlank(itemId) ? applicationName : itemId; + requestParam.setAppName(appName); + requestParam.setIdentify(IdentifyUtil.getIdentify()); + hippo4jSendMessageService.sendChangeMessage(requestParam); + } +} diff --git a/hippo4j-core/src/main/java/cn/hippo4j/core/executor/manage/GlobalNotifyAlarmManage.java b/hippo4j-message/src/main/java/cn/hippo4j/message/service/GlobalNotifyAlarmManage.java similarity index 94% rename from hippo4j-core/src/main/java/cn/hippo4j/core/executor/manage/GlobalNotifyAlarmManage.java rename to hippo4j-message/src/main/java/cn/hippo4j/message/service/GlobalNotifyAlarmManage.java index fee2a1ee..c9f9fdc8 100644 --- a/hippo4j-core/src/main/java/cn/hippo4j/core/executor/manage/GlobalNotifyAlarmManage.java +++ b/hippo4j-message/src/main/java/cn/hippo4j/message/service/GlobalNotifyAlarmManage.java @@ -15,9 +15,7 @@ * limitations under the License. */ -package cn.hippo4j.core.executor.manage; - -import cn.hippo4j.message.service.ThreadPoolNotifyAlarm; +package cn.hippo4j.message.service; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; diff --git a/hippo4j-message/src/main/java/cn/hippo4j/message/service/Hippo4jBaseSendMessageService.java b/hippo4j-message/src/main/java/cn/hippo4j/message/service/Hippo4jBaseSendMessageService.java index 2f5eedbd..0792d6f1 100644 --- a/hippo4j-message/src/main/java/cn/hippo4j/message/service/Hippo4jBaseSendMessageService.java +++ b/hippo4j-message/src/main/java/cn/hippo4j/message/service/Hippo4jBaseSendMessageService.java @@ -46,7 +46,7 @@ public class Hippo4jBaseSendMessageService implements Hippo4jSendMessageService, private final AlarmControlHandler alarmControlHandler; @Getter - public final Map> notifyConfigs = new HashMap<>(); + private final Map> notifyConfigs = new HashMap<>(); private final Map sendMessageHandlers = new HashMap<>(); diff --git a/hippo4j-message/src/main/java/cn/hippo4j/message/service/SendMessageHandler.java b/hippo4j-message/src/main/java/cn/hippo4j/message/service/SendMessageHandler.java index 9e61f362..37e939bf 100644 --- a/hippo4j-message/src/main/java/cn/hippo4j/message/service/SendMessageHandler.java +++ b/hippo4j-message/src/main/java/cn/hippo4j/message/service/SendMessageHandler.java @@ -18,7 +18,7 @@ package cn.hippo4j.message.service; import cn.hippo4j.message.dto.NotifyConfigDTO; -import cn.hippo4j.message.request.base.NotifyRequest; +import cn.hippo4j.common.api.NotifyRequest; /** * Send message handler. diff --git a/hippo4j-message/src/main/resources/message/robot/dynamic-thread-pool/ding-alarm.txt b/hippo4j-message/src/main/resources/message/robot/dynamic-thread-pool/ding-alarm.txt index 7fda29d7..094e4505 100644 --- a/hippo4j-message/src/main/resources/message/robot/dynamic-thread-pool/ding-alarm.txt +++ b/hippo4j-message/src/main/resources/message/robot/dynamic-thread-pool/ding-alarm.txt @@ -34,7 +34,7 @@ --- - ${timout-content} + ${timeout-content} 拒绝策略:%s diff --git a/hippo4j-message/src/main/resources/message/robot/dynamic-thread-pool/wechat-alarm.txt b/hippo4j-message/src/main/resources/message/robot/dynamic-thread-pool/wechat-alarm.txt index 00dd33b2..1e1aa9c4 100644 --- a/hippo4j-message/src/main/resources/message/robot/dynamic-thread-pool/wechat-alarm.txt +++ b/hippo4j-message/src/main/resources/message/robot/dynamic-thread-pool/wechat-alarm.txt @@ -14,7 +14,7 @@ > 队列元素个数:%s > 队列剩余个数:%s > 拒绝策略:%s -> 拒绝策略执行次数:%s ${timout-content} +> 拒绝策略执行次数:%s ${timeout-content} > OWNER:<@%s> > 提示:%d 分钟内此线程池不会重复告警(可配置) diff --git a/hippo4j-monitor/hippo4j-monitor-base/src/main/java/cn/hippo4j/monitor/base/AbstractDynamicThreadPoolMonitor.java b/hippo4j-monitor/hippo4j-monitor-base/src/main/java/cn/hippo4j/monitor/base/AbstractDynamicThreadPoolMonitor.java index 81943cbd..2e8a77ac 100644 --- a/hippo4j-monitor/hippo4j-monitor-base/src/main/java/cn/hippo4j/monitor/base/AbstractDynamicThreadPoolMonitor.java +++ b/hippo4j-monitor/hippo4j-monitor-base/src/main/java/cn/hippo4j/monitor/base/AbstractDynamicThreadPoolMonitor.java @@ -42,9 +42,6 @@ public abstract class AbstractDynamicThreadPoolMonitor implements DynamicThreadP @Override public void collect() { List listDynamicThreadPoolId = GlobalThreadPoolManage.listThreadPoolId(); - for (String each : listDynamicThreadPoolId) { - ThreadPoolRunStateInfo poolRunState = threadPoolRunStateHandler.getPoolRunState(each); - execute(poolRunState); - } + listDynamicThreadPoolId.forEach(each -> execute(threadPoolRunStateHandler.getPoolRunState(each))); } } diff --git a/hippo4j-monitor/hippo4j-monitor-base/src/main/java/cn/hippo4j/monitor/base/AdapterThreadPoolMonitor.java b/hippo4j-monitor/hippo4j-monitor-base/src/main/java/cn/hippo4j/monitor/base/AdapterThreadPoolMonitor.java index cebdc7e2..520b4ffd 100644 --- a/hippo4j-monitor/hippo4j-monitor-base/src/main/java/cn/hippo4j/monitor/base/AdapterThreadPoolMonitor.java +++ b/hippo4j-monitor/hippo4j-monitor-base/src/main/java/cn/hippo4j/monitor/base/AdapterThreadPoolMonitor.java @@ -21,5 +21,4 @@ package cn.hippo4j.monitor.base; * Adapter thread-pool monitor. */ public interface AdapterThreadPoolMonitor extends ThreadPoolMonitor { - } diff --git a/hippo4j-monitor/hippo4j-monitor-base/src/main/java/cn/hippo4j/monitor/base/DynamicThreadPoolMonitor.java b/hippo4j-monitor/hippo4j-monitor-base/src/main/java/cn/hippo4j/monitor/base/DynamicThreadPoolMonitor.java index e3135db4..7e8c7452 100644 --- a/hippo4j-monitor/hippo4j-monitor-base/src/main/java/cn/hippo4j/monitor/base/DynamicThreadPoolMonitor.java +++ b/hippo4j-monitor/hippo4j-monitor-base/src/main/java/cn/hippo4j/monitor/base/DynamicThreadPoolMonitor.java @@ -21,5 +21,4 @@ package cn.hippo4j.monitor.base; * Dynamic thread-pool monitor. */ public interface DynamicThreadPoolMonitor extends ThreadPoolMonitor { - } diff --git a/hippo4j-monitor/hippo4j-monitor-base/src/main/java/cn/hippo4j/monitor/base/WebThreadPoolMonitor.java b/hippo4j-monitor/hippo4j-monitor-base/src/main/java/cn/hippo4j/monitor/base/WebThreadPoolMonitor.java index 333c0dbd..75b40fb7 100644 --- a/hippo4j-monitor/hippo4j-monitor-base/src/main/java/cn/hippo4j/monitor/base/WebThreadPoolMonitor.java +++ b/hippo4j-monitor/hippo4j-monitor-base/src/main/java/cn/hippo4j/monitor/base/WebThreadPoolMonitor.java @@ -21,5 +21,4 @@ package cn.hippo4j.monitor.base; * Web thread-pool monitor. */ public interface WebThreadPoolMonitor extends ThreadPoolMonitor { - } diff --git a/hippo4j-monitor/hippo4j-monitor-elasticsearch/pom.xml b/hippo4j-monitor/hippo4j-monitor-elasticsearch/pom.xml index 3ced6cef..0fcd444c 100644 --- a/hippo4j-monitor/hippo4j-monitor-elasticsearch/pom.xml +++ b/hippo4j-monitor/hippo4j-monitor-elasticsearch/pom.xml @@ -9,10 +9,6 @@ hippo4j-monitor-elasticsearch - - 6.8.17 - - cn.hippo4j diff --git a/hippo4j-monitor/hippo4j-monitor-elasticsearch/src/main/java/cn/hippo4j/monitor/elasticsearch/DynamicThreadPoolElasticSearchMonitorHandler.java b/hippo4j-monitor/hippo4j-monitor-elasticsearch/src/main/java/cn/hippo4j/monitor/elasticsearch/DynamicThreadPoolElasticSearchMonitorHandler.java index 36101cb8..203d2457 100644 --- a/hippo4j-monitor/hippo4j-monitor-elasticsearch/src/main/java/cn/hippo4j/monitor/elasticsearch/DynamicThreadPoolElasticSearchMonitorHandler.java +++ b/hippo4j-monitor/hippo4j-monitor-elasticsearch/src/main/java/cn/hippo4j/monitor/elasticsearch/DynamicThreadPoolElasticSearchMonitorHandler.java @@ -25,6 +25,8 @@ import cn.hippo4j.common.toolkit.JSONUtil; import cn.hippo4j.monitor.base.AbstractDynamicThreadPoolMonitor; import cn.hippo4j.monitor.base.MonitorTypeEnum; import cn.hippo4j.monitor.elasticsearch.model.ElasticSearchThreadPoolRunStateInfo; +import lombok.Builder; +import lombok.Getter; import lombok.extern.slf4j.Slf4j; import org.elasticsearch.action.admin.indices.alias.Alias; import org.elasticsearch.action.admin.indices.create.CreateIndexRequest; @@ -63,7 +65,7 @@ public class DynamicThreadPoolElasticSearchMonitorHandler extends AbstractDynami List rawMapping = FileUtil.readLines(Thread.currentThread().getContextClassLoader().getResource("mapping.json").getPath(), StandardCharsets.UTF_8); String mapping = String.join(" ", rawMapping); // if index doesn't exsit, this function may try to create one, but recommend to create index manually. - this.createIndex(indexName, "_doc", mapping, null, null, null); + this.createIndex(EsIndex.builder().index(indexName).type("_doc").mapping(mapping).build()); } esThreadPoolRunStateInfo.setApplicationName(applicationName); esThreadPoolRunStateInfo.setId(indexName + "-" + System.currentTimeMillis()); @@ -104,20 +106,20 @@ public class DynamicThreadPoolElasticSearchMonitorHandler extends AbstractDynami return isIndexExist.get(); } - public void createIndex(String index, String type, String mapping, Integer shards, Integer replicas, String alias) { + public void createIndex(EsIndex esIndex) { RestHighLevelClient client = ElasticSearchClientHolder.getClient(); boolean acknowledged = false; - CreateIndexRequest request = new CreateIndexRequest(index); - if (StringUtils.hasText(mapping)) { - request.mapping(type, mapping, XContentType.JSON); + CreateIndexRequest request = new CreateIndexRequest(esIndex.getIndex()); + if (StringUtils.hasText(esIndex.getMapping())) { + request.mapping(esIndex.getType(), esIndex.getMapping(), XContentType.JSON); } - if (!Objects.isNull(shards) && !Objects.isNull(replicas)) { + if (!Objects.isNull(esIndex.getShards()) && !Objects.isNull(esIndex.getReplicas())) { request.settings(Settings.builder() - .put("index.number_of_shards", shards) // 5 - .put("index.number_of_replicas", replicas));// 1 + .put("index.number_of_shards", esIndex.getShards()) + .put("index.number_of_replicas", esIndex.getReplicas())); } - if (StringUtils.hasText(alias)) { - request.alias(new Alias(alias)); + if (StringUtils.hasText(esIndex.getAlias())) { + request.alias(new Alias(esIndex.getAlias())); } try { CreateIndexResponse createIndexResponse = client.indices().create(request, RequestOptions.DEFAULT); @@ -138,4 +140,18 @@ public class DynamicThreadPoolElasticSearchMonitorHandler extends AbstractDynami public String getType() { return MonitorTypeEnum.ELASTICSEARCH.name().toLowerCase(); } + + /** + * Es Index + */ + @Getter + @Builder + private static class EsIndex { + String index; + String type; + String mapping; + Integer shards; + Integer replicas; + String alias; + } } diff --git a/hippo4j-monitor/hippo4j-monitor-elasticsearch/src/main/java/cn/hippo4j/monitor/elasticsearch/ElasticSearchClientHolder.java b/hippo4j-monitor/hippo4j-monitor-elasticsearch/src/main/java/cn/hippo4j/monitor/elasticsearch/ElasticSearchClientHolder.java index f30bbdc6..ba428722 100644 --- a/hippo4j-monitor/hippo4j-monitor-elasticsearch/src/main/java/cn/hippo4j/monitor/elasticsearch/ElasticSearchClientHolder.java +++ b/hippo4j-monitor/hippo4j-monitor-elasticsearch/src/main/java/cn/hippo4j/monitor/elasticsearch/ElasticSearchClientHolder.java @@ -28,8 +28,6 @@ import org.elasticsearch.client.RestClient; import org.elasticsearch.client.RestHighLevelClient; import org.springframework.core.env.Environment; -import java.io.PrintWriter; -import java.io.StringWriter; import java.util.ArrayList; import java.util.List; @@ -66,9 +64,7 @@ public class ElasticSearchClientHolder { log.info("[ES RestHighLevelClient] success to connect es!host:{},scheme:{}", host, scheme); return client; } catch (Exception ex) { - StringWriter stackTrace = new StringWriter(); - ex.printStackTrace(new PrintWriter(stackTrace)); - log.error("[ES RestHighLevelClient] fail to connect es! cause:{}", stackTrace); + log.error("[ES RestHighLevelClient] fail to connect es! cause:", ex); } return null; } diff --git a/hippo4j-monitor/hippo4j-monitor-elasticsearch/src/main/java/cn/hippo4j/monitor/elasticsearch/model/ElasticSearchThreadPoolRunStateInfo.java b/hippo4j-monitor/hippo4j-monitor-elasticsearch/src/main/java/cn/hippo4j/monitor/elasticsearch/model/ElasticSearchThreadPoolRunStateInfo.java index cc4da6e1..e72e9a27 100644 --- a/hippo4j-monitor/hippo4j-monitor-elasticsearch/src/main/java/cn/hippo4j/monitor/elasticsearch/model/ElasticSearchThreadPoolRunStateInfo.java +++ b/hippo4j-monitor/hippo4j-monitor-elasticsearch/src/main/java/cn/hippo4j/monitor/elasticsearch/model/ElasticSearchThreadPoolRunStateInfo.java @@ -28,7 +28,7 @@ import lombok.Setter; @Setter public class ElasticSearchThreadPoolRunStateInfo extends ThreadPoolRunStateInfo { - private String Id; + private String id; private String applicationName; } diff --git a/hippo4j-monitor/hippo4j-monitor-micrometer/src/main/java/cn/hippo4j/monitor/micrometer/AdapterThreadPoolMicrometerMonitorHandler.java b/hippo4j-monitor/hippo4j-monitor-micrometer/src/main/java/cn/hippo4j/monitor/micrometer/AdapterThreadPoolMicrometerMonitorHandler.java index 697ca2cf..b5e20608 100644 --- a/hippo4j-monitor/hippo4j-monitor-micrometer/src/main/java/cn/hippo4j/monitor/micrometer/AdapterThreadPoolMicrometerMonitorHandler.java +++ b/hippo4j-monitor/hippo4j-monitor-micrometer/src/main/java/cn/hippo4j/monitor/micrometer/AdapterThreadPoolMicrometerMonitorHandler.java @@ -35,21 +35,21 @@ import java.util.concurrent.ConcurrentHashMap; */ public class AdapterThreadPoolMicrometerMonitorHandler extends AbstractAdapterThreadPoolMonitor { - private final static String METRIC_NAME_PREFIX = "adapter.thread-pool"; + private static final String METRIC_NAME_PREFIX = "adapter.thread-pool"; - private final static String ADAPTER_THREAD_POOL_ID_TAG = METRIC_NAME_PREFIX + ".id"; + private static final String ADAPTER_THREAD_POOL_ID_TAG = METRIC_NAME_PREFIX + ".id"; - private final static String APPLICATION_NAME_TAG = "application.name"; + private static final String APPLICATION_NAME_TAG = "application.name"; - private final Map RUN_STATE_CACHE = new ConcurrentHashMap<>(); + private final Map runStateCache = new ConcurrentHashMap<>(); @Override protected void execute(ThreadPoolAdapterState threadPoolAdapterState) { - ThreadPoolAdapterState stateInfo = RUN_STATE_CACHE.get(threadPoolAdapterState.getThreadPoolKey()); - if (stateInfo == null) { - RUN_STATE_CACHE.put(threadPoolAdapterState.getThreadPoolKey(), threadPoolAdapterState); - } else { + ThreadPoolAdapterState stateInfo = runStateCache.get(threadPoolAdapterState.getThreadPoolKey()); + if (stateInfo != null) { BeanUtil.convert(threadPoolAdapterState, stateInfo); + } else { + runStateCache.put(threadPoolAdapterState.getThreadPoolKey(), threadPoolAdapterState); } Environment environment = ApplicationContextHolder.getInstance().getEnvironment(); String applicationName = environment.getProperty("spring.application.name", "application"); diff --git a/hippo4j-monitor/hippo4j-monitor-micrometer/src/main/java/cn/hippo4j/monitor/micrometer/DynamicThreadPoolMicrometerMonitorHandler.java b/hippo4j-monitor/hippo4j-monitor-micrometer/src/main/java/cn/hippo4j/monitor/micrometer/DynamicThreadPoolMicrometerMonitorHandler.java index 5b2cc068..19dac923 100644 --- a/hippo4j-monitor/hippo4j-monitor-micrometer/src/main/java/cn/hippo4j/monitor/micrometer/DynamicThreadPoolMicrometerMonitorHandler.java +++ b/hippo4j-monitor/hippo4j-monitor-micrometer/src/main/java/cn/hippo4j/monitor/micrometer/DynamicThreadPoolMicrometerMonitorHandler.java @@ -35,21 +35,21 @@ import java.util.concurrent.ConcurrentHashMap; */ public class DynamicThreadPoolMicrometerMonitorHandler extends AbstractDynamicThreadPoolMonitor { - private final static String METRIC_NAME_PREFIX = "dynamic.thread-pool"; + private static final String METRIC_NAME_PREFIX = "dynamic.thread-pool"; - private final static String DYNAMIC_THREAD_POOL_ID_TAG = METRIC_NAME_PREFIX + ".id"; + private static final String DYNAMIC_THREAD_POOL_ID_TAG = METRIC_NAME_PREFIX + ".id"; - private final static String APPLICATION_NAME_TAG = "application.name"; + private static final String APPLICATION_NAME_TAG = "application.name"; - private final Map RUN_STATE_CACHE = new ConcurrentHashMap<>(); + private final Map runStateCache = new ConcurrentHashMap<>(); @Override protected void execute(ThreadPoolRunStateInfo poolRunStateInfo) { - ThreadPoolRunStateInfo stateInfo = RUN_STATE_CACHE.get(poolRunStateInfo.getTpId()); - if (stateInfo == null) { - RUN_STATE_CACHE.put(poolRunStateInfo.getTpId(), poolRunStateInfo); - } else { + ThreadPoolRunStateInfo stateInfo = runStateCache.get(poolRunStateInfo.getTpId()); + if (stateInfo != null) { BeanUtil.convert(poolRunStateInfo, stateInfo); + } else { + runStateCache.put(poolRunStateInfo.getTpId(), poolRunStateInfo); } Environment environment = ApplicationContextHolder.getInstance().getEnvironment(); String applicationName = environment.getProperty("spring.application.name", "application"); diff --git a/hippo4j-monitor/hippo4j-monitor-micrometer/src/main/java/cn/hippo4j/monitor/micrometer/WebThreadPoolMicrometerMonitorHandler.java b/hippo4j-monitor/hippo4j-monitor-micrometer/src/main/java/cn/hippo4j/monitor/micrometer/WebThreadPoolMicrometerMonitorHandler.java index e7042a04..078cb8c1 100644 --- a/hippo4j-monitor/hippo4j-monitor-micrometer/src/main/java/cn/hippo4j/monitor/micrometer/WebThreadPoolMicrometerMonitorHandler.java +++ b/hippo4j-monitor/hippo4j-monitor-micrometer/src/main/java/cn/hippo4j/monitor/micrometer/WebThreadPoolMicrometerMonitorHandler.java @@ -35,21 +35,21 @@ import java.util.concurrent.ConcurrentHashMap; */ public class WebThreadPoolMicrometerMonitorHandler extends AbstractWebThreadPoolMonitor { - private final static String METRIC_NAME_PREFIX = "web.thread-pool"; + private static final String METRIC_NAME_PREFIX = "web.thread-pool"; - private final static String APPLICATION_NAME_TAG = "application.name"; + private static final String APPLICATION_NAME_TAG = "application.name"; - private final Map RUN_STATE_CACHE = new ConcurrentHashMap<>(); + private final Map runStateCache = new ConcurrentHashMap<>(); @Override protected void execute(ThreadPoolRunStateInfo webThreadPoolRunStateInfo) { Environment environment = ApplicationContextHolder.getInstance().getEnvironment(); String applicationName = environment.getProperty("spring.application.name", "application"); - ThreadPoolRunStateInfo stateInfo = RUN_STATE_CACHE.get(applicationName); - if (stateInfo == null) { - RUN_STATE_CACHE.put(applicationName, webThreadPoolRunStateInfo); - } else { + ThreadPoolRunStateInfo stateInfo = runStateCache.get(applicationName); + if (stateInfo != null) { BeanUtil.convert(webThreadPoolRunStateInfo, stateInfo); + } else { + runStateCache.put(applicationName, webThreadPoolRunStateInfo); } Iterable tags = CollectionUtil.newArrayList(Tag.of(APPLICATION_NAME_TAG, applicationName)); Metrics.gauge(metricName("current.load"), tags, webThreadPoolRunStateInfo, ThreadPoolRunStateInfo::getSimpleCurrentLoad); diff --git a/hippo4j-monitor/pom.xml b/hippo4j-monitor/pom.xml index 8550b18c..f7a28f85 100644 --- a/hippo4j-monitor/pom.xml +++ b/hippo4j-monitor/pom.xml @@ -16,35 +16,4 @@ hippo4j-monitor-local-log hippo4j-monitor-micrometer - - - - - org.apache.maven.plugins - maven-jar-plugin - - - - ${project.artifactId} - ${project.version} - ${maven.build.timestamp} - chen.ma - - - - - - org.apache.maven.plugins - maven-javadoc-plugin - 2.10.3 - - - - jar - - - - - - diff --git a/hippo4j-rpc/pom.xml b/hippo4j-rpc/pom.xml new file mode 100644 index 00000000..49058de8 --- /dev/null +++ b/hippo4j-rpc/pom.xml @@ -0,0 +1,32 @@ + + + 4.0.0 + + cn.hippo4j + hippo4j-all + ${revision} + + hippo4j-rpc + + + + cn.hippo4j + hippo4j-common + ${revision} + + + org.springframework.boot + spring-boot-starter-test + test + + + org.projectlombok + lombok + + + io.netty + netty-all + + + diff --git a/hippo4j-server/hippo4j-config/src/main/java/cn/hippo4j/config/rpc/client/Client.java b/hippo4j-rpc/src/main/java/cn/hippo4j/rpc/client/Client.java similarity index 82% rename from hippo4j-server/hippo4j-config/src/main/java/cn/hippo4j/config/rpc/client/Client.java rename to hippo4j-rpc/src/main/java/cn/hippo4j/rpc/client/Client.java index e2c4a64e..81957ce5 100644 --- a/hippo4j-server/hippo4j-config/src/main/java/cn/hippo4j/config/rpc/client/Client.java +++ b/hippo4j-rpc/src/main/java/cn/hippo4j/rpc/client/Client.java @@ -15,10 +15,10 @@ * limitations under the License. */ -package cn.hippo4j.config.rpc.client; +package cn.hippo4j.rpc.client; -import cn.hippo4j.config.rpc.request.Request; -import cn.hippo4j.config.rpc.response.Response; +import cn.hippo4j.rpc.request.Request; +import cn.hippo4j.rpc.response.Response; import java.io.Closeable; @@ -31,4 +31,12 @@ public interface Client extends Closeable { * Start the client and try to send and receive data */ Response connection(Request request); + + /** + * Check whether the client is active + * + * @return Whether active + */ + boolean isActive(); + } diff --git a/hippo4j-server/hippo4j-config/src/main/java/cn/hippo4j/config/rpc/client/ClientConnection.java b/hippo4j-rpc/src/main/java/cn/hippo4j/rpc/client/ClientConnection.java similarity index 86% rename from hippo4j-server/hippo4j-config/src/main/java/cn/hippo4j/config/rpc/client/ClientConnection.java rename to hippo4j-rpc/src/main/java/cn/hippo4j/rpc/client/ClientConnection.java index f8b22c62..8d04a213 100644 --- a/hippo4j-server/hippo4j-config/src/main/java/cn/hippo4j/config/rpc/client/ClientConnection.java +++ b/hippo4j-rpc/src/main/java/cn/hippo4j/rpc/client/ClientConnection.java @@ -15,11 +15,11 @@ * limitations under the License. */ -package cn.hippo4j.config.rpc.client; +package cn.hippo4j.rpc.client; -import cn.hippo4j.config.rpc.handler.Connection; -import cn.hippo4j.config.rpc.request.Request; -import cn.hippo4j.config.rpc.response.Response; +import cn.hippo4j.rpc.handler.Connection; +import cn.hippo4j.rpc.request.Request; +import cn.hippo4j.rpc.response.Response; /** * Applicable to client connections diff --git a/hippo4j-server/hippo4j-config/src/main/java/cn/hippo4j/config/rpc/client/NettyClientConnection.java b/hippo4j-rpc/src/main/java/cn/hippo4j/rpc/client/NettyClientConnection.java similarity index 68% rename from hippo4j-server/hippo4j-config/src/main/java/cn/hippo4j/config/rpc/client/NettyClientConnection.java rename to hippo4j-rpc/src/main/java/cn/hippo4j/rpc/client/NettyClientConnection.java index 0b02c48c..a725ed6a 100644 --- a/hippo4j-server/hippo4j-config/src/main/java/cn/hippo4j/config/rpc/client/NettyClientConnection.java +++ b/hippo4j-rpc/src/main/java/cn/hippo4j/rpc/client/NettyClientConnection.java @@ -15,21 +15,23 @@ * limitations under the License. */ -package cn.hippo4j.config.rpc.client; +package cn.hippo4j.rpc.client; -import cn.hippo4j.config.rpc.exception.TimeOutException; -import cn.hippo4j.config.rpc.process.ActivePostProcess; -import cn.hippo4j.config.rpc.request.Request; -import cn.hippo4j.config.rpc.response.Response; -import cn.hippo4j.config.rpc.support.NettyConnectPool; -import cn.hippo4j.config.rpc.support.NettyConnectPoolHolder; -import cn.hippo4j.config.rpc.support.ResultHolder; import cn.hippo4j.common.toolkit.Assert; import cn.hippo4j.common.web.exception.IllegalException; +import cn.hippo4j.rpc.exception.TimeOutException; +import cn.hippo4j.rpc.process.ActivePostProcess; +import cn.hippo4j.rpc.process.ActiveProcessChain; +import cn.hippo4j.rpc.request.Request; +import cn.hippo4j.rpc.response.Response; +import cn.hippo4j.rpc.support.NettyConnectPool; +import cn.hippo4j.rpc.support.NettyConnectPoolHolder; +import cn.hippo4j.rpc.support.ResultHolder; import io.netty.channel.Channel; import io.netty.channel.ChannelFuture; import io.netty.channel.EventLoopGroup; import io.netty.channel.nio.NioEventLoopGroup; +import io.netty.channel.pool.ChannelPoolHandler; import lombok.extern.slf4j.Slf4j; import java.util.LinkedList; @@ -46,47 +48,50 @@ public class NettyClientConnection implements ClientConnection { Integer port; // Obtain the connection timeout period. The default value is 30s long timeout = 30000L; - Channel channel; EventLoopGroup worker = new NioEventLoopGroup(); - List activeProcesses; - ChannelFuture future; + ActiveProcessChain activeProcessChain; NettyConnectPool connectionPool; + ChannelFuture future; + Channel channel; public NettyClientConnection(String host, int port, - List activeProcesses) { + List activeProcesses, + ChannelPoolHandler handler) { Assert.notNull(worker); this.host = host; this.port = port; - this.activeProcesses = activeProcesses; - this.connectionPool = NettyConnectPoolHolder.getPool(host, port, timeout, worker); + this.activeProcessChain = new ActiveProcessChain(activeProcesses); + this.connectionPool = NettyConnectPoolHolder.getPool(host, port, timeout, worker, handler); } - public NettyClientConnection(String host, int port) { - this(host, port, new LinkedList<>()); + public NettyClientConnection(String host, int port, ChannelPoolHandler handler) { + this(host, port, new LinkedList<>(), handler); } @Override public Response connect(Request request) { - preHandlers(request); + activeProcessChain.applyPreHandle(request); this.channel = connectionPool.acquire(timeout); + Response response = null; try { String key = request.getKey(); this.future = channel.writeAndFlush(request); log.info("Call successful, target address is {}:{}, request key is {}", host, port, key); // Wait for execution to complete - ResultHolder.put(key, Thread.currentThread()); + ResultHolder.putThread(key, Thread.currentThread()); LockSupport.parkNanos(timeout() * 1000000); - Response response = ResultHolder.get(key); + response = ResultHolder.get(key); if (response == null) { throw new TimeOutException("Timeout waiting for server-side response"); } - postHandlers(request, response); + activeProcessChain.applyPostHandle(request, response); log.info("The response from {}:{} was received successfully with the response key {}.", host, port, key); return response; } catch (Exception ex) { - afterCompletions(request, null, ex); + activeProcessChain.afterCompletion(request, response, ex); throw new IllegalException(ex); } finally { + activeProcessChain.afterCompletion(request, response, null); connectionPool.release(this.channel); } } @@ -111,22 +116,8 @@ public class NettyClientConnection implements ClientConnection { this.channel.close(); } - private void preHandlers(Request request) { - for (ActivePostProcess process : activeProcesses) { - process.preHandler(request); - } - } - - private void postHandlers(Request request, Response response) { - for (ActivePostProcess process : activeProcesses) { - process.postHandler(request, response); - } - } - - private void afterCompletions(Request request, Response response, Exception e) { - for (ActivePostProcess process : activeProcesses) { - process.afterCompletion(request, response, e); - } + @Override + public boolean isActive() { + return channel.isActive(); } - } diff --git a/hippo4j-server/hippo4j-config/src/main/java/cn/hippo4j/config/rpc/client/RPCClient.java b/hippo4j-rpc/src/main/java/cn/hippo4j/rpc/client/RPCClient.java similarity index 87% rename from hippo4j-server/hippo4j-config/src/main/java/cn/hippo4j/config/rpc/client/RPCClient.java rename to hippo4j-rpc/src/main/java/cn/hippo4j/rpc/client/RPCClient.java index 8b8451c8..e3094076 100644 --- a/hippo4j-server/hippo4j-config/src/main/java/cn/hippo4j/config/rpc/client/RPCClient.java +++ b/hippo4j-rpc/src/main/java/cn/hippo4j/rpc/client/RPCClient.java @@ -15,10 +15,10 @@ * limitations under the License. */ -package cn.hippo4j.config.rpc.client; +package cn.hippo4j.rpc.client; -import cn.hippo4j.config.rpc.request.Request; -import cn.hippo4j.config.rpc.response.Response; +import cn.hippo4j.rpc.request.Request; +import cn.hippo4j.rpc.response.Response; import java.io.IOException; @@ -38,6 +38,11 @@ public class RPCClient implements Client { return clientConnection.connect(request); } + @Override + public boolean isActive() { + return clientConnection.isActive(); + } + /** * Close the client and release all connections. * diff --git a/hippo4j-server/hippo4j-config/src/main/java/cn/hippo4j/config/rpc/coder/CompactObjectOutputStream.java b/hippo4j-rpc/src/main/java/cn/hippo4j/rpc/coder/CompactObjectOutputStream.java similarity index 97% rename from hippo4j-server/hippo4j-config/src/main/java/cn/hippo4j/config/rpc/coder/CompactObjectOutputStream.java rename to hippo4j-rpc/src/main/java/cn/hippo4j/rpc/coder/CompactObjectOutputStream.java index a8592ef0..599cf118 100644 --- a/hippo4j-server/hippo4j-config/src/main/java/cn/hippo4j/config/rpc/coder/CompactObjectOutputStream.java +++ b/hippo4j-rpc/src/main/java/cn/hippo4j/rpc/coder/CompactObjectOutputStream.java @@ -15,7 +15,7 @@ * limitations under the License. */ -package cn.hippo4j.config.rpc.coder; +package cn.hippo4j.rpc.coder; import java.io.IOException; import java.io.ObjectOutputStream; diff --git a/hippo4j-server/hippo4j-config/src/main/java/cn/hippo4j/config/rpc/coder/NettyDecoder.java b/hippo4j-rpc/src/main/java/cn/hippo4j/rpc/coder/NettyDecoder.java similarity index 95% rename from hippo4j-server/hippo4j-config/src/main/java/cn/hippo4j/config/rpc/coder/NettyDecoder.java rename to hippo4j-rpc/src/main/java/cn/hippo4j/rpc/coder/NettyDecoder.java index 334fa4c5..42223e44 100644 --- a/hippo4j-server/hippo4j-config/src/main/java/cn/hippo4j/config/rpc/coder/NettyDecoder.java +++ b/hippo4j-rpc/src/main/java/cn/hippo4j/rpc/coder/NettyDecoder.java @@ -15,9 +15,9 @@ * limitations under the License. */ -package cn.hippo4j.config.rpc.coder; +package cn.hippo4j.rpc.coder; -import cn.hippo4j.config.rpc.exception.CoderException; +import cn.hippo4j.rpc.exception.CoderException; import io.netty.buffer.ByteBuf; import io.netty.channel.ChannelHandlerContext; import io.netty.handler.codec.serialization.ClassResolver; diff --git a/hippo4j-server/hippo4j-config/src/main/java/cn/hippo4j/config/rpc/coder/NettyEncoder.java b/hippo4j-rpc/src/main/java/cn/hippo4j/rpc/coder/NettyEncoder.java similarity index 95% rename from hippo4j-server/hippo4j-config/src/main/java/cn/hippo4j/config/rpc/coder/NettyEncoder.java rename to hippo4j-rpc/src/main/java/cn/hippo4j/rpc/coder/NettyEncoder.java index 48ebe628..856aae2a 100644 --- a/hippo4j-server/hippo4j-config/src/main/java/cn/hippo4j/config/rpc/coder/NettyEncoder.java +++ b/hippo4j-rpc/src/main/java/cn/hippo4j/rpc/coder/NettyEncoder.java @@ -15,9 +15,9 @@ * limitations under the License. */ -package cn.hippo4j.config.rpc.coder; +package cn.hippo4j.rpc.coder; -import cn.hippo4j.config.rpc.exception.CoderException; +import cn.hippo4j.rpc.exception.CoderException; import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBufOutputStream; import io.netty.channel.ChannelHandlerContext; diff --git a/hippo4j-server/hippo4j-config/src/main/java/cn/hippo4j/config/rpc/discovery/DiscoveryAdapter.java b/hippo4j-rpc/src/main/java/cn/hippo4j/rpc/discovery/DiscoveryAdapter.java similarity index 96% rename from hippo4j-server/hippo4j-config/src/main/java/cn/hippo4j/config/rpc/discovery/DiscoveryAdapter.java rename to hippo4j-rpc/src/main/java/cn/hippo4j/rpc/discovery/DiscoveryAdapter.java index d91fe15f..3a788f30 100644 --- a/hippo4j-server/hippo4j-config/src/main/java/cn/hippo4j/config/rpc/discovery/DiscoveryAdapter.java +++ b/hippo4j-rpc/src/main/java/cn/hippo4j/rpc/discovery/DiscoveryAdapter.java @@ -15,7 +15,7 @@ * limitations under the License. */ -package cn.hippo4j.config.rpc.discovery; +package cn.hippo4j.rpc.discovery; import java.net.InetSocketAddress; diff --git a/hippo4j-server/hippo4j-config/src/main/java/cn/hippo4j/config/rpc/exception/CoderException.java b/hippo4j-rpc/src/main/java/cn/hippo4j/rpc/exception/CoderException.java similarity index 97% rename from hippo4j-server/hippo4j-config/src/main/java/cn/hippo4j/config/rpc/exception/CoderException.java rename to hippo4j-rpc/src/main/java/cn/hippo4j/rpc/exception/CoderException.java index aa0e107a..5ac64a5a 100644 --- a/hippo4j-server/hippo4j-config/src/main/java/cn/hippo4j/config/rpc/exception/CoderException.java +++ b/hippo4j-rpc/src/main/java/cn/hippo4j/rpc/exception/CoderException.java @@ -15,7 +15,7 @@ * limitations under the License. */ -package cn.hippo4j.config.rpc.exception; +package cn.hippo4j.rpc.exception; /** * During decoding and encoding, if an exception occurs, an exception of type {@link CoderException} is thrown, diff --git a/hippo4j-server/hippo4j-config/src/main/java/cn/hippo4j/config/rpc/exception/ConnectionException.java b/hippo4j-rpc/src/main/java/cn/hippo4j/rpc/exception/ConnectionException.java similarity index 97% rename from hippo4j-server/hippo4j-config/src/main/java/cn/hippo4j/config/rpc/exception/ConnectionException.java rename to hippo4j-rpc/src/main/java/cn/hippo4j/rpc/exception/ConnectionException.java index e43a0465..87e29423 100644 --- a/hippo4j-server/hippo4j-config/src/main/java/cn/hippo4j/config/rpc/exception/ConnectionException.java +++ b/hippo4j-rpc/src/main/java/cn/hippo4j/rpc/exception/ConnectionException.java @@ -15,7 +15,7 @@ * limitations under the License. */ -package cn.hippo4j.config.rpc.exception; +package cn.hippo4j.rpc.exception; /** * If an exception occurs during the connection between the server and the client, an exception of type diff --git a/hippo4j-server/hippo4j-config/src/main/java/cn/hippo4j/config/rpc/exception/TimeOutException.java b/hippo4j-rpc/src/main/java/cn/hippo4j/rpc/exception/TimeOutException.java similarity index 97% rename from hippo4j-server/hippo4j-config/src/main/java/cn/hippo4j/config/rpc/exception/TimeOutException.java rename to hippo4j-rpc/src/main/java/cn/hippo4j/rpc/exception/TimeOutException.java index 50b902d9..ef808b57 100644 --- a/hippo4j-server/hippo4j-config/src/main/java/cn/hippo4j/config/rpc/exception/TimeOutException.java +++ b/hippo4j-rpc/src/main/java/cn/hippo4j/rpc/exception/TimeOutException.java @@ -15,7 +15,7 @@ * limitations under the License. */ -package cn.hippo4j.config.rpc.exception; +package cn.hippo4j.rpc.exception; /** * If there is a timeout between the server and the client, you will get a {@link TimeOutException}, diff --git a/hippo4j-server/hippo4j-config/src/main/java/cn/hippo4j/config/rpc/handler/NettyClientTakeHandler.java b/hippo4j-rpc/src/main/java/cn/hippo4j/rpc/handler/AbstractNettyTakeHandler.java similarity index 66% rename from hippo4j-server/hippo4j-config/src/main/java/cn/hippo4j/config/rpc/handler/NettyClientTakeHandler.java rename to hippo4j-rpc/src/main/java/cn/hippo4j/rpc/handler/AbstractNettyTakeHandler.java index 9e459a4b..08fac1db 100644 --- a/hippo4j-server/hippo4j-config/src/main/java/cn/hippo4j/config/rpc/handler/NettyClientTakeHandler.java +++ b/hippo4j-rpc/src/main/java/cn/hippo4j/rpc/handler/AbstractNettyTakeHandler.java @@ -15,33 +15,26 @@ * limitations under the License. */ -package cn.hippo4j.config.rpc.handler; +package cn.hippo4j.rpc.handler; -import cn.hippo4j.config.rpc.exception.ConnectionException; -import cn.hippo4j.config.rpc.support.ResultHolder; -import cn.hippo4j.config.rpc.response.Response; -import cn.hippo4j.common.web.exception.IllegalException; +import cn.hippo4j.rpc.exception.ConnectionException; +import cn.hippo4j.rpc.response.Response; +import cn.hippo4j.rpc.support.ResultHolder; import io.netty.channel.Channel; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelInboundHandlerAdapter; /** - * Interconnect with the netty mediation layer + * the abstract base of {@link ConnectHandler} and {@link ChannelInboundHandlerAdapter} */ -public class NettyClientTakeHandler extends ChannelInboundHandlerAdapter implements ConnectHandler { - - @Override - public void channelRead(ChannelHandlerContext ctx, Object msg) { - try { - Response response = (Response) msg; - handler(response); - ctx.flush(); - } catch (Exception e) { - ctx.close(); - throw new IllegalException(e); - } - } +public abstract class AbstractNettyTakeHandler extends ChannelInboundHandlerAdapter implements ConnectHandler { + /** + * Manual disconnection is used here in case the server and client are disconnected due to a sudden exception + * + * @param ctx the context + * @param cause the throwable + */ @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { super.exceptionCaught(ctx, cause); @@ -53,9 +46,15 @@ public class NettyClientTakeHandler extends ChannelInboundHandlerAdapter impleme } } + /** + * This is a generic process that puts in the result and wakes up the thread + * + * @param response response + */ @Override public void handler(Response response) { ResultHolder.put(response.getKey(), response); ResultHolder.wake(response.getKey()); } + } diff --git a/hippo4j-server/hippo4j-config/src/main/java/cn/hippo4j/config/rpc/handler/ConnectHandler.java b/hippo4j-rpc/src/main/java/cn/hippo4j/rpc/handler/ConnectHandler.java similarity index 80% rename from hippo4j-server/hippo4j-config/src/main/java/cn/hippo4j/config/rpc/handler/ConnectHandler.java rename to hippo4j-rpc/src/main/java/cn/hippo4j/rpc/handler/ConnectHandler.java index 4170e5b5..21e36fb9 100644 --- a/hippo4j-server/hippo4j-config/src/main/java/cn/hippo4j/config/rpc/handler/ConnectHandler.java +++ b/hippo4j-rpc/src/main/java/cn/hippo4j/rpc/handler/ConnectHandler.java @@ -15,15 +15,16 @@ * limitations under the License. */ -package cn.hippo4j.config.rpc.handler; +package cn.hippo4j.rpc.handler; -import cn.hippo4j.config.rpc.request.Request; -import cn.hippo4j.config.rpc.response.Response; +import cn.hippo4j.rpc.request.Request; +import cn.hippo4j.rpc.response.Response; /** * The handler in each connection, where the specific behavior of the connection * must be specified, such as serialization and parsing, requesting and receiving - * requests, and so on + * requests, and so on
+ * */ public interface ConnectHandler { @@ -32,12 +33,13 @@ public interface ConnectHandler { * * @param request request */ - default Response handler(Request request) { + default Response sendHandler(Request request) { return null; } /** - * Processing after receiving Response + * Processing after receiving Response
+ * This is mainly for subsequent processing of the results * * @param response response */ diff --git a/hippo4j-rpc/src/main/java/cn/hippo4j/rpc/handler/Connection.java b/hippo4j-rpc/src/main/java/cn/hippo4j/rpc/handler/Connection.java new file mode 100644 index 00000000..77ce2211 --- /dev/null +++ b/hippo4j-rpc/src/main/java/cn/hippo4j/rpc/handler/Connection.java @@ -0,0 +1,41 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.hippo4j.rpc.handler; + +import java.io.Closeable; + +/** + * Represents a network request connection and provides IO layer support + */ +public interface Connection extends Closeable { + + /** + * Gets the state of the connection, which is interpreted differently by different programs
+ *

+ * Client: Active connection indicates that a connection is being maintained with the server. + * Inactive connection indicates that no connection is being established with the server
+ *

+ * Server: The active connection indicates that the server has been started, is receiving ports, + * and can obtain requests at any time. The inactive connection indicates that the server has been + * shut down and the ports have been released + * + * @return Whether active + */ + boolean isActive(); + +} diff --git a/hippo4j-rpc/src/main/java/cn/hippo4j/rpc/handler/HandlerManager.java b/hippo4j-rpc/src/main/java/cn/hippo4j/rpc/handler/HandlerManager.java new file mode 100644 index 00000000..7d0f3d29 --- /dev/null +++ b/hippo4j-rpc/src/main/java/cn/hippo4j/rpc/handler/HandlerManager.java @@ -0,0 +1,95 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.hippo4j.rpc.handler; + +import lombok.AllArgsConstructor; +import lombok.Data; + +/** + * Manage the Handler used in the processing.
+ * The Handler must be able to exist multiple times and be invoked once in a single execution + */ +public interface HandlerManager { + + /** + * Add handler to the end of the Handler chain + * + * @param name name + * @param handler handler + */ + HandlerManager addLast(String name, T handler); + + /** + * Add handler to the head of the Handler chain + * + * @param name name + * @param handler handler + */ + HandlerManager addFirst(String name, T handler); + + /** + * Add handler to the end of the Handler chain, without specifying a name + * + * @param handler handler + */ + HandlerManager addLast(T handler); + + /** + * Adds handler to the head of the Handler chain, without specifying a name + * + * @param handler handler + */ + HandlerManager addFirst(T handler); + + /** + * Create a handler + * + * @param order order + * @param handler Handler + * @param name Handler name + * @return HandlerEntity + */ + default HandlerEntity getHandlerEntity(long order, T handler, String name) { + return new HandlerEntity<>(order, handler, name); + } + + @Data + @AllArgsConstructor + class HandlerEntity implements Comparable> { + + /** + * order, The Handler with a larger value is executed after the Handler with a smaller value + */ + long order; + + /** + * handler + */ + T handler; + + /** + * A high level summary of handler functionality + */ + String name; + + @Override + public int compareTo(HandlerEntity o) { + return (int) (this.getOrder() - o.getOrder()); + } + } +} diff --git a/hippo4j-server/hippo4j-config/src/main/java/cn/hippo4j/config/rpc/handler/NettyClientPoolHandler.java b/hippo4j-rpc/src/main/java/cn/hippo4j/rpc/handler/NettyClientPoolHandler.java similarity index 55% rename from hippo4j-server/hippo4j-config/src/main/java/cn/hippo4j/config/rpc/handler/NettyClientPoolHandler.java rename to hippo4j-rpc/src/main/java/cn/hippo4j/rpc/handler/NettyClientPoolHandler.java index bb124e81..b9e38d36 100644 --- a/hippo4j-server/hippo4j-config/src/main/java/cn/hippo4j/config/rpc/handler/NettyClientPoolHandler.java +++ b/hippo4j-rpc/src/main/java/cn/hippo4j/rpc/handler/NettyClientPoolHandler.java @@ -15,22 +15,57 @@ * limitations under the License. */ -package cn.hippo4j.config.rpc.handler; +package cn.hippo4j.rpc.handler; -import cn.hippo4j.config.rpc.coder.NettyDecoder; -import cn.hippo4j.config.rpc.coder.NettyEncoder; +import cn.hippo4j.rpc.coder.NettyDecoder; +import cn.hippo4j.rpc.coder.NettyEncoder; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; +import io.netty.channel.ChannelHandler; import io.netty.channel.pool.ChannelPoolHandler; import io.netty.channel.socket.nio.NioSocketChannel; import io.netty.handler.codec.serialization.ClassResolvers; import lombok.extern.slf4j.Slf4j; +import java.util.List; + /** * Processing by the client connection pool handler to clean the buffer and define new connection properties */ @Slf4j -public class NettyClientPoolHandler implements ChannelPoolHandler { +public class NettyClientPoolHandler extends NettyHandlerManager implements ChannelPoolHandler { + + public NettyClientPoolHandler(List handlers) { + super(handlers); + } + + public NettyClientPoolHandler(ChannelHandler... handlers) { + super(handlers); + } + + public NettyClientPoolHandler() { + super(); + } + + public NettyClientPoolHandler addLast(String name, ChannelHandler handler) { + super.addLast(name, handler); + return this; + } + + public NettyClientPoolHandler addFirst(String name, ChannelHandler handler) { + super.addFirst(name, handler); + return this; + } + + public NettyClientPoolHandler addLast(ChannelHandler handler) { + super.addLast(handler); + return this; + } + + public NettyClientPoolHandler addFirst(ChannelHandler handler) { + super.addFirst(handler); + return this; + } @Override public void channelReleased(Channel ch) { @@ -50,6 +85,15 @@ public class NettyClientPoolHandler implements ChannelPoolHandler { .setTcpNoDelay(false); ch.pipeline().addLast(new NettyDecoder(ClassResolvers.cacheDisabled(null))); ch.pipeline().addLast(new NettyEncoder()); - ch.pipeline().addLast(new NettyClientTakeHandler()); + this.handlers.stream() + .sorted() + .forEach(h -> { + if (h.getName() == null) { + ch.pipeline().addLast(h.getHandler()); + } else { + ch.pipeline().addLast(h.getName(), h.getHandler()); + } + }); } + } diff --git a/hippo4j-server/hippo4j-config/src/main/java/cn/hippo4j/config/event/ConfigDataChangeEvent.java b/hippo4j-rpc/src/main/java/cn/hippo4j/rpc/handler/NettyClientTakeHandler.java similarity index 53% rename from hippo4j-server/hippo4j-config/src/main/java/cn/hippo4j/config/event/ConfigDataChangeEvent.java rename to hippo4j-rpc/src/main/java/cn/hippo4j/rpc/handler/NettyClientTakeHandler.java index 0c3cd1e1..b2cd5d6f 100644 --- a/hippo4j-server/hippo4j-config/src/main/java/cn/hippo4j/config/event/ConfigDataChangeEvent.java +++ b/hippo4j-rpc/src/main/java/cn/hippo4j/rpc/handler/NettyClientTakeHandler.java @@ -15,30 +15,29 @@ * limitations under the License. */ -package cn.hippo4j.config.event; +package cn.hippo4j.rpc.handler; -import org.springframework.util.StringUtils; +import cn.hippo4j.common.web.exception.IllegalException; +import cn.hippo4j.rpc.response.Response; +import io.netty.channel.ChannelHandler; +import io.netty.channel.ChannelHandlerContext; /** - * Config data change event. + * Interconnect with the netty mediation layer */ -public class ConfigDataChangeEvent extends AbstractEvent { - - public final String tenantId; - - public final String itemId; - - public final String tpId; - - public final long lastModifiedTs; - - public ConfigDataChangeEvent(String tenantId, String itemId, String tpId, Long gmtModified) { - if (StringUtils.isEmpty(tenantId) || StringUtils.isEmpty(itemId) || StringUtils.isEmpty(tpId)) { - throw new IllegalArgumentException("DataId is null or group is null"); +@ChannelHandler.Sharable +public class NettyClientTakeHandler extends AbstractNettyTakeHandler implements ConnectHandler { + + @Override + public void channelRead(ChannelHandlerContext ctx, Object msg) { + try { + Response response = (Response) msg; + handler(response); + ctx.flush(); + } catch (Exception e) { + ctx.close(); + throw new IllegalException(e); } - this.tenantId = tenantId; - this.itemId = itemId; - this.tpId = tpId; - this.lastModifiedTs = gmtModified; } + } diff --git a/hippo4j-rpc/src/main/java/cn/hippo4j/rpc/handler/NettyHandlerManager.java b/hippo4j-rpc/src/main/java/cn/hippo4j/rpc/handler/NettyHandlerManager.java new file mode 100644 index 00000000..0649dde3 --- /dev/null +++ b/hippo4j-rpc/src/main/java/cn/hippo4j/rpc/handler/NettyHandlerManager.java @@ -0,0 +1,102 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.hippo4j.rpc.handler; + +import cn.hippo4j.common.toolkit.Assert; +import io.netty.channel.ChannelHandler; + +import java.util.*; +import java.util.concurrent.atomic.AtomicLong; +import java.util.stream.Collectors; + +/** + * Processor manager for ChannelHandler in netty + */ +public abstract class NettyHandlerManager implements HandlerManager { + + protected final List> handlers; + + AtomicLong firstIndex = new AtomicLong(-1); + + AtomicLong lastIndex = new AtomicLong(0); + + protected NettyHandlerManager(List handlers) { + this.handlers = handlers.stream() + .filter(Objects::nonNull) + .map(c -> getHandlerEntity(lastIndex.getAndIncrement(), c, null)) + .collect(Collectors.toList()); + } + + protected NettyHandlerManager(ChannelHandler... handlers) { + this(handlers != null ? Arrays.asList(handlers) : Collections.emptyList()); + } + + protected NettyHandlerManager() { + this.handlers = new LinkedList<>(); + } + + /** + * {@inheritDoc} + * + * @param name name + * @param handler handler + * @return NettyHandlerManager + */ + public NettyHandlerManager addLast(String name, ChannelHandler handler) { + Assert.notNull(handler); + this.handlers.add(getHandlerEntity(lastIndex.getAndIncrement(), handler, name)); + return this; + } + + /** + * {@inheritDoc} + * + * @param name name + * @param handler handler + * @return NettyHandlerManager + */ + public NettyHandlerManager addFirst(String name, ChannelHandler handler) { + Assert.notNull(handler); + this.handlers.add(getHandlerEntity(firstIndex.getAndIncrement(), handler, name)); + return this; + } + + /** + * {@inheritDoc} + * + * @param handler handler + * @return NettyHandlerManager + */ + public NettyHandlerManager addLast(ChannelHandler handler) { + Assert.notNull(handler); + this.handlers.add(getHandlerEntity(lastIndex.getAndIncrement(), handler, null)); + return this; + } + + /** + * {@inheritDoc} + * + * @param handler handler + * @return NettyHandlerManager + */ + public NettyHandlerManager addFirst(ChannelHandler handler) { + Assert.notNull(handler); + this.handlers.add(getHandlerEntity(firstIndex.getAndDecrement(), handler, null)); + return this; + } +} diff --git a/hippo4j-server/hippo4j-config/src/main/java/cn/hippo4j/config/rpc/handler/NettyServerTakeHandler.java b/hippo4j-rpc/src/main/java/cn/hippo4j/rpc/handler/NettyServerTakeHandler.java similarity index 50% rename from hippo4j-server/hippo4j-config/src/main/java/cn/hippo4j/config/rpc/handler/NettyServerTakeHandler.java rename to hippo4j-rpc/src/main/java/cn/hippo4j/rpc/handler/NettyServerTakeHandler.java index cac4ad6e..0bbf7b02 100644 --- a/hippo4j-server/hippo4j-config/src/main/java/cn/hippo4j/config/rpc/handler/NettyServerTakeHandler.java +++ b/hippo4j-rpc/src/main/java/cn/hippo4j/rpc/handler/NettyServerTakeHandler.java @@ -15,20 +15,19 @@ * limitations under the License. */ -package cn.hippo4j.config.rpc.handler; +package cn.hippo4j.rpc.handler; -import cn.hippo4j.config.rpc.exception.ConnectionException; -import cn.hippo4j.config.rpc.process.ActivePostProcess; -import cn.hippo4j.config.rpc.response.DefaultResponse; -import cn.hippo4j.config.rpc.support.ClassRegistry; -import cn.hippo4j.config.rpc.support.Instance; -import cn.hippo4j.config.rpc.request.Request; -import cn.hippo4j.config.rpc.response.Response; import cn.hippo4j.common.toolkit.Assert; import cn.hippo4j.common.toolkit.ReflectUtil; -import io.netty.channel.Channel; +import cn.hippo4j.rpc.process.ActivePostProcess; +import cn.hippo4j.rpc.process.ActiveProcessChain; +import cn.hippo4j.rpc.request.Request; +import cn.hippo4j.rpc.response.DefaultResponse; +import cn.hippo4j.rpc.response.Response; +import cn.hippo4j.rpc.support.ClassRegistry; +import cn.hippo4j.rpc.support.Instance; +import io.netty.channel.ChannelHandler; import io.netty.channel.ChannelHandlerContext; -import io.netty.channel.ChannelInboundHandlerAdapter; import java.lang.reflect.Method; import java.util.LinkedList; @@ -37,13 +36,14 @@ import java.util.List; /** * netty adaptation layer */ -public class NettyServerTakeHandler extends ChannelInboundHandlerAdapter implements ConnectHandler { +@ChannelHandler.Sharable +public class NettyServerTakeHandler extends AbstractNettyTakeHandler implements ConnectHandler { - List processes; + ActiveProcessChain activeProcessChain; Instance instance; public NettyServerTakeHandler(List processes, Instance instance) { - this.processes = processes; + this.activeProcessChain = new ActiveProcessChain(processes); this.instance = instance; } @@ -57,58 +57,30 @@ public class NettyServerTakeHandler extends ChannelInboundHandlerAdapter impleme return; } Request request = (Request) msg; - Response response = handler(request); + Response response = sendHandler(request); ctx.writeAndFlush(response); } @Override - public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { - Channel channel = ctx.channel(); - if (channel.isActive()) { - ctx.close(); - } else { - throw new ConnectionException(cause); - } - } - - @Override - public Response handler(Request request) { - if (!preHandlers(request)) { + public Response sendHandler(Request request) { + if (!activeProcessChain.applyPreHandle(request)) { return null; } + Response response = null; try { Class cls = ClassRegistry.get(request.getClassName()); Method method = ReflectUtil.getMethodByName(cls, request.getMethodName(), request.getParameterTypes()); Assert.notNull(method); Object invoke = ReflectUtil.invoke(instance.getInstance(cls), method, request.getParameters()); - Response response = new DefaultResponse(request.getKey(), invoke.getClass(), invoke); - postHandlers(request, response); + response = new DefaultResponse(request.getKey(), invoke.getClass(), invoke); + activeProcessChain.applyPostHandle(request, response); return response; } catch (Exception e) { - Response response = new DefaultResponse(request.getKey(), e, e.getMessage()); - afterCompletions(request, response, e); + response = new DefaultResponse(request.getKey(), e, e.getMessage()); + activeProcessChain.afterCompletion(request, response, e); return response; - } - } - - private boolean preHandlers(Request request) { - for (ActivePostProcess process : processes) { - if (!process.preHandler(request)) { - return false; - } - } - return true; - } - - private void postHandlers(Request request, Response response) { - for (ActivePostProcess process : processes) { - process.postHandler(request, response); - } - } - - private void afterCompletions(Request request, Response response, Exception e) { - for (ActivePostProcess process : processes) { - process.afterCompletion(request, response, e); + } finally { + activeProcessChain.afterCompletion(request, response, null); } } diff --git a/hippo4j-server/hippo4j-config/src/main/java/cn/hippo4j/config/rpc/process/ActivePostProcess.java b/hippo4j-rpc/src/main/java/cn/hippo4j/rpc/process/ActivePostProcess.java similarity index 93% rename from hippo4j-server/hippo4j-config/src/main/java/cn/hippo4j/config/rpc/process/ActivePostProcess.java rename to hippo4j-rpc/src/main/java/cn/hippo4j/rpc/process/ActivePostProcess.java index 98df5998..816335f6 100644 --- a/hippo4j-server/hippo4j-config/src/main/java/cn/hippo4j/config/rpc/process/ActivePostProcess.java +++ b/hippo4j-rpc/src/main/java/cn/hippo4j/rpc/process/ActivePostProcess.java @@ -15,10 +15,10 @@ * limitations under the License. */ -package cn.hippo4j.config.rpc.process; +package cn.hippo4j.rpc.process; -import cn.hippo4j.config.rpc.request.Request; -import cn.hippo4j.config.rpc.response.Response; +import cn.hippo4j.rpc.request.Request; +import cn.hippo4j.rpc.response.Response; /** * Callback while the connection is in progress diff --git a/hippo4j-rpc/src/main/java/cn/hippo4j/rpc/process/ActiveProcessChain.java b/hippo4j-rpc/src/main/java/cn/hippo4j/rpc/process/ActiveProcessChain.java new file mode 100644 index 00000000..693f83ce --- /dev/null +++ b/hippo4j-rpc/src/main/java/cn/hippo4j/rpc/process/ActiveProcessChain.java @@ -0,0 +1,102 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.hippo4j.rpc.process; + +import cn.hippo4j.rpc.request.Request; +import cn.hippo4j.rpc.response.Response; +import lombok.extern.slf4j.Slf4j; + +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +/** + * Processor chain for easier processing of processors in different scenarios
+ * reference resources: spring HandlerExecutionChain + * + * @see ActivePostProcess + */ +@Slf4j +public final class ActiveProcessChain { + + /** + * A collection of processors that will be applied to their assigned programs. + * Processors will perform different actions on different occasions for both the server and the client, + * but the execution period of that action must be the same + */ + List processes; + + /** + * index
+ * that identifies where the {@link ActivePostProcess#preHandler(Request)} processing is performed
+ * This allows for the fact that some processors will add shutable operations to the class
+ * eg: {@link java.io.Closeable}, The {@link ActivePostProcess#afterCompletion(Request, Response, Exception)} + * operation is not performed after an exception if the preprocessor is not executed + */ + int index = -1; + + public ActiveProcessChain(List processes) { + this.processes = processes; + } + + public ActiveProcessChain(ActivePostProcess... processes) { + this((processes != null ? Arrays.asList(processes) : Collections.emptyList())); + } + + /** + * Apply postHandle methods of registered processes. + */ + public boolean applyPreHandle(Request request) { + for (int i = 0; i < this.processes.size(); i++) { + ActivePostProcess handle = processes.get(i); + if (!handle.preHandler(request)) { + afterCompletion(request, null, null); + return false; + } + this.index = i; + } + return true; + } + + /** + * Apply postHandle methods of registered processes. + */ + public void applyPostHandle(Request request, Response response) { + for (int i = processes.size() - 1; i >= 0; i--) { + ActivePostProcess handle = processes.get(i); + handle.postHandler(request, response); + } + } + + /** + * Trigger afterCompletion callbacks on the mapped ActivePostProcess. + * Will just invoke afterCompletion for all interceptors whose preHandle invocation + * has successfully completed and returned true. + */ + public void afterCompletion(Request request, Response response, Exception ex) { + for (int i = this.index; i >= 0; i--) { + ActivePostProcess handle = processes.get(i); + try { + handle.afterCompletion(request, response, ex); + } catch (Throwable e) { + log.error("HandlerInterceptor.afterCompletion threw exception", e); + } + } + } + +} diff --git a/hippo4j-server/hippo4j-config/src/main/java/cn/hippo4j/config/rpc/request/DefaultRequest.java b/hippo4j-rpc/src/main/java/cn/hippo4j/rpc/request/DefaultRequest.java similarity index 96% rename from hippo4j-server/hippo4j-config/src/main/java/cn/hippo4j/config/rpc/request/DefaultRequest.java rename to hippo4j-rpc/src/main/java/cn/hippo4j/rpc/request/DefaultRequest.java index 6b82a102..a1d346fa 100644 --- a/hippo4j-server/hippo4j-config/src/main/java/cn/hippo4j/config/rpc/request/DefaultRequest.java +++ b/hippo4j-rpc/src/main/java/cn/hippo4j/rpc/request/DefaultRequest.java @@ -15,7 +15,7 @@ * limitations under the License. */ -package cn.hippo4j.config.rpc.request; +package cn.hippo4j.rpc.request; import java.io.IOException; import java.io.ObjectInputStream; @@ -94,7 +94,7 @@ public final class DefaultRequest implements Request { if (parameters == null) { return; } - // 序列化属性 parameters + // Serialization parameters for (Object parameter : parameters) { s.writeObject(parameter); } @@ -110,7 +110,7 @@ public final class DefaultRequest implements Request { if (parameterTypes == null) { return; } - // 反序列化属性 parameters + // Deserialization parameters int length = parameterTypes.length; Object[] a = new Object[length]; for (int i = 0; i < length; i++) { diff --git a/hippo4j-server/hippo4j-config/src/main/java/cn/hippo4j/config/rpc/request/Request.java b/hippo4j-rpc/src/main/java/cn/hippo4j/rpc/request/Request.java similarity index 97% rename from hippo4j-server/hippo4j-config/src/main/java/cn/hippo4j/config/rpc/request/Request.java rename to hippo4j-rpc/src/main/java/cn/hippo4j/rpc/request/Request.java index a045fbbf..db68fe3d 100644 --- a/hippo4j-server/hippo4j-config/src/main/java/cn/hippo4j/config/rpc/request/Request.java +++ b/hippo4j-rpc/src/main/java/cn/hippo4j/rpc/request/Request.java @@ -15,7 +15,7 @@ * limitations under the License. */ -package cn.hippo4j.config.rpc.request; +package cn.hippo4j.rpc.request; import java.io.Serializable; diff --git a/hippo4j-server/hippo4j-config/src/main/java/cn/hippo4j/config/rpc/response/DefaultResponse.java b/hippo4j-rpc/src/main/java/cn/hippo4j/rpc/response/DefaultResponse.java similarity index 97% rename from hippo4j-server/hippo4j-config/src/main/java/cn/hippo4j/config/rpc/response/DefaultResponse.java rename to hippo4j-rpc/src/main/java/cn/hippo4j/rpc/response/DefaultResponse.java index 408d299f..e2d38c4d 100644 --- a/hippo4j-server/hippo4j-config/src/main/java/cn/hippo4j/config/rpc/response/DefaultResponse.java +++ b/hippo4j-rpc/src/main/java/cn/hippo4j/rpc/response/DefaultResponse.java @@ -15,7 +15,7 @@ * limitations under the License. */ -package cn.hippo4j.config.rpc.response; +package cn.hippo4j.rpc.response; import java.io.IOException; import java.io.ObjectInputStream; @@ -105,7 +105,7 @@ public class DefaultResponse implements Response { if (obj == null) { return; } - // 序列化属性 obj + // Serialization obj s.writeObject(this.obj); } @@ -116,7 +116,7 @@ public class DefaultResponse implements Response { */ private void readObject(ObjectInputStream s) throws IOException, ClassNotFoundException { s.defaultReadObject(); - // 反序列化属性 obj + // Deserialization obj this.obj = s.readObject(); } } diff --git a/hippo4j-server/hippo4j-config/src/main/java/cn/hippo4j/config/rpc/response/Response.java b/hippo4j-rpc/src/main/java/cn/hippo4j/rpc/response/Response.java similarity index 97% rename from hippo4j-server/hippo4j-config/src/main/java/cn/hippo4j/config/rpc/response/Response.java rename to hippo4j-rpc/src/main/java/cn/hippo4j/rpc/response/Response.java index 3c06fbaa..cdb26e5b 100644 --- a/hippo4j-server/hippo4j-config/src/main/java/cn/hippo4j/config/rpc/response/Response.java +++ b/hippo4j-rpc/src/main/java/cn/hippo4j/rpc/response/Response.java @@ -15,7 +15,7 @@ * limitations under the License. */ -package cn.hippo4j.config.rpc.response; +package cn.hippo4j.rpc.response; import java.io.Serializable; diff --git a/hippo4j-server/hippo4j-config/src/main/java/cn/hippo4j/config/rpc/server/NettyServerConnection.java b/hippo4j-rpc/src/main/java/cn/hippo4j/rpc/server/NettyServerConnection.java similarity index 59% rename from hippo4j-server/hippo4j-config/src/main/java/cn/hippo4j/config/rpc/server/NettyServerConnection.java rename to hippo4j-rpc/src/main/java/cn/hippo4j/rpc/server/NettyServerConnection.java index cb240442..671e0748 100644 --- a/hippo4j-server/hippo4j-config/src/main/java/cn/hippo4j/config/rpc/server/NettyServerConnection.java +++ b/hippo4j-rpc/src/main/java/cn/hippo4j/rpc/server/NettyServerConnection.java @@ -15,14 +15,12 @@ * limitations under the License. */ -package cn.hippo4j.config.rpc.server; +package cn.hippo4j.rpc.server; -import cn.hippo4j.config.rpc.coder.NettyDecoder; -import cn.hippo4j.config.rpc.coder.NettyEncoder; -import cn.hippo4j.config.rpc.handler.NettyServerTakeHandler; -import cn.hippo4j.config.rpc.process.ActivePostProcess; -import cn.hippo4j.config.rpc.support.Instance; import cn.hippo4j.common.toolkit.Assert; +import cn.hippo4j.rpc.coder.NettyDecoder; +import cn.hippo4j.rpc.coder.NettyEncoder; +import cn.hippo4j.rpc.handler.NettyHandlerManager; import io.netty.bootstrap.ServerBootstrap; import io.netty.channel.*; import io.netty.channel.nio.NioEventLoopGroup; @@ -31,44 +29,42 @@ import io.netty.channel.socket.nio.NioServerSocketChannel; import io.netty.handler.codec.serialization.ClassResolvers; import lombok.extern.slf4j.Slf4j; -import java.util.LinkedList; +import java.util.Arrays; +import java.util.Collections; import java.util.List; /** * adapter to the netty server */ @Slf4j -public class NettyServerConnection implements ServerConnection { +public class NettyServerConnection extends NettyHandlerManager implements ServerConnection { Integer port; EventLoopGroup leader; EventLoopGroup worker; Class socketChannelCls = NioServerSocketChannel.class; - List processes; - Instance instance; ChannelFuture future; + Channel channel; - public NettyServerConnection(EventLoopGroup leader, EventLoopGroup worker, List processes, Instance instance) { - Assert.notNull(processes); - Assert.notNull(instance); + public NettyServerConnection(EventLoopGroup leader, EventLoopGroup worker, List handlers) { + super(handlers); + Assert.notNull(handlers); Assert.notNull(leader); Assert.notNull(worker); this.leader = leader; this.worker = worker; - this.processes = processes; - this.instance = instance; } - public NettyServerConnection(EventLoopGroup leader, EventLoopGroup worker, Instance instance) { - this(leader, worker, new LinkedList<>(), instance); + public NettyServerConnection(EventLoopGroup leader, EventLoopGroup worker, ChannelHandler... handlers) { + this(leader, worker, (handlers != null ? Arrays.asList(handlers) : Collections.emptyList())); } - public NettyServerConnection(List processes, Instance instance) { - this(new NioEventLoopGroup(), new NioEventLoopGroup(), processes, instance); + public NettyServerConnection(ChannelHandler... handlers) { + this(handlers != null ? Arrays.asList(handlers) : Collections.emptyList()); } - public NettyServerConnection(Instance instance) { - this(new NioEventLoopGroup(), new NioEventLoopGroup(), new LinkedList<>(), instance); + public NettyServerConnection(List handlers) { + this(new NioEventLoopGroup(), new NioEventLoopGroup(), handlers); } @Override @@ -83,11 +79,20 @@ public class NettyServerConnection implements ServerConnection { protected void initChannel(SocketChannel ch) throws Exception { ch.pipeline().addLast(new NettyDecoder(ClassResolvers.cacheDisabled(null))); ch.pipeline().addLast(new NettyEncoder()); - ch.pipeline().addLast(new NettyServerTakeHandler(processes, instance)); + handlers.stream() + .sorted() + .forEach(h -> { + if (h.getName() == null) { + ch.pipeline().addLast(h.getHandler()); + } else { + ch.pipeline().addLast(h.getName(), h.getHandler()); + } + }); } }); try { this.future = server.bind(port); + this.channel = this.future.channel(); log.info("The server is started and can receive requests. The listening port is {}", port); this.port = port; this.future.channel().closeFuture().sync(); @@ -106,4 +111,29 @@ public class NettyServerConnection implements ServerConnection { this.future.channel().close(); log.info("The server is shut down and no more requests are received. The release port is {}", port); } + + @Override + public boolean isActive() { + return channel.isActive(); + } + + public NettyServerConnection addLast(String name, ChannelHandler handler) { + super.addLast(name, handler); + return this; + } + + public NettyServerConnection addFirst(String name, ChannelHandler handler) { + super.addFirst(name, handler); + return this; + } + + public NettyServerConnection addLast(ChannelHandler handler) { + super.addLast(handler); + return this; + } + + public NettyServerConnection addFirst(ChannelHandler handler) { + super.addFirst(handler); + return this; + } } diff --git a/hippo4j-server/hippo4j-config/src/main/java/cn/hippo4j/config/rpc/server/RPCServer.java b/hippo4j-rpc/src/main/java/cn/hippo4j/rpc/server/RPCServer.java similarity index 91% rename from hippo4j-server/hippo4j-config/src/main/java/cn/hippo4j/config/rpc/server/RPCServer.java rename to hippo4j-rpc/src/main/java/cn/hippo4j/rpc/server/RPCServer.java index b961aaf6..abb5f6ff 100644 --- a/hippo4j-server/hippo4j-config/src/main/java/cn/hippo4j/config/rpc/server/RPCServer.java +++ b/hippo4j-rpc/src/main/java/cn/hippo4j/rpc/server/RPCServer.java @@ -15,7 +15,7 @@ * limitations under the License. */ -package cn.hippo4j.config.rpc.server; +package cn.hippo4j.rpc.server; import java.io.IOException; @@ -37,6 +37,11 @@ public class RPCServer implements Server { serverConnection.bind(port); } + @Override + public boolean isActive() { + return serverConnection.isActive(); + } + /** * Shut down the server and release the port */ diff --git a/hippo4j-server/hippo4j-config/src/main/java/cn/hippo4j/config/rpc/server/Server.java b/hippo4j-rpc/src/main/java/cn/hippo4j/rpc/server/Server.java similarity index 88% rename from hippo4j-server/hippo4j-config/src/main/java/cn/hippo4j/config/rpc/server/Server.java rename to hippo4j-rpc/src/main/java/cn/hippo4j/rpc/server/Server.java index 69056286..9c21f788 100644 --- a/hippo4j-server/hippo4j-config/src/main/java/cn/hippo4j/config/rpc/server/Server.java +++ b/hippo4j-rpc/src/main/java/cn/hippo4j/rpc/server/Server.java @@ -15,7 +15,7 @@ * limitations under the License. */ -package cn.hippo4j.config.rpc.server; +package cn.hippo4j.rpc.server; import java.io.Closeable; @@ -30,4 +30,11 @@ public interface Server extends Closeable { */ void bind(); + /** + * Check whether the server is active + * + * @return Whether active + */ + boolean isActive(); + } diff --git a/hippo4j-server/hippo4j-config/src/main/java/cn/hippo4j/config/rpc/server/ServerConnection.java b/hippo4j-rpc/src/main/java/cn/hippo4j/rpc/server/ServerConnection.java similarity index 91% rename from hippo4j-server/hippo4j-config/src/main/java/cn/hippo4j/config/rpc/server/ServerConnection.java rename to hippo4j-rpc/src/main/java/cn/hippo4j/rpc/server/ServerConnection.java index 1e1d8a4b..fcb5a9e1 100644 --- a/hippo4j-server/hippo4j-config/src/main/java/cn/hippo4j/config/rpc/server/ServerConnection.java +++ b/hippo4j-rpc/src/main/java/cn/hippo4j/rpc/server/ServerConnection.java @@ -15,9 +15,9 @@ * limitations under the License. */ -package cn.hippo4j.config.rpc.server; +package cn.hippo4j.rpc.server; -import cn.hippo4j.config.rpc.handler.Connection; +import cn.hippo4j.rpc.handler.Connection; /** * This applies to server-side connections diff --git a/hippo4j-server/hippo4j-config/src/main/java/cn/hippo4j/config/rpc/support/ClassRegistry.java b/hippo4j-rpc/src/main/java/cn/hippo4j/rpc/support/ClassRegistry.java similarity index 98% rename from hippo4j-server/hippo4j-config/src/main/java/cn/hippo4j/config/rpc/support/ClassRegistry.java rename to hippo4j-rpc/src/main/java/cn/hippo4j/rpc/support/ClassRegistry.java index 4b938550..ebcc86f6 100644 --- a/hippo4j-server/hippo4j-config/src/main/java/cn/hippo4j/config/rpc/support/ClassRegistry.java +++ b/hippo4j-rpc/src/main/java/cn/hippo4j/rpc/support/ClassRegistry.java @@ -15,7 +15,7 @@ * limitations under the License. */ -package cn.hippo4j.config.rpc.support; +package cn.hippo4j.rpc.support; import lombok.AccessLevel; import lombok.NoArgsConstructor; diff --git a/hippo4j-server/hippo4j-config/src/main/java/cn/hippo4j/config/rpc/support/DefaultInstance.java b/hippo4j-rpc/src/main/java/cn/hippo4j/rpc/support/DefaultInstance.java similarity index 97% rename from hippo4j-server/hippo4j-config/src/main/java/cn/hippo4j/config/rpc/support/DefaultInstance.java rename to hippo4j-rpc/src/main/java/cn/hippo4j/rpc/support/DefaultInstance.java index 1c5ec559..c6cf9a6c 100644 --- a/hippo4j-server/hippo4j-config/src/main/java/cn/hippo4j/config/rpc/support/DefaultInstance.java +++ b/hippo4j-rpc/src/main/java/cn/hippo4j/rpc/support/DefaultInstance.java @@ -15,7 +15,7 @@ * limitations under the License. */ -package cn.hippo4j.config.rpc.support; +package cn.hippo4j.rpc.support; import cn.hippo4j.common.toolkit.ReflectUtil; import cn.hippo4j.common.web.exception.IllegalException; diff --git a/hippo4j-server/hippo4j-config/src/main/java/cn/hippo4j/config/rpc/support/Instance.java b/hippo4j-rpc/src/main/java/cn/hippo4j/rpc/support/Instance.java similarity index 97% rename from hippo4j-server/hippo4j-config/src/main/java/cn/hippo4j/config/rpc/support/Instance.java rename to hippo4j-rpc/src/main/java/cn/hippo4j/rpc/support/Instance.java index e1b7f33a..840dff3a 100644 --- a/hippo4j-server/hippo4j-config/src/main/java/cn/hippo4j/config/rpc/support/Instance.java +++ b/hippo4j-rpc/src/main/java/cn/hippo4j/rpc/support/Instance.java @@ -15,7 +15,7 @@ * limitations under the License. */ -package cn.hippo4j.config.rpc.support; +package cn.hippo4j.rpc.support; /** * Instance interface to get an instance diff --git a/hippo4j-server/hippo4j-config/src/main/java/cn/hippo4j/config/rpc/support/NettyConnectPool.java b/hippo4j-rpc/src/main/java/cn/hippo4j/rpc/support/NettyConnectPool.java similarity index 93% rename from hippo4j-server/hippo4j-config/src/main/java/cn/hippo4j/config/rpc/support/NettyConnectPool.java rename to hippo4j-rpc/src/main/java/cn/hippo4j/rpc/support/NettyConnectPool.java index 4268ba4c..a34159e9 100644 --- a/hippo4j-server/hippo4j-config/src/main/java/cn/hippo4j/config/rpc/support/NettyConnectPool.java +++ b/hippo4j-rpc/src/main/java/cn/hippo4j/rpc/support/NettyConnectPool.java @@ -15,10 +15,9 @@ * limitations under the License. */ -package cn.hippo4j.config.rpc.support; +package cn.hippo4j.rpc.support; -import cn.hippo4j.config.rpc.exception.ConnectionException; -import cn.hippo4j.config.rpc.handler.NettyClientPoolHandler; +import cn.hippo4j.rpc.exception.ConnectionException; import io.netty.bootstrap.Bootstrap; import io.netty.channel.Channel; import io.netty.channel.EventLoopGroup; @@ -41,14 +40,15 @@ public class NettyConnectPool { ChannelHealthChecker healthCheck = ChannelHealthChecker.ACTIVE; FixedChannelPool.AcquireTimeoutAction acquireTimeoutAction = FixedChannelPool.AcquireTimeoutAction.NEW; int maxPendingAcquires = Integer.MAX_VALUE; - ChannelPoolHandler handler = new NettyClientPoolHandler(); + ChannelPoolHandler handler; ChannelPool pool; String host; int port; public NettyConnectPool(String host, int port, int maxConnect, long timeout, EventLoopGroup worker, - Class socketChannelCls) { + Class socketChannelCls, + ChannelPoolHandler handler) { InetSocketAddress socketAddress = InetSocketAddress.createUnresolved(host, port); Bootstrap bootstrap = new Bootstrap() .group(worker) @@ -56,6 +56,7 @@ public class NettyConnectPool { .remoteAddress(socketAddress); this.host = host; this.port = port; + this.handler = handler; this.pool = new FixedChannelPool(bootstrap, handler, healthCheck, acquireTimeoutAction, timeout, maxConnect, maxPendingAcquires, true, true); log.info("The connection pool is established with the connection target {}:{}", host, port); diff --git a/hippo4j-server/hippo4j-config/src/main/java/cn/hippo4j/config/rpc/support/NettyConnectPoolHolder.java b/hippo4j-rpc/src/main/java/cn/hippo4j/rpc/support/NettyConnectPoolHolder.java similarity index 81% rename from hippo4j-server/hippo4j-config/src/main/java/cn/hippo4j/config/rpc/support/NettyConnectPoolHolder.java rename to hippo4j-rpc/src/main/java/cn/hippo4j/rpc/support/NettyConnectPoolHolder.java index d7cb7b86..e143948f 100644 --- a/hippo4j-server/hippo4j-config/src/main/java/cn/hippo4j/config/rpc/support/NettyConnectPoolHolder.java +++ b/hippo4j-rpc/src/main/java/cn/hippo4j/rpc/support/NettyConnectPoolHolder.java @@ -15,10 +15,11 @@ * limitations under the License. */ -package cn.hippo4j.config.rpc.support; +package cn.hippo4j.rpc.support; import io.netty.channel.Channel; import io.netty.channel.EventLoopGroup; +import io.netty.channel.pool.ChannelPoolHandler; import io.netty.channel.socket.nio.NioSocketChannel; import io.netty.util.concurrent.EventExecutorGroup; import lombok.AccessLevel; @@ -38,11 +39,13 @@ public class NettyConnectPoolHolder { static Map connectPoolMap = new ConcurrentHashMap<>(); private static NettyConnectPool initPool(String host, int port, - long timeout, EventLoopGroup worker) { + long timeout, EventLoopGroup worker, + ChannelPoolHandler handler) { return new NettyConnectPool( host, port, maxConnect, timeout, worker, - NioSocketChannel.class); + NioSocketChannel.class, + handler); } private static String getKey(String host, int port) { @@ -75,21 +78,22 @@ public class NettyConnectPoolHolder { /** * Gets a connection pool, and if there is no connectPoolMapping, creates one with the values provided and joins the connectPoolMapping * - * @param host the host - * @param port the port - * @param timeout timeout - * @param worker Special {@link EventExecutorGroup} which allows registering {@link Channel}s - * that get processed for later selection during the event loop. + * @param host the host + * @param port the port + * @param timeout timeout + * @param worker Special {@link EventExecutorGroup} which allows registering {@link Channel}s + * that get processed for later selection during the event loop. + * @param handler the chandler for netty * @return Map to the connection pool */ public static synchronized NettyConnectPool getPool(String host, int port, - long timeout, EventLoopGroup worker) { + long timeout, EventLoopGroup worker, + ChannelPoolHandler handler) { /* - * this cannot use the computeIfAbsent method directly here because put is already used in init. - * Details refer to https://bugs.openjdk.java.net/browse/JDK-8062841 + * this cannot use the computeIfAbsent method directly here because put is already used in init. Details refer to https://bugs.openjdk.java.net/browse/JDK-8062841 */ NettyConnectPool pool = getPool(host, port); - return pool == null ? initPool(host, port, timeout, worker) : pool; + return pool == null ? initPool(host, port, timeout, worker, handler) : pool; } /** diff --git a/hippo4j-server/hippo4j-config/src/main/java/cn/hippo4j/config/rpc/support/NettyProxyCenter.java b/hippo4j-rpc/src/main/java/cn/hippo4j/rpc/support/NettyProxyCenter.java similarity index 82% rename from hippo4j-server/hippo4j-config/src/main/java/cn/hippo4j/config/rpc/support/NettyProxyCenter.java rename to hippo4j-rpc/src/main/java/cn/hippo4j/rpc/support/NettyProxyCenter.java index 6ba1dcf6..e73ef944 100644 --- a/hippo4j-server/hippo4j-config/src/main/java/cn/hippo4j/config/rpc/support/NettyProxyCenter.java +++ b/hippo4j-rpc/src/main/java/cn/hippo4j/rpc/support/NettyProxyCenter.java @@ -15,14 +15,15 @@ * limitations under the License. */ -package cn.hippo4j.config.rpc.support; +package cn.hippo4j.rpc.support; -import cn.hippo4j.config.rpc.request.DefaultRequest; -import cn.hippo4j.config.rpc.client.NettyClientConnection; -import cn.hippo4j.config.rpc.request.Request; -import cn.hippo4j.config.rpc.response.Response; import cn.hippo4j.common.toolkit.IdUtil; import cn.hippo4j.common.web.exception.IllegalException; +import cn.hippo4j.rpc.client.NettyClientConnection; +import cn.hippo4j.rpc.request.DefaultRequest; +import cn.hippo4j.rpc.request.Request; +import cn.hippo4j.rpc.response.Response; +import io.netty.channel.pool.ChannelPoolHandler; import lombok.AccessLevel; import lombok.NoArgsConstructor; @@ -41,16 +42,17 @@ public class NettyProxyCenter { static Map, Object> map = new HashMap<>(); /** - * 通过一个接口得到一个适用于PRC的代理对象 + * A proxy object for PRC is obtained through an interface * - * @param cls 接口类型 - * @param host 请求地址 - * @param port 端口 - * @param 对象类型 - * @return 代理对象 + * @param cls The interface type + * @param host Request the address + * @param port port + * @param Object type + * @param handler the pool handler for netty + * @return Proxy objects */ - public static T getProxy(Class cls, String host, int port) { - NettyClientConnection connection = new NettyClientConnection(host, port); + public static T getProxy(Class cls, String host, int port, ChannelPoolHandler handler) { + NettyClientConnection connection = new NettyClientConnection(host, port, handler); return getProxy(connection, cls, host, port); } diff --git a/hippo4j-server/hippo4j-config/src/main/java/cn/hippo4j/config/rpc/support/ResultHolder.java b/hippo4j-rpc/src/main/java/cn/hippo4j/rpc/support/ResultHolder.java similarity index 96% rename from hippo4j-server/hippo4j-config/src/main/java/cn/hippo4j/config/rpc/support/ResultHolder.java rename to hippo4j-rpc/src/main/java/cn/hippo4j/rpc/support/ResultHolder.java index 2220fe8e..141368c3 100644 --- a/hippo4j-server/hippo4j-config/src/main/java/cn/hippo4j/config/rpc/support/ResultHolder.java +++ b/hippo4j-rpc/src/main/java/cn/hippo4j/rpc/support/ResultHolder.java @@ -15,7 +15,7 @@ * limitations under the License. */ -package cn.hippo4j.config.rpc.support; +package cn.hippo4j.rpc.support; import lombok.AccessLevel; import lombok.NoArgsConstructor; @@ -56,7 +56,7 @@ public class ResultHolder { * @param key Request and response keys * @param t The Thread */ - public static void put(String key, Thread t) { + public static void putThread(String key, Thread t) { log.debug("Write thread, waiting to wake up"); threadMap.put(key, t); } diff --git a/hippo4j-server/hippo4j-config/src/main/java/cn/hippo4j/config/rpc/support/SpringContextInstance.java b/hippo4j-rpc/src/main/java/cn/hippo4j/rpc/support/SpringContextInstance.java similarity index 96% rename from hippo4j-server/hippo4j-config/src/main/java/cn/hippo4j/config/rpc/support/SpringContextInstance.java rename to hippo4j-rpc/src/main/java/cn/hippo4j/rpc/support/SpringContextInstance.java index 9bd6ec56..a0d2db7a 100644 --- a/hippo4j-server/hippo4j-config/src/main/java/cn/hippo4j/config/rpc/support/SpringContextInstance.java +++ b/hippo4j-rpc/src/main/java/cn/hippo4j/rpc/support/SpringContextInstance.java @@ -15,7 +15,7 @@ * limitations under the License. */ -package cn.hippo4j.config.rpc.support; +package cn.hippo4j.rpc.support; import cn.hippo4j.common.config.ApplicationContextHolder; diff --git a/hippo4j-server/hippo4j-config/src/test/java/cn/hippo4j/config/rpc/client/CallManager.java b/hippo4j-rpc/src/test/java/cn/hippo4j/rpc/client/CallManager.java similarity index 89% rename from hippo4j-server/hippo4j-config/src/test/java/cn/hippo4j/config/rpc/client/CallManager.java rename to hippo4j-rpc/src/test/java/cn/hippo4j/rpc/client/CallManager.java index d3fae3ae..6ad49004 100644 --- a/hippo4j-server/hippo4j-config/src/test/java/cn/hippo4j/config/rpc/client/CallManager.java +++ b/hippo4j-rpc/src/test/java/cn/hippo4j/rpc/client/CallManager.java @@ -15,7 +15,7 @@ * limitations under the License. */ -package cn.hippo4j.config.rpc.client; +package cn.hippo4j.rpc.client; public class CallManager { @@ -23,4 +23,8 @@ public class CallManager { return 1; } + public int callTest(Integer a, Integer b) { + return a + b; + } + } diff --git a/hippo4j-rpc/src/test/java/cn/hippo4j/rpc/client/RPCClientTest.java b/hippo4j-rpc/src/test/java/cn/hippo4j/rpc/client/RPCClientTest.java new file mode 100644 index 00000000..3db8311e --- /dev/null +++ b/hippo4j-rpc/src/test/java/cn/hippo4j/rpc/client/RPCClientTest.java @@ -0,0 +1,112 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.hippo4j.rpc.client; + +import cn.hippo4j.rpc.handler.NettyClientPoolHandler; +import cn.hippo4j.rpc.handler.NettyClientTakeHandler; +import cn.hippo4j.rpc.handler.NettyServerTakeHandler; +import cn.hippo4j.rpc.request.DefaultRequest; +import cn.hippo4j.rpc.request.Request; +import cn.hippo4j.rpc.response.Response; +import cn.hippo4j.rpc.server.NettyServerConnection; +import cn.hippo4j.rpc.server.RPCServer; +import cn.hippo4j.rpc.server.ServerConnection; +import cn.hippo4j.rpc.support.ClassRegistry; +import cn.hippo4j.rpc.support.DefaultInstance; +import cn.hippo4j.rpc.support.Instance; +import io.netty.channel.pool.ChannelPoolHandler; +import org.junit.Assert; +import org.junit.Test; + +import java.io.IOException; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.TimeUnit; + +public class RPCClientTest { + + String host = "localhost"; + int port = 8888; + int portTest = 8889; + + @Test + public void connection() throws IOException { + Class cls = CallManager.class; + String className = cls.getName(); + ClassRegistry.put(className, cls); + // The mode connection was denied when the server was started on the specified port + Instance instance = new DefaultInstance(); + NettyServerTakeHandler handler = new NettyServerTakeHandler(instance); + ServerConnection connection = new NettyServerConnection(handler); + RPCServer rpcServer = new RPCServer(port, connection); + CompletableFuture.runAsync(rpcServer::bind); + try { + TimeUnit.SECONDS.sleep(3); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + ChannelPoolHandler channelPoolHandler = new NettyClientPoolHandler(new NettyClientTakeHandler()); + NettyClientConnection clientConnection = new NettyClientConnection(host, port, channelPoolHandler); + RPCClient rpcClient = new RPCClient(clientConnection); + Request request = new DefaultRequest("127.0.0.18888", className, "call", null, null); + for (int i = 0; i < 100; i++) { + Response response = rpcClient.connection(request); + boolean active = rpcClient.isActive(); + Assert.assertTrue(active); + Assert.assertEquals(response.getObj(), 1); + } + rpcClient.close(); + rpcServer.close(); + } + + /** + * This test case can be overridden under the handler and coder packages + */ + @Test + public void connectionTest() throws IOException { + Class cls = CallManager.class; + String className = cls.getName(); + ClassRegistry.put(className, cls); + // The mode connection was denied when the server was started on the specified port + Instance instance = new DefaultInstance(); + NettyServerTakeHandler handler = new NettyServerTakeHandler(instance); + ServerConnection connection = new NettyServerConnection(handler); + RPCServer rpcServer = new RPCServer(portTest, connection); + CompletableFuture.runAsync(rpcServer::bind); + try { + TimeUnit.SECONDS.sleep(3); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + ChannelPoolHandler channelPoolHandler = new NettyClientPoolHandler(new NettyClientTakeHandler()); + NettyClientConnection clientConnection = new NettyClientConnection(host, portTest, channelPoolHandler); + RPCClient rpcClient = new RPCClient(clientConnection); + Class[] classes = new Class[2]; + classes[0] = Integer.class; + classes[1] = Integer.class; + Object[] objects = new Object[2]; + objects[0] = 1; + objects[1] = 2; + Request request = new DefaultRequest("127.0.0.18889", className, "callTest", classes, objects); + Response response = rpcClient.connection(request); + boolean active = rpcClient.isActive(); + Assert.assertTrue(active); + Assert.assertEquals(response.getObj(), 3); + rpcClient.close(); + rpcServer.close(); + } +} \ No newline at end of file diff --git a/hippo4j-server/hippo4j-config/src/test/java/cn/hippo4j/config/rpc/server/RPCServerTest.java b/hippo4j-rpc/src/test/java/cn/hippo4j/rpc/server/RPCServerTest.java similarity index 79% rename from hippo4j-server/hippo4j-config/src/test/java/cn/hippo4j/config/rpc/server/RPCServerTest.java rename to hippo4j-rpc/src/test/java/cn/hippo4j/rpc/server/RPCServerTest.java index 726ca910..5d06b9f8 100644 --- a/hippo4j-server/hippo4j-config/src/test/java/cn/hippo4j/config/rpc/server/RPCServerTest.java +++ b/hippo4j-rpc/src/test/java/cn/hippo4j/rpc/server/RPCServerTest.java @@ -15,12 +15,14 @@ * limitations under the License. */ -package cn.hippo4j.config.rpc.server; +package cn.hippo4j.rpc.server; -import cn.hippo4j.config.rpc.support.DefaultInstance; -import cn.hippo4j.config.rpc.support.Instance; +import cn.hippo4j.rpc.handler.NettyServerTakeHandler; +import cn.hippo4j.rpc.support.DefaultInstance; +import cn.hippo4j.rpc.support.Instance; import io.netty.channel.EventLoopGroup; import io.netty.channel.nio.NioEventLoopGroup; +import org.junit.Assert; import org.junit.Test; import java.io.IOException; @@ -34,7 +36,8 @@ public class RPCServerTest { @Test public void bind() throws IOException { Instance instance = new DefaultInstance(); - ServerConnection connection = new NettyServerConnection(instance); + NettyServerTakeHandler handler = new NettyServerTakeHandler(instance); + ServerConnection connection = new NettyServerConnection(handler); RPCServer rpcServer = new RPCServer(port, connection); CompletableFuture.runAsync(rpcServer::bind); try { @@ -42,7 +45,11 @@ public class RPCServerTest { } catch (InterruptedException e) { throw new RuntimeException(e); } + boolean active = rpcServer.isActive(); + Assert.assertTrue(active); rpcServer.close(); + boolean serverActive = rpcServer.isActive(); + Assert.assertFalse(serverActive); } @Test @@ -50,7 +57,8 @@ public class RPCServerTest { Instance instance = new DefaultInstance(); EventLoopGroup leader = new NioEventLoopGroup(); EventLoopGroup worker = new NioEventLoopGroup(); - ServerConnection connection = new NettyServerConnection(leader, worker, instance); + NettyServerTakeHandler handler = new NettyServerTakeHandler(instance); + ServerConnection connection = new NettyServerConnection(leader, worker, handler); RPCServer rpcServer = new RPCServer(port, connection); CompletableFuture.runAsync(rpcServer::bind); try { diff --git a/hippo4j-server/hippo4j-config/src/test/java/cn/hippo4j/config/rpc/support/ClassRegistryTest.java b/hippo4j-rpc/src/test/java/cn/hippo4j/rpc/support/ClassRegistryTest.java similarity index 98% rename from hippo4j-server/hippo4j-config/src/test/java/cn/hippo4j/config/rpc/support/ClassRegistryTest.java rename to hippo4j-rpc/src/test/java/cn/hippo4j/rpc/support/ClassRegistryTest.java index 403a7114..80fa3a53 100644 --- a/hippo4j-server/hippo4j-config/src/test/java/cn/hippo4j/config/rpc/support/ClassRegistryTest.java +++ b/hippo4j-rpc/src/test/java/cn/hippo4j/rpc/support/ClassRegistryTest.java @@ -15,7 +15,7 @@ * limitations under the License. */ -package cn.hippo4j.config.rpc.support; +package cn.hippo4j.rpc.support; import org.junit.Assert; import org.junit.Test; diff --git a/hippo4j-server/hippo4j-config/src/test/java/cn/hippo4j/config/rpc/support/DefaultInstanceTest.java b/hippo4j-rpc/src/test/java/cn/hippo4j/rpc/support/DefaultInstanceTest.java similarity index 92% rename from hippo4j-server/hippo4j-config/src/test/java/cn/hippo4j/config/rpc/support/DefaultInstanceTest.java rename to hippo4j-rpc/src/test/java/cn/hippo4j/rpc/support/DefaultInstanceTest.java index 6d070446..aa6dca00 100644 --- a/hippo4j-server/hippo4j-config/src/test/java/cn/hippo4j/config/rpc/support/DefaultInstanceTest.java +++ b/hippo4j-rpc/src/test/java/cn/hippo4j/rpc/support/DefaultInstanceTest.java @@ -15,7 +15,7 @@ * limitations under the License. */ -package cn.hippo4j.config.rpc.support; +package cn.hippo4j.rpc.support; import lombok.AllArgsConstructor; import lombok.Getter; @@ -38,7 +38,7 @@ public class DefaultInstanceTest { @Test public void testGetInstance() { - String className = "cn.hippo4j.config.rpc.support.DefaultInstanceTest$InstanceModel"; + String className = "cn.hippo4j.rpc.support.DefaultInstanceTest$InstanceModel"; Object instanceInstance = instance.getInstance(className); Assert.assertNotNull(instanceInstance); Assert.assertEquals(className, instanceInstance.getClass().getName()); diff --git a/hippo4j-server/hippo4j-config/src/test/java/cn/hippo4j/config/rpc/support/NettyConnectPoolHolderTest.java b/hippo4j-rpc/src/test/java/cn/hippo4j/rpc/support/NettyConnectPoolHolderTest.java similarity index 81% rename from hippo4j-server/hippo4j-config/src/test/java/cn/hippo4j/config/rpc/support/NettyConnectPoolHolderTest.java rename to hippo4j-rpc/src/test/java/cn/hippo4j/rpc/support/NettyConnectPoolHolderTest.java index f510ecd5..ce68b9a0 100644 --- a/hippo4j-server/hippo4j-config/src/test/java/cn/hippo4j/config/rpc/support/NettyConnectPoolHolderTest.java +++ b/hippo4j-rpc/src/test/java/cn/hippo4j/rpc/support/NettyConnectPoolHolderTest.java @@ -15,8 +15,10 @@ * limitations under the License. */ -package cn.hippo4j.config.rpc.support; +package cn.hippo4j.rpc.support; +import cn.hippo4j.rpc.handler.NettyClientPoolHandler; +import cn.hippo4j.rpc.handler.NettyClientTakeHandler; import io.netty.channel.Channel; import io.netty.channel.EventLoopGroup; import io.netty.channel.nio.NioEventLoopGroup; @@ -35,7 +37,8 @@ public class NettyConnectPoolHolderTest { @Test public void createPool() { - NettyConnectPool pool = new NettyConnectPool(host, port, maxCount, timeout, group, cls); + NettyClientPoolHandler handler = new NettyClientPoolHandler(new NettyClientTakeHandler()); + NettyConnectPool pool = new NettyConnectPool(host, port, maxCount, timeout, group, cls, handler); NettyConnectPool connectPool = NettyConnectPoolHolder.getPool(host, port); Assert.assertEquals(pool, connectPool); NettyConnectPoolHolder.clear(); @@ -45,7 +48,8 @@ public class NettyConnectPoolHolderTest { @Test public void testGetPool() { - NettyConnectPool connectPool = NettyConnectPoolHolder.getPool(host, port, timeout, group); + NettyClientPoolHandler handler = new NettyClientPoolHandler(new NettyClientTakeHandler()); + NettyConnectPool connectPool = NettyConnectPoolHolder.getPool(host, port, timeout, group, handler); NettyConnectPool connectPool1 = NettyConnectPoolHolder.getPool(host, port); Assert.assertEquals(connectPool1, connectPool); NettyConnectPoolHolder.clear(); @@ -55,7 +59,8 @@ public class NettyConnectPoolHolderTest { @Test public void remove() { - NettyConnectPool connectPool = NettyConnectPoolHolder.getPool(host, port, timeout, group); + NettyClientPoolHandler handler = new NettyClientPoolHandler(new NettyClientTakeHandler()); + NettyConnectPool connectPool = NettyConnectPoolHolder.getPool(host, port, timeout, group, handler); NettyConnectPool connectPool1 = NettyConnectPoolHolder.getPool(host, port); Assert.assertEquals(connectPool1, connectPool); NettyConnectPoolHolder.remove(host, port); diff --git a/hippo4j-server/hippo4j-config/src/test/java/cn/hippo4j/config/rpc/support/NettyConnectPoolTest.java b/hippo4j-rpc/src/test/java/cn/hippo4j/rpc/support/NettyConnectPoolTest.java similarity index 78% rename from hippo4j-server/hippo4j-config/src/test/java/cn/hippo4j/config/rpc/support/NettyConnectPoolTest.java rename to hippo4j-rpc/src/test/java/cn/hippo4j/rpc/support/NettyConnectPoolTest.java index 622e575d..fd8457a4 100644 --- a/hippo4j-server/hippo4j-config/src/test/java/cn/hippo4j/config/rpc/support/NettyConnectPoolTest.java +++ b/hippo4j-rpc/src/test/java/cn/hippo4j/rpc/support/NettyConnectPoolTest.java @@ -15,11 +15,14 @@ * limitations under the License. */ -package cn.hippo4j.config.rpc.support; +package cn.hippo4j.rpc.support; -import cn.hippo4j.config.rpc.server.NettyServerConnection; -import cn.hippo4j.config.rpc.server.RPCServer; -import cn.hippo4j.config.rpc.server.ServerConnection; +import cn.hippo4j.rpc.handler.NettyClientPoolHandler; +import cn.hippo4j.rpc.handler.NettyClientTakeHandler; +import cn.hippo4j.rpc.handler.NettyServerTakeHandler; +import cn.hippo4j.rpc.server.NettyServerConnection; +import cn.hippo4j.rpc.server.RPCServer; +import cn.hippo4j.rpc.server.ServerConnection; import io.netty.channel.Channel; import io.netty.channel.EventLoopGroup; import io.netty.channel.nio.NioEventLoopGroup; @@ -45,7 +48,8 @@ public class NettyConnectPoolTest { public void acquire() throws IOException { // The mode connection was denied when the server was started on the specified port Instance instance = new DefaultInstance(); - ServerConnection connection = new NettyServerConnection(instance); + NettyServerTakeHandler handler = new NettyServerTakeHandler(instance); + ServerConnection connection = new NettyServerConnection(handler); RPCServer rpcServer = new RPCServer(port, connection); CompletableFuture.runAsync(rpcServer::bind); // Given the delay in starting the server, wait here @@ -54,8 +58,8 @@ public class NettyConnectPoolTest { } catch (InterruptedException e) { throw new RuntimeException(e); } - - NettyConnectPool pool = new NettyConnectPool(host, port, maxCount, timeout, group, cls); + NettyClientPoolHandler poolHandler = new NettyClientPoolHandler(new NettyClientTakeHandler()); + NettyConnectPool pool = new NettyConnectPool(host, port, maxCount, timeout, group, cls, poolHandler); Channel acquire = pool.acquire(timeout); Assert.assertNotNull(acquire); pool.release(acquire); @@ -66,7 +70,8 @@ public class NettyConnectPoolTest { public void testAcquire() throws IOException { // The mode connection was denied when the server was started on the specified port Instance instance = new DefaultInstance(); - ServerConnection connection = new NettyServerConnection(instance); + NettyServerTakeHandler handler = new NettyServerTakeHandler(instance); + ServerConnection connection = new NettyServerConnection(handler); RPCServer rpcServer = new RPCServer(port, connection); CompletableFuture.runAsync(rpcServer::bind); // Given the delay in starting the server, wait here @@ -75,8 +80,8 @@ public class NettyConnectPoolTest { } catch (InterruptedException e) { throw new RuntimeException(e); } - - NettyConnectPool pool = new NettyConnectPool(host, port, maxCount, timeout, group, cls); + NettyClientPoolHandler poolHandler = new NettyClientPoolHandler(new NettyClientTakeHandler()); + NettyConnectPool pool = new NettyConnectPool(host, port, maxCount, timeout, group, cls, poolHandler); Future acquire = pool.acquire(); Assert.assertNotNull(acquire); rpcServer.close(); @@ -86,7 +91,8 @@ public class NettyConnectPoolTest { public void close() throws IOException { // The mode connection was denied when the server was started on the specified port Instance instance = new DefaultInstance(); - ServerConnection connection = new NettyServerConnection(instance); + NettyServerTakeHandler handler = new NettyServerTakeHandler(instance); + ServerConnection connection = new NettyServerConnection(handler); RPCServer rpcServer = new RPCServer(port, connection); CompletableFuture.runAsync(rpcServer::bind); // Given the delay in starting the server, wait here @@ -96,7 +102,8 @@ public class NettyConnectPoolTest { throw new RuntimeException(e); } - NettyConnectPool pool = new NettyConnectPool(host, port, maxCount, timeout, group, cls); + NettyClientPoolHandler poolHandler = new NettyClientPoolHandler(new NettyClientTakeHandler()); + NettyConnectPool pool = new NettyConnectPool(host, port, maxCount, timeout, group, cls, poolHandler); Channel acquire = pool.acquire(timeout); Assert.assertNotNull(acquire); pool.release(acquire); diff --git a/hippo4j-server/hippo4j-config/src/test/java/cn/hippo4j/config/rpc/support/NettyProxyCenterTest.java b/hippo4j-rpc/src/test/java/cn/hippo4j/rpc/support/NettyProxyCenterTest.java similarity index 60% rename from hippo4j-server/hippo4j-config/src/test/java/cn/hippo4j/config/rpc/support/NettyProxyCenterTest.java rename to hippo4j-rpc/src/test/java/cn/hippo4j/rpc/support/NettyProxyCenterTest.java index 9ae4ac50..41d2de53 100644 --- a/hippo4j-server/hippo4j-config/src/test/java/cn/hippo4j/config/rpc/support/NettyProxyCenterTest.java +++ b/hippo4j-rpc/src/test/java/cn/hippo4j/rpc/support/NettyProxyCenterTest.java @@ -15,9 +15,12 @@ * limitations under the License. */ -package cn.hippo4j.config.rpc.support; +package cn.hippo4j.rpc.support; import cn.hippo4j.common.web.exception.IllegalException; +import cn.hippo4j.rpc.exception.ConnectionException; +import cn.hippo4j.rpc.handler.NettyClientPoolHandler; +import cn.hippo4j.rpc.handler.NettyClientTakeHandler; import org.junit.Assert; import org.junit.Test; @@ -25,17 +28,29 @@ public class NettyProxyCenterTest { @Test public void getProxy() { - ProxyInterface localhost = NettyProxyCenter.getProxy(ProxyInterface.class, "localhost", 8888); + NettyClientPoolHandler handler = new NettyClientPoolHandler(new NettyClientTakeHandler()); + ProxyInterface localhost = NettyProxyCenter.getProxy(ProxyInterface.class, "localhost", 8888, handler); Assert.assertNotNull(localhost); } @Test(expected = IllegalException.class) public void getProxyTest() { - ProxyClass localhost = NettyProxyCenter.getProxy(ProxyClass.class, "localhost", 8888); + NettyClientPoolHandler handler = new NettyClientPoolHandler(new NettyClientTakeHandler()); + ProxyClass localhost = NettyProxyCenter.getProxy(ProxyClass.class, "localhost", 8888, handler); Assert.assertNotNull(localhost); } + + @Test(expected = ConnectionException.class) + public void getProxyTestCall() { + NettyClientPoolHandler handler = new NettyClientPoolHandler(new NettyClientTakeHandler()); + ProxyInterface localhost = NettyProxyCenter.getProxy(ProxyInterface.class, "localhost", 8888, handler); + localhost.hello(); + Assert.assertNotNull(localhost); + } + interface ProxyInterface { + void hello(); } static class ProxyClass { diff --git a/hippo4j-server/hippo4j-config/src/test/java/cn/hippo4j/config/rpc/support/ResultHolderTest.java b/hippo4j-rpc/src/test/java/cn/hippo4j/rpc/support/ResultHolderTest.java similarity index 63% rename from hippo4j-server/hippo4j-config/src/test/java/cn/hippo4j/config/rpc/support/ResultHolderTest.java rename to hippo4j-rpc/src/test/java/cn/hippo4j/rpc/support/ResultHolderTest.java index 3defaf3b..4302a335 100644 --- a/hippo4j-server/hippo4j-config/src/test/java/cn/hippo4j/config/rpc/support/ResultHolderTest.java +++ b/hippo4j-rpc/src/test/java/cn/hippo4j/rpc/support/ResultHolderTest.java @@ -15,12 +15,17 @@ * limitations under the License. */ -package cn.hippo4j.config.rpc.support; +package cn.hippo4j.rpc.support; import cn.hippo4j.common.toolkit.IdUtil; import org.junit.Assert; import org.junit.Test; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.locks.LockSupport; + public class ResultHolderTest { @Test @@ -39,4 +44,21 @@ public class ResultHolderTest { Assert.assertEquals(r1, o1); Assert.assertEquals(r2, o2); } + + @Test + public void testThread() throws InterruptedException { + AtomicInteger a = new AtomicInteger(); + String s1 = IdUtil.simpleUUID(); + String o1 = s1 + "1"; + CompletableFuture.runAsync(() -> { + ResultHolder.putThread(o1, Thread.currentThread()); + LockSupport.park(); + a.set(1); + }); + Assert.assertEquals(0, a.get()); + TimeUnit.SECONDS.sleep(1); + ResultHolder.wake(o1); + TimeUnit.SECONDS.sleep(1); + Assert.assertEquals(1, a.get()); + } } \ No newline at end of file diff --git a/hippo4j-server/hippo4j-auth/src/main/java/cn/hippo4j/auth/config/FilterConfig.java b/hippo4j-server/hippo4j-auth/src/main/java/cn/hippo4j/auth/config/FilterConfig.java index 76aa3602..ae53a759 100644 --- a/hippo4j-server/hippo4j-auth/src/main/java/cn/hippo4j/auth/config/FilterConfig.java +++ b/hippo4j-server/hippo4j-auth/src/main/java/cn/hippo4j/auth/config/FilterConfig.java @@ -23,7 +23,7 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; /** - * + * Filter config. */ @Configuration public class FilterConfig { diff --git a/hippo4j-server/hippo4j-auth/src/main/java/cn/hippo4j/auth/filter/JWTAuthorizationFilter.java b/hippo4j-server/hippo4j-auth/src/main/java/cn/hippo4j/auth/filter/JWTAuthorizationFilter.java index 3b6cf69e..78f3bee5 100644 --- a/hippo4j-server/hippo4j-auth/src/main/java/cn/hippo4j/auth/filter/JWTAuthorizationFilter.java +++ b/hippo4j-server/hippo4j-auth/src/main/java/cn/hippo4j/auth/filter/JWTAuthorizationFilter.java @@ -68,14 +68,12 @@ public class JWTAuthorizationFilter extends BasicAuthenticationFilter { chain.doFilter(request, response); return; } - // If there is no Authorization information in the request header, it will be released directly. String tokenHeader = request.getHeader(JwtTokenUtil.TOKEN_HEADER); if (tokenHeader == null || !tokenHeader.startsWith(JwtTokenUtil.TOKEN_PREFIX)) { chain.doFilter(request, response); return; } - // If there is a Token in the request header, it is parsed and the authentication information is set. try { SecurityContextHolder.getContext().setAuthentication(getAuthentication(tokenHeader)); diff --git a/hippo4j-server/hippo4j-auth/src/main/java/cn/hippo4j/auth/security/JwtTokenManager.java b/hippo4j-server/hippo4j-auth/src/main/java/cn/hippo4j/auth/security/JwtTokenManager.java index 17f52aaa..2abd58d6 100644 --- a/hippo4j-server/hippo4j-auth/src/main/java/cn/hippo4j/auth/security/JwtTokenManager.java +++ b/hippo4j-server/hippo4j-auth/src/main/java/cn/hippo4j/auth/security/JwtTokenManager.java @@ -41,15 +41,30 @@ import static cn.hippo4j.common.constant.Constants.AUTHORITIES_KEY; @Component public class JwtTokenManager { + /** + * Create token. + * + * @param userName user-name + * @return new token + */ public String createToken(String userName) { long now = System.currentTimeMillis(); Date validity; validity = new Date(now + TOKEN_VALIDITY_IN_SECONDS * 1000L); Claims claims = Jwts.claims().setSubject(userName); - return Jwts.builder().setClaims(claims).setExpiration(validity) - .signWith(SignatureAlgorithm.HS512, SECRET).compact(); + String token = Jwts.builder() + .setClaims(claims) + .setExpiration(validity) + .signWith(SignatureAlgorithm.HS512, SECRET) + .compact(); + return token; } + /** + * Validate token. + * + * @param token token + */ public void validateToken(String token) { Jwts.parser().setSigningKey(SECRET).parseClaimsJws(token); } diff --git a/hippo4j-server/hippo4j-auth/src/main/java/cn/hippo4j/auth/service/impl/UserServiceImpl.java b/hippo4j-server/hippo4j-auth/src/main/java/cn/hippo4j/auth/service/impl/UserServiceImpl.java index b500fa06..c2cf1988 100644 --- a/hippo4j-server/hippo4j-auth/src/main/java/cn/hippo4j/auth/service/impl/UserServiceImpl.java +++ b/hippo4j-server/hippo4j-auth/src/main/java/cn/hippo4j/auth/service/impl/UserServiceImpl.java @@ -22,7 +22,6 @@ import cn.hippo4j.auth.model.UserInfo; import cn.hippo4j.auth.model.biz.user.UserQueryPageReqDTO; import cn.hippo4j.auth.model.biz.user.UserReqDTO; import cn.hippo4j.auth.model.biz.user.UserRespDTO; -import cn.hippo4j.auth.service.RoleService; import cn.hippo4j.auth.service.UserService; import cn.hippo4j.common.toolkit.BeanUtil; import cn.hippo4j.common.toolkit.StringUtil; @@ -49,8 +48,6 @@ public class UserServiceImpl implements UserService { private final UserMapper userMapper; - private final RoleService roleService; - private final BCryptPasswordEncoder bCryptPasswordEncoder; @Override diff --git a/hippo4j-server/hippo4j-auth/src/main/java/cn/hippo4j/auth/toolkit/JwtTokenUtil.java b/hippo4j-server/hippo4j-auth/src/main/java/cn/hippo4j/auth/toolkit/JwtTokenUtil.java index c78af646..40a831c0 100644 --- a/hippo4j-server/hippo4j-auth/src/main/java/cn/hippo4j/auth/toolkit/JwtTokenUtil.java +++ b/hippo4j-server/hippo4j-auth/src/main/java/cn/hippo4j/auth/toolkit/JwtTokenUtil.java @@ -36,9 +36,11 @@ import static cn.hippo4j.common.constant.Constants.MAP_INITIAL_CAPACITY; public class JwtTokenUtil { public static final String TOKEN_HEADER = "Authorization"; + public static final String TOKEN_PREFIX = "Bearer "; public static final String SECRET = "SecretKey039245678901232039487623456783092349288901402967890140939827"; + public static final String ISS = "admin"; /** diff --git a/hippo4j-server/hippo4j-auth/src/main/java/cn/hippo4j/auth/toolkit/ReturnT.java b/hippo4j-server/hippo4j-auth/src/main/java/cn/hippo4j/auth/toolkit/ReturnT.java index ccc1ab1c..47743239 100644 --- a/hippo4j-server/hippo4j-auth/src/main/java/cn/hippo4j/auth/toolkit/ReturnT.java +++ b/hippo4j-server/hippo4j-auth/src/main/java/cn/hippo4j/auth/toolkit/ReturnT.java @@ -32,13 +32,17 @@ public class ReturnT implements Serializable { public static final long serialVersionUID = 42L; public static final int SUCCESS_CODE = 200; + public static final int FAIL_CODE = 500; public static final ReturnT SUCCESS = new ReturnT<>(null); + public static final ReturnT FAIL = new ReturnT<>(FAIL_CODE, null); private int code; + private String msg; + private T content; public ReturnT(int code, String msg) { diff --git a/hippo4j-server/hippo4j-bootstrap/src/main/java/cn/hippo4j/server/ServerApplication.java b/hippo4j-server/hippo4j-bootstrap/src/main/java/cn/hippo4j/server/ServerApplication.java index 239a632f..e235e69a 100644 --- a/hippo4j-server/hippo4j-bootstrap/src/main/java/cn/hippo4j/server/ServerApplication.java +++ b/hippo4j-server/hippo4j-bootstrap/src/main/java/cn/hippo4j/server/ServerApplication.java @@ -22,6 +22,9 @@ import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.transaction.annotation.EnableTransactionManagement; +/** + * ServerApplication + */ @EnableTransactionManagement @SpringBootApplication(scanBasePackages = "cn.hippo4j") @MapperScan(basePackages = {"cn.hippo4j.config.mapper", "cn.hippo4j.auth.mapper"}) diff --git a/hippo4j-server/hippo4j-bootstrap/src/main/java/cn/hippo4j/server/init/LocalDataSourceLoader.java b/hippo4j-server/hippo4j-bootstrap/src/main/java/cn/hippo4j/server/init/LocalDataSourceLoader.java index ae59559b..6cba358f 100644 --- a/hippo4j-server/hippo4j-bootstrap/src/main/java/cn/hippo4j/server/init/LocalDataSourceLoader.java +++ b/hippo4j-server/hippo4j-bootstrap/src/main/java/cn/hippo4j/server/init/LocalDataSourceLoader.java @@ -35,7 +35,8 @@ import java.io.IOException; import java.io.InputStreamReader; import java.io.Reader; import java.nio.charset.StandardCharsets; -import java.sql.*; +import java.sql.Connection; +import java.sql.DriverManager; import java.util.Objects; /** diff --git a/hippo4j-server/hippo4j-config/pom.xml b/hippo4j-server/hippo4j-config/pom.xml index b4ec93d8..f548e2cc 100644 --- a/hippo4j-server/hippo4j-config/pom.xml +++ b/hippo4j-server/hippo4j-config/pom.xml @@ -11,7 +11,6 @@ true - 2.1.214 @@ -50,6 +49,7 @@ cn.hippo4j hippo4j-adapter-base + ${revision} cn.hippo4j @@ -63,6 +63,7 @@ org.hibernate.validator hibernate-validator + ${hibernate-validator.version} org.springframework.boot diff --git a/hippo4j-server/hippo4j-config/src/main/java/cn/hippo4j/config/monitor/AbstractMonitorDataExecuteStrategy.java b/hippo4j-server/hippo4j-config/src/main/java/cn/hippo4j/config/monitor/AbstractMonitorDataExecuteStrategy.java index ae0dc032..78d89bcf 100644 --- a/hippo4j-server/hippo4j-config/src/main/java/cn/hippo4j/config/monitor/AbstractMonitorDataExecuteStrategy.java +++ b/hippo4j-server/hippo4j-config/src/main/java/cn/hippo4j/config/monitor/AbstractMonitorDataExecuteStrategy.java @@ -27,14 +27,14 @@ public abstract class AbstractMonitorDataExecuteStrategy { /** * Mark. * - * @return + * @return mark */ public abstract String mark(); /** * Execute. * - * @param message + * @param message message */ public abstract void execute(T message); } diff --git a/hippo4j-server/hippo4j-config/src/main/java/cn/hippo4j/config/monitor/QueryMonitorExecuteChoose.java b/hippo4j-server/hippo4j-config/src/main/java/cn/hippo4j/config/monitor/QueryMonitorExecuteChoose.java index 2dfd9a6b..525ee8ee 100644 --- a/hippo4j-server/hippo4j-config/src/main/java/cn/hippo4j/config/monitor/QueryMonitorExecuteChoose.java +++ b/hippo4j-server/hippo4j-config/src/main/java/cn/hippo4j/config/monitor/QueryMonitorExecuteChoose.java @@ -33,7 +33,7 @@ import java.util.Map; public class QueryMonitorExecuteChoose implements CommandLineRunner { /** - * Storage monitoring data execution container. + * Storage monitoring data execution container */ private Map monitorDataExecuteStrategyChooseMap = new HashMap<>(); diff --git a/hippo4j-server/hippo4j-config/src/main/java/cn/hippo4j/config/notify/DefaultPublisher.java b/hippo4j-server/hippo4j-config/src/main/java/cn/hippo4j/config/notify/DefaultPublisher.java index 7b8f67e6..39612b11 100644 --- a/hippo4j-server/hippo4j-config/src/main/java/cn/hippo4j/config/notify/DefaultPublisher.java +++ b/hippo4j-server/hippo4j-config/src/main/java/cn/hippo4j/config/notify/DefaultPublisher.java @@ -63,7 +63,6 @@ public class DefaultPublisher extends Thread implements EventPublisher { @Override public synchronized void start() { if (!initialized) { - // start just called once super.start(); if (queueMaxSize == -1) { queueMaxSize = NotifyCenter.ringBufferSize; @@ -100,7 +99,7 @@ public class DefaultPublisher extends Thread implements EventPublisher { UPDATER.compareAndSet(this, lastEventSequence, Math.max(lastEventSequence, event.sequence())); } } catch (Throwable ex) { - log.error("Event listener exception: {}", ex); + log.error("Event listener exception.", ex); } } @@ -123,9 +122,7 @@ public class DefaultPublisher extends Thread implements EventPublisher { @Override public void notifySubscriber(AbstractSubscriber subscriber, AbstractEvent event) { final Runnable job = () -> subscriber.onEvent(event); - final Executor executor = subscriber.executor(); - if (executor != null) { executor.execute(job); } else { diff --git a/hippo4j-server/hippo4j-config/src/main/java/cn/hippo4j/config/notify/EventPublisher.java b/hippo4j-server/hippo4j-config/src/main/java/cn/hippo4j/config/notify/EventPublisher.java index 858b30f2..1a726308 100644 --- a/hippo4j-server/hippo4j-config/src/main/java/cn/hippo4j/config/notify/EventPublisher.java +++ b/hippo4j-server/hippo4j-config/src/main/java/cn/hippo4j/config/notify/EventPublisher.java @@ -28,31 +28,31 @@ public interface EventPublisher { /** * Init. * - * @param type - * @param bufferSize + * @param type type + * @param bufferSize buffer size */ void init(Class type, int bufferSize); /** * Add subscriber. * - * @param subscriber + * @param subscriber subscriber */ void addSubscriber(AbstractSubscriber subscriber); /** * Publish. * - * @param event - * @return + * @param event event + * @return publish result */ boolean publish(AbstractEvent event); /** * Notify subscriber. * - * @param subscriber - * @param event + * @param subscriber subscriber + * @param event event */ void notifySubscriber(AbstractSubscriber subscriber, AbstractEvent event); } diff --git a/hippo4j-server/hippo4j-config/src/main/java/cn/hippo4j/config/notify/NotifyCenter.java b/hippo4j-server/hippo4j-config/src/main/java/cn/hippo4j/config/notify/NotifyCenter.java index 0fce3453..78101e86 100644 --- a/hippo4j-server/hippo4j-config/src/main/java/cn/hippo4j/config/notify/NotifyCenter.java +++ b/hippo4j-server/hippo4j-config/src/main/java/cn/hippo4j/config/notify/NotifyCenter.java @@ -43,11 +43,9 @@ public class NotifyCenter { private DefaultSharePublisher sharePublisher; - private static Class clazz = null; - private static EventPublisher eventPublisher = new DefaultPublisher(); - private static BiFunction, Integer, EventPublisher> publisherFactory = null; + private static BiFunction, Integer, EventPublisher> publisherFactory; private final Map publisherMap = new ConcurrentHashMap(16); diff --git a/hippo4j-server/hippo4j-config/src/main/java/cn/hippo4j/config/notify/listener/AbstractSubscriber.java b/hippo4j-server/hippo4j-config/src/main/java/cn/hippo4j/config/notify/listener/AbstractSubscriber.java index 16357b47..50705b97 100644 --- a/hippo4j-server/hippo4j-config/src/main/java/cn/hippo4j/config/notify/listener/AbstractSubscriber.java +++ b/hippo4j-server/hippo4j-config/src/main/java/cn/hippo4j/config/notify/listener/AbstractSubscriber.java @@ -40,6 +40,11 @@ public abstract class AbstractSubscriber { */ public abstract Class subscribeType(); + /** + * Executor. + * + * @return executor + */ public Executor executor() { return null; } diff --git a/hippo4j-server/hippo4j-config/src/main/java/cn/hippo4j/config/service/ConfigChangePublisher.java b/hippo4j-server/hippo4j-config/src/main/java/cn/hippo4j/config/service/ConfigChangePublisher.java index 084c8925..7ae44a12 100644 --- a/hippo4j-server/hippo4j-config/src/main/java/cn/hippo4j/config/service/ConfigChangePublisher.java +++ b/hippo4j-server/hippo4j-config/src/main/java/cn/hippo4j/config/service/ConfigChangePublisher.java @@ -28,7 +28,7 @@ public class ConfigChangePublisher { /** * Notify configChange. * - * @param event + * @param event event */ public static void notifyConfigChange(LocalDataChangeEvent event) { NotifyCenter.publishEvent(event); diff --git a/hippo4j-server/hippo4j-config/src/main/java/cn/hippo4j/config/service/LongPollingService.java b/hippo4j-server/hippo4j-config/src/main/java/cn/hippo4j/config/service/LongPollingService.java index b5d667a0..a485048c 100644 --- a/hippo4j-server/hippo4j-config/src/main/java/cn/hippo4j/config/service/LongPollingService.java +++ b/hippo4j-server/hippo4j-config/src/main/java/cn/hippo4j/config/service/LongPollingService.java @@ -68,13 +68,9 @@ public class LongPollingService { @Override public void onEvent(AbstractEvent event) { - if (isFixedPolling()) { - // Ignore. - } else { - if (event instanceof LocalDataChangeEvent) { - LocalDataChangeEvent evt = (LocalDataChangeEvent) event; - ConfigExecutor.executeLongPolling(new DataChangeTask(evt.identify, evt.groupKey)); - } + if (!isFixedPolling() && event instanceof LocalDataChangeEvent) { + LocalDataChangeEvent evt = (LocalDataChangeEvent) event; + ConfigExecutor.executeLongPolling(new DataChangeTask(evt.identify, evt.groupKey)); } } @@ -300,11 +296,11 @@ public class LongPollingService { /** * Is support long polling. * - * @param req + * @param request * @return */ - public static boolean isSupportLongPolling(HttpServletRequest req) { - return null != req.getHeader(LONG_POLLING_HEADER); + public static boolean isSupportLongPolling(HttpServletRequest request) { + return request.getHeader(LONG_POLLING_HEADER) != null; } /** diff --git a/hippo4j-server/hippo4j-config/src/main/java/cn/hippo4j/config/service/biz/impl/ConfigServiceImpl.java b/hippo4j-server/hippo4j-config/src/main/java/cn/hippo4j/config/service/biz/impl/ConfigServiceImpl.java index bf70a5b9..ab5c43a2 100644 --- a/hippo4j-server/hippo4j-config/src/main/java/cn/hippo4j/config/service/biz/impl/ConfigServiceImpl.java +++ b/hippo4j-server/hippo4j-config/src/main/java/cn/hippo4j/config/service/biz/impl/ConfigServiceImpl.java @@ -151,7 +151,7 @@ public class ConfigServiceImpl implements ConfigService { ConfigServiceImpl configService = ApplicationContextHolder.getBean(this.getClass()); configService.updateConfigInfo(null, false, configAllInfo); } - DynamicThreadPoolRegisterServerNotifyParameter serverNotifyParameter = registerWrapper.getDynamicThreadPoolRegisterServerNotifyParameter(); + DynamicThreadPoolRegisterServerNotifyParameter serverNotifyParameter = registerWrapper.getServerNotify(); if (serverNotifyParameter != null) { ArrayList notifyTypes = new ArrayList<>(); Collections.addAll(notifyTypes, "CONFIG", "ALARM"); @@ -177,7 +177,7 @@ public class ConfigServiceImpl implements ConfigService { } private ConfigAllInfo parseConfigAllInfo(DynamicThreadPoolRegisterWrapper registerWrapper) { - DynamicThreadPoolRegisterParameter registerParameter = registerWrapper.getDynamicThreadPoolRegisterParameter(); + DynamicThreadPoolRegisterParameter registerParameter = registerWrapper.getParameter(); ConfigAllInfo configAllInfo = JSONUtil.parseObject(JSONUtil.toJSONString(registerParameter), ConfigAllInfo.class); configAllInfo.setTenantId(registerWrapper.getTenantId()); configAllInfo.setItemId(registerWrapper.getItemId()); diff --git a/hippo4j-server/hippo4j-config/src/main/java/cn/hippo4j/config/verify/ConfigModificationVerifyServiceChoose.java b/hippo4j-server/hippo4j-config/src/main/java/cn/hippo4j/config/verify/ConfigModificationVerifyServiceChoose.java index 98769559..2eb72589 100644 --- a/hippo4j-server/hippo4j-config/src/main/java/cn/hippo4j/config/verify/ConfigModificationVerifyServiceChoose.java +++ b/hippo4j-server/hippo4j-config/src/main/java/cn/hippo4j/config/verify/ConfigModificationVerifyServiceChoose.java @@ -33,7 +33,7 @@ import java.util.Map; public class ConfigModificationVerifyServiceChoose implements CommandLineRunner { /** - * Storage config change verify service container. + * Storage config change verify service container */ private Map configChangeVerifyServiceChooseMap = new HashMap<>(); @@ -44,8 +44,7 @@ public class ConfigModificationVerifyServiceChoose implements CommandLineRunner * @return */ public ConfigModificationVerifyService choose(Integer type) { - ConfigModificationVerifyService verifyService = configChangeVerifyServiceChooseMap.get(type); - return verifyService; + return configChangeVerifyServiceChooseMap.get(type); } @Override diff --git a/hippo4j-server/hippo4j-config/src/test/java/cn/hippo4j/config/rpc/client/RPCClientTest.java b/hippo4j-server/hippo4j-config/src/test/java/cn/hippo4j/config/rpc/client/RPCClientTest.java deleted file mode 100644 index 54c2633e..00000000 --- a/hippo4j-server/hippo4j-config/src/test/java/cn/hippo4j/config/rpc/client/RPCClientTest.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package cn.hippo4j.config.rpc.client; - -import cn.hippo4j.config.rpc.request.DefaultRequest; -import cn.hippo4j.config.rpc.request.Request; -import cn.hippo4j.config.rpc.response.Response; -import cn.hippo4j.config.rpc.server.NettyServerConnection; -import cn.hippo4j.config.rpc.server.RPCServer; -import cn.hippo4j.config.rpc.server.ServerConnection; -import cn.hippo4j.config.rpc.support.DefaultInstance; -import cn.hippo4j.config.rpc.support.Instance; -import cn.hippo4j.config.rpc.support.ClassRegistry; -import org.junit.Assert; -import org.junit.Test; - -import java.io.IOException; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.TimeUnit; - -public class RPCClientTest { - - String host = "localhost"; - int port = 8888; - - @Test - public void connection() throws IOException { - - Class cls = CallManager.class; - String className = cls.getName(); - ClassRegistry.put(className, cls); - // The mode connection was denied when the server was started on the specified port - Instance instance = new DefaultInstance(); - ServerConnection connection = new NettyServerConnection(instance); - RPCServer rpcServer = new RPCServer(port, connection); - CompletableFuture.runAsync(rpcServer::bind); - try { - TimeUnit.SECONDS.sleep(3); - } catch (InterruptedException e) { - throw new RuntimeException(e); - } - NettyClientConnection clientConnection = new NettyClientConnection(host, port); - RPCClient rpcClient = new RPCClient(clientConnection); - Request request = new DefaultRequest("127.0.0.18888", className, "call", null, null); - for (int i = 0; i < 100; i++) { - Response response = rpcClient.connection(request); - Assert.assertEquals(response.getObj(), 1); - } - rpcClient.close(); - rpcServer.close(); - } - -} \ No newline at end of file diff --git a/hippo4j-server/hippo4j-console/pom.xml b/hippo4j-server/hippo4j-console/pom.xml index 5f89640a..193658a6 100644 --- a/hippo4j-server/hippo4j-console/pom.xml +++ b/hippo4j-server/hippo4j-console/pom.xml @@ -29,9 +29,5 @@ hippo4j-auth ${revision} - - org.hibernate.validator - hibernate-validator - diff --git a/hippo4j-server/hippo4j-console/src/main/resources/static/index.html b/hippo4j-server/hippo4j-console/src/main/resources/static/index.html index 16ce63d4..6fb8e8db 100644 --- a/hippo4j-server/hippo4j-console/src/main/resources/static/index.html +++ b/hippo4j-server/hippo4j-console/src/main/resources/static/index.html @@ -1 +1 @@ -Hippo4J Web

\ No newline at end of file +Hippo4J Web
\ No newline at end of file diff --git a/hippo4j-server/hippo4j-console/src/main/resources/static/static/css/chunk-70528506.0840a153.css b/hippo4j-server/hippo4j-console/src/main/resources/static/static/css/chunk-65cbbb82.fcbf3365.css similarity index 85% rename from hippo4j-server/hippo4j-console/src/main/resources/static/static/css/chunk-70528506.0840a153.css rename to hippo4j-server/hippo4j-console/src/main/resources/static/static/css/chunk-65cbbb82.fcbf3365.css index 560ca5db..3195dc02 100644 --- a/hippo4j-server/hippo4j-console/src/main/resources/static/static/css/chunk-70528506.0840a153.css +++ b/hippo4j-server/hippo4j-console/src/main/resources/static/static/css/chunk-65cbbb82.fcbf3365.css @@ -1 +1 @@ -.waves-ripple{position:absolute;border-radius:100%;background-color:rgba(0,0,0,.15);background-clip:padding-box;pointer-events:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-transform:scale(0);transform:scale(0);opacity:1}.waves-ripple.z-active{opacity:0;-webkit-transform:scale(2);transform:scale(2);-webkit-transition:opacity 1.2s ease-out,-webkit-transform .6s ease-out;transition:opacity 1.2s ease-out,-webkit-transform .6s ease-out;transition:opacity 1.2s ease-out,transform .6s ease-out;transition:opacity 1.2s ease-out,transform .6s ease-out,-webkit-transform .6s ease-out}.dashboard-editor-container[data-v-a25e0782]{padding:32px;background-color:#f0f2f5;position:relative;min-height:100vh} \ No newline at end of file +.waves-ripple{position:absolute;border-radius:100%;background-color:rgba(0,0,0,.15);background-clip:padding-box;pointer-events:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-transform:scale(0);transform:scale(0);opacity:1}.waves-ripple.z-active{opacity:0;-webkit-transform:scale(2);transform:scale(2);-webkit-transition:opacity 1.2s ease-out,-webkit-transform .6s ease-out;transition:opacity 1.2s ease-out,-webkit-transform .6s ease-out;transition:opacity 1.2s ease-out,transform .6s ease-out;transition:opacity 1.2s ease-out,transform .6s ease-out,-webkit-transform .6s ease-out}.dashboard-editor-container[data-v-6226f7fa]{padding:32px;background-color:#f0f2f5;position:relative;min-height:100vh} \ No newline at end of file diff --git a/hippo4j-server/hippo4j-console/src/main/resources/static/static/js/app.a27d19f1.js b/hippo4j-server/hippo4j-console/src/main/resources/static/static/js/app.d0f020af.js similarity index 99% rename from hippo4j-server/hippo4j-console/src/main/resources/static/static/js/app.a27d19f1.js rename to hippo4j-server/hippo4j-console/src/main/resources/static/static/js/app.d0f020af.js index 20ce4db4..6a1c388c 100644 --- a/hippo4j-server/hippo4j-console/src/main/resources/static/static/js/app.a27d19f1.js +++ b/hippo4j-server/hippo4j-console/src/main/resources/static/static/js/app.d0f020af.js @@ -1 +1 @@ -(window["webpackJsonp"]=window["webpackJsonp"]||[]).push([["app"],{0:function(t,e,n){t.exports=n("56d7")},"0781":function(t,e,n){"use strict";n.r(e);var a=n("24ab"),i=n.n(a),o=n("83d6"),c=n.n(o),r=c.a.showSettings,s=c.a.tagsView,l=c.a.fixedHeader,u=c.a.sidebarLogo,d={theme:i.a.theme,showSettings:r,tagsView:s,fixedHeader:l,sidebarLogo:u},f={CHANGE_SETTING:function(t,e){var n=e.key,a=e.value;t.hasOwnProperty(n)&&(t[n]=a)}},h={changeSetting:function(t,e){var n=t.commit;n("CHANGE_SETTING",e)}};e["default"]={namespaced:!0,state:d,mutations:f,actions:h}},"07c6":function(t,e,n){"use strict";n("48c1")},"0d3d":function(t,e,n){"use strict";n("a4f4")},"0f9a":function(t,e,n){"use strict";n.r(e);var a=n("c80c"),i=(n("96cf"),n("3b8d")),o=n("b775");function c(t){return Object(o["a"])({url:"/hippo4j/v1/cs/auth/login",method:"post",data:t})}var r=n("5f87"),s=n("a18c"),l={token:Object(r["a"])(),name:"",avatar:"",introduction:"",roles:[]},u={SET_TOKEN:function(t,e){t.token=e},SET_INTRODUCTION:function(t,e){t.introduction=e},SET_NAME:function(t,e){t.name=e},SET_AVATAR:function(t,e){t.avatar=e},SET_ROLES:function(t,e){t.roles=e}},d={login:function(t,e){var n=t.commit,a=e.username,i=e.password;return new Promise((function(t,e){c({username:a.trim(),password:i,rememberMe:1}).then((function(e){var a=e.data,i=e.roles;n("SET_TOKEN",a),localStorage.setItem("roles",JSON.stringify(i)),localStorage.setItem("USER_ROLE",i[0]),Object(r["c"])(a),t()})).catch((function(t){alert("登录失败"),e(t)}))}))},getInfo:function(t){var e=t.commit;t.state;return new Promise((function(t,n){var a={};a.roles=JSON.parse(localStorage.getItem("roles")),e("SET_ROLES",a.roles),t(a)}))},logout:function(t){var e=t.commit;t.state;return new Promise((function(t){e("SET_TOKEN",""),e("SET_ROLES",[]),Object(r["b"])(),Object(s["d"])(),t()}))},resetToken:function(t){var e=t.commit;return new Promise((function(t){e("SET_TOKEN",""),e("SET_ROLES",[]),Object(r["b"])(),t()}))},changeRoles:function(t,e){var n=t.commit,o=t.dispatch;return new Promise(function(){var t=Object(i["a"])(Object(a["a"])().mark((function t(i){var c,l,u,d;return Object(a["a"])().wrap((function(t){while(1)switch(t.prev=t.next){case 0:return c=e+"-token",n("SET_TOKEN",c),Object(r["c"])(c),t.next=5,o("getInfo");case 5:return l=t.sent,u=l.roles,Object(s["d"])(),t.next=10,o("permission/generateRoutes",u,{root:!0});case 10:d=t.sent,s["c"].addRoutes(d),o("tagsView/delAllViews",null,{root:!0}),i();case 14:case"end":return t.stop()}}),t)})));return function(e){return t.apply(this,arguments)}}())}};e["default"]={namespaced:!0,state:l,mutations:u,actions:d}},"119b":function(t,e,n){"use strict";n.r(e);var a=n("e017"),i=n.n(a),o=n("21a1"),c=n.n(o),r=new i.a({id:"icon-other4",use:"icon-other4-usage",viewBox:"0 0 1024 1024",content:''});c.a.add(r);e["default"]=r},1424:function(t,e,n){"use strict";n.r(e);var a=n("e017"),i=n.n(a),o=n("21a1"),c=n.n(o),r=new i.a({id:"icon-tenant_logo2",use:"icon-tenant_logo2-usage",viewBox:"0 0 1331 1024",content:''});c.a.add(r);e["default"]=r},"187a":function(t,e,n){},"24ab":function(t,e,n){t.exports={theme:"#1890ff"}},2538:function(t,e,n){"use strict";n.r(e);var a=n("e017"),i=n.n(a),o=n("21a1"),c=n.n(o),r=new i.a({id:"icon-json",use:"icon-json-usage",viewBox:"0 0 1024 1024",content:''});c.a.add(r);e["default"]=r},2580:function(t,e,n){"use strict";n.r(e);var a=n("e017"),i=n.n(a),o=n("21a1"),c=n.n(o),r=new i.a({id:"icon-language",use:"icon-language-usage",viewBox:"0 0 128 128",content:''});c.a.add(r);e["default"]=r},"273d":function(t,e,n){"use strict";n.r(e);var a=n("e017"),i=n.n(a),o=n("21a1"),c=n.n(o),r=new i.a({id:"icon-user6",use:"icon-user6-usage",viewBox:"0 0 1024 1024",content:''});c.a.add(r);e["default"]=r},"29aa":function(t,e,n){},3150:function(t,e,n){},"31c2":function(t,e,n){"use strict";n.r(e),n.d(e,"filterAsyncRoutes",(function(){return c}));var a=n("db72"),i=(n("ac6a"),n("6762"),n("2fdb"),n("a18c"));function o(t,e){return!e.meta||!e.meta.roles||t.some((function(t){return e.meta.roles.includes(t)}))}function c(t,e){var n=[];return t.forEach((function(t){var i=Object(a["a"])({},t);o(e,i)&&(i.children&&(i.children=c(i.children,e)),n.push(i))})),n}var r={routes:[],addRoutes:[]},s={SET_ROUTES:function(t,e){t.addRoutes=e,t.routes=i["b"].concat(e)}},l={generateRoutes:function(t,e){var n=t.commit;return new Promise((function(t){var a;a=e.includes("ROLE_ADMIN")?i["a"]||[]:c(i["a"],e),n("SET_ROUTES",a),t(a)}))}};e["default"]={namespaced:!0,state:r,mutations:s,actions:l}},4093:function(t,e,n){},4213:function(t,e,n){"use strict";n.r(e);var a=n("e017"),i=n.n(a),o=n("21a1"),c=n.n(o),r=new i.a({id:"icon-link3",use:"icon-link3-usage",viewBox:"0 0 1024 1024",content:''});c.a.add(r);e["default"]=r},4360:function(t,e,n){"use strict";n("a481"),n("ac6a");var a=n("2b0e"),i=n("2f62"),o=(n("7f7f"),{sidebar:function(t){return t.app.sidebar},size:function(t){return t.app.size},device:function(t){return t.app.device},visitedViews:function(t){return t.tagsView.visitedViews},cachedViews:function(t){return t.tagsView.cachedViews},token:function(t){return t.user.token},avatar:function(t){return t.user.avatar},name:function(t){return t.user.name},introduction:function(t){return t.user.introduction},roles:function(t){return t.user.roles},permission_routes:function(t){return t.permission.routes},errorLogs:function(t){return t.errorLog.logs}}),c=o;a["default"].use(i["a"]);var r=n("c653"),s=r.keys().reduce((function(t,e){var n=e.replace(/^\.\/(.*)\.\w+$/,"$1"),a=r(e);return t[n]=a.default,t}),{}),l=new i["a"].Store({modules:s,getters:c});e["a"]=l},"48c1":function(t,e,n){},"4d49":function(t,e,n){"use strict";n.r(e);var a={logs:[]},i={ADD_ERROR_LOG:function(t,e){t.logs.push(e)},CLEAR_ERROR_LOG:function(t){t.logs.splice(0)}},o={addErrorLog:function(t,e){var n=t.commit;n("ADD_ERROR_LOG",e)},clearErrorLog:function(t){var e=t.commit;e("CLEAR_ERROR_LOG")}};e["default"]={namespaced:!0,state:a,mutations:i,actions:o}},"51ff":function(t,e,n){var a={"./404.svg":"a14a","./audit.svg":"d393","./dashboard2.svg":"ea93","./item4.svg":"f385","./item_logo4.svg":"8811","./json.svg":"2538","./language.svg":"2580","./lessee.svg":"dbd7","./link3.svg":"4213","./log3.svg":"6ba9","./notify.svg":"5448","./other4.svg":"119b","./pool3.svg":"a551","./tenant_logo2.svg":"1424","./threadPool_logo1.svg":"b6d1","./threadPool_logo2.svg":"9bc4","./user6.svg":"273d","./vessel3.svg":"6e71"};function i(t){var e=o(t);return n(e)}function o(t){var e=a[t];if(!(e+1)){var n=new Error("Cannot find module '"+t+"'");throw n.code="MODULE_NOT_FOUND",n}return e}i.keys=function(){return Object.keys(a)},i.resolve=o,t.exports=i,i.id="51ff"},5448:function(t,e,n){"use strict";n.r(e);var a=n("e017"),i=n.n(a),o=n("21a1"),c=n.n(o),r=new i.a({id:"icon-notify",use:"icon-notify-usage",viewBox:"0 0 1024 1024",content:''});c.a.add(r);e["default"]=r},"56d7":function(t,e,n){"use strict";n.r(e);var a={};n.r(a),n.d(a,"parseTime",(function(){return $["c"]})),n.d(a,"formatTime",(function(){return $["b"]})),n.d(a,"timeAgo",(function(){return R})),n.d(a,"numberFormatter",(function(){return P})),n.d(a,"toThousandFilter",(function(){return I})),n.d(a,"uppercaseFirst",(function(){return N}));n("456d"),n("ac6a"),n("cadf"),n("551c"),n("f751"),n("097d");var i=n("2b0e"),o=n("a78e"),c=n.n(o),r=(n("f5df"),n("5c96")),s=n.n(r),l=(n("24ab"),n("b20f"),function(){var t=this,e=t.$createElement,n=t._self._c||e;return n("div",{attrs:{id:"app"}},[n("router-view")],1)}),u=[],d={name:"App"},f=d,h=n("2877"),p=Object(h["a"])(f,l,u,!1,null,null,null),m=p.exports,v=n("4360"),b=n("a18c"),g=function(){var t=this,e=t.$createElement,n=t._self._c||e;return t.isExternal?n("div",t._g({staticClass:"svg-external-icon svg-icon",style:t.styleExternalIcon},t.$listeners)):n("svg",t._g({class:t.svgClass,attrs:{"aria-hidden":"true"}},t.$listeners),[n("use",{attrs:{"xlink:href":t.iconName}})])},w=[],x=n("61f7"),y={name:"SvgIcon",props:{iconClass:{type:String,required:!0},className:{type:String,default:""}},computed:{isExternal:function(){return Object(x["a"])(this.iconClass)},iconName:function(){return"#icon-".concat(this.iconClass)},svgClass:function(){return this.className?"svg-icon "+this.className:"svg-icon"},styleExternalIcon:function(){return{mask:"url(".concat(this.iconClass,") no-repeat 50% 50%"),"-webkit-mask":"url(".concat(this.iconClass,") no-repeat 50% 50%")}}}},_=y,k=(n("64df"),Object(h["a"])(_,g,w,!1,null,"f9f7fefc",null)),M=k.exports;i["default"].component("svg-icon",M);var E=n("51ff"),z=function(t){return t.keys().map(t)};z(E);var C=n("c80c"),O=n("db72"),L=(n("96cf"),n("3b8d")),S=n("323e"),j=n.n(S),A=(n("a5d8"),n("5f87")),B=n("83d6"),H=n.n(B),T=H.a.title||"Vue Element Admin";function F(t){return t?"".concat(t," - ").concat(T):"".concat(T)}j.a.configure({showSpinner:!1});var V=["/login","/auth-redirect"];b["c"].beforeEach(function(){var t=Object(L["a"])(Object(C["a"])().mark((function t(e,n,a){var i,o,c,s,l;return Object(C["a"])().wrap((function(t){while(1)switch(t.prev=t.next){case 0:if(j.a.start(),document.title=F(e.meta.title),i=Object(A["a"])(),!i){t.next=35;break}if("/login"!==e.path){t.next=9;break}a({path:"/"}),j.a.done(),t.next=33;break;case 9:if(o=v["a"].getters.roles&&v["a"].getters.roles.length>0,!o){t.next=14;break}a(),t.next=33;break;case 14:return t.prev=14,t.next=17,v["a"].dispatch("user/getInfo");case 17:return c=t.sent,s=c.roles,t.next=21,v["a"].dispatch("permission/generateRoutes",s);case 21:l=t.sent,b["c"].addRoutes(l),a(Object(O["a"])(Object(O["a"])({},e),{},{replace:!0})),t.next=33;break;case 26:return t.prev=26,t.t0=t["catch"](14),t.next=30,v["a"].dispatch("user/resetToken");case 30:r["Message"].error(t.t0||"Has Error"),a("/login?redirect=".concat(e.path)),j.a.done();case 33:t.next=36;break;case 35:-1!==V.indexOf(e.path)?a():(a("/login?redirect=".concat(e.path)),j.a.done());case 36:case"end":return t.stop()}}),t,null,[[14,26]])})));return function(e,n,a){return t.apply(this,arguments)}}()),b["c"].afterEach((function(){j.a.done()}));n("6b54"),n("a481"),n("c5f6");var $=n("ed08");function D(t,e){return 1===t?t+e:t+e+"s"}function R(t){var e=Date.now()/1e3-Number(t);return e<3600?D(~~(e/60)," minute"):e<86400?D(~~(e/3600)," hour"):D(~~(e/86400)," day")}function P(t,e){for(var n=[{value:1e18,symbol:"E"},{value:1e15,symbol:"P"},{value:1e12,symbol:"T"},{value:1e9,symbol:"G"},{value:1e6,symbol:"M"},{value:1e3,symbol:"k"}],a=0;a=n[a].value)return(t/n[a].value+.1).toFixed(e).replace(/\.0+$|(\.[0-9]*[1-9])0+$/,"$1")+n[a].symbol;return t.toString()}function I(t){return(+t||0).toString().replace(/^-?\d+/g,(function(t){return t.replace(/(?=(?!\b)(\d{3})+$)/g,",")}))}function N(t){return t.charAt(0).toUpperCase()+t.slice(1)}var G=n("313e"),q=n("00e7"),U=n.n(q);i["default"].prototype.$echarts=G["default"],i["default"].prototype.$cookie=U.a,i["default"].use(s.a,{size:c.a.get("size")||"medium"}),Object.keys(a).forEach((function(t){i["default"].filter(t,a[t])})),i["default"].config.productionTip=!1,new i["default"]({el:"#app",router:b["c"],store:v["a"],render:function(t){return t(m)}})},"5e10":function(t,e,n){"use strict";n("3150")},"5f87":function(t,e,n){"use strict";n.d(e,"a",(function(){return c})),n.d(e,"c",(function(){return r})),n.d(e,"b",(function(){return s}));var a=n("a78e"),i=n.n(a),o="Admin-Token";function c(){return i.a.get(o)}function r(t){return i.a.set(o,t)}function s(){return i.a.remove(o)}},"61f7":function(t,e,n){"use strict";n.d(e,"a",(function(){return a}));n("6b54");function a(t){return/^(https?:|mailto:|tel:)/.test(t)}},"64df":function(t,e,n){"use strict";n("78bf")},6820:function(t,e,n){"use strict";n("4093")},"6ba9":function(t,e,n){"use strict";n.r(e);var a=n("e017"),i=n.n(a),o=n("21a1"),c=n.n(o),r=new i.a({id:"icon-log3",use:"icon-log3-usage",viewBox:"0 0 1024 1024",content:''});c.a.add(r);e["default"]=r},"6e71":function(t,e,n){"use strict";n.r(e);var a=n("e017"),i=n.n(a),o=n("21a1"),c=n.n(o),r=new i.a({id:"icon-vessel3",use:"icon-vessel3-usage",viewBox:"0 0 1024 1024",content:''});c.a.add(r);e["default"]=r},"78bf":function(t,e,n){},8326:function(t,e,n){},"83d6":function(t,e){t.exports={title:"Hippo4J Web",showSettings:!0,tagsView:!0,fixedHeader:!1,sidebarLogo:!0,errorLog:"production"}},8811:function(t,e,n){"use strict";n.r(e);var a=n("e017"),i=n.n(a),o=n("21a1"),c=n.n(o),r=new i.a({id:"icon-item_logo4",use:"icon-item_logo4-usage",viewBox:"0 0 1024 1024",content:''});c.a.add(r);e["default"]=r},"89f5":function(t,e,n){"use strict";n("29aa")},"8af8":function(t,e,n){"use strict";n("9c98")},"9bc4":function(t,e,n){"use strict";n.r(e);var a=n("e017"),i=n.n(a),o=n("21a1"),c=n.n(o),r=new i.a({id:"icon-threadPool_logo2",use:"icon-threadPool_logo2-usage",viewBox:"0 0 1044 1024",content:''});c.a.add(r);e["default"]=r},"9c98":function(t,e,n){},a14a:function(t,e,n){"use strict";n.r(e);var a=n("e017"),i=n.n(a),o=n("21a1"),c=n.n(o),r=new i.a({id:"icon-404",use:"icon-404-usage",viewBox:"0 0 128 128",content:''});c.a.add(r);e["default"]=r},a18c:function(t,e,n){"use strict";var a,i,o=n("2b0e"),c=n("8c4f"),r=function(){var t=this,e=t.$createElement,n=t._self._c||e;return n("div",{staticClass:"app-wrapper",class:t.classObj},["mobile"===t.device&&t.sidebar.opened?n("div",{staticClass:"drawer-bg",on:{click:t.handleClickOutside}}):t._e(),t._v(" "),n("sidebar",{staticClass:"sidebar-container"}),t._v(" "),n("div",{staticClass:"main-container"},[n("div",{class:{"fixed-header":t.fixedHeader}},[n("navbar")],1),t._v(" "),n("app-main")],1)],1)},s=[],l=n("db72"),u=function(){var t=this,e=t.$createElement,n=t._self._c||e;return n("section",{staticClass:"app-main"},[n("transition",{attrs:{name:"fade-transform",mode:"out-in"}},[n("router-view",{key:t.key})],1)],1)},d=[],f={name:"AppMain",computed:{cachedViews:function(){return this.$store.state.tagsView.cachedViews},key:function(){return this.$route.path}}},h=f,p=(n("5e10"),n("0d3d"),n("2877")),m=Object(p["a"])(h,u,d,!1,null,"5ad61798",null),v=m.exports,b=function(){var t=this,e=t.$createElement,a=t._self._c||e;return a("div",{staticClass:"navbar"},[a("hamburger",{staticClass:"hamburger-container",attrs:{id:"hamburger-container","is-active":t.sidebar.opened},on:{toggleClick:t.toggleSideBar}}),t._v(" "),a("breadcrumb",{staticClass:"breadcrumb-container",attrs:{id:"breadcrumb-container"}}),t._v(" "),a("div",{staticClass:"right-menu"},["mobile"!==t.device?void 0:t._e(),t._v(" "),a("el-dropdown",{staticClass:"avatar-container right-menu-item hover-effect",attrs:{trigger:"click"}},[a("div",{staticClass:"avatar-wrapper"},[a("img",{staticClass:"user-avatar",attrs:{src:n("f561")}}),t._v(" "),a("i",{staticClass:"el-icon-caret-bottom"})]),t._v(" "),a("el-dropdown-menu",{attrs:{slot:"dropdown"},slot:"dropdown"},[a("router-link",{attrs:{to:"/"}},[a("el-dropdown-item",[t._v("Dashboard")])],1),t._v(" "),a("el-dropdown-item",{attrs:{divided:""}},[a("span",{staticStyle:{display:"block"},on:{click:t.logout}},[t._v("Log Out")])])],1)],1)],2)],1)},g=[],w=n("c80c"),x=(n("96cf"),n("3b8d")),y=n("2f62"),_=function(){var t=this,e=t.$createElement,n=t._self._c||e;return n("el-breadcrumb",{staticClass:"app-breadcrumb",attrs:{separator:"/"}},[n("transition-group",{attrs:{name:"breadcrumb"}},t._l(t.levelList,(function(e,a){return n("el-breadcrumb-item",{key:e.path},["noRedirect"===e.redirect||a==t.levelList.length-1?n("span",{staticClass:"no-redirect"},[t._v(t._s(e.meta.title))]):n("a",{on:{click:function(n){return n.preventDefault(),t.handleLink(e)}}},[t._v(t._s(e.meta.title))])])})),1)],1)},k=[],M=(n("7f7f"),n("f559"),n("bd11")),E=n.n(M),z={data:function(){return{levelList:null}},watch:{$route:function(t){t.path.startsWith("/redirect/")||this.getBreadcrumb()}},created:function(){this.getBreadcrumb()},methods:{getBreadcrumb:function(){var t=this.$route.matched.filter((function(t){return t.meta&&t.meta.title})),e=t[0];this.isDashboard(e)||(t=[{path:"/dashboard",meta:{title:"Dashboard"}}].concat(t)),this.levelList=t.filter((function(t){return t.meta&&t.meta.title&&!1!==t.meta.breadcrumb}))},isDashboard:function(t){var e=t&&t.name;return!!e&&e.trim().toLocaleLowerCase()==="Dashboard".toLocaleLowerCase()},pathCompile:function(t){var e=this.$route.params,n=E.a.compile(t);return n(e)},handleLink:function(t){var e=t.redirect,n=t.path;e?this.$router.push(e):this.$router.push(this.pathCompile(n))}}},C=z,O=(n("89f5"),Object(p["a"])(C,_,k,!1,null,"1919fc1a",null)),L=O.exports,S=function(){var t=this,e=t.$createElement,n=t._self._c||e;return n("div",{staticStyle:{padding:"0 15px"},on:{click:t.toggleClick}},[n("svg",{staticClass:"hamburger",class:{"is-active":t.isActive},attrs:{viewBox:"0 0 1024 1024",xmlns:"http://www.w3.org/2000/svg",width:"64",height:"64"}},[n("path",{attrs:{d:"M408 442h480c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8H408c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8zm-8 204c0 4.4 3.6 8 8 8h480c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8H408c-4.4 0-8 3.6-8 8v56zm504-486H120c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zm0 632H120c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zM142.4 642.1L298.7 519a8.84 8.84 0 0 0 0-13.9L142.4 381.9c-5.8-4.6-14.4-.5-14.4 6.9v246.3a8.9 8.9 0 0 0 14.4 7z"}})])])},j=[],A={name:"Hamburger",props:{isActive:{type:Boolean,default:!1}},methods:{toggleClick:function(){this.$emit("toggleClick")}}},B=A,H=(n("d49d"),Object(p["a"])(B,S,j,!1,null,"49e15297",null)),T=H.exports,F=function(){var t=this,e=t.$createElement,n=t._self._c||e;return t.errorLogs.length>0?n("div",[n("el-badge",{staticStyle:{"line-height":"25px","margin-top":"-5px"},attrs:{"is-dot":!0},nativeOn:{click:function(e){t.dialogTableVisible=!0}}},[n("el-button",{staticStyle:{padding:"8px 10px"},attrs:{size:"small",type:"danger"}},[n("svg-icon",{attrs:{"icon-class":"bug"}})],1)],1),t._v(" "),n("el-dialog",{attrs:{visible:t.dialogTableVisible,width:"80%","append-to-body":""},on:{"update:visible":function(e){t.dialogTableVisible=e}}},[n("div",{attrs:{slot:"title"},slot:"title"},[n("span",{staticStyle:{"padding-right":"10px"}},[t._v("Error Log")]),t._v(" "),n("el-button",{attrs:{size:"mini",type:"primary",icon:"el-icon-delete"},on:{click:t.clearAll}},[t._v("Clear All")])],1),t._v(" "),n("el-table",{attrs:{data:t.errorLogs,border:""}},[n("el-table-column",{attrs:{label:"Message"},scopedSlots:t._u([{key:"default",fn:function(e){var a=e.row;return[n("div",[n("span",{staticClass:"message-title"},[t._v("Msg:")]),t._v(" "),n("el-tag",{attrs:{type:"danger"}},[t._v("\n "+t._s(a.err.message)+"\n ")])],1),t._v(" "),n("br"),t._v(" "),n("div",[n("span",{staticClass:"message-title",staticStyle:{"padding-right":"10px"}},[t._v("Info: ")]),t._v(" "),n("el-tag",{attrs:{type:"warning"}},[t._v("\n "+t._s(a.vm.$vnode.tag)+" error in "+t._s(a.info)+"\n ")])],1),t._v(" "),n("br"),t._v(" "),n("div",[n("span",{staticClass:"message-title",staticStyle:{"padding-right":"16px"}},[t._v("Url: ")]),t._v(" "),n("el-tag",{attrs:{type:"success"}},[t._v("\n "+t._s(a.url)+"\n ")])],1)]}}],null,!1,3621415002)}),t._v(" "),n("el-table-column",{attrs:{label:"Stack"},scopedSlots:t._u([{key:"default",fn:function(e){return[t._v("\n "+t._s(e.row.err.stack)+"\n ")]}}],null,!1,1726869048)})],1)],1)],1):t._e()},V=[],$={name:"ErrorLog",data:function(){return{dialogTableVisible:!1}},computed:{errorLogs:function(){return this.$store.getters.errorLogs}},methods:{clearAll:function(){this.dialogTableVisible=!1,this.$store.dispatch("errorLog/clearErrorLog")}}},D=$,R=(n("b36c"),Object(p["a"])(D,F,V,!1,null,"be34583a",null)),P=R.exports,I={components:{Breadcrumb:L,Hamburger:T,ErrorLog:P},computed:Object(l["a"])({},Object(y["b"])(["sidebar","avatar","device"])),methods:{toggleSideBar:function(){this.$store.dispatch("app/toggleSideBar")},logout:function(){var t=Object(x["a"])(Object(w["a"])().mark((function t(){return Object(w["a"])().wrap((function(t){while(1)switch(t.prev=t.next){case 0:return this.$cookie.delete("userName"),t.next=3,this.$store.dispatch("user/logout");case 3:this.$router.push("/login?redirect=".concat(this.$route.fullPath));case 4:case"end":return t.stop()}}),t,this)})));function e(){return t.apply(this,arguments)}return e}()}},N=I,G=(n("07c6"),Object(p["a"])(N,b,g,!1,null,"6ab05616",null)),q=G.exports,U=function(){var t=this,e=t.$createElement,n=t._self._c||e;return n("div",{class:{"has-logo":t.showLogo}},[t.showLogo?n("logo",{attrs:{collapse:t.isCollapse}}):t._e(),t._v(" "),n("el-scrollbar",{attrs:{"wrap-class":"scrollbar-wrapper"}},[n("el-menu",{attrs:{"default-active":t.activeMenu,collapse:t.isCollapse,"background-color":t.variables.menuBg,"text-color":t.variables.menuText,"unique-opened":!1,"active-text-color":t.variables.menuActiveText,"collapse-transition":!1,mode:"vertical"}},t._l(t.permission_routes,(function(t){return n("sidebar-item",{key:t.path,attrs:{item:t,"base-path":t.path}})})),1)],1)],1)},J=[],K=function(){var t=this,e=t.$createElement,n=t._self._c||e;return n("div",{staticClass:"sidebar-logo-container",class:{collapse:t.collapse}},[n("transition",{attrs:{name:"sidebarLogoFade"}},[t.collapse?n("router-link",{key:"collapse",staticClass:"sidebar-logo-link",attrs:{to:"/"}},[t.logo?n("img",{staticClass:"sidebar-logo",attrs:{src:t.logo}}):n("h1",{staticClass:"sidebar-title"},[t._v(t._s(t.title))])]):n("router-link",{key:"expand",staticClass:"sidebar-logo-link",attrs:{to:"/"}},[t.logo?n("img",{staticClass:"sidebar-logo",attrs:{src:t.logo}}):t._e(),t._v(" "),n("h1",{staticClass:"sidebar-title"},[t._v(t._s(t.title))])])],1)],1)},Q=[],W={name:"SidebarLogo",props:{collapse:{type:Boolean,required:!0}},data:function(){return{title:"hippo4j 1.4.3"}}},Z=W,Y=(n("8af8"),Object(p["a"])(Z,K,Q,!1,null,"741ab93c",null)),X=Y.exports,tt=function(){var t=this,e=t.$createElement,n=t._self._c||e;return t.item.hidden?t._e():n("div",{staticClass:"menu-wrapper"},[!t.hasOneShowingChild(t.item.children,t.item)||t.onlyOneChild.children&&!t.onlyOneChild.noShowingChildren||t.item.alwaysShow?n("el-submenu",{ref:"subMenu",attrs:{index:t.resolvePath(t.item.path),"popper-append-to-body":""}},[n("template",{slot:"title"},[t.item.meta?n("item",{attrs:{icon:t.item.meta&&t.item.meta.icon,title:t.item.meta.title}}):t._e()],1),t._v(" "),t._l(t.item.children,(function(e){return n("sidebar-item",{key:e.path,staticClass:"nest-menu",attrs:{"is-nest":!0,item:e,"base-path":t.resolvePath(e.path)}})}))],2):[t.onlyOneChild.meta?n("app-link",{attrs:{to:t.resolvePath(t.onlyOneChild.path)}},[n("el-menu-item",{class:{"submenu-title-noDropdown":!t.isNest},attrs:{index:t.resolvePath(t.onlyOneChild.path)}},[n("item",{attrs:{icon:t.onlyOneChild.meta.icon||t.item.meta&&t.item.meta.icon,title:t.onlyOneChild.meta.title}})],1)],1):t._e()]],2)},et=[],nt=n("df7c"),at=n.n(nt),it=n("61f7"),ot={name:"MenuItem",functional:!0,props:{icon:{type:String,default:""},title:{type:String,default:""}},render:function(t,e){var n=e.props,a=n.icon,i=n.title,o=[];return a&&o.push(t("svg-icon",{attrs:{"icon-class":a}})),i&&o.push(t("span",{slot:"title"},[i])),o}},ct=ot,rt=Object(p["a"])(ct,a,i,!1,null,null,null),st=rt.exports,lt=function(){var t=this,e=t.$createElement,n=t._self._c||e;return n("component",t._b({},"component",t.linkProps(t.to),!1),[t._t("default")],2)},ut=[],dt={props:{to:{type:String,required:!0}},methods:{linkProps:function(t){return Object(it["a"])(t)?{is:"a",href:t,target:"_blank",rel:"noopener"}:{is:"router-link",to:t}}}},ft=dt,ht=Object(p["a"])(ft,lt,ut,!1,null,null,null),pt=ht.exports,mt={computed:{device:function(){return this.$store.state.app.device}},mounted:function(){this.fixBugIniOS()},methods:{fixBugIniOS:function(){var t=this,e=this.$refs.subMenu;if(e){var n=e.handleMouseleave;e.handleMouseleave=function(e){"mobile"!==t.device&&n(e)}}}}},vt={name:"SidebarItem",components:{Item:st,AppLink:pt},mixins:[mt],props:{item:{type:Object,required:!0},isNest:{type:Boolean,default:!1},basePath:{type:String,default:""}},data:function(){return this.onlyOneChild=null,{}},methods:{hasOneShowingChild:function(){var t=this,e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[],n=arguments.length>1?arguments[1]:void 0,a=e.filter((function(e){return!e.hidden&&(t.onlyOneChild=e,!0)}));return 1===a.length||0===a.length&&(this.onlyOneChild=Object(l["a"])(Object(l["a"])({},n),{},{path:"",noShowingChildren:!0}),!0)},resolvePath:function(t){return Object(it["a"])(t)?t:Object(it["a"])(this.basePath)?this.basePath:at.a.resolve(this.basePath,t)}}},bt=vt,gt=Object(p["a"])(bt,tt,et,!1,null,null,null),wt=gt.exports,xt=n("cf1e"),yt=n.n(xt),_t={components:{SidebarItem:wt,Logo:X},computed:Object(l["a"])(Object(l["a"])({},Object(y["b"])(["permission_routes","sidebar"])),{},{activeMenu:function(){var t=this.$route,e=t.meta,n=t.path;return e.activeMenu?e.activeMenu:n},showLogo:function(){return this.$store.state.settings.sidebarLogo},variables:function(){return yt.a},isCollapse:function(){return!this.sidebar.opened}})},kt=_t,Mt=Object(p["a"])(kt,U,J,!1,null,null,null),Et=Mt.exports,zt=n("4360"),Ct=document,Ot=Ct.body,Lt=992,St={watch:{$route:function(t){"mobile"===this.device&&this.sidebar.opened&&zt["a"].dispatch("app/closeSideBar",{withoutAnimation:!1})}},beforeMount:function(){window.addEventListener("resize",this.$_resizeHandler)},beforeDestroy:function(){window.removeEventListener("resize",this.$_resizeHandler)},mounted:function(){var t=this.$_isMobile();t&&(zt["a"].dispatch("app/toggleDevice","mobile"),zt["a"].dispatch("app/closeSideBar",{withoutAnimation:!0}))},methods:{$_isMobile:function(){var t=Ot.getBoundingClientRect();return t.width-1'});c.a.add(r);e["default"]=r},b20f:function(t,e,n){t.exports={menuText:"#bfcbd9",menuActiveText:"#409eff",subMenuActiveText:"#f4f4f5",menuBg:"#304156",menuHover:"#263445",subMenuBg:"#1f2d3d",subMenuHover:"#001528",sideBarWidth:"210px"}},b36c:function(t,e,n){"use strict";n("187a")},b6d1:function(t,e,n){"use strict";n.r(e);var a=n("e017"),i=n.n(a),o=n("21a1"),c=n.n(o),r=new i.a({id:"icon-threadPool_logo1",use:"icon-threadPool_logo1-usage",viewBox:"0 0 1024 1024",content:''});c.a.add(r);e["default"]=r},b775:function(t,e,n){"use strict";var a=n("bc3a"),i=n.n(a),o=n("5c96"),c=n("4360"),r=n("5f87"),s=n("a18c"),l=i.a.create({baseURL:"",timeout:2e4});l.interceptors.request.use((function(t){return c["a"].getters.token&&(t.headers["Authorization"]=Object(r["a"])()),t}),(function(t){return console.log(t),Promise.reject(t)})),l.interceptors.response.use((function(t){var e=t.data;if("A000004"!==e.code){if("20000"!==e.code&&"0"!==e.code&&"200"!==e.code)return Object(o["Message"])({message:e.message||"Error",type:"error",duration:5e3}),"50008"!==e.code&&"50012"!==e.code&&"50014"!==e.code||o["MessageBox"].confirm("You have been logged out, you can cancel to stay on this page, or log in again","Confirm logout",{confirmButtonText:"Re-Login",cancelButtonText:"Cancel",type:"warning"}).then((function(){c["a"].dispatch("user/resetToken").then((function(){location.reload()}))})),Promise.reject(new Error(e.message||"Error"));var n=t.data,a=n.code;if("0"===a){var i=n.data;return i}return"200"===a?n:e}Object(r["b"])(),Object(s["d"])(),alert(e.message),document.location.href="index.html"}),(function(t){return console.log("err"+t),Object(o["Message"])({message:t.message,type:"error",duration:5e3}),Promise.reject(t)})),e["a"]=l},c653:function(t,e,n){var a={"./app.js":"d9cd","./errorLog.js":"4d49","./permission.js":"31c2","./settings.js":"0781","./user.js":"0f9a"};function i(t){var e=o(t);return n(e)}function o(t){var e=a[t];if(!(e+1)){var n=new Error("Cannot find module '"+t+"'");throw n.code="MODULE_NOT_FOUND",n}return e}i.keys=function(){return Object.keys(a)},i.resolve=o,t.exports=i,i.id="c653"},cf1e:function(t,e,n){t.exports={menuText:"#bfcbd9",menuActiveText:"#409eff",subMenuActiveText:"#f4f4f5",menuBg:"#304156",menuHover:"#263445",subMenuBg:"#1f2d3d",subMenuHover:"#001528",sideBarWidth:"210px"}},d393:function(t,e,n){"use strict";n.r(e);var a=n("e017"),i=n.n(a),o=n("21a1"),c=n.n(o),r=new i.a({id:"icon-audit",use:"icon-audit-usage",viewBox:"0 0 1024 1024",content:''});c.a.add(r);e["default"]=r},d49d:function(t,e,n){"use strict";n("8326")},d9cd:function(t,e,n){"use strict";n.r(e);var a=n("a78e"),i=n.n(a),o={sidebar:{opened:!i.a.get("sidebarStatus")||!!+i.a.get("sidebarStatus"),withoutAnimation:!1},device:"desktop",size:i.a.get("size")||"medium"},c={TOGGLE_SIDEBAR:function(t){t.sidebar.opened=!t.sidebar.opened,t.sidebar.withoutAnimation=!1,t.sidebar.opened?i.a.set("sidebarStatus",1):i.a.set("sidebarStatus",0)},CLOSE_SIDEBAR:function(t,e){i.a.set("sidebarStatus",0),t.sidebar.opened=!1,t.sidebar.withoutAnimation=e},TOGGLE_DEVICE:function(t,e){t.device=e},SET_SIZE:function(t,e){t.size=e,i.a.set("size",e)}},r={toggleSideBar:function(t){var e=t.commit;e("TOGGLE_SIDEBAR")},closeSideBar:function(t,e){var n=t.commit,a=e.withoutAnimation;n("CLOSE_SIDEBAR",a)},toggleDevice:function(t,e){var n=t.commit;n("TOGGLE_DEVICE",e)},setSize:function(t,e){var n=t.commit;n("SET_SIZE",e)}};e["default"]={namespaced:!0,state:o,mutations:c,actions:r}},dbd7:function(t,e,n){"use strict";n.r(e);var a=n("e017"),i=n.n(a),o=n("21a1"),c=n.n(o),r=new i.a({id:"icon-lessee",use:"icon-lessee-usage",viewBox:"0 0 1024 1024",content:''});c.a.add(r);e["default"]=r},ea93:function(t,e,n){"use strict";n.r(e);var a=n("e017"),i=n.n(a),o=n("21a1"),c=n.n(o),r=new i.a({id:"icon-dashboard2",use:"icon-dashboard2-usage",viewBox:"0 0 1024 1024",content:''});c.a.add(r);e["default"]=r},ed08:function(t,e,n){"use strict";n.d(e,"c",(function(){return i})),n.d(e,"b",(function(){return o})),n.d(e,"a",(function(){return c}));n("3b2b"),n("4917"),n("4f7f"),n("5df3"),n("1c4c"),n("28a5"),n("ac6a"),n("456d"),n("a481"),n("6b54");var a=n("7618");function i(t,e){if(0===arguments.length)return null;var n,i=e||"{y}-{m}-{d} {h}:{i}:{s}";"object"===Object(a["a"])(t)?n=t:("string"===typeof t&&/^[0-9]+$/.test(t)&&(t=parseInt(t)),"number"===typeof t&&10===t.toString().length&&(t*=1e3),n=new Date(t));var o={y:n.getFullYear(),m:n.getMonth()+1,d:n.getDate(),h:n.getHours(),i:n.getMinutes(),s:n.getSeconds(),a:n.getDay()},c=i.replace(/{(y|m|d|h|i|s|a)+}/g,(function(t,e){var n=o[e];return"a"===e?["日","一","二","三","四","五","六"][n]:(t.length>0&&n<10&&(n="0"+n),n||0)}));return c}function o(t,e){t=10===(""+t).length?1e3*parseInt(t):+t;var n=new Date(t),a=Date.now(),o=(a-n)/1e3;return o<30?"刚刚":o<3600?Math.ceil(o/60)+"分钟前":o<86400?Math.ceil(o/3600)+"小时前":o<172800?"1天前":e?i(t,e):n.getMonth()+1+"月"+n.getDate()+"日"+n.getHours()+"时"+n.getMinutes()+"分"}function c(t,e,n){var a,i,o,c,r,s=function s(){var l=+new Date-c;l0?a=setTimeout(s,e-l):(a=null,n||(r=t.apply(o,i),a||(o=i=null)))};return function(){for(var i=arguments.length,l=new Array(i),u=0;u'});c.a.add(r);e["default"]=r},f561:function(t,e,n){t.exports=n.p+"static/img/hippo4j.ecba1844.gif"}},[[0,"runtime","chunk-elementUI","chunk-libs"]]]); \ No newline at end of file +(window["webpackJsonp"]=window["webpackJsonp"]||[]).push([["app"],{0:function(t,e,n){t.exports=n("56d7")},"0781":function(t,e,n){"use strict";n.r(e);var a=n("24ab"),i=n.n(a),o=n("83d6"),c=n.n(o),r=c.a.showSettings,s=c.a.tagsView,l=c.a.fixedHeader,u=c.a.sidebarLogo,d={theme:i.a.theme,showSettings:r,tagsView:s,fixedHeader:l,sidebarLogo:u},f={CHANGE_SETTING:function(t,e){var n=e.key,a=e.value;t.hasOwnProperty(n)&&(t[n]=a)}},h={changeSetting:function(t,e){var n=t.commit;n("CHANGE_SETTING",e)}};e["default"]={namespaced:!0,state:d,mutations:f,actions:h}},"07c6":function(t,e,n){"use strict";n("48c1")},"0d3d":function(t,e,n){"use strict";n("a4f4")},"0f9a":function(t,e,n){"use strict";n.r(e);var a=n("c80c"),i=(n("96cf"),n("3b8d")),o=n("b775");function c(t){return Object(o["a"])({url:"/hippo4j/v1/cs/auth/login",method:"post",data:t})}var r=n("5f87"),s=n("a18c"),l={token:Object(r["a"])(),name:"",avatar:"",introduction:"",roles:[]},u={SET_TOKEN:function(t,e){t.token=e},SET_INTRODUCTION:function(t,e){t.introduction=e},SET_NAME:function(t,e){t.name=e},SET_AVATAR:function(t,e){t.avatar=e},SET_ROLES:function(t,e){t.roles=e}},d={login:function(t,e){var n=t.commit,a=e.username,i=e.password;return new Promise((function(t,e){c({username:a.trim(),password:i,rememberMe:1}).then((function(e){var a=e.data,i=e.roles;n("SET_TOKEN",a),localStorage.setItem("roles",JSON.stringify(i)),localStorage.setItem("USER_ROLE",i[0]),Object(r["c"])(a),t()})).catch((function(t){alert("登录失败"),e(t)}))}))},getInfo:function(t){var e=t.commit;t.state;return new Promise((function(t,n){var a={};a.roles=JSON.parse(localStorage.getItem("roles")),e("SET_ROLES",a.roles),t(a)}))},logout:function(t){var e=t.commit;t.state;return new Promise((function(t){e("SET_TOKEN",""),e("SET_ROLES",[]),Object(r["b"])(),Object(s["d"])(),t()}))},resetToken:function(t){var e=t.commit;return new Promise((function(t){e("SET_TOKEN",""),e("SET_ROLES",[]),Object(r["b"])(),t()}))},changeRoles:function(t,e){var n=t.commit,o=t.dispatch;return new Promise(function(){var t=Object(i["a"])(Object(a["a"])().mark((function t(i){var c,l,u,d;return Object(a["a"])().wrap((function(t){while(1)switch(t.prev=t.next){case 0:return c=e+"-token",n("SET_TOKEN",c),Object(r["c"])(c),t.next=5,o("getInfo");case 5:return l=t.sent,u=l.roles,Object(s["d"])(),t.next=10,o("permission/generateRoutes",u,{root:!0});case 10:d=t.sent,s["c"].addRoutes(d),o("tagsView/delAllViews",null,{root:!0}),i();case 14:case"end":return t.stop()}}),t)})));return function(e){return t.apply(this,arguments)}}())}};e["default"]={namespaced:!0,state:l,mutations:u,actions:d}},"119b":function(t,e,n){"use strict";n.r(e);var a=n("e017"),i=n.n(a),o=n("21a1"),c=n.n(o),r=new i.a({id:"icon-other4",use:"icon-other4-usage",viewBox:"0 0 1024 1024",content:''});c.a.add(r);e["default"]=r},1424:function(t,e,n){"use strict";n.r(e);var a=n("e017"),i=n.n(a),o=n("21a1"),c=n.n(o),r=new i.a({id:"icon-tenant_logo2",use:"icon-tenant_logo2-usage",viewBox:"0 0 1331 1024",content:''});c.a.add(r);e["default"]=r},"187a":function(t,e,n){},"24ab":function(t,e,n){t.exports={theme:"#1890ff"}},2538:function(t,e,n){"use strict";n.r(e);var a=n("e017"),i=n.n(a),o=n("21a1"),c=n.n(o),r=new i.a({id:"icon-json",use:"icon-json-usage",viewBox:"0 0 1024 1024",content:''});c.a.add(r);e["default"]=r},2580:function(t,e,n){"use strict";n.r(e);var a=n("e017"),i=n.n(a),o=n("21a1"),c=n.n(o),r=new i.a({id:"icon-language",use:"icon-language-usage",viewBox:"0 0 128 128",content:''});c.a.add(r);e["default"]=r},"273d":function(t,e,n){"use strict";n.r(e);var a=n("e017"),i=n.n(a),o=n("21a1"),c=n.n(o),r=new i.a({id:"icon-user6",use:"icon-user6-usage",viewBox:"0 0 1024 1024",content:''});c.a.add(r);e["default"]=r},"29aa":function(t,e,n){},3150:function(t,e,n){},"31c2":function(t,e,n){"use strict";n.r(e),n.d(e,"filterAsyncRoutes",(function(){return c}));var a=n("db72"),i=(n("ac6a"),n("6762"),n("2fdb"),n("a18c"));function o(t,e){return!e.meta||!e.meta.roles||t.some((function(t){return e.meta.roles.includes(t)}))}function c(t,e){var n=[];return t.forEach((function(t){var i=Object(a["a"])({},t);o(e,i)&&(i.children&&(i.children=c(i.children,e)),n.push(i))})),n}var r={routes:[],addRoutes:[]},s={SET_ROUTES:function(t,e){t.addRoutes=e,t.routes=i["b"].concat(e)}},l={generateRoutes:function(t,e){var n=t.commit;return new Promise((function(t){var a;a=e.includes("ROLE_ADMIN")?i["a"]||[]:c(i["a"],e),n("SET_ROUTES",a),t(a)}))}};e["default"]={namespaced:!0,state:r,mutations:s,actions:l}},4093:function(t,e,n){},4213:function(t,e,n){"use strict";n.r(e);var a=n("e017"),i=n.n(a),o=n("21a1"),c=n.n(o),r=new i.a({id:"icon-link3",use:"icon-link3-usage",viewBox:"0 0 1024 1024",content:''});c.a.add(r);e["default"]=r},4360:function(t,e,n){"use strict";n("a481"),n("ac6a");var a=n("2b0e"),i=n("2f62"),o=(n("7f7f"),{sidebar:function(t){return t.app.sidebar},size:function(t){return t.app.size},device:function(t){return t.app.device},visitedViews:function(t){return t.tagsView.visitedViews},cachedViews:function(t){return t.tagsView.cachedViews},token:function(t){return t.user.token},avatar:function(t){return t.user.avatar},name:function(t){return t.user.name},introduction:function(t){return t.user.introduction},roles:function(t){return t.user.roles},permission_routes:function(t){return t.permission.routes},errorLogs:function(t){return t.errorLog.logs}}),c=o;a["default"].use(i["a"]);var r=n("c653"),s=r.keys().reduce((function(t,e){var n=e.replace(/^\.\/(.*)\.\w+$/,"$1"),a=r(e);return t[n]=a.default,t}),{}),l=new i["a"].Store({modules:s,getters:c});e["a"]=l},"48c1":function(t,e,n){},"4d49":function(t,e,n){"use strict";n.r(e);var a={logs:[]},i={ADD_ERROR_LOG:function(t,e){t.logs.push(e)},CLEAR_ERROR_LOG:function(t){t.logs.splice(0)}},o={addErrorLog:function(t,e){var n=t.commit;n("ADD_ERROR_LOG",e)},clearErrorLog:function(t){var e=t.commit;e("CLEAR_ERROR_LOG")}};e["default"]={namespaced:!0,state:a,mutations:i,actions:o}},"51ff":function(t,e,n){var a={"./404.svg":"a14a","./audit.svg":"d393","./dashboard2.svg":"ea93","./item4.svg":"f385","./item_logo4.svg":"8811","./json.svg":"2538","./language.svg":"2580","./lessee.svg":"dbd7","./link3.svg":"4213","./log3.svg":"6ba9","./notify.svg":"5448","./other4.svg":"119b","./pool3.svg":"a551","./tenant_logo2.svg":"1424","./threadPool_logo1.svg":"b6d1","./threadPool_logo2.svg":"9bc4","./user6.svg":"273d","./vessel3.svg":"6e71"};function i(t){var e=o(t);return n(e)}function o(t){var e=a[t];if(!(e+1)){var n=new Error("Cannot find module '"+t+"'");throw n.code="MODULE_NOT_FOUND",n}return e}i.keys=function(){return Object.keys(a)},i.resolve=o,t.exports=i,i.id="51ff"},5448:function(t,e,n){"use strict";n.r(e);var a=n("e017"),i=n.n(a),o=n("21a1"),c=n.n(o),r=new i.a({id:"icon-notify",use:"icon-notify-usage",viewBox:"0 0 1024 1024",content:''});c.a.add(r);e["default"]=r},"56d7":function(t,e,n){"use strict";n.r(e);var a={};n.r(a),n.d(a,"parseTime",(function(){return $["c"]})),n.d(a,"formatTime",(function(){return $["b"]})),n.d(a,"timeAgo",(function(){return R})),n.d(a,"numberFormatter",(function(){return P})),n.d(a,"toThousandFilter",(function(){return I})),n.d(a,"uppercaseFirst",(function(){return N}));n("456d"),n("ac6a"),n("cadf"),n("551c"),n("f751"),n("097d");var i=n("2b0e"),o=n("a78e"),c=n.n(o),r=(n("f5df"),n("5c96")),s=n.n(r),l=(n("24ab"),n("b20f"),function(){var t=this,e=t.$createElement,n=t._self._c||e;return n("div",{attrs:{id:"app"}},[n("router-view")],1)}),u=[],d={name:"App"},f=d,h=n("2877"),p=Object(h["a"])(f,l,u,!1,null,null,null),m=p.exports,v=n("4360"),b=n("a18c"),g=function(){var t=this,e=t.$createElement,n=t._self._c||e;return t.isExternal?n("div",t._g({staticClass:"svg-external-icon svg-icon",style:t.styleExternalIcon},t.$listeners)):n("svg",t._g({class:t.svgClass,attrs:{"aria-hidden":"true"}},t.$listeners),[n("use",{attrs:{"xlink:href":t.iconName}})])},w=[],x=n("61f7"),y={name:"SvgIcon",props:{iconClass:{type:String,required:!0},className:{type:String,default:""}},computed:{isExternal:function(){return Object(x["a"])(this.iconClass)},iconName:function(){return"#icon-".concat(this.iconClass)},svgClass:function(){return this.className?"svg-icon "+this.className:"svg-icon"},styleExternalIcon:function(){return{mask:"url(".concat(this.iconClass,") no-repeat 50% 50%"),"-webkit-mask":"url(".concat(this.iconClass,") no-repeat 50% 50%")}}}},_=y,k=(n("64df"),Object(h["a"])(_,g,w,!1,null,"f9f7fefc",null)),M=k.exports;i["default"].component("svg-icon",M);var E=n("51ff"),z=function(t){return t.keys().map(t)};z(E);var C=n("c80c"),O=n("db72"),L=(n("96cf"),n("3b8d")),S=n("323e"),j=n.n(S),A=(n("a5d8"),n("5f87")),B=n("83d6"),H=n.n(B),T=H.a.title||"Vue Element Admin";function F(t){return t?"".concat(t," - ").concat(T):"".concat(T)}j.a.configure({showSpinner:!1});var V=["/login","/auth-redirect"];b["c"].beforeEach(function(){var t=Object(L["a"])(Object(C["a"])().mark((function t(e,n,a){var i,o,c,s,l;return Object(C["a"])().wrap((function(t){while(1)switch(t.prev=t.next){case 0:if(j.a.start(),document.title=F(e.meta.title),i=Object(A["a"])(),!i){t.next=35;break}if("/login"!==e.path){t.next=9;break}a({path:"/"}),j.a.done(),t.next=33;break;case 9:if(o=v["a"].getters.roles&&v["a"].getters.roles.length>0,!o){t.next=14;break}a(),t.next=33;break;case 14:return t.prev=14,t.next=17,v["a"].dispatch("user/getInfo");case 17:return c=t.sent,s=c.roles,t.next=21,v["a"].dispatch("permission/generateRoutes",s);case 21:l=t.sent,b["c"].addRoutes(l),a(Object(O["a"])(Object(O["a"])({},e),{},{replace:!0})),t.next=33;break;case 26:return t.prev=26,t.t0=t["catch"](14),t.next=30,v["a"].dispatch("user/resetToken");case 30:r["Message"].error(t.t0||"Has Error"),a("/login?redirect=".concat(e.path)),j.a.done();case 33:t.next=36;break;case 35:-1!==V.indexOf(e.path)?a():(a("/login?redirect=".concat(e.path)),j.a.done());case 36:case"end":return t.stop()}}),t,null,[[14,26]])})));return function(e,n,a){return t.apply(this,arguments)}}()),b["c"].afterEach((function(){j.a.done()}));n("6b54"),n("a481"),n("c5f6");var $=n("ed08");function D(t,e){return 1===t?t+e:t+e+"s"}function R(t){var e=Date.now()/1e3-Number(t);return e<3600?D(~~(e/60)," minute"):e<86400?D(~~(e/3600)," hour"):D(~~(e/86400)," day")}function P(t,e){for(var n=[{value:1e18,symbol:"E"},{value:1e15,symbol:"P"},{value:1e12,symbol:"T"},{value:1e9,symbol:"G"},{value:1e6,symbol:"M"},{value:1e3,symbol:"k"}],a=0;a=n[a].value)return(t/n[a].value+.1).toFixed(e).replace(/\.0+$|(\.[0-9]*[1-9])0+$/,"$1")+n[a].symbol;return t.toString()}function I(t){return(+t||0).toString().replace(/^-?\d+/g,(function(t){return t.replace(/(?=(?!\b)(\d{3})+$)/g,",")}))}function N(t){return t.charAt(0).toUpperCase()+t.slice(1)}var G=n("313e"),q=n("00e7"),U=n.n(q);i["default"].prototype.$echarts=G["default"],i["default"].prototype.$cookie=U.a,i["default"].use(s.a,{size:c.a.get("size")||"medium"}),Object.keys(a).forEach((function(t){i["default"].filter(t,a[t])})),i["default"].config.productionTip=!1,new i["default"]({el:"#app",router:b["c"],store:v["a"],render:function(t){return t(m)}})},"5e10":function(t,e,n){"use strict";n("3150")},"5f87":function(t,e,n){"use strict";n.d(e,"a",(function(){return c})),n.d(e,"c",(function(){return r})),n.d(e,"b",(function(){return s}));var a=n("a78e"),i=n.n(a),o="Admin-Token";function c(){return i.a.get(o)}function r(t){return i.a.set(o,t)}function s(){return i.a.remove(o)}},"61f7":function(t,e,n){"use strict";n.d(e,"a",(function(){return a}));n("6b54");function a(t){return/^(https?:|mailto:|tel:)/.test(t)}},"64df":function(t,e,n){"use strict";n("78bf")},6820:function(t,e,n){"use strict";n("4093")},"6ba9":function(t,e,n){"use strict";n.r(e);var a=n("e017"),i=n.n(a),o=n("21a1"),c=n.n(o),r=new i.a({id:"icon-log3",use:"icon-log3-usage",viewBox:"0 0 1024 1024",content:''});c.a.add(r);e["default"]=r},"6e71":function(t,e,n){"use strict";n.r(e);var a=n("e017"),i=n.n(a),o=n("21a1"),c=n.n(o),r=new i.a({id:"icon-vessel3",use:"icon-vessel3-usage",viewBox:"0 0 1024 1024",content:''});c.a.add(r);e["default"]=r},"78bf":function(t,e,n){},8326:function(t,e,n){},"83d6":function(t,e){t.exports={title:"Hippo4J Web",showSettings:!0,tagsView:!0,fixedHeader:!1,sidebarLogo:!0,errorLog:"production"}},8811:function(t,e,n){"use strict";n.r(e);var a=n("e017"),i=n.n(a),o=n("21a1"),c=n.n(o),r=new i.a({id:"icon-item_logo4",use:"icon-item_logo4-usage",viewBox:"0 0 1024 1024",content:''});c.a.add(r);e["default"]=r},"89f5":function(t,e,n){"use strict";n("29aa")},"8af8":function(t,e,n){"use strict";n("9c98")},"9bc4":function(t,e,n){"use strict";n.r(e);var a=n("e017"),i=n.n(a),o=n("21a1"),c=n.n(o),r=new i.a({id:"icon-threadPool_logo2",use:"icon-threadPool_logo2-usage",viewBox:"0 0 1044 1024",content:''});c.a.add(r);e["default"]=r},"9c98":function(t,e,n){},a14a:function(t,e,n){"use strict";n.r(e);var a=n("e017"),i=n.n(a),o=n("21a1"),c=n.n(o),r=new i.a({id:"icon-404",use:"icon-404-usage",viewBox:"0 0 128 128",content:''});c.a.add(r);e["default"]=r},a18c:function(t,e,n){"use strict";var a,i,o=n("2b0e"),c=n("8c4f"),r=function(){var t=this,e=t.$createElement,n=t._self._c||e;return n("div",{staticClass:"app-wrapper",class:t.classObj},["mobile"===t.device&&t.sidebar.opened?n("div",{staticClass:"drawer-bg",on:{click:t.handleClickOutside}}):t._e(),t._v(" "),n("sidebar",{staticClass:"sidebar-container"}),t._v(" "),n("div",{staticClass:"main-container"},[n("div",{class:{"fixed-header":t.fixedHeader}},[n("navbar")],1),t._v(" "),n("app-main")],1)],1)},s=[],l=n("db72"),u=function(){var t=this,e=t.$createElement,n=t._self._c||e;return n("section",{staticClass:"app-main"},[n("transition",{attrs:{name:"fade-transform",mode:"out-in"}},[n("router-view",{key:t.key})],1)],1)},d=[],f={name:"AppMain",computed:{cachedViews:function(){return this.$store.state.tagsView.cachedViews},key:function(){return this.$route.path}}},h=f,p=(n("5e10"),n("0d3d"),n("2877")),m=Object(p["a"])(h,u,d,!1,null,"5ad61798",null),v=m.exports,b=function(){var t=this,e=t.$createElement,a=t._self._c||e;return a("div",{staticClass:"navbar"},[a("hamburger",{staticClass:"hamburger-container",attrs:{id:"hamburger-container","is-active":t.sidebar.opened},on:{toggleClick:t.toggleSideBar}}),t._v(" "),a("breadcrumb",{staticClass:"breadcrumb-container",attrs:{id:"breadcrumb-container"}}),t._v(" "),a("div",{staticClass:"right-menu"},["mobile"!==t.device?void 0:t._e(),t._v(" "),a("el-dropdown",{staticClass:"avatar-container right-menu-item hover-effect",attrs:{trigger:"click"}},[a("div",{staticClass:"avatar-wrapper"},[a("img",{staticClass:"user-avatar",attrs:{src:n("f561")}}),t._v(" "),a("i",{staticClass:"el-icon-caret-bottom"})]),t._v(" "),a("el-dropdown-menu",{attrs:{slot:"dropdown"},slot:"dropdown"},[a("router-link",{attrs:{to:"/"}},[a("el-dropdown-item",[t._v("Dashboard")])],1),t._v(" "),a("el-dropdown-item",{attrs:{divided:""}},[a("span",{staticStyle:{display:"block"},on:{click:t.logout}},[t._v("Log Out")])])],1)],1)],2)],1)},g=[],w=n("c80c"),x=(n("96cf"),n("3b8d")),y=n("2f62"),_=function(){var t=this,e=t.$createElement,n=t._self._c||e;return n("el-breadcrumb",{staticClass:"app-breadcrumb",attrs:{separator:"/"}},[n("transition-group",{attrs:{name:"breadcrumb"}},t._l(t.levelList,(function(e,a){return n("el-breadcrumb-item",{key:e.path},["noRedirect"===e.redirect||a==t.levelList.length-1?n("span",{staticClass:"no-redirect"},[t._v(t._s(e.meta.title))]):n("a",{on:{click:function(n){return n.preventDefault(),t.handleLink(e)}}},[t._v(t._s(e.meta.title))])])})),1)],1)},k=[],M=(n("7f7f"),n("f559"),n("bd11")),E=n.n(M),z={data:function(){return{levelList:null}},watch:{$route:function(t){t.path.startsWith("/redirect/")||this.getBreadcrumb()}},created:function(){this.getBreadcrumb()},methods:{getBreadcrumb:function(){var t=this.$route.matched.filter((function(t){return t.meta&&t.meta.title})),e=t[0];this.isDashboard(e)||(t=[{path:"/dashboard",meta:{title:"Dashboard"}}].concat(t)),this.levelList=t.filter((function(t){return t.meta&&t.meta.title&&!1!==t.meta.breadcrumb}))},isDashboard:function(t){var e=t&&t.name;return!!e&&e.trim().toLocaleLowerCase()==="Dashboard".toLocaleLowerCase()},pathCompile:function(t){var e=this.$route.params,n=E.a.compile(t);return n(e)},handleLink:function(t){var e=t.redirect,n=t.path;e?this.$router.push(e):this.$router.push(this.pathCompile(n))}}},C=z,O=(n("89f5"),Object(p["a"])(C,_,k,!1,null,"1919fc1a",null)),L=O.exports,S=function(){var t=this,e=t.$createElement,n=t._self._c||e;return n("div",{staticStyle:{padding:"0 15px"},on:{click:t.toggleClick}},[n("svg",{staticClass:"hamburger",class:{"is-active":t.isActive},attrs:{viewBox:"0 0 1024 1024",xmlns:"http://www.w3.org/2000/svg",width:"64",height:"64"}},[n("path",{attrs:{d:"M408 442h480c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8H408c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8zm-8 204c0 4.4 3.6 8 8 8h480c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8H408c-4.4 0-8 3.6-8 8v56zm504-486H120c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zm0 632H120c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zM142.4 642.1L298.7 519a8.84 8.84 0 0 0 0-13.9L142.4 381.9c-5.8-4.6-14.4-.5-14.4 6.9v246.3a8.9 8.9 0 0 0 14.4 7z"}})])])},j=[],A={name:"Hamburger",props:{isActive:{type:Boolean,default:!1}},methods:{toggleClick:function(){this.$emit("toggleClick")}}},B=A,H=(n("d49d"),Object(p["a"])(B,S,j,!1,null,"49e15297",null)),T=H.exports,F=function(){var t=this,e=t.$createElement,n=t._self._c||e;return t.errorLogs.length>0?n("div",[n("el-badge",{staticStyle:{"line-height":"25px","margin-top":"-5px"},attrs:{"is-dot":!0},nativeOn:{click:function(e){t.dialogTableVisible=!0}}},[n("el-button",{staticStyle:{padding:"8px 10px"},attrs:{size:"small",type:"danger"}},[n("svg-icon",{attrs:{"icon-class":"bug"}})],1)],1),t._v(" "),n("el-dialog",{attrs:{visible:t.dialogTableVisible,width:"80%","append-to-body":""},on:{"update:visible":function(e){t.dialogTableVisible=e}}},[n("div",{attrs:{slot:"title"},slot:"title"},[n("span",{staticStyle:{"padding-right":"10px"}},[t._v("Error Log")]),t._v(" "),n("el-button",{attrs:{size:"mini",type:"primary",icon:"el-icon-delete"},on:{click:t.clearAll}},[t._v("Clear All")])],1),t._v(" "),n("el-table",{attrs:{data:t.errorLogs,border:""}},[n("el-table-column",{attrs:{label:"Message"},scopedSlots:t._u([{key:"default",fn:function(e){var a=e.row;return[n("div",[n("span",{staticClass:"message-title"},[t._v("Msg:")]),t._v(" "),n("el-tag",{attrs:{type:"danger"}},[t._v("\n "+t._s(a.err.message)+"\n ")])],1),t._v(" "),n("br"),t._v(" "),n("div",[n("span",{staticClass:"message-title",staticStyle:{"padding-right":"10px"}},[t._v("Info: ")]),t._v(" "),n("el-tag",{attrs:{type:"warning"}},[t._v("\n "+t._s(a.vm.$vnode.tag)+" error in "+t._s(a.info)+"\n ")])],1),t._v(" "),n("br"),t._v(" "),n("div",[n("span",{staticClass:"message-title",staticStyle:{"padding-right":"16px"}},[t._v("Url: ")]),t._v(" "),n("el-tag",{attrs:{type:"success"}},[t._v("\n "+t._s(a.url)+"\n ")])],1)]}}],null,!1,3621415002)}),t._v(" "),n("el-table-column",{attrs:{label:"Stack"},scopedSlots:t._u([{key:"default",fn:function(e){return[t._v("\n "+t._s(e.row.err.stack)+"\n ")]}}],null,!1,1726869048)})],1)],1)],1):t._e()},V=[],$={name:"ErrorLog",data:function(){return{dialogTableVisible:!1}},computed:{errorLogs:function(){return this.$store.getters.errorLogs}},methods:{clearAll:function(){this.dialogTableVisible=!1,this.$store.dispatch("errorLog/clearErrorLog")}}},D=$,R=(n("b36c"),Object(p["a"])(D,F,V,!1,null,"be34583a",null)),P=R.exports,I={components:{Breadcrumb:L,Hamburger:T,ErrorLog:P},computed:Object(l["a"])({},Object(y["b"])(["sidebar","avatar","device"])),methods:{toggleSideBar:function(){this.$store.dispatch("app/toggleSideBar")},logout:function(){var t=Object(x["a"])(Object(w["a"])().mark((function t(){return Object(w["a"])().wrap((function(t){while(1)switch(t.prev=t.next){case 0:return this.$cookie.delete("userName"),t.next=3,this.$store.dispatch("user/logout");case 3:this.$router.push("/login?redirect=".concat(this.$route.fullPath));case 4:case"end":return t.stop()}}),t,this)})));function e(){return t.apply(this,arguments)}return e}()}},N=I,G=(n("07c6"),Object(p["a"])(N,b,g,!1,null,"6ab05616",null)),q=G.exports,U=function(){var t=this,e=t.$createElement,n=t._self._c||e;return n("div",{class:{"has-logo":t.showLogo}},[t.showLogo?n("logo",{attrs:{collapse:t.isCollapse}}):t._e(),t._v(" "),n("el-scrollbar",{attrs:{"wrap-class":"scrollbar-wrapper"}},[n("el-menu",{attrs:{"default-active":t.activeMenu,collapse:t.isCollapse,"background-color":t.variables.menuBg,"text-color":t.variables.menuText,"unique-opened":!1,"active-text-color":t.variables.menuActiveText,"collapse-transition":!1,mode:"vertical"}},t._l(t.permission_routes,(function(t){return n("sidebar-item",{key:t.path,attrs:{item:t,"base-path":t.path}})})),1)],1)],1)},J=[],K=function(){var t=this,e=t.$createElement,n=t._self._c||e;return n("div",{staticClass:"sidebar-logo-container",class:{collapse:t.collapse}},[n("transition",{attrs:{name:"sidebarLogoFade"}},[t.collapse?n("router-link",{key:"collapse",staticClass:"sidebar-logo-link",attrs:{to:"/"}},[t.logo?n("img",{staticClass:"sidebar-logo",attrs:{src:t.logo}}):n("h1",{staticClass:"sidebar-title"},[t._v(t._s(t.title))])]):n("router-link",{key:"expand",staticClass:"sidebar-logo-link",attrs:{to:"/"}},[t.logo?n("img",{staticClass:"sidebar-logo",attrs:{src:t.logo}}):t._e(),t._v(" "),n("h1",{staticClass:"sidebar-title"},[t._v(t._s(t.title))])])],1)],1)},Q=[],W={name:"SidebarLogo",props:{collapse:{type:Boolean,required:!0}},data:function(){return{title:"hippo4j 1.4.3"}}},Z=W,Y=(n("8af8"),Object(p["a"])(Z,K,Q,!1,null,"741ab93c",null)),X=Y.exports,tt=function(){var t=this,e=t.$createElement,n=t._self._c||e;return t.item.hidden?t._e():n("div",{staticClass:"menu-wrapper"},[!t.hasOneShowingChild(t.item.children,t.item)||t.onlyOneChild.children&&!t.onlyOneChild.noShowingChildren||t.item.alwaysShow?n("el-submenu",{ref:"subMenu",attrs:{index:t.resolvePath(t.item.path),"popper-append-to-body":""}},[n("template",{slot:"title"},[t.item.meta?n("item",{attrs:{icon:t.item.meta&&t.item.meta.icon,title:t.item.meta.title}}):t._e()],1),t._v(" "),t._l(t.item.children,(function(e){return n("sidebar-item",{key:e.path,staticClass:"nest-menu",attrs:{"is-nest":!0,item:e,"base-path":t.resolvePath(e.path)}})}))],2):[t.onlyOneChild.meta?n("app-link",{attrs:{to:t.resolvePath(t.onlyOneChild.path)}},[n("el-menu-item",{class:{"submenu-title-noDropdown":!t.isNest},attrs:{index:t.resolvePath(t.onlyOneChild.path)}},[n("item",{attrs:{icon:t.onlyOneChild.meta.icon||t.item.meta&&t.item.meta.icon,title:t.onlyOneChild.meta.title}})],1)],1):t._e()]],2)},et=[],nt=n("df7c"),at=n.n(nt),it=n("61f7"),ot={name:"MenuItem",functional:!0,props:{icon:{type:String,default:""},title:{type:String,default:""}},render:function(t,e){var n=e.props,a=n.icon,i=n.title,o=[];return a&&o.push(t("svg-icon",{attrs:{"icon-class":a}})),i&&o.push(t("span",{slot:"title"},[i])),o}},ct=ot,rt=Object(p["a"])(ct,a,i,!1,null,null,null),st=rt.exports,lt=function(){var t=this,e=t.$createElement,n=t._self._c||e;return n("component",t._b({},"component",t.linkProps(t.to),!1),[t._t("default")],2)},ut=[],dt={props:{to:{type:String,required:!0}},methods:{linkProps:function(t){return Object(it["a"])(t)?{is:"a",href:t,target:"_blank",rel:"noopener"}:{is:"router-link",to:t}}}},ft=dt,ht=Object(p["a"])(ft,lt,ut,!1,null,null,null),pt=ht.exports,mt={computed:{device:function(){return this.$store.state.app.device}},mounted:function(){this.fixBugIniOS()},methods:{fixBugIniOS:function(){var t=this,e=this.$refs.subMenu;if(e){var n=e.handleMouseleave;e.handleMouseleave=function(e){"mobile"!==t.device&&n(e)}}}}},vt={name:"SidebarItem",components:{Item:st,AppLink:pt},mixins:[mt],props:{item:{type:Object,required:!0},isNest:{type:Boolean,default:!1},basePath:{type:String,default:""}},data:function(){return this.onlyOneChild=null,{}},methods:{hasOneShowingChild:function(){var t=this,e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[],n=arguments.length>1?arguments[1]:void 0,a=e.filter((function(e){return!e.hidden&&(t.onlyOneChild=e,!0)}));return 1===a.length||0===a.length&&(this.onlyOneChild=Object(l["a"])(Object(l["a"])({},n),{},{path:"",noShowingChildren:!0}),!0)},resolvePath:function(t){return Object(it["a"])(t)?t:Object(it["a"])(this.basePath)?this.basePath:at.a.resolve(this.basePath,t)}}},bt=vt,gt=Object(p["a"])(bt,tt,et,!1,null,null,null),wt=gt.exports,xt=n("cf1e"),yt=n.n(xt),_t={components:{SidebarItem:wt,Logo:X},computed:Object(l["a"])(Object(l["a"])({},Object(y["b"])(["permission_routes","sidebar"])),{},{activeMenu:function(){var t=this.$route,e=t.meta,n=t.path;return e.activeMenu?e.activeMenu:n},showLogo:function(){return this.$store.state.settings.sidebarLogo},variables:function(){return yt.a},isCollapse:function(){return!this.sidebar.opened}})},kt=_t,Mt=Object(p["a"])(kt,U,J,!1,null,null,null),Et=Mt.exports,zt=n("4360"),Ct=document,Ot=Ct.body,Lt=992,St={watch:{$route:function(t){"mobile"===this.device&&this.sidebar.opened&&zt["a"].dispatch("app/closeSideBar",{withoutAnimation:!1})}},beforeMount:function(){window.addEventListener("resize",this.$_resizeHandler)},beforeDestroy:function(){window.removeEventListener("resize",this.$_resizeHandler)},mounted:function(){var t=this.$_isMobile();t&&(zt["a"].dispatch("app/toggleDevice","mobile"),zt["a"].dispatch("app/closeSideBar",{withoutAnimation:!0}))},methods:{$_isMobile:function(){var t=Ot.getBoundingClientRect();return t.width-1'});c.a.add(r);e["default"]=r},b20f:function(t,e,n){t.exports={menuText:"#bfcbd9",menuActiveText:"#409eff",subMenuActiveText:"#f4f4f5",menuBg:"#304156",menuHover:"#263445",subMenuBg:"#1f2d3d",subMenuHover:"#001528",sideBarWidth:"210px"}},b36c:function(t,e,n){"use strict";n("187a")},b6d1:function(t,e,n){"use strict";n.r(e);var a=n("e017"),i=n.n(a),o=n("21a1"),c=n.n(o),r=new i.a({id:"icon-threadPool_logo1",use:"icon-threadPool_logo1-usage",viewBox:"0 0 1024 1024",content:''});c.a.add(r);e["default"]=r},b775:function(t,e,n){"use strict";var a=n("bc3a"),i=n.n(a),o=n("5c96"),c=n("4360"),r=n("5f87"),s=n("a18c"),l=i.a.create({baseURL:"",timeout:2e4});l.interceptors.request.use((function(t){return c["a"].getters.token&&(t.headers["Authorization"]=Object(r["a"])()),t}),(function(t){return console.log(t),Promise.reject(t)})),l.interceptors.response.use((function(t){var e=t.data;if("A000004"!==e.code){if("20000"!==e.code&&"0"!==e.code&&"200"!==e.code)return Object(o["Message"])({message:e.message||"Error",type:"error",duration:5e3}),"50008"!==e.code&&"50012"!==e.code&&"50014"!==e.code||o["MessageBox"].confirm("You have been logged out, you can cancel to stay on this page, or log in again","Confirm logout",{confirmButtonText:"Re-Login",cancelButtonText:"Cancel",type:"warning"}).then((function(){c["a"].dispatch("user/resetToken").then((function(){location.reload()}))})),Promise.reject(new Error(e.message||"Error"));var n=t.data,a=n.code;if("0"===a){var i=n.data;return i}return"200"===a?n:e}Object(r["b"])(),Object(s["d"])(),alert(e.message),document.location.href="index.html"}),(function(t){return console.log("err"+t),Object(o["Message"])({message:t.message,type:"error",duration:5e3}),Promise.reject(t)})),e["a"]=l},c653:function(t,e,n){var a={"./app.js":"d9cd","./errorLog.js":"4d49","./permission.js":"31c2","./settings.js":"0781","./user.js":"0f9a"};function i(t){var e=o(t);return n(e)}function o(t){var e=a[t];if(!(e+1)){var n=new Error("Cannot find module '"+t+"'");throw n.code="MODULE_NOT_FOUND",n}return e}i.keys=function(){return Object.keys(a)},i.resolve=o,t.exports=i,i.id="c653"},cf1e:function(t,e,n){t.exports={menuText:"#bfcbd9",menuActiveText:"#409eff",subMenuActiveText:"#f4f4f5",menuBg:"#304156",menuHover:"#263445",subMenuBg:"#1f2d3d",subMenuHover:"#001528",sideBarWidth:"210px"}},d393:function(t,e,n){"use strict";n.r(e);var a=n("e017"),i=n.n(a),o=n("21a1"),c=n.n(o),r=new i.a({id:"icon-audit",use:"icon-audit-usage",viewBox:"0 0 1024 1024",content:''});c.a.add(r);e["default"]=r},d49d:function(t,e,n){"use strict";n("8326")},d9cd:function(t,e,n){"use strict";n.r(e);var a=n("a78e"),i=n.n(a),o={sidebar:{opened:!i.a.get("sidebarStatus")||!!+i.a.get("sidebarStatus"),withoutAnimation:!1},device:"desktop",size:i.a.get("size")||"medium"},c={TOGGLE_SIDEBAR:function(t){t.sidebar.opened=!t.sidebar.opened,t.sidebar.withoutAnimation=!1,t.sidebar.opened?i.a.set("sidebarStatus",1):i.a.set("sidebarStatus",0)},CLOSE_SIDEBAR:function(t,e){i.a.set("sidebarStatus",0),t.sidebar.opened=!1,t.sidebar.withoutAnimation=e},TOGGLE_DEVICE:function(t,e){t.device=e},SET_SIZE:function(t,e){t.size=e,i.a.set("size",e)}},r={toggleSideBar:function(t){var e=t.commit;e("TOGGLE_SIDEBAR")},closeSideBar:function(t,e){var n=t.commit,a=e.withoutAnimation;n("CLOSE_SIDEBAR",a)},toggleDevice:function(t,e){var n=t.commit;n("TOGGLE_DEVICE",e)},setSize:function(t,e){var n=t.commit;n("SET_SIZE",e)}};e["default"]={namespaced:!0,state:o,mutations:c,actions:r}},dbd7:function(t,e,n){"use strict";n.r(e);var a=n("e017"),i=n.n(a),o=n("21a1"),c=n.n(o),r=new i.a({id:"icon-lessee",use:"icon-lessee-usage",viewBox:"0 0 1024 1024",content:''});c.a.add(r);e["default"]=r},ea93:function(t,e,n){"use strict";n.r(e);var a=n("e017"),i=n.n(a),o=n("21a1"),c=n.n(o),r=new i.a({id:"icon-dashboard2",use:"icon-dashboard2-usage",viewBox:"0 0 1024 1024",content:''});c.a.add(r);e["default"]=r},ed08:function(t,e,n){"use strict";n.d(e,"c",(function(){return i})),n.d(e,"b",(function(){return o})),n.d(e,"a",(function(){return c}));n("3b2b"),n("4917"),n("4f7f"),n("5df3"),n("1c4c"),n("28a5"),n("ac6a"),n("456d"),n("a481"),n("6b54");var a=n("7618");function i(t,e){if(0===arguments.length)return null;var n,i=e||"{y}-{m}-{d} {h}:{i}:{s}";"object"===Object(a["a"])(t)?n=t:("string"===typeof t&&/^[0-9]+$/.test(t)&&(t=parseInt(t)),"number"===typeof t&&10===t.toString().length&&(t*=1e3),n=new Date(t));var o={y:n.getFullYear(),m:n.getMonth()+1,d:n.getDate(),h:n.getHours(),i:n.getMinutes(),s:n.getSeconds(),a:n.getDay()},c=i.replace(/{(y|m|d|h|i|s|a)+}/g,(function(t,e){var n=o[e];return"a"===e?["日","一","二","三","四","五","六"][n]:(t.length>0&&n<10&&(n="0"+n),n||0)}));return c}function o(t,e){t=10===(""+t).length?1e3*parseInt(t):+t;var n=new Date(t),a=Date.now(),o=(a-n)/1e3;return o<30?"刚刚":o<3600?Math.ceil(o/60)+"分钟前":o<86400?Math.ceil(o/3600)+"小时前":o<172800?"1天前":e?i(t,e):n.getMonth()+1+"月"+n.getDate()+"日"+n.getHours()+"时"+n.getMinutes()+"分"}function c(t,e,n){var a,i,o,c,r,s=function s(){var l=+new Date-c;l0?a=setTimeout(s,e-l):(a=null,n||(r=t.apply(o,i),a||(o=i=null)))};return function(){for(var i=arguments.length,l=new Array(i),u=0;u'});c.a.add(r);e["default"]=r},f561:function(t,e,n){t.exports=n.p+"static/img/hippo4j.ecba1844.gif"}},[[0,"runtime","chunk-elementUI","chunk-libs"]]]); \ No newline at end of file diff --git a/hippo4j-server/hippo4j-console/src/main/resources/static/static/js/chunk-078a7535.61dbc5da.js b/hippo4j-server/hippo4j-console/src/main/resources/static/static/js/chunk-078a7535.61dbc5da.js new file mode 100644 index 00000000..d5701286 --- /dev/null +++ b/hippo4j-server/hippo4j-console/src/main/resources/static/static/js/chunk-078a7535.61dbc5da.js @@ -0,0 +1 @@ +(window["webpackJsonp"]=window["webpackJsonp"]||[]).push([["chunk-078a7535"],{3737:function(e,t,i){"use strict";i.d(t,"c",(function(){return a})),i.d(t,"d",(function(){return l})),i.d(t,"a",(function(){return r})),i.d(t,"b",(function(){return o}));var n=i("b775");function a(e){return Object(n["a"])({url:"/hippo4j/v1/cs/item/query/page",method:"post",data:e})}function l(e){return Object(n["a"])({url:"/hippo4j/v1/cs/item/update",method:"post",data:e})}function r(e){return Object(n["a"])({url:"/hippo4j/v1/cs/item/save",method:"post",data:e})}function o(e){return Object(n["a"])({url:"/hippo4j/v1/cs/item/delete/"+e[0]+"/"+e[1],method:"delete"})}},"395c":function(e,t,i){"use strict";i.r(t);var n=function(){var e=this,t=e.$createElement,i=e._self._c||t;return i("div",{staticClass:"app-container"},[i("div",{staticClass:"filter-container"},[i("el-select",{staticClass:"filter-item",staticStyle:{width:"220px"},attrs:{placeholder:"租户(必填)",filterable:""},on:{change:function(t){return e.tenantSelectList()}},model:{value:e.listQuery.tenantId,callback:function(t){e.$set(e.listQuery,"tenantId",t)},expression:"listQuery.tenantId"}},e._l(e.tenantOptions,(function(e){return i("el-option",{key:e.key,attrs:{label:e.display_name,value:e.key}})})),1),e._v(" "),i("el-select",{staticClass:"filter-item",staticStyle:{width:"220px"},attrs:{placeholder:"项目(必填)",filterable:""},on:{change:function(t){return e.itemSelectList()}},model:{value:e.listQuery.itemId,callback:function(t){e.$set(e.listQuery,"itemId",t)},expression:"listQuery.itemId"}},e._l(e.itemOptions,(function(e){return i("el-option",{key:e.key,attrs:{label:e.display_name,value:e.key}})})),1),e._v(" "),i("el-select",{staticClass:"filter-item",staticStyle:{width:"220px"},attrs:{placeholder:"线程池标识(必填)",filterable:""},model:{value:e.listQuery.threadPoolKey,callback:function(t){e.$set(e.listQuery,"threadPoolKey",t)},expression:"listQuery.threadPoolKey"}},e._l(e.threadPoolKeyOptions,(function(e){return i("el-option",{key:e.key,attrs:{label:e.display_name,value:e.key}})})),1),e._v(" "),i("el-button",{directives:[{name:"waves",rawName:"v-waves"}],staticClass:"filter-item",attrs:{type:"primary",icon:"el-icon-search"},on:{click:e.fetchData}},[e._v("\n 搜索\n ")]),e._v(" "),i("el-button",{directives:[{name:"waves",rawName:"v-waves"}],staticClass:"filter-item",staticStyle:{"margin-left":"10px"},attrs:{type:"primary",icon:"el-icon-refresh"},on:{click:e.refreshData}},[e._v("\n 重置\n ")])],1),e._v(" "),i("el-table",{directives:[{name:"loading",rawName:"v-loading",value:e.listLoading,expression:"listLoading"}],attrs:{data:e.list,"element-loading-text":"Loading",border:"",fit:"","max-height":"714","highlight-current-row":""}},[i("el-table-column",{attrs:{label:"序号",width:"95"},scopedSlots:e._u([{key:"default",fn:function(t){return[e._v(e._s(t.$index+1))]}}])}),e._v(" "),i("el-table-column",{attrs:{label:"实例标识",width:"260"},scopedSlots:e._u([{key:"default",fn:function(t){return[i("el-link",{attrs:{type:"primary",underline:!1}},[e._v(e._s(t.row.identify))])]}}])}),e._v(" "),i("el-table-column",{attrs:{label:"Active"},scopedSlots:e._u([{key:"default",fn:function(t){return[i("el-tag",{attrs:{type:e._f("statusFilter")(t.row.active)}},[e._v("\n "+e._s(t.row.active)+"\n ")])]}}])}),e._v(" "),i("el-table-column",{attrs:{label:"线程池标识"},scopedSlots:e._u([{key:"default",fn:function(t){return[e._v("\n "+e._s(t.row.threadPoolKey)+"\n ")]}}])}),e._v(" "),i("el-table-column",{attrs:{label:"核心线程"},scopedSlots:e._u([{key:"default",fn:function(t){return[i("el-link",{attrs:{type:"success",underline:!1}},[e._v(e._s(t.row.coreSize))])]}}])}),e._v(" "),i("el-table-column",{attrs:{label:"最大线程"},scopedSlots:e._u([{key:"default",fn:function(t){return[i("el-link",{attrs:{type:"danger",underline:!1}},[e._v(e._s(t.row.maximumSize))])]}}])}),e._v(" "),i("el-table-column",{attrs:{label:"操作",width:"180","class-name":"small-padding fixed-width"},scopedSlots:e._u([{key:"default",fn:function(t){var n=t.row;return[i("el-button",{attrs:{type:"text",size:"small"},on:{click:function(t){return e.handleUpdate(n)}}},[e._v(" 编辑 ")])]}}])})],1),e._v(" "),i("el-dialog",{attrs:{title:e.textMap[e.dialogStatus],visible:e.dialogFormVisible},on:{"update:visible":function(t){e.dialogFormVisible=t}}},[i("el-form",{ref:"dataForm",attrs:{rules:e.rules,model:e.temp,"label-position":"left","label-width":"110px"}},[i("el-form-item",{attrs:{label:"核心线程",prop:"coreSize"}},[[i("el-input-number",{attrs:{"controls-position":"right",min:1,max:9999},model:{value:e.temp.coreSize,callback:function(t){e.$set(e.temp,"coreSize",t)},expression:"temp.coreSize"}})]],2),e._v(" "),i("el-form-item",{attrs:{label:"最大线程",prop:"maximumSize"}},[[i("el-input-number",{attrs:{"controls-position":"right",min:1,max:9999},model:{value:e.temp.maximumSize,callback:function(t){e.$set(e.temp,"maximumSize",t)},expression:"temp.maximumSize"}})]],2),e._v(" "),i("el-form-item",{attrs:{label:"全部修改",prop:"allUpdate"}},[i("el-switch",{model:{value:e.temp.allUpdate,callback:function(t){e.$set(e.temp,"allUpdate",t)},expression:"temp.allUpdate"}})],1)],1),e._v(" "),i("div",{staticClass:"dialog-footer",attrs:{slot:"footer"},slot:"footer"},[i("el-button",{on:{click:function(t){e.dialogFormVisible=!1}}},[e._v(" 取消 ")]),e._v(" "),i("el-button",{attrs:{type:"primary"},on:{click:function(t){return e.updateData()}}},[e._v(" 确认 ")])],1)],1),e._v(" "),i("el-dialog",{attrs:{visible:e.dialogPluginVisible,title:"Reading statistics"},on:{"update:visible":function(t){e.dialogPluginVisible=t}}},[i("el-table",{staticStyle:{width:"100%"},attrs:{data:e.pluginData,border:"",fit:"","highlight-current-row":""}},[i("el-table-column",{attrs:{prop:"key",label:"Channel"}}),e._v(" "),i("el-table-column",{attrs:{prop:"pv",label:"Pv"}})],1),e._v(" "),i("span",{staticClass:"dialog-footer",attrs:{slot:"footer"},slot:"footer"},[i("el-button",{attrs:{type:"primary"},on:{click:function(t){e.dialogPvVisible=!1}}},[e._v("Confirm")])],1)],1)],1)},a=[],l=i("3737"),r=i("dd71"),o=i("4d85"),s=i("47ec"),u=i("6724"),d={name:"JobProject",directives:{waves:u["a"]},filters:{statusFilter:function(e){var t={DEV:"info",TEST:"success",UAT:"warning",PROD:"danger"};return t[e]}},data:function(){return{isRejectShow:!1,list:null,listLoading:!1,total:0,listQuery:{itemId:"",mark:"Hystrix",tenantId:"",threadPoolKey:""},pluginTypeOptions:["reader","writer"],dialogPluginVisible:!1,pluginData:[],dialogFormVisible:!1,runTimeTemp:{},typeOptions:[{key:"Dubbo",display_name:"Dubbo"},{key:"RocketMQ",display_name:"RocketMQ"},{key:"RocketMQSpringCloudStream",display_name:"RocketMQSpringCloudStream"},{key:"RabbitMQ",display_name:"RabbitMQ"},{key:"RabbitMQSpringCloudStream",display_name:"RabbitMQSpringCloudStream"}],tenantOptions:[],instanceDialogFormVisible:!1,threadPoolOptions:[],itemOptions:[],threadPoolKeyOptions:[],itemTempOptions:[],queueTypeOptions:[{key:1,display_name:"ArrayBlockingQueue"},{key:2,display_name:"LinkedBlockingQueue"},{key:3,display_name:"LinkedBlockingDeque"},{key:4,display_name:"SynchronousQueue"},{key:5,display_name:"LinkedTransferQueue"},{key:6,display_name:"PriorityBlockingQueue"},{key:9,display_name:"ResizableLinkedBlockingQueue (动态修改队列大小)"}],rejectedOptions:[{key:1,display_name:"CallerRunsPolicy"},{key:2,display_name:"AbortPolicy"},{key:3,display_name:"DiscardPolicy"},{key:4,display_name:"DiscardOldestPolicy"},{key:5,display_name:"RunsOldestTaskPolicy"},{key:6,display_name:"SyncPutQueuePolicy"},{key:99,display_name:"CustomRejectedPolicy(自定义 SPI 策略)"}],alarmTypes:[{key:1,display_name:"报警"},{key:0,display_name:"不报警"}],allowCoreThreadTimeOutTypes:[{key:1,display_name:"超时"},{key:0,display_name:"不超时"}],size:500,dialogStatus:"",textMap:{update:"Edit",create:"Create"},rules:{coreSize:[{required:!0,message:"this is required",trigger:"blur"}],maximumSize:[{required:!0,message:"this is required",trigger:"blur"}]},temp:{id:void 0,tenantId:"",itemId:"",rejectedType:null,allUpdate:"1",customRejectedType:null},visible:!0}},created:function(){this.initSelect()},methods:{onInput:function(){this.$forceUpdate()},fetchData:function(){var e=this;this.listQuery.mark?this.listQuery.tenantId?this.listQuery.itemId?this.listQuery.threadPoolKey?(this.listLoading=!0,s["a"](this.listQuery).then((function(t){null==t&&(e.listLoading=!1),e.list=t,e.listLoading=!1}))):this.$message.warning("线程池标识不允许为空"):this.$message.warning("项目不允许为空"):this.$message.warning("租户不允许为空"):this.$message.warning("线程池类型不允许为空")},initSelect:function(){var e=this;r["c"]({size:this.size}).then((function(t){for(var i=t.records,n=0;n { - private final int containerSize = 1024; + private static final int CONTAINER_SIZE = 1024; - private final ConcurrentHashMap>> registry = new ConcurrentHashMap(containerSize); + private final ConcurrentHashMap>> registry = new ConcurrentHashMap<>(CONTAINER_SIZE); @Override public List> listInstance(String appName) { Map> appNameLeaseMap = registry.get(appName); - if (CollectionUtils.isEmpty(appNameLeaseMap)) { - return new ArrayList<>(); - } - List> appNameLeaseList = new ArrayList<>(); - appNameLeaseMap.values().forEach(each -> appNameLeaseList.add(each)); - return appNameLeaseList; + return CollectionUtils.isEmpty(appNameLeaseMap) ? Collections.emptyList() : new ArrayList<>(appNameLeaseMap.values()); } @Override public void register(InstanceInfo registrant) { Map> registerMap = registry.get(registrant.getAppName()); if (registerMap == null) { - ConcurrentHashMap> registerNewMap = new ConcurrentHashMap(12); + ConcurrentHashMap> registerNewMap = new ConcurrentHashMap<>(); registerMap = registry.putIfAbsent(registrant.getAppName(), registerNewMap); if (registerMap == null) { registerMap = registerNewMap; @@ -98,8 +95,11 @@ public class BaseInstanceRegistry implements InstanceRegistry { String appName = instanceRenew.getAppName(); String instanceId = instanceRenew.getInstanceId(); Map> registryMap = registry.get(appName); - Lease leaseToRenew; - if (registryMap == null || (leaseToRenew = registryMap.get(instanceId)) == null) { + if (registryMap == null) { + return false; + } + Lease leaseToRenew = registryMap.get(instanceId); + if (leaseToRenew == null) { return false; } leaseToRenew.renew(); @@ -111,20 +111,20 @@ public class BaseInstanceRegistry implements InstanceRegistry { String appName = info.getAppName(); String instanceId = info.getInstanceId(); Map> leaseMap = registry.get(appName); - if (CollectionUtils.isEmpty(leaseMap)) { + if (CollectionUtil.isNotEmpty(leaseMap)) { + Lease remove = leaseMap.remove(instanceId); + if (remove != null) { + log.info("Remove unhealthy node, node ID: {}", instanceId); + } else { + log.warn("Failed to remove unhealthy node, no instance found: {}", instanceId); + } + } else { log.warn("Failed to remove unhealthy node, no application found: {}", appName); - return; - } - Lease remove = leaseMap.remove(instanceId); - if (remove == null) { - log.warn("Failed to remove unhealthy node, no instance found: {}", instanceId); - return; } - log.info("Remove unhealthy node, node ID: {}", instanceId); } public void evict(long additionalLeaseMs) { - List> expiredLeases = new ArrayList(); + List> expiredLeases = new ArrayList<>(); for (Map.Entry>> groupEntry : registry.entrySet()) { Map> leaseMap = groupEntry.getValue(); if (leaseMap != null) { @@ -146,7 +146,7 @@ public class BaseInstanceRegistry implements InstanceRegistry { protected boolean internalCancel(String appName, String id, String identify) { Map> registerMap = registry.get(appName); - if (!CollectionUtils.isEmpty(registerMap)) { + if (CollectionUtil.isNotEmpty(registerMap)) { registerMap.remove(id); AbstractSubjectCenter.notify(AbstractSubjectCenter.SubjectType.CLEAR_CONFIG_CACHE, () -> identify); log.info("Clean up unhealthy nodes. Node id: {}", id); @@ -154,6 +154,9 @@ public class BaseInstanceRegistry implements InstanceRegistry { return true; } + /** + * EvictionTask + */ public class EvictionTask extends TimerTask { private final AtomicLong lastExecutionNanosRef = new AtomicLong(0L); @@ -177,7 +180,7 @@ public class BaseInstanceRegistry implements InstanceRegistry { } long elapsedMs = TimeUnit.NANOSECONDS.toMillis(currNanos - lastNanos); long compensationTime = elapsedMs - EVICTION_INTERVAL_TIMER_IN_MS; - return compensationTime <= 0L ? 0L : compensationTime; + return Math.max(compensationTime, 0L); } long getCurrentTimeNano() { @@ -193,7 +196,7 @@ public class BaseInstanceRegistry implements InstanceRegistry { .daemon(true) .build()); - private final AtomicReference evictionTaskRef = new AtomicReference(); + private final AtomicReference evictionTaskRef = new AtomicReference<>(); public void postInit() { evictionTaskRef.set(new BaseInstanceRegistry.EvictionTask()); diff --git a/hippo4j-server/hippo4j-discovery/src/main/java/cn/hippo4j/discovery/core/Lease.java b/hippo4j-server/hippo4j-discovery/src/main/java/cn/hippo4j/discovery/core/Lease.java index e604760b..0d796f9e 100644 --- a/hippo4j-server/hippo4j-discovery/src/main/java/cn/hippo4j/discovery/core/Lease.java +++ b/hippo4j-server/hippo4j-discovery/src/main/java/cn/hippo4j/discovery/core/Lease.java @@ -17,32 +17,19 @@ package cn.hippo4j.discovery.core; +import lombok.Getter; + /** * Lease. */ public class Lease { - enum Action { - /** - * REGISTER - */ - REGISTER, - - /** - * CANCEL - */ - CANCEL, - - /** - * RENEW - */ - RENEW - } - private T holder; + @Getter private long evictionTimestamp; + @Getter private long registrationTimestamp; private long serviceUpTimestamp; @@ -50,17 +37,18 @@ public class Lease { /** * Make it volatile so that the expiration task would see this quicker */ + @Getter private volatile long lastUpdateTimestamp; private long duration; - public static final int DEFAULT_DURATION_IN_SECS = 90; + public static final long DEFAULT_DURATION_IN_SECS = 90 * 1000L; public Lease(T r) { holder = r; registrationTimestamp = System.currentTimeMillis(); lastUpdateTimestamp = registrationTimestamp; - duration = DEFAULT_DURATION_IN_SECS * 1000; + duration = DEFAULT_DURATION_IN_SECS; } public void renew() { @@ -91,18 +79,6 @@ public class Lease { return (evictionTimestamp > 0 || System.currentTimeMillis() > (lastUpdateTimestamp + additionalLeaseMs)); } - public long getRegistrationTimestamp() { - return registrationTimestamp; - } - - public long getLastRenewalTimestamp() { - return lastUpdateTimestamp; - } - - public long getEvictionTimestamp() { - return evictionTimestamp; - } - public long getServiceUpTimestamp() { return serviceUpTimestamp; } diff --git a/hippo4j-spring-boot/hippo4j-config-spring-boot-starter/pom.xml b/hippo4j-spring-boot/hippo4j-config-spring-boot-starter/pom.xml index abf69151..837a1f3b 100644 --- a/hippo4j-spring-boot/hippo4j-config-spring-boot-starter/pom.xml +++ b/hippo4j-spring-boot/hippo4j-config-spring-boot-starter/pom.xml @@ -22,6 +22,12 @@ cn.hippo4j hippo4j-core + ${revision} + + + cn.hippo4j + hippo4j-message + ${revision} com.alibaba.nacos @@ -39,21 +45,18 @@ com.ctrip.framework.apollo apollo-client ${apollo.version} - compile true org.apache.curator curator-framework ${curator-framework.version} - compile true io.etcd jetcd-core ${jetcd.version} - compile true @@ -104,6 +107,7 @@ cn.hippo4j hippo4j-adapter-base + ${revision} cn.hippo4j diff --git a/hippo4j-spring-boot/hippo4j-config-spring-boot-starter/src/main/java/cn/hippo4j/config/springboot/starter/config/DynamicThreadPoolAutoConfiguration.java b/hippo4j-spring-boot/hippo4j-config-spring-boot-starter/src/main/java/cn/hippo4j/config/springboot/starter/config/DynamicThreadPoolAutoConfiguration.java index b30b235c..6dcf8475 100644 --- a/hippo4j-spring-boot/hippo4j-config-spring-boot-starter/src/main/java/cn/hippo4j/config/springboot/starter/config/DynamicThreadPoolAutoConfiguration.java +++ b/hippo4j-spring-boot/hippo4j-config-spring-boot-starter/src/main/java/cn/hippo4j/config/springboot/starter/config/DynamicThreadPoolAutoConfiguration.java @@ -17,6 +17,8 @@ package cn.hippo4j.config.springboot.starter.config; +import cn.hippo4j.common.api.ThreadPoolCheckAlarm; +import cn.hippo4j.common.api.ThreadPoolConfigChange; import cn.hippo4j.common.config.ApplicationContextHolder; import cn.hippo4j.config.springboot.starter.monitor.ThreadPoolMonitorExecutor; import cn.hippo4j.config.springboot.starter.notify.CoreNotifyConfigBuilder; @@ -29,11 +31,12 @@ import cn.hippo4j.config.springboot.starter.support.DynamicThreadPoolConfigServi import cn.hippo4j.config.springboot.starter.support.DynamicThreadPoolPostProcessor; import cn.hippo4j.core.config.UtilAutoConfiguration; import cn.hippo4j.core.enable.MarkerConfiguration; -import cn.hippo4j.core.executor.ThreadPoolNotifyAlarmHandler; import cn.hippo4j.core.handler.DynamicThreadPoolBannerHandler; import cn.hippo4j.message.api.NotifyConfigBuilder; import cn.hippo4j.message.config.MessageConfiguration; import cn.hippo4j.message.service.AlarmControlHandler; +import cn.hippo4j.message.service.DefaultThreadPoolCheckAlarmHandler; +import cn.hippo4j.message.service.DefaultThreadPoolConfigChangeHandler; import cn.hippo4j.message.service.Hippo4jBaseSendMessageService; import cn.hippo4j.message.service.Hippo4jSendMessageService; import cn.hippo4j.springboot.starter.adapter.web.WebAdapterConfiguration; @@ -76,8 +79,15 @@ public class DynamicThreadPoolAutoConfiguration { } @Bean - public ThreadPoolNotifyAlarmHandler threadPoolNotifyAlarmHandler(Hippo4jSendMessageService hippo4jSendMessageService) { - return new ThreadPoolNotifyAlarmHandler(hippo4jSendMessageService); + @ConditionalOnMissingBean + public ThreadPoolCheckAlarm defaultThreadPoolCheckAlarmHandler(Hippo4jSendMessageService hippo4jSendMessageService) { + return new DefaultThreadPoolCheckAlarmHandler(hippo4jSendMessageService); + } + + @Bean + @ConditionalOnMissingBean + public ThreadPoolConfigChange defaultThreadPoolConfigChangeHandler(Hippo4jSendMessageService hippo4jSendMessageService) { + return new DefaultThreadPoolConfigChangeHandler(hippo4jSendMessageService); } @Bean @@ -92,10 +102,10 @@ public class DynamicThreadPoolAutoConfiguration { @Bean @SuppressWarnings("all") - public DynamicThreadPoolRefreshListener hippo4jExecutorsListener(ThreadPoolNotifyAlarmHandler threadPoolNotifyAlarmHandler, + public DynamicThreadPoolRefreshListener hippo4jExecutorsListener(ThreadPoolConfigChange threadPoolConfigChange, CoreNotifyConfigBuilder coreNotifyConfigBuilder, Hippo4jBaseSendMessageService hippoBaseSendMessageService) { - return new DynamicThreadPoolRefreshListener(threadPoolNotifyAlarmHandler, coreNotifyConfigBuilder, hippoBaseSendMessageService); + return new DynamicThreadPoolRefreshListener(threadPoolConfigChange, coreNotifyConfigBuilder, hippoBaseSendMessageService); } @Bean diff --git a/hippo4j-spring-boot/hippo4j-config-spring-boot-starter/src/main/java/cn/hippo4j/config/springboot/starter/monitor/ThreadPoolMonitorExecutor.java b/hippo4j-spring-boot/hippo4j-config-spring-boot-starter/src/main/java/cn/hippo4j/config/springboot/starter/monitor/ThreadPoolMonitorExecutor.java index 8d87c0c3..286db868 100644 --- a/hippo4j-spring-boot/hippo4j-config-spring-boot-starter/src/main/java/cn/hippo4j/config/springboot/starter/monitor/ThreadPoolMonitorExecutor.java +++ b/hippo4j-spring-boot/hippo4j-config-spring-boot-starter/src/main/java/cn/hippo4j/config/springboot/starter/monitor/ThreadPoolMonitorExecutor.java @@ -28,6 +28,7 @@ import cn.hippo4j.monitor.base.DynamicThreadPoolMonitor; import cn.hippo4j.monitor.base.ThreadPoolMonitor; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.DisposableBean; import org.springframework.boot.ApplicationArguments; import org.springframework.boot.ApplicationRunner; @@ -35,6 +36,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.List; +import java.util.Optional; import java.util.concurrent.ScheduledThreadPoolExecutor; import java.util.concurrent.TimeUnit; @@ -45,11 +47,11 @@ import static cn.hippo4j.core.executor.manage.GlobalThreadPoolManage.getThreadPo */ @Slf4j @RequiredArgsConstructor -public class ThreadPoolMonitorExecutor implements ApplicationRunner { +public class ThreadPoolMonitorExecutor implements ApplicationRunner, DisposableBean { private final BootstrapConfigProperties properties; - private ScheduledThreadPoolExecutor collectExecutor; + private ScheduledThreadPoolExecutor collectScheduledExecutor; private List threadPoolMonitors; @@ -64,7 +66,7 @@ public class ThreadPoolMonitorExecutor implements ApplicationRunner { } log.info("Start monitoring the running status of dynamic thread pool."); threadPoolMonitors = new ArrayList<>(); - collectExecutor = new ScheduledThreadPoolExecutor( + collectScheduledExecutor = new ScheduledThreadPoolExecutor( new Integer(1), ThreadFactoryBuilder.builder().daemon(true).prefix("client.scheduled.collect.data").build()); // Get dynamic thread pool monitoring component. @@ -74,7 +76,7 @@ public class ThreadPoolMonitorExecutor implements ApplicationRunner { DynamicThreadPoolServiceLoader.getSingletonServiceInstances(DynamicThreadPoolMonitor.class); dynamicThreadPoolMonitors.stream().filter(each -> collectTypes.contains(each.getType())).forEach(each -> threadPoolMonitors.add(each)); // Execute dynamic thread pool monitoring component. - collectExecutor.scheduleWithFixedDelay( + collectScheduledExecutor.scheduleWithFixedDelay( () -> scheduleRunnable(), properties.getInitialDelay(), properties.getCollectInterval(), @@ -93,4 +95,9 @@ public class ThreadPoolMonitorExecutor implements ApplicationRunner { } } } + + @Override + public void destroy() throws Exception { + Optional.ofNullable(collectScheduledExecutor).ifPresent(each -> each.shutdown()); + } } diff --git a/hippo4j-spring-boot/hippo4j-config-spring-boot-starter/src/main/java/cn/hippo4j/config/springboot/starter/refresher/ZookeeperRefresherHandler.java b/hippo4j-spring-boot/hippo4j-config-spring-boot-starter/src/main/java/cn/hippo4j/config/springboot/starter/refresher/ZookeeperRefresherHandler.java index 0f01b047..00f6e6e5 100644 --- a/hippo4j-spring-boot/hippo4j-config-spring-boot-starter/src/main/java/cn/hippo4j/config/springboot/starter/refresher/ZookeeperRefresherHandler.java +++ b/hippo4j-spring-boot/hippo4j-config-spring-boot-starter/src/main/java/cn/hippo4j/config/springboot/starter/refresher/ZookeeperRefresherHandler.java @@ -17,11 +17,7 @@ package cn.hippo4j.config.springboot.starter.refresher; -import java.nio.charset.StandardCharsets; -import java.util.List; -import java.util.Map; - -import cn.hippo4j.core.executor.manage.GlobalNotifyAlarmManage; +import cn.hippo4j.message.service.GlobalNotifyAlarmManage; import cn.hippo4j.message.service.ThreadPoolNotifyAlarm; import lombok.extern.slf4j.Slf4j; import org.apache.curator.framework.CuratorFramework; @@ -35,6 +31,10 @@ import org.apache.curator.retry.ExponentialBackoffRetry; import org.apache.curator.utils.ZKPaths; import org.apache.zookeeper.WatchedEvent; +import java.nio.charset.StandardCharsets; +import java.util.List; +import java.util.Map; + /** * Zookeeper refresher handler. */ diff --git a/hippo4j-spring-boot/hippo4j-config-spring-boot-starter/src/main/java/cn/hippo4j/config/springboot/starter/refresher/event/DynamicThreadPoolRefreshListener.java b/hippo4j-spring-boot/hippo4j-config-spring-boot-starter/src/main/java/cn/hippo4j/config/springboot/starter/refresher/event/DynamicThreadPoolRefreshListener.java index 8f1e4a3b..fe30533c 100644 --- a/hippo4j-spring-boot/hippo4j-config-spring-boot-starter/src/main/java/cn/hippo4j/config/springboot/starter/refresher/event/DynamicThreadPoolRefreshListener.java +++ b/hippo4j-spring-boot/hippo4j-config-spring-boot-starter/src/main/java/cn/hippo4j/config/springboot/starter/refresher/event/DynamicThreadPoolRefreshListener.java @@ -17,6 +17,7 @@ package cn.hippo4j.config.springboot.starter.refresher.event; +import cn.hippo4j.common.api.ThreadPoolConfigChange; import cn.hippo4j.common.executor.support.BlockingQueueTypeEnum; import cn.hippo4j.common.executor.support.RejectedPolicyTypeEnum; import cn.hippo4j.common.executor.support.ResizableCapacityLinkedBlockingQueue; @@ -26,18 +27,21 @@ import cn.hippo4j.config.springboot.starter.config.ExecutorProperties; import cn.hippo4j.config.springboot.starter.notify.CoreNotifyConfigBuilder; import cn.hippo4j.config.springboot.starter.support.GlobalCoreThreadPoolManage; import cn.hippo4j.core.executor.DynamicThreadPoolExecutor; -import cn.hippo4j.core.executor.ThreadPoolNotifyAlarmHandler; -import cn.hippo4j.core.executor.manage.GlobalNotifyAlarmManage; import cn.hippo4j.core.executor.manage.GlobalThreadPoolManage; import cn.hippo4j.message.dto.NotifyConfigDTO; import cn.hippo4j.message.request.ChangeParameterNotifyRequest; +import cn.hippo4j.message.service.GlobalNotifyAlarmManage; import cn.hippo4j.message.service.Hippo4jBaseSendMessageService; import cn.hippo4j.message.service.ThreadPoolNotifyAlarm; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.core.annotation.Order; -import java.util.*; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Optional; import java.util.concurrent.RejectedExecutionHandler; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; @@ -54,7 +58,7 @@ import static cn.hippo4j.config.springboot.starter.refresher.event.Hippo4jConfig @Order(EXECUTORS_LISTENER) public class DynamicThreadPoolRefreshListener extends AbstractRefreshListener { - private final ThreadPoolNotifyAlarmHandler threadPoolNotifyAlarmHandler; + private final ThreadPoolConfigChange threadPoolConfigChange; private final CoreNotifyConfigBuilder coreNotifyConfigBuilder; @@ -95,7 +99,7 @@ public class DynamicThreadPoolRefreshListener extends AbstractRefreshListener new RuntimeException("The thread pool id does not exist in the configuration.")); try { - newDynamicPoolExecutor = buildNewDynamicThreadPool(executorProperties); + threadPoolParamReplace(executor, executorProperties); } catch (Exception ex) { - log.error("Failed to initialize thread pool configuration. error: {}", ex); + log.error("Failed to initialize thread pool configuration.", ex); } finally { - if (Objects.isNull(dynamicThreadPoolWrapper.getExecutor())) { - dynamicThreadPoolWrapper.setExecutor(CommonDynamicThreadPoolProviderFactory.getInstance(threadPoolId)); - } dynamicThreadPoolWrapper.setInitFlag(Boolean.TRUE); } ThreadPoolNotifyAlarm threadPoolNotifyAlarm = buildThreadPoolNotifyAlarm(executorProperties); GlobalNotifyAlarmManage.put(threadPoolId, threadPoolNotifyAlarm); - DynamicThreadPoolExecutor actualDynamicThreadPoolExecutor = (DynamicThreadPoolExecutor) dynamicThreadPoolWrapper.getExecutor(); - TaskDecorator taskDecorator = actualDynamicThreadPoolExecutor.getTaskDecorator(); - ((DynamicThreadPoolExecutor) newDynamicPoolExecutor).setTaskDecorator(taskDecorator); - long awaitTerminationMillis = actualDynamicThreadPoolExecutor.getAwaitTerminationMillis(); - boolean waitForTasksToCompleteOnShutdown = actualDynamicThreadPoolExecutor.isWaitForTasksToCompleteOnShutdown(); - ((DynamicThreadPoolExecutor) newDynamicPoolExecutor).setSupportParam(awaitTerminationMillis, waitForTasksToCompleteOnShutdown); - dynamicThreadPoolWrapper.setExecutor(newDynamicPoolExecutor); } GlobalThreadPoolManage.registerPool(dynamicThreadPoolWrapper.getThreadPoolId(), dynamicThreadPoolWrapper); GlobalCoreThreadPoolManage.register( threadPoolId, executorProperties == null - ? buildExecutorProperties(threadPoolId, newDynamicPoolExecutor) + ? buildDefaultExecutorProperties(threadPoolId, executor) : buildActualExecutorProperties(executorProperties)); - return newDynamicPoolExecutor; + return executor; } + /** + * Build actual executor properties. + * + * @param executorProperties executor properties + * @return executor properties + */ private ExecutorProperties buildActualExecutorProperties(ExecutorProperties executorProperties) { return Optional.ofNullable(configProperties.getDefaultExecutor()).map(each -> buildExecutorProperties(executorProperties)).orElse(executorProperties); } - private ExecutorProperties buildExecutorProperties(String threadPoolId, ThreadPoolExecutor executor) { + /** + * Build default executor properties. + * + * @param threadPoolId thread-pool id + * @param executor dynamic thread-pool executor + * @return executor properties + */ + private ExecutorProperties buildDefaultExecutorProperties(String threadPoolId, ThreadPoolExecutor executor) { ExecutorProperties executorProperties = new ExecutorProperties(); BlockingQueue blockingQueue = executor.getQueue(); int queueSize = blockingQueue.size(); @@ -160,23 +161,32 @@ public final class DynamicThreadPoolPostProcessor implements BeanPostProcessor { return executorProperties; } - private ThreadPoolExecutor buildNewDynamicThreadPool(ExecutorProperties executorProperties) { - String threadNamePrefix = executorProperties.getThreadNamePrefix(); - ExecutorProperties newExecutorProperties = buildExecutorProperties(executorProperties); - ThreadPoolExecutor newDynamicPoolExecutor = ThreadPoolBuilder.builder() - .threadPoolId(executorProperties.getThreadPoolId()) - .threadFactory(StringUtil.isNotBlank(threadNamePrefix) ? threadNamePrefix : executorProperties.getThreadPoolId()) - .poolThreadSize(newExecutorProperties.getCorePoolSize(), newExecutorProperties.getMaximumPoolSize()) - .workQueue(BlockingQueueTypeEnum.createBlockingQueue(newExecutorProperties.getBlockingQueue(), newExecutorProperties.getQueueCapacity())) - .executeTimeOut(newExecutorProperties.getExecuteTimeOut()) - .keepAliveTime(newExecutorProperties.getKeepAliveTime(), TimeUnit.SECONDS) - .rejected(RejectedPolicyTypeEnum.createPolicy(newExecutorProperties.getRejectedHandler())) - .allowCoreThreadTimeOut(newExecutorProperties.getAllowCoreThreadTimeOut()) - .dynamicPool() - .build(); - return newDynamicPoolExecutor; + /** + * Thread-pool param replace. + * + * @param executor dynamic thread-pool executor + * @param executorProperties executor properties + */ + private void threadPoolParamReplace(ThreadPoolExecutor executor, ExecutorProperties executorProperties) { + BlockingQueue workQueue = BlockingQueueTypeEnum.createBlockingQueue(executorProperties.getBlockingQueue(), executorProperties.getQueueCapacity()); + ReflectUtil.setFieldValue(executor, "workQueue", workQueue); + executor.setCorePoolSize(executorProperties.getCorePoolSize()); + executor.setMaximumPoolSize(executorProperties.getMaximumPoolSize()); + executor.setKeepAliveTime(executorProperties.getKeepAliveTime(), TimeUnit.SECONDS); + executor.allowCoreThreadTimeOut(executorProperties.getAllowCoreThreadTimeOut()); + executor.setRejectedExecutionHandler(RejectedPolicyTypeEnum.createPolicy(executorProperties.getRejectedHandler())); + if (executor instanceof DynamicThreadPoolExecutor) { + Optional.ofNullable(executorProperties.getExecuteTimeOut()) + .ifPresent(executeTimeOut -> ((DynamicThreadPoolExecutor) executor).setExecuteTimeOut(executeTimeOut)); + } } + /** + * Build executor properties. + * + * @param executorProperties executor properties + * @return executor properties + */ private ExecutorProperties buildExecutorProperties(ExecutorProperties executorProperties) { ExecutorProperties newExecutorProperties = ExecutorProperties.builder() .corePoolSize(Optional.ofNullable(executorProperties.getCorePoolSize()) @@ -201,6 +211,12 @@ public final class DynamicThreadPoolPostProcessor implements BeanPostProcessor { return newExecutorProperties; } + /** + * Build thread-pool notify alarm + * + * @param executorProperties executor properties + * @return thread-pool notify alarm + */ private ThreadPoolNotifyAlarm buildThreadPoolNotifyAlarm(ExecutorProperties executorProperties) { DynamicThreadPoolNotifyProperties notify = Optional.ofNullable(executorProperties).map(ExecutorProperties::getNotify).orElse(null); boolean isAlarm = Optional.ofNullable(executorProperties.getAlarm()) diff --git a/hippo4j-spring-boot/hippo4j-spring-boot-starter-adapter/hippo4j-spring-boot-starter-adapter-kafka/pom.xml b/hippo4j-spring-boot/hippo4j-spring-boot-starter-adapter/hippo4j-spring-boot-starter-adapter-kafka/pom.xml deleted file mode 100644 index 85b4f49d..00000000 --- a/hippo4j-spring-boot/hippo4j-spring-boot-starter-adapter/hippo4j-spring-boot-starter-adapter-kafka/pom.xml +++ /dev/null @@ -1,19 +0,0 @@ - - - 4.0.0 - - cn.hippo4j - hippo4j-spring-boot-starter-adapter - ${revision} - - hippo4j-spring-boot-starter-adapter-kafka - - - - cn.hippo4j - hippo4j-adapter-kafka - ${revision} - - - diff --git a/hippo4j-spring-boot/hippo4j-spring-boot-starter-adapter/hippo4j-spring-boot-starter-adapter-kafka/src/main/java/cn/hippo4j/springboot/starter/adapter/kafka/KafkaAdapterAutoConfiguration.java b/hippo4j-spring-boot/hippo4j-spring-boot-starter-adapter/hippo4j-spring-boot-starter-adapter-kafka/src/main/java/cn/hippo4j/springboot/starter/adapter/kafka/KafkaAdapterAutoConfiguration.java deleted file mode 100644 index b362f0b4..00000000 --- a/hippo4j-spring-boot/hippo4j-spring-boot-starter-adapter/hippo4j-spring-boot-starter-adapter-kafka/src/main/java/cn/hippo4j/springboot/starter/adapter/kafka/KafkaAdapterAutoConfiguration.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package cn.hippo4j.springboot.starter.adapter.kafka; - -import cn.hippo4j.adapter.kafka.KafkaThreadPoolAdapter; -import cn.hippo4j.common.config.ApplicationContextHolder; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - -/** - * Kafka adapter auto configuration. - */ -@Configuration -public class KafkaAdapterAutoConfiguration { - - @Bean - @ConditionalOnMissingBean - public ApplicationContextHolder simpleApplicationContextHolder() { - return new ApplicationContextHolder(); - } - - @Bean - @SuppressWarnings("all") - @ConditionalOnProperty(name = "spring.kafka.bootstrap-servers") - public KafkaThreadPoolAdapter kafkaMQThreadPoolAdapter(ApplicationContextHolder applicationContextHolder) { - return new KafkaThreadPoolAdapter(); - } -} diff --git a/hippo4j-spring-boot/hippo4j-spring-boot-starter-adapter/hippo4j-spring-boot-starter-adapter-kafka/src/main/resources/META-INF/spring.factories b/hippo4j-spring-boot/hippo4j-spring-boot-starter-adapter/hippo4j-spring-boot-starter-adapter-kafka/src/main/resources/META-INF/spring.factories deleted file mode 100644 index 592fba93..00000000 --- a/hippo4j-spring-boot/hippo4j-spring-boot-starter-adapter/hippo4j-spring-boot-starter-adapter-kafka/src/main/resources/META-INF/spring.factories +++ /dev/null @@ -1 +0,0 @@ -org.springframework.boot.autoconfigure.EnableAutoConfiguration=cn.hippo4j.springboot.starter.adapter.kafka.KafkaAdapterAutoConfiguration diff --git a/hippo4j-spring-boot/hippo4j-spring-boot-starter-adapter/hippo4j-spring-boot-starter-adapter-rabbitmq/pom.xml b/hippo4j-spring-boot/hippo4j-spring-boot-starter-adapter/hippo4j-spring-boot-starter-adapter-rabbitmq/pom.xml index ef170472..0ca029cc 100644 --- a/hippo4j-spring-boot/hippo4j-spring-boot-starter-adapter/hippo4j-spring-boot-starter-adapter-rabbitmq/pom.xml +++ b/hippo4j-spring-boot/hippo4j-spring-boot-starter-adapter/hippo4j-spring-boot-starter-adapter-rabbitmq/pom.xml @@ -15,5 +15,10 @@ hippo4j-adapter-rabbitmq ${revision} + + org.springframework.boot + spring-boot-starter-amqp + true + diff --git a/hippo4j-spring-boot/hippo4j-spring-boot-starter-adapter/hippo4j-spring-boot-starter-adapter-spring-cloud-stream-kafka/pom.xml b/hippo4j-spring-boot/hippo4j-spring-boot-starter-adapter/hippo4j-spring-boot-starter-adapter-spring-cloud-stream-kafka/pom.xml deleted file mode 100644 index 85d57b0c..00000000 --- a/hippo4j-spring-boot/hippo4j-spring-boot-starter-adapter/hippo4j-spring-boot-starter-adapter-spring-cloud-stream-kafka/pom.xml +++ /dev/null @@ -1,19 +0,0 @@ - - - 4.0.0 - - cn.hippo4j - hippo4j-spring-boot-starter-adapter - ${revision} - - hippo4j-spring-boot-starter-adapter-spring-cloud-stream-kafka - - - - cn.hippo4j - hippo4j-adapter-spring-cloud-stream-kafka - ${revision} - - - diff --git a/hippo4j-spring-boot/hippo4j-spring-boot-starter-adapter/hippo4j-spring-boot-starter-adapter-spring-cloud-stream-kafka/src/main/java/cn/hippo4j/springboot/starter/adapter/springcloud/stream/kafka/SpringCloudStreamKafkaAdapterAutoConfiguration.java b/hippo4j-spring-boot/hippo4j-spring-boot-starter-adapter/hippo4j-spring-boot-starter-adapter-spring-cloud-stream-kafka/src/main/java/cn/hippo4j/springboot/starter/adapter/springcloud/stream/kafka/SpringCloudStreamKafkaAdapterAutoConfiguration.java deleted file mode 100644 index cc8ddb6e..00000000 --- a/hippo4j-spring-boot/hippo4j-spring-boot-starter-adapter/hippo4j-spring-boot-starter-adapter-spring-cloud-stream-kafka/src/main/java/cn/hippo4j/springboot/starter/adapter/springcloud/stream/kafka/SpringCloudStreamKafkaAdapterAutoConfiguration.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package cn.hippo4j.springboot.starter.adapter.springcloud.stream.kafka; - -import cn.hippo4j.adapter.springcloud.stream.kafka.SpringCloudStreamKafkaThreadPoolAdapter; -import cn.hippo4j.common.config.ApplicationContextHolder; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - -/** - * Spring cloud stream kafka adapter auto configuration. - */ -@Configuration -public class SpringCloudStreamKafkaAdapterAutoConfiguration { - - @Bean - @ConditionalOnMissingBean - public ApplicationContextHolder simpleApplicationContextHolder() { - return new ApplicationContextHolder(); - } - - @Bean - @SuppressWarnings("all") - @ConditionalOnProperty(name = "xxx") - public SpringCloudStreamKafkaThreadPoolAdapter springCloudStreamKafkaThreadPoolAdapter(ApplicationContextHolder applicationContextHolder) { - return new SpringCloudStreamKafkaThreadPoolAdapter(); - } -} diff --git a/hippo4j-spring-boot/hippo4j-spring-boot-starter-adapter/hippo4j-spring-boot-starter-adapter-spring-cloud-stream-kafka/src/main/resources/META-INF/spring.factories b/hippo4j-spring-boot/hippo4j-spring-boot-starter-adapter/hippo4j-spring-boot-starter-adapter-spring-cloud-stream-kafka/src/main/resources/META-INF/spring.factories deleted file mode 100644 index 065332d1..00000000 --- a/hippo4j-spring-boot/hippo4j-spring-boot-starter-adapter/hippo4j-spring-boot-starter-adapter-spring-cloud-stream-kafka/src/main/resources/META-INF/spring.factories +++ /dev/null @@ -1 +0,0 @@ -org.springframework.boot.autoconfigure.EnableAutoConfiguration=cn.hippo4j.springboot.starter.adapter.springcloud.stream.kafka.SpringCloudStreamKafkaAdapterAutoConfiguration diff --git a/hippo4j-spring-boot/hippo4j-spring-boot-starter-adapter/hippo4j-spring-boot-starter-adapter-spring-cloud-stream-rabbitmq/pom.xml b/hippo4j-spring-boot/hippo4j-spring-boot-starter-adapter/hippo4j-spring-boot-starter-adapter-spring-cloud-stream-rabbitmq/pom.xml index c6a049fc..c2d58f96 100644 --- a/hippo4j-spring-boot/hippo4j-spring-boot-starter-adapter/hippo4j-spring-boot-starter-adapter-spring-cloud-stream-rabbitmq/pom.xml +++ b/hippo4j-spring-boot/hippo4j-spring-boot-starter-adapter/hippo4j-spring-boot-starter-adapter-spring-cloud-stream-rabbitmq/pom.xml @@ -15,5 +15,11 @@ hippo4j-adapter-spring-cloud-stream-rabbitmq ${revision} + + org.springframework.cloud + spring-cloud-starter-stream-rabbit + ${spring-cloud-starter-stream-rabbitmq.version} + true + diff --git a/hippo4j-spring-boot/hippo4j-spring-boot-starter-adapter/pom.xml b/hippo4j-spring-boot/hippo4j-spring-boot-starter-adapter/pom.xml index 337ef55b..258c092e 100644 --- a/hippo4j-spring-boot/hippo4j-spring-boot-starter-adapter/pom.xml +++ b/hippo4j-spring-boot/hippo4j-spring-boot-starter-adapter/pom.xml @@ -14,11 +14,9 @@ hippo4j-spring-boot-starter-adapter-all hippo4j-spring-boot-starter-adapter-dubbo hippo4j-spring-boot-starter-adapter-alibaba-dubbo - hippo4j-spring-boot-starter-adapter-kafka hippo4j-spring-boot-starter-adapter-rabbitmq hippo4j-spring-boot-starter-adapter-rocketmq hippo4j-spring-boot-starter-adapter-hystrix - hippo4j-spring-boot-starter-adapter-spring-cloud-stream-kafka hippo4j-spring-boot-starter-adapter-spring-cloud-stream-rocketmq hippo4j-spring-boot-starter-adapter-spring-cloud-stream-rabbitmq hippo4j-spring-boot-starter-adapter-web diff --git a/hippo4j-spring-boot/hippo4j-spring-boot-starter/pom.xml b/hippo4j-spring-boot/hippo4j-spring-boot-starter/pom.xml index 70131d65..5de5c2ee 100644 --- a/hippo4j-spring-boot/hippo4j-spring-boot-starter/pom.xml +++ b/hippo4j-spring-boot/hippo4j-spring-boot-starter/pom.xml @@ -21,12 +21,18 @@ cn.hippo4j hippo4j-core + ${revision} cn.hippo4j hippo4j-common ${revision} + + cn.hippo4j + hippo4j-message + ${revision} + org.springframework.boot spring-boot-configuration-processor @@ -36,39 +42,25 @@ org.projectlombok lombok - - com.aliyun - alibaba-dingtalk-service-sdk - - - - log4j - log4j - - - org.springframework.boot spring-boot-starter-tomcat - compile true org.springframework.boot spring-boot-starter-jetty - compile true org.springframework.boot spring-boot-starter-undertow - compile true cn.hippo4j hippo4j-adapter-base + ${revision} io.netty diff --git a/hippo4j-spring-boot/hippo4j-spring-boot-starter/src/main/java/cn/hippo4j/springboot/starter/config/DynamicThreadPoolAutoConfiguration.java b/hippo4j-spring-boot/hippo4j-spring-boot-starter/src/main/java/cn/hippo4j/springboot/starter/config/DynamicThreadPoolAutoConfiguration.java index b950b423..5c1dee41 100644 --- a/hippo4j-spring-boot/hippo4j-spring-boot-starter/src/main/java/cn/hippo4j/springboot/starter/config/DynamicThreadPoolAutoConfiguration.java +++ b/hippo4j-spring-boot/hippo4j-spring-boot-starter/src/main/java/cn/hippo4j/springboot/starter/config/DynamicThreadPoolAutoConfiguration.java @@ -20,11 +20,12 @@ package cn.hippo4j.springboot.starter.config; import cn.hippo4j.adapter.base.ThreadPoolAdapterBeanContainer; import cn.hippo4j.adapter.web.WebThreadPoolHandlerChoose; import cn.hippo4j.common.api.ThreadDetailState; +import cn.hippo4j.common.api.ThreadPoolCheckAlarm; +import cn.hippo4j.common.api.ThreadPoolConfigChange; import cn.hippo4j.common.api.ThreadPoolDynamicRefresh; import cn.hippo4j.common.config.ApplicationContextHolder; import cn.hippo4j.core.config.UtilAutoConfiguration; import cn.hippo4j.core.enable.MarkerConfiguration; -import cn.hippo4j.core.executor.ThreadPoolNotifyAlarmHandler; import cn.hippo4j.core.executor.state.ThreadPoolRunStateHandler; import cn.hippo4j.core.executor.support.service.DynamicThreadPoolService; import cn.hippo4j.core.handler.DynamicThreadPoolBannerHandler; @@ -33,6 +34,8 @@ import cn.hippo4j.core.toolkit.inet.InetUtils; import cn.hippo4j.message.api.NotifyConfigBuilder; import cn.hippo4j.message.config.MessageConfiguration; import cn.hippo4j.message.service.AlarmControlHandler; +import cn.hippo4j.message.service.DefaultThreadPoolCheckAlarmHandler; +import cn.hippo4j.message.service.DefaultThreadPoolConfigChangeHandler; import cn.hippo4j.message.service.Hippo4jBaseSendMessageService; import cn.hippo4j.message.service.Hippo4jSendMessageService; import cn.hippo4j.springboot.starter.adapter.web.WebAdapterConfiguration; @@ -56,6 +59,7 @@ import cn.hippo4j.springboot.starter.remote.ServerHealthCheck; import cn.hippo4j.springboot.starter.remote.ServerHttpAgent; import cn.hippo4j.springboot.starter.support.DynamicThreadPoolConfigService; import cn.hippo4j.springboot.starter.support.DynamicThreadPoolPostProcessor; +import cn.hippo4j.springboot.starter.support.ThreadPoolPluginRegisterPostProcessor; import lombok.AllArgsConstructor; import org.springframework.boot.autoconfigure.ImportAutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; @@ -195,8 +199,20 @@ public class DynamicThreadPoolAutoConfiguration { } @Bean - public ThreadPoolDynamicRefresh threadPoolDynamicRefresh(ThreadPoolNotifyAlarmHandler threadPoolNotifyAlarmHandler) { - return new ServerThreadPoolDynamicRefresh(threadPoolNotifyAlarmHandler); + @ConditionalOnMissingBean + public ThreadPoolCheckAlarm defaultThreadPoolCheckAlarmHandler(Hippo4jSendMessageService hippo4jSendMessageService) { + return new DefaultThreadPoolCheckAlarmHandler(hippo4jSendMessageService); + } + + @Bean + @ConditionalOnMissingBean + public ThreadPoolConfigChange defaultThreadPoolConfigChangeHandler(Hippo4jSendMessageService hippo4jSendMessageService) { + return new DefaultThreadPoolConfigChangeHandler(hippo4jSendMessageService); + } + + @Bean + public ThreadPoolDynamicRefresh threadPoolDynamicRefresh(ThreadPoolConfigChange threadPoolConfigChange) { + return new ServerThreadPoolDynamicRefresh(threadPoolConfigChange); } @Bean @@ -206,12 +222,13 @@ public class DynamicThreadPoolAutoConfiguration { } @Bean - public ThreadPoolNotifyAlarmHandler threadPoolNotifyAlarmHandler(Hippo4jSendMessageService hippo4jSendMessageService) { - return new ThreadPoolNotifyAlarmHandler(hippo4jSendMessageService); + public HttpAgent httpAgent(BootstrapProperties properties) { + return new ServerHttpAgent(properties); } @Bean - public HttpAgent httpAgent(BootstrapProperties properties) { - return new ServerHttpAgent(properties); + public ThreadPoolPluginRegisterPostProcessor threadPoolPluginRegisterPostProcessor() { + return new ThreadPoolPluginRegisterPostProcessor(); } + } diff --git a/hippo4j-spring-boot/hippo4j-spring-boot-starter/src/main/java/cn/hippo4j/springboot/starter/core/ServerThreadPoolDynamicRefresh.java b/hippo4j-spring-boot/hippo4j-spring-boot-starter/src/main/java/cn/hippo4j/springboot/starter/core/ServerThreadPoolDynamicRefresh.java index 55e93559..0b9ba60d 100644 --- a/hippo4j-spring-boot/hippo4j-spring-boot-starter/src/main/java/cn/hippo4j/springboot/starter/core/ServerThreadPoolDynamicRefresh.java +++ b/hippo4j-spring-boot/hippo4j-spring-boot-starter/src/main/java/cn/hippo4j/springboot/starter/core/ServerThreadPoolDynamicRefresh.java @@ -17,6 +17,7 @@ package cn.hippo4j.springboot.starter.core; +import cn.hippo4j.common.api.ThreadPoolConfigChange; import cn.hippo4j.common.api.ThreadPoolDynamicRefresh; import cn.hippo4j.common.enums.EnableEnum; import cn.hippo4j.common.executor.support.BlockingQueueTypeEnum; @@ -26,7 +27,6 @@ import cn.hippo4j.common.model.ThreadPoolParameter; import cn.hippo4j.common.model.ThreadPoolParameterInfo; import cn.hippo4j.common.toolkit.JSONUtil; import cn.hippo4j.core.executor.DynamicThreadPoolExecutor; -import cn.hippo4j.core.executor.ThreadPoolNotifyAlarmHandler; import cn.hippo4j.core.executor.manage.GlobalThreadPoolManage; import cn.hippo4j.message.request.ChangeParameterNotifyRequest; import lombok.AllArgsConstructor; @@ -48,7 +48,7 @@ import static cn.hippo4j.common.constant.ChangeThreadPoolConstants.CHANGE_THREAD @AllArgsConstructor public class ServerThreadPoolDynamicRefresh implements ThreadPoolDynamicRefresh { - private final ThreadPoolNotifyAlarmHandler threadPoolNotifyAlarmHandler; + private final ThreadPoolConfigChange threadPoolConfigChange; @Override public void dynamicRefresh(String content) { @@ -95,7 +95,7 @@ public class ServerThreadPoolDynamicRefresh implements ThreadPoolDynamicRefresh .nowExecuteTimeOut(executeTimeOut) .build(); changeNotifyRequest.setThreadPoolId(threadPoolId); - threadPoolNotifyAlarmHandler.sendPoolConfigChange(changeNotifyRequest); + threadPoolConfigChange.sendPoolConfigChange(changeNotifyRequest); log.info(CHANGE_THREAD_POOL_TEXT, threadPoolId, String.format(CHANGE_DELIMITER, originalCoreSize, afterExecutor.getCorePoolSize()), diff --git a/hippo4j-spring-boot/hippo4j-spring-boot-starter/src/main/java/cn/hippo4j/springboot/starter/support/DynamicThreadPoolConfigService.java b/hippo4j-spring-boot/hippo4j-spring-boot-starter/src/main/java/cn/hippo4j/springboot/starter/support/DynamicThreadPoolConfigService.java index 96e8d717..663b07dc 100644 --- a/hippo4j-spring-boot/hippo4j-spring-boot-starter/src/main/java/cn/hippo4j/springboot/starter/support/DynamicThreadPoolConfigService.java +++ b/hippo4j-spring-boot/hippo4j-spring-boot-starter/src/main/java/cn/hippo4j/springboot/starter/support/DynamicThreadPoolConfigService.java @@ -27,21 +27,18 @@ import cn.hippo4j.common.toolkit.JSONUtil; import cn.hippo4j.common.web.base.Result; import cn.hippo4j.common.web.exception.ServiceException; import cn.hippo4j.core.executor.DynamicThreadPoolWrapper; -import cn.hippo4j.core.executor.manage.GlobalNotifyAlarmManage; import cn.hippo4j.core.executor.manage.GlobalThreadPoolManage; import cn.hippo4j.core.executor.support.service.AbstractDynamicThreadPoolService; import cn.hippo4j.message.dto.NotifyConfigDTO; +import cn.hippo4j.message.service.GlobalNotifyAlarmManage; import cn.hippo4j.message.service.Hippo4jBaseSendMessageService; import cn.hippo4j.message.service.ThreadPoolNotifyAlarm; import cn.hippo4j.springboot.starter.config.BootstrapProperties; -import cn.hippo4j.springboot.starter.core.ClientWorker; import cn.hippo4j.springboot.starter.core.DynamicThreadPoolSubscribeConfig; -import cn.hippo4j.springboot.starter.event.ApplicationRefreshedEvent; import cn.hippo4j.springboot.starter.notify.ServerNotifyConfigBuilder; import cn.hippo4j.springboot.starter.remote.HttpAgent; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; -import org.springframework.context.ApplicationListener; import java.util.List; import java.util.Map; @@ -76,7 +73,7 @@ public class DynamicThreadPoolConfigService extends AbstractDynamicThreadPoolSer } private ThreadPoolExecutor registerExecutor(DynamicThreadPoolRegisterWrapper registerWrapper) { - DynamicThreadPoolRegisterParameter registerParameter = registerWrapper.getDynamicThreadPoolRegisterParameter(); + DynamicThreadPoolRegisterParameter registerParameter = registerWrapper.getParameter(); checkThreadPoolParameter(registerParameter); String threadPoolId = registerParameter.getThreadPoolId(); try { @@ -101,11 +98,11 @@ public class DynamicThreadPoolConfigService extends AbstractDynamicThreadPoolSer } private void subscribeConfig(DynamicThreadPoolRegisterWrapper registerWrapper) { - dynamicThreadPoolSubscribeConfig.subscribeConfig(registerWrapper.getDynamicThreadPoolRegisterParameter().getThreadPoolId()); + dynamicThreadPoolSubscribeConfig.subscribeConfig(registerWrapper.getParameter().getThreadPoolId()); } private void putNotifyAlarmConfig(DynamicThreadPoolRegisterWrapper registerWrapper) { - DynamicThreadPoolRegisterParameter registerParameter = registerWrapper.getDynamicThreadPoolRegisterParameter(); + DynamicThreadPoolRegisterParameter registerParameter = registerWrapper.getParameter(); ThreadPoolNotifyAlarm threadPoolNotifyAlarm = new ThreadPoolNotifyAlarm( BooleanUtil.toBoolean(String.valueOf(registerParameter.getIsAlarm())), registerParameter.getActiveAlarm(), diff --git a/hippo4j-spring-boot/hippo4j-spring-boot-starter/src/main/java/cn/hippo4j/springboot/starter/support/DynamicThreadPoolPostProcessor.java b/hippo4j-spring-boot/hippo4j-spring-boot-starter/src/main/java/cn/hippo4j/springboot/starter/support/DynamicThreadPoolPostProcessor.java index 0d3006d8..62bbe59b 100644 --- a/hippo4j-spring-boot/hippo4j-spring-boot-starter/src/main/java/cn/hippo4j/springboot/starter/support/DynamicThreadPoolPostProcessor.java +++ b/hippo4j-spring-boot/hippo4j-spring-boot-starter/src/main/java/cn/hippo4j/springboot/starter/support/DynamicThreadPoolPostProcessor.java @@ -27,16 +27,15 @@ import cn.hippo4j.common.model.register.DynamicThreadPoolRegisterParameter; import cn.hippo4j.common.model.register.DynamicThreadPoolRegisterWrapper; import cn.hippo4j.common.toolkit.BooleanUtil; import cn.hippo4j.common.toolkit.JSONUtil; +import cn.hippo4j.common.toolkit.ReflectUtil; import cn.hippo4j.common.web.base.Result; import cn.hippo4j.core.executor.DynamicThreadPool; import cn.hippo4j.core.executor.DynamicThreadPoolExecutor; import cn.hippo4j.core.executor.DynamicThreadPoolWrapper; -import cn.hippo4j.core.executor.manage.GlobalNotifyAlarmManage; import cn.hippo4j.core.executor.manage.GlobalThreadPoolManage; -import cn.hippo4j.core.executor.support.ThreadPoolBuilder; import cn.hippo4j.core.executor.support.adpter.DynamicThreadPoolAdapterChoose; -import cn.hippo4j.core.provider.CommonDynamicThreadPoolProviderFactory; import cn.hippo4j.core.toolkit.DynamicThreadPoolAnnotationUtil; +import cn.hippo4j.message.service.GlobalNotifyAlarmManage; import cn.hippo4j.message.service.ThreadPoolNotifyAlarm; import cn.hippo4j.springboot.starter.config.BootstrapProperties; import cn.hippo4j.springboot.starter.core.DynamicThreadPoolSubscribeConfig; @@ -45,7 +44,6 @@ import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.BeansException; import org.springframework.beans.factory.config.BeanPostProcessor; -import org.springframework.core.task.TaskDecorator; import java.util.HashMap; import java.util.Map; @@ -114,7 +112,7 @@ public final class DynamicThreadPoolPostProcessor implements BeanPostProcessor { /** * Register and subscribe. * - * @param dynamicThreadPoolWrapper + * @param dynamicThreadPoolWrapper dynamic thread-pool wrapper */ protected void registerAndSubscribe(DynamicThreadPoolWrapper dynamicThreadPoolWrapper) { fillPoolAndRegister(dynamicThreadPoolWrapper); @@ -124,7 +122,7 @@ public final class DynamicThreadPoolPostProcessor implements BeanPostProcessor { /** * Fill the thread pool and register. * - * @param dynamicThreadPoolWrapper + * @param dynamicThreadPoolWrapper dynamic thread-pool wrapper */ protected ThreadPoolExecutor fillPoolAndRegister(DynamicThreadPoolWrapper dynamicThreadPoolWrapper) { String threadPoolId = dynamicThreadPoolWrapper.getThreadPoolId(); @@ -133,42 +131,14 @@ public final class DynamicThreadPoolPostProcessor implements BeanPostProcessor { queryStrMap.put(TP_ID, threadPoolId); queryStrMap.put(ITEM_ID, properties.getItemId()); queryStrMap.put(NAMESPACE, properties.getNamespace()); - ThreadPoolExecutor newDynamicThreadPoolExecutor = null; ThreadPoolParameterInfo threadPoolParameterInfo = new ThreadPoolParameterInfo(); try { Result result = httpAgent.httpGetByConfig(Constants.CONFIG_CONTROLLER_PATH, null, queryStrMap, 5000L); if (result.isSuccess() && result.getData() != null) { String resultJsonStr = JSONUtil.toJSONString(result.getData()); if ((threadPoolParameterInfo = JSONUtil.parseObject(resultJsonStr, ThreadPoolParameterInfo.class)) != null) { - // Create a thread pool with relevant parameters. - BlockingQueue workQueue = BlockingQueueTypeEnum.createBlockingQueue(threadPoolParameterInfo.getQueueType(), threadPoolParameterInfo.getCapacity()); - newDynamicThreadPoolExecutor = ThreadPoolBuilder.builder() - .dynamicPool() - .threadPoolId(threadPoolId) - .workQueue(workQueue) - .threadFactory(executor.getThreadFactory()) - .poolThreadSize(threadPoolParameterInfo.corePoolSizeAdapt(), threadPoolParameterInfo.maximumPoolSizeAdapt()) - .keepAliveTime(threadPoolParameterInfo.getKeepAliveTime(), TimeUnit.SECONDS) - .rejected(RejectedPolicyTypeEnum.createPolicy(threadPoolParameterInfo.getRejectedType())) - .allowCoreThreadTimeOut(EnableEnum.getBool(threadPoolParameterInfo.getAllowCoreThreadTimeOut())) - .build(); - // Set dynamic thread pool enhancement parameters. - if (executor instanceof DynamicThreadPoolExecutor) { - ThreadPoolNotifyAlarm threadPoolNotifyAlarm = new ThreadPoolNotifyAlarm( - BooleanUtil.toBoolean(threadPoolParameterInfo.getIsAlarm().toString()), - threadPoolParameterInfo.getLivenessAlarm(), - threadPoolParameterInfo.getCapacityAlarm()); - GlobalNotifyAlarmManage.put(threadPoolId, threadPoolNotifyAlarm); - TaskDecorator taskDecorator = ((DynamicThreadPoolExecutor) executor).getTaskDecorator(); - ((DynamicThreadPoolExecutor) newDynamicThreadPoolExecutor).setTaskDecorator(taskDecorator); - long awaitTerminationMillis = ((DynamicThreadPoolExecutor) executor).getAwaitTerminationMillis(); - boolean waitForTasksToCompleteOnShutdown = ((DynamicThreadPoolExecutor) executor).isWaitForTasksToCompleteOnShutdown(); - ((DynamicThreadPoolExecutor) newDynamicThreadPoolExecutor).setSupportParam(awaitTerminationMillis, waitForTasksToCompleteOnShutdown); - long executeTimeOut = Optional.ofNullable(threadPoolParameterInfo.getExecuteTimeOut()) - .orElse(((DynamicThreadPoolExecutor) executor).getExecuteTimeOut()); - ((DynamicThreadPoolExecutor) newDynamicThreadPoolExecutor).setExecuteTimeOut(executeTimeOut); - } - dynamicThreadPoolWrapper.setExecutor(newDynamicThreadPoolExecutor); + threadPoolParamReplace(executor, threadPoolParameterInfo); + registerNotifyAlarm(threadPoolParameterInfo); } } else { // DynamicThreadPool configuration undefined in server @@ -186,27 +156,55 @@ public final class DynamicThreadPoolPostProcessor implements BeanPostProcessor { .rejectedPolicyType(RejectedPolicyTypeEnum.getRejectedPolicyTypeEnumByName(executor.getRejectedExecutionHandler().getClass().getSimpleName())) .build(); DynamicThreadPoolRegisterWrapper registerWrapper = DynamicThreadPoolRegisterWrapper.builder() - .dynamicThreadPoolRegisterParameter(parameterInfo) + .parameter(parameterInfo) .build(); GlobalThreadPoolManage.dynamicRegister(registerWrapper); } } catch (Exception ex) { - newDynamicThreadPoolExecutor = executor != null ? executor : CommonDynamicThreadPoolProviderFactory.getInstance(threadPoolId); - dynamicThreadPoolWrapper.setExecutor(newDynamicThreadPoolExecutor); log.error("Failed to initialize thread pool configuration. error message: {}", ex.getMessage()); - } finally { - if (Objects.isNull(executor)) { - dynamicThreadPoolWrapper.setExecutor(CommonDynamicThreadPoolProviderFactory.getInstance(threadPoolId)); - } } GlobalThreadPoolManage.register(dynamicThreadPoolWrapper.getThreadPoolId(), threadPoolParameterInfo, dynamicThreadPoolWrapper); - return newDynamicThreadPoolExecutor; + return executor; + } + + /** + * Thread-pool param replace. + * + * @param executor dynamic thread-pool executor + * @param threadPoolParameterInfo thread-pool parameter info + */ + private void threadPoolParamReplace(ThreadPoolExecutor executor, ThreadPoolParameterInfo threadPoolParameterInfo) { + BlockingQueue workQueue = BlockingQueueTypeEnum.createBlockingQueue(threadPoolParameterInfo.getQueueType(), threadPoolParameterInfo.getCapacity()); + ReflectUtil.setFieldValue(executor, "workQueue", workQueue); + executor.setCorePoolSize(threadPoolParameterInfo.corePoolSizeAdapt()); + executor.setMaximumPoolSize(threadPoolParameterInfo.maximumPoolSizeAdapt()); + executor.setKeepAliveTime(threadPoolParameterInfo.getKeepAliveTime(), TimeUnit.SECONDS); + executor.allowCoreThreadTimeOut(EnableEnum.getBool(threadPoolParameterInfo.getAllowCoreThreadTimeOut())); + executor.setRejectedExecutionHandler(RejectedPolicyTypeEnum.createPolicy(threadPoolParameterInfo.getRejectedType())); + if (executor instanceof DynamicThreadPoolExecutor) { + Optional.ofNullable(threadPoolParameterInfo.getExecuteTimeOut()) + .ifPresent(executeTimeOut -> ((DynamicThreadPoolExecutor) executor).setExecuteTimeOut(executeTimeOut)); + } + } + + /** + * Register notify alarm. + * + * @param threadPoolParameterInfo thread-pool parameter info + */ + private void registerNotifyAlarm(ThreadPoolParameterInfo threadPoolParameterInfo) { + // Set dynamic thread pool enhancement parameters. + ThreadPoolNotifyAlarm threadPoolNotifyAlarm = new ThreadPoolNotifyAlarm( + BooleanUtil.toBoolean(threadPoolParameterInfo.getIsAlarm().toString()), + threadPoolParameterInfo.getLivenessAlarm(), + threadPoolParameterInfo.getCapacityAlarm()); + GlobalNotifyAlarmManage.put(threadPoolParameterInfo.getTpId(), threadPoolNotifyAlarm); } /** * Client dynamic thread pool subscription server configuration. * - * @param dynamicThreadPoolWrapper + * @param dynamicThreadPoolWrapper dynamic thread-pool wrapper */ protected void subscribeConfig(DynamicThreadPoolWrapper dynamicThreadPoolWrapper) { if (dynamicThreadPoolWrapper.isSubscribeFlag()) { diff --git a/hippo4j-spring-boot/hippo4j-spring-boot-starter/src/main/java/cn/hippo4j/springboot/starter/support/ThreadPoolPluginRegisterPostProcessor.java b/hippo4j-spring-boot/hippo4j-spring-boot-starter/src/main/java/cn/hippo4j/springboot/starter/support/ThreadPoolPluginRegisterPostProcessor.java new file mode 100644 index 00000000..6f48e8fc --- /dev/null +++ b/hippo4j-spring-boot/hippo4j-spring-boot-starter/src/main/java/cn/hippo4j/springboot/starter/support/ThreadPoolPluginRegisterPostProcessor.java @@ -0,0 +1,152 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.hippo4j.springboot.starter.support; + +import cn.hippo4j.common.toolkit.Assert; +import cn.hippo4j.core.plugin.ThreadPoolPlugin; +import cn.hippo4j.core.plugin.manager.DefaultGlobalThreadPoolPluginManager; +import cn.hippo4j.core.plugin.manager.GlobalThreadPoolPluginManager; +import cn.hippo4j.core.plugin.manager.ThreadPoolPluginRegistrar; +import cn.hippo4j.core.plugin.manager.ThreadPoolPluginSupport; +import lombok.extern.slf4j.Slf4j; +import org.springframework.aop.framework.autoproxy.AutoProxyUtils; +import org.springframework.beans.BeansException; +import org.springframework.beans.factory.BeanInitializationException; +import org.springframework.beans.factory.InitializingBean; +import org.springframework.beans.factory.NoSuchBeanDefinitionException; +import org.springframework.beans.factory.config.AutowireCapableBeanFactory; +import org.springframework.beans.factory.config.BeanPostProcessor; +import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; +import org.springframework.context.ApplicationContext; +import org.springframework.context.ApplicationContextAware; +import org.springframework.context.ApplicationContextException; +import org.springframework.context.ApplicationEventPublisherAware; +import org.springframework.context.MessageSourceAware; +import org.springframework.context.ResourceLoaderAware; + +import java.util.Objects; + +/** + *

The extension implementation of {@link GlobalThreadPoolPluginManager} and {@link BeanPostProcessor}, + * used to register {@link ThreadPoolPlugin} for the bean initialization stage of the {@link ThreadPoolPluginSupport}. + * + *

NOTE: + * If the {@link ThreadPoolPlugin}, {@link ThreadPoolPluginRegistrar}, and {@link ThreadPoolPluginSupport} is set to lazy load, + * The processor will not perceive the bean unless the user actively triggers the initialization of the bean. + * + * @see ThreadPoolPluginSupport + * @see ThreadPoolPluginRegistrar + * @see ThreadPoolPlugin + * @see GlobalThreadPoolPluginManager + * @see DefaultGlobalThreadPoolPluginManager + */ +@Slf4j +public class ThreadPoolPluginRegisterPostProcessor extends DefaultGlobalThreadPoolPluginManager implements BeanPostProcessor, ApplicationContextAware { + + /** + * application context + */ + private ConfigurableListableBeanFactory beanFactory; + + /** + *

Post process bean, if bean is instance of {@link ThreadPoolPlugin}, + * {@link ThreadPoolPluginRegistrar} or {@link ThreadPoolPluginSupport}, + * then take beans as an available component and register to {@link GlobalThreadPoolPluginManager}. + * + * @param bean the new bean instance + * @param beanName the name of the bean + * @return the bean instance to use, either the original or a wrapped one; + * if {@code null}, no subsequent BeanPostProcessors will be invoked + * @throws BeansException in case of errors + * @see GlobalThreadPoolPluginManager#enableThreadPoolPlugin + * @see GlobalThreadPoolPluginManager#enableThreadPoolPluginRegistrar + * @see GlobalThreadPoolPluginManager#registerThreadPoolPluginSupport + */ + @Override + public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { + Class beanType = null; + try { + beanType = AutoProxyUtils.determineTargetClass(beanFactory, beanName); + } catch (NoSuchBeanDefinitionException ex) { + if (log.isDebugEnabled()) { + log.debug("Could not resolve target class for bean with name '" + beanName + "'", ex); + } + } + if (Objects.isNull(beanType)) { + log.warn("cannot resolve type for bean [{}]", beanName); + return bean; + } + + // register bean if necessary + registerThreadPoolPluginRegistrarIfNecessary(bean, beanType); + registerThreadPoolPluginIfNecessary(bean, beanType); + registerThreadPoolPluginSupportIfNecessary(bean, beanType); + return bean; + } + + private void registerThreadPoolPluginSupportIfNecessary(Object bean, Class beanType) { + if (ThreadPoolPluginSupport.class.isAssignableFrom(beanType)) { + ThreadPoolPluginSupport support = (ThreadPoolPluginSupport) bean; + if (registerThreadPoolPluginSupport(support) && log.isDebugEnabled()) { + log.info("register ThreadPoolPluginSupport [{}]", support.getThreadPoolId()); + } + } + } + + private void registerThreadPoolPluginIfNecessary(Object bean, Class beanType) { + if (ThreadPoolPlugin.class.isAssignableFrom(beanType)) { + ThreadPoolPlugin plugin = (ThreadPoolPlugin) bean; + if (enableThreadPoolPlugin(plugin) && log.isDebugEnabled()) { + log.info("register ThreadPoolPlugin [{}]", plugin.getId()); + } + } + } + + private void registerThreadPoolPluginRegistrarIfNecessary(Object bean, Class beanType) { + if (ThreadPoolPluginRegistrar.class.isAssignableFrom(beanType)) { + ThreadPoolPluginRegistrar registrar = (ThreadPoolPluginRegistrar) bean; + if (enableThreadPoolPluginRegistrar(registrar) && log.isDebugEnabled()) { + log.info("register ThreadPoolPluginRegistrar [{}]", registrar.getId()); + } + } + } + + /** + * Set the ApplicationContext that this object runs in. + * Normally this call will be used to initialize the object. + *

Invoked after population of normal bean properties but before an init callback such + * as {@link InitializingBean#afterPropertiesSet()} + * or a custom init-method. Invoked after {@link ResourceLoaderAware#setResourceLoader}, + * {@link ApplicationEventPublisherAware#setApplicationEventPublisher} and + * {@link MessageSourceAware}, if applicable. + * + * @param applicationContext the ApplicationContext object to be used by this object + * @throws ApplicationContextException in case of context initialization errors + * @throws BeansException if thrown by application context methods + * @see BeanInitializationException + */ + @Override + public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { + AutowireCapableBeanFactory factory = applicationContext.getAutowireCapableBeanFactory(); + Assert.isTrue( + factory instanceof ConfigurableListableBeanFactory, + "factory cannot cast to ConfigurableListableBeanFactory"); + this.beanFactory = (ConfigurableListableBeanFactory) factory; + } + +} diff --git a/hippo4j-server/hippo4j-ui/.editorconfig b/hippo4j-ui/.editorconfig similarity index 100% rename from hippo4j-server/hippo4j-ui/.editorconfig rename to hippo4j-ui/.editorconfig diff --git a/hippo4j-server/hippo4j-ui/.env.development b/hippo4j-ui/.env.development similarity index 100% rename from hippo4j-server/hippo4j-ui/.env.development rename to hippo4j-ui/.env.development diff --git a/hippo4j-server/hippo4j-ui/.env.production b/hippo4j-ui/.env.production similarity index 100% rename from hippo4j-server/hippo4j-ui/.env.production rename to hippo4j-ui/.env.production diff --git a/hippo4j-server/hippo4j-ui/.env.staging b/hippo4j-ui/.env.staging similarity index 100% rename from hippo4j-server/hippo4j-ui/.env.staging rename to hippo4j-ui/.env.staging diff --git a/hippo4j-server/hippo4j-ui/.eslintignore b/hippo4j-ui/.eslintignore similarity index 100% rename from hippo4j-server/hippo4j-ui/.eslintignore rename to hippo4j-ui/.eslintignore diff --git a/hippo4j-server/hippo4j-ui/.eslintrc.js b/hippo4j-ui/.eslintrc.js similarity index 100% rename from hippo4j-server/hippo4j-ui/.eslintrc.js rename to hippo4j-ui/.eslintrc.js diff --git a/hippo4j-server/hippo4j-ui/.gitignore b/hippo4j-ui/.gitignore similarity index 100% rename from hippo4j-server/hippo4j-ui/.gitignore rename to hippo4j-ui/.gitignore diff --git a/hippo4j-server/hippo4j-ui/.prettierrc.js b/hippo4j-ui/.prettierrc.js similarity index 100% rename from hippo4j-server/hippo4j-ui/.prettierrc.js rename to hippo4j-ui/.prettierrc.js diff --git a/hippo4j-server/hippo4j-ui/.travis.yml b/hippo4j-ui/.travis.yml similarity index 100% rename from hippo4j-server/hippo4j-ui/.travis.yml rename to hippo4j-ui/.travis.yml diff --git a/hippo4j-server/hippo4j-ui/README.md b/hippo4j-ui/README.md similarity index 100% rename from hippo4j-server/hippo4j-ui/README.md rename to hippo4j-ui/README.md diff --git a/hippo4j-server/hippo4j-ui/babel.config.js b/hippo4j-ui/babel.config.js similarity index 100% rename from hippo4j-server/hippo4j-ui/babel.config.js rename to hippo4j-ui/babel.config.js diff --git a/hippo4j-server/hippo4j-ui/jest.config.js b/hippo4j-ui/jest.config.js similarity index 100% rename from hippo4j-server/hippo4j-ui/jest.config.js rename to hippo4j-ui/jest.config.js diff --git a/hippo4j-server/hippo4j-ui/package.json b/hippo4j-ui/package.json similarity index 97% rename from hippo4j-server/hippo4j-ui/package.json rename to hippo4j-ui/package.json index bbe30325..9adc89b8 100755 --- a/hippo4j-server/hippo4j-ui/package.json +++ b/hippo4j-ui/package.json @@ -59,6 +59,7 @@ "vue": "2.6.10", "vue-cookie": "^1.1.4", "vue-count-to": "1.0.13", + "vue-i18n": "^6.1.3", "vue-router": "3.0.2", "vue-splitpane": "1.0.4", "vue2-jsoneditor": "^1.0.6", @@ -68,7 +69,7 @@ "devDependencies": { "@babel/core": "7.0.0", "@babel/register": "7.0.0", - "@vue/cli-plugin-babel": "3.5.3", + "@vue/cli-plugin-babel": "~4", "@vue/cli-plugin-eslint": "3.5.1", "@vue/cli-plugin-unit-jest": "3.5.3", "@vue/cli-service": "3.5.3", diff --git a/hippo4j-server/hippo4j-ui/plopfile.js b/hippo4j-ui/plopfile.js similarity index 100% rename from hippo4j-server/hippo4j-ui/plopfile.js rename to hippo4j-ui/plopfile.js diff --git a/hippo4j-server/hippo4j-ui/postcss.config.js b/hippo4j-ui/postcss.config.js similarity index 100% rename from hippo4j-server/hippo4j-ui/postcss.config.js rename to hippo4j-ui/postcss.config.js diff --git a/hippo4j-server/hippo4j-ui/public/favicon.ico b/hippo4j-ui/public/favicon.ico similarity index 100% rename from hippo4j-server/hippo4j-ui/public/favicon.ico rename to hippo4j-ui/public/favicon.ico diff --git a/hippo4j-server/hippo4j-ui/public/hippo4j.gif b/hippo4j-ui/public/hippo4j.gif similarity index 100% rename from hippo4j-server/hippo4j-ui/public/hippo4j.gif rename to hippo4j-ui/public/hippo4j.gif diff --git a/hippo4j-server/hippo4j-ui/public/index.html b/hippo4j-ui/public/index.html similarity index 100% rename from hippo4j-server/hippo4j-ui/public/index.html rename to hippo4j-ui/public/index.html diff --git a/hippo4j-server/hippo4j-ui/src/App.vue b/hippo4j-ui/src/App.vue similarity index 100% rename from hippo4j-server/hippo4j-ui/src/App.vue rename to hippo4j-ui/src/App.vue diff --git a/hippo4j-server/hippo4j-ui/src/api/dashborad.js b/hippo4j-ui/src/api/dashborad.js similarity index 100% rename from hippo4j-server/hippo4j-ui/src/api/dashborad.js rename to hippo4j-ui/src/api/dashborad.js diff --git a/hippo4j-server/hippo4j-ui/src/api/hippo4j-adapterThreadPool.js b/hippo4j-ui/src/api/hippo4j-adapterThreadPool.js similarity index 100% rename from hippo4j-server/hippo4j-ui/src/api/hippo4j-adapterThreadPool.js rename to hippo4j-ui/src/api/hippo4j-adapterThreadPool.js diff --git a/hippo4j-server/hippo4j-ui/src/api/hippo4j-instance.js b/hippo4j-ui/src/api/hippo4j-instance.js similarity index 100% rename from hippo4j-server/hippo4j-ui/src/api/hippo4j-instance.js rename to hippo4j-ui/src/api/hippo4j-instance.js diff --git a/hippo4j-server/hippo4j-ui/src/api/hippo4j-item.js b/hippo4j-ui/src/api/hippo4j-item.js similarity index 100% rename from hippo4j-server/hippo4j-ui/src/api/hippo4j-item.js rename to hippo4j-ui/src/api/hippo4j-item.js diff --git a/hippo4j-server/hippo4j-ui/src/api/hippo4j-log.js b/hippo4j-ui/src/api/hippo4j-log.js similarity index 100% rename from hippo4j-server/hippo4j-ui/src/api/hippo4j-log.js rename to hippo4j-ui/src/api/hippo4j-log.js diff --git a/hippo4j-server/hippo4j-ui/src/api/hippo4j-monitor.js b/hippo4j-ui/src/api/hippo4j-monitor.js similarity index 100% rename from hippo4j-server/hippo4j-ui/src/api/hippo4j-monitor.js rename to hippo4j-ui/src/api/hippo4j-monitor.js diff --git a/hippo4j-server/hippo4j-ui/src/api/hippo4j-notify.js b/hippo4j-ui/src/api/hippo4j-notify.js similarity index 100% rename from hippo4j-server/hippo4j-ui/src/api/hippo4j-notify.js rename to hippo4j-ui/src/api/hippo4j-notify.js diff --git a/hippo4j-server/hippo4j-ui/src/api/hippo4j-tenant.js b/hippo4j-ui/src/api/hippo4j-tenant.js similarity index 100% rename from hippo4j-server/hippo4j-ui/src/api/hippo4j-tenant.js rename to hippo4j-ui/src/api/hippo4j-tenant.js diff --git a/hippo4j-server/hippo4j-ui/src/api/hippo4j-threadPool.js b/hippo4j-ui/src/api/hippo4j-threadPool.js similarity index 100% rename from hippo4j-server/hippo4j-ui/src/api/hippo4j-threadPool.js rename to hippo4j-ui/src/api/hippo4j-threadPool.js diff --git a/hippo4j-server/hippo4j-ui/src/api/hippo4j-user.js b/hippo4j-ui/src/api/hippo4j-user.js similarity index 100% rename from hippo4j-server/hippo4j-ui/src/api/hippo4j-user.js rename to hippo4j-ui/src/api/hippo4j-user.js diff --git a/hippo4j-server/hippo4j-ui/src/api/metadata-query.js b/hippo4j-ui/src/api/metadata-query.js similarity index 100% rename from hippo4j-server/hippo4j-ui/src/api/metadata-query.js rename to hippo4j-ui/src/api/metadata-query.js diff --git a/hippo4j-server/hippo4j-ui/src/api/remote-search.js b/hippo4j-ui/src/api/remote-search.js similarity index 100% rename from hippo4j-server/hippo4j-ui/src/api/remote-search.js rename to hippo4j-ui/src/api/remote-search.js diff --git a/hippo4j-server/hippo4j-ui/src/api/role.js b/hippo4j-ui/src/api/role.js similarity index 100% rename from hippo4j-server/hippo4j-ui/src/api/role.js rename to hippo4j-ui/src/api/role.js diff --git a/hippo4j-server/hippo4j-ui/src/api/user.js b/hippo4j-ui/src/api/user.js similarity index 100% rename from hippo4j-server/hippo4j-ui/src/api/user.js rename to hippo4j-ui/src/api/user.js diff --git a/hippo4j-server/hippo4j-ui/src/api/verify.js b/hippo4j-ui/src/api/verify.js similarity index 100% rename from hippo4j-server/hippo4j-ui/src/api/verify.js rename to hippo4j-ui/src/api/verify.js diff --git a/hippo4j-server/hippo4j-ui/src/assets/401_images/401.gif b/hippo4j-ui/src/assets/401_images/401.gif similarity index 100% rename from hippo4j-server/hippo4j-ui/src/assets/401_images/401.gif rename to hippo4j-ui/src/assets/401_images/401.gif diff --git a/hippo4j-server/hippo4j-ui/src/assets/404_images/404.png b/hippo4j-ui/src/assets/404_images/404.png similarity index 100% rename from hippo4j-server/hippo4j-ui/src/assets/404_images/404.png rename to hippo4j-ui/src/assets/404_images/404.png diff --git a/hippo4j-server/hippo4j-ui/src/assets/404_images/404_cloud.png b/hippo4j-ui/src/assets/404_images/404_cloud.png similarity index 100% rename from hippo4j-server/hippo4j-ui/src/assets/404_images/404_cloud.png rename to hippo4j-ui/src/assets/404_images/404_cloud.png diff --git a/hippo4j-server/hippo4j-ui/src/assets/custom-theme/fonts/element-icons.ttf b/hippo4j-ui/src/assets/custom-theme/fonts/element-icons.ttf similarity index 100% rename from hippo4j-server/hippo4j-ui/src/assets/custom-theme/fonts/element-icons.ttf rename to hippo4j-ui/src/assets/custom-theme/fonts/element-icons.ttf diff --git a/hippo4j-server/hippo4j-ui/src/assets/custom-theme/fonts/element-icons.woff b/hippo4j-ui/src/assets/custom-theme/fonts/element-icons.woff similarity index 100% rename from hippo4j-server/hippo4j-ui/src/assets/custom-theme/fonts/element-icons.woff rename to hippo4j-ui/src/assets/custom-theme/fonts/element-icons.woff diff --git a/hippo4j-server/hippo4j-ui/src/assets/custom-theme/index.css b/hippo4j-ui/src/assets/custom-theme/index.css similarity index 100% rename from hippo4j-server/hippo4j-ui/src/assets/custom-theme/index.css rename to hippo4j-ui/src/assets/custom-theme/index.css diff --git a/hippo4j-server/hippo4j-ui/src/components/BackToTop/index.vue b/hippo4j-ui/src/components/BackToTop/index.vue similarity index 100% rename from hippo4j-server/hippo4j-ui/src/components/BackToTop/index.vue rename to hippo4j-ui/src/components/BackToTop/index.vue diff --git a/hippo4j-server/hippo4j-ui/src/components/Breadcrumb/index.vue b/hippo4j-ui/src/components/Breadcrumb/index.vue similarity index 100% rename from hippo4j-server/hippo4j-ui/src/components/Breadcrumb/index.vue rename to hippo4j-ui/src/components/Breadcrumb/index.vue diff --git a/hippo4j-server/hippo4j-ui/src/components/Charts/Keyboard.vue b/hippo4j-ui/src/components/Charts/Keyboard.vue similarity index 100% rename from hippo4j-server/hippo4j-ui/src/components/Charts/Keyboard.vue rename to hippo4j-ui/src/components/Charts/Keyboard.vue diff --git a/hippo4j-server/hippo4j-ui/src/components/Charts/LineMarker.vue b/hippo4j-ui/src/components/Charts/LineMarker.vue similarity index 100% rename from hippo4j-server/hippo4j-ui/src/components/Charts/LineMarker.vue rename to hippo4j-ui/src/components/Charts/LineMarker.vue diff --git a/hippo4j-server/hippo4j-ui/src/components/Charts/MixChart.vue b/hippo4j-ui/src/components/Charts/MixChart.vue similarity index 100% rename from hippo4j-server/hippo4j-ui/src/components/Charts/MixChart.vue rename to hippo4j-ui/src/components/Charts/MixChart.vue diff --git a/hippo4j-server/hippo4j-ui/src/components/Charts/mixins/resize.js b/hippo4j-ui/src/components/Charts/mixins/resize.js similarity index 100% rename from hippo4j-server/hippo4j-ui/src/components/Charts/mixins/resize.js rename to hippo4j-ui/src/components/Charts/mixins/resize.js diff --git a/hippo4j-server/hippo4j-ui/src/components/ErrorLog/index.vue b/hippo4j-ui/src/components/ErrorLog/index.vue similarity index 100% rename from hippo4j-server/hippo4j-ui/src/components/ErrorLog/index.vue rename to hippo4j-ui/src/components/ErrorLog/index.vue diff --git a/hippo4j-server/hippo4j-ui/src/components/GithubCorner/index.vue b/hippo4j-ui/src/components/GithubCorner/index.vue similarity index 100% rename from hippo4j-server/hippo4j-ui/src/components/GithubCorner/index.vue rename to hippo4j-ui/src/components/GithubCorner/index.vue diff --git a/hippo4j-server/hippo4j-ui/src/components/Hamburger/index.vue b/hippo4j-ui/src/components/Hamburger/index.vue similarity index 100% rename from hippo4j-server/hippo4j-ui/src/components/Hamburger/index.vue rename to hippo4j-ui/src/components/Hamburger/index.vue diff --git a/hippo4j-server/hippo4j-ui/src/components/HeaderSearch/index.vue b/hippo4j-ui/src/components/HeaderSearch/index.vue similarity index 100% rename from hippo4j-server/hippo4j-ui/src/components/HeaderSearch/index.vue rename to hippo4j-ui/src/components/HeaderSearch/index.vue diff --git a/hippo4j-server/hippo4j-ui/src/components/ImageCropper/index.vue b/hippo4j-ui/src/components/ImageCropper/index.vue similarity index 100% rename from hippo4j-server/hippo4j-ui/src/components/ImageCropper/index.vue rename to hippo4j-ui/src/components/ImageCropper/index.vue diff --git a/hippo4j-server/hippo4j-ui/src/components/ImageCropper/utils/data2blob.js b/hippo4j-ui/src/components/ImageCropper/utils/data2blob.js similarity index 100% rename from hippo4j-server/hippo4j-ui/src/components/ImageCropper/utils/data2blob.js rename to hippo4j-ui/src/components/ImageCropper/utils/data2blob.js diff --git a/hippo4j-server/hippo4j-ui/src/components/ImageCropper/utils/effectRipple.js b/hippo4j-ui/src/components/ImageCropper/utils/effectRipple.js similarity index 100% rename from hippo4j-server/hippo4j-ui/src/components/ImageCropper/utils/effectRipple.js rename to hippo4j-ui/src/components/ImageCropper/utils/effectRipple.js diff --git a/hippo4j-server/hippo4j-ui/src/components/ImageCropper/utils/language.js b/hippo4j-ui/src/components/ImageCropper/utils/language.js similarity index 100% rename from hippo4j-server/hippo4j-ui/src/components/ImageCropper/utils/language.js rename to hippo4j-ui/src/components/ImageCropper/utils/language.js diff --git a/hippo4j-server/hippo4j-ui/src/components/ImageCropper/utils/mimes.js b/hippo4j-ui/src/components/ImageCropper/utils/mimes.js similarity index 100% rename from hippo4j-server/hippo4j-ui/src/components/ImageCropper/utils/mimes.js rename to hippo4j-ui/src/components/ImageCropper/utils/mimes.js diff --git a/hippo4j-server/hippo4j-ui/src/components/JsonEditor/index.vue b/hippo4j-ui/src/components/JsonEditor/index.vue similarity index 100% rename from hippo4j-server/hippo4j-ui/src/components/JsonEditor/index.vue rename to hippo4j-ui/src/components/JsonEditor/index.vue diff --git a/hippo4j-server/hippo4j-ui/src/components/Pagination/index.vue b/hippo4j-ui/src/components/Pagination/index.vue similarity index 100% rename from hippo4j-server/hippo4j-ui/src/components/Pagination/index.vue rename to hippo4j-ui/src/components/Pagination/index.vue diff --git a/hippo4j-server/hippo4j-ui/src/components/RightPanel/index.vue b/hippo4j-ui/src/components/RightPanel/index.vue similarity index 100% rename from hippo4j-server/hippo4j-ui/src/components/RightPanel/index.vue rename to hippo4j-ui/src/components/RightPanel/index.vue diff --git a/hippo4j-server/hippo4j-ui/src/components/Screenfull/index.vue b/hippo4j-ui/src/components/Screenfull/index.vue similarity index 100% rename from hippo4j-server/hippo4j-ui/src/components/Screenfull/index.vue rename to hippo4j-ui/src/components/Screenfull/index.vue diff --git a/hippo4j-server/hippo4j-ui/src/components/Sticky/index.vue b/hippo4j-ui/src/components/Sticky/index.vue similarity index 100% rename from hippo4j-server/hippo4j-ui/src/components/Sticky/index.vue rename to hippo4j-ui/src/components/Sticky/index.vue diff --git a/hippo4j-server/hippo4j-ui/src/components/SvgIcon/index.vue b/hippo4j-ui/src/components/SvgIcon/index.vue similarity index 100% rename from hippo4j-server/hippo4j-ui/src/components/SvgIcon/index.vue rename to hippo4j-ui/src/components/SvgIcon/index.vue diff --git a/hippo4j-server/hippo4j-ui/src/directive/clipboard/clipboard.js b/hippo4j-ui/src/directive/clipboard/clipboard.js similarity index 100% rename from hippo4j-server/hippo4j-ui/src/directive/clipboard/clipboard.js rename to hippo4j-ui/src/directive/clipboard/clipboard.js diff --git a/hippo4j-server/hippo4j-ui/src/directive/clipboard/index.js b/hippo4j-ui/src/directive/clipboard/index.js similarity index 100% rename from hippo4j-server/hippo4j-ui/src/directive/clipboard/index.js rename to hippo4j-ui/src/directive/clipboard/index.js diff --git a/hippo4j-server/hippo4j-ui/src/directive/el-drag-dialog/drag.js b/hippo4j-ui/src/directive/el-drag-dialog/drag.js similarity index 100% rename from hippo4j-server/hippo4j-ui/src/directive/el-drag-dialog/drag.js rename to hippo4j-ui/src/directive/el-drag-dialog/drag.js diff --git a/hippo4j-server/hippo4j-ui/src/directive/el-drag-dialog/index.js b/hippo4j-ui/src/directive/el-drag-dialog/index.js similarity index 100% rename from hippo4j-server/hippo4j-ui/src/directive/el-drag-dialog/index.js rename to hippo4j-ui/src/directive/el-drag-dialog/index.js diff --git a/hippo4j-server/hippo4j-ui/src/directive/el-table/adaptive.js b/hippo4j-ui/src/directive/el-table/adaptive.js similarity index 100% rename from hippo4j-server/hippo4j-ui/src/directive/el-table/adaptive.js rename to hippo4j-ui/src/directive/el-table/adaptive.js diff --git a/hippo4j-server/hippo4j-ui/src/directive/el-table/index.js b/hippo4j-ui/src/directive/el-table/index.js similarity index 100% rename from hippo4j-server/hippo4j-ui/src/directive/el-table/index.js rename to hippo4j-ui/src/directive/el-table/index.js diff --git a/hippo4j-server/hippo4j-ui/src/directive/permission/index.js b/hippo4j-ui/src/directive/permission/index.js similarity index 100% rename from hippo4j-server/hippo4j-ui/src/directive/permission/index.js rename to hippo4j-ui/src/directive/permission/index.js diff --git a/hippo4j-server/hippo4j-ui/src/directive/permission/permission.js b/hippo4j-ui/src/directive/permission/permission.js similarity index 100% rename from hippo4j-server/hippo4j-ui/src/directive/permission/permission.js rename to hippo4j-ui/src/directive/permission/permission.js diff --git a/hippo4j-server/hippo4j-ui/src/directive/sticky.js b/hippo4j-ui/src/directive/sticky.js similarity index 100% rename from hippo4j-server/hippo4j-ui/src/directive/sticky.js rename to hippo4j-ui/src/directive/sticky.js diff --git a/hippo4j-server/hippo4j-ui/src/directive/waves/index.js b/hippo4j-ui/src/directive/waves/index.js similarity index 100% rename from hippo4j-server/hippo4j-ui/src/directive/waves/index.js rename to hippo4j-ui/src/directive/waves/index.js diff --git a/hippo4j-server/hippo4j-ui/src/directive/waves/waves.css b/hippo4j-ui/src/directive/waves/waves.css similarity index 100% rename from hippo4j-server/hippo4j-ui/src/directive/waves/waves.css rename to hippo4j-ui/src/directive/waves/waves.css diff --git a/hippo4j-server/hippo4j-ui/src/directive/waves/waves.js b/hippo4j-ui/src/directive/waves/waves.js similarity index 100% rename from hippo4j-server/hippo4j-ui/src/directive/waves/waves.js rename to hippo4j-ui/src/directive/waves/waves.js diff --git a/hippo4j-server/hippo4j-ui/src/filters/index.js b/hippo4j-ui/src/filters/index.js similarity index 100% rename from hippo4j-server/hippo4j-ui/src/filters/index.js rename to hippo4j-ui/src/filters/index.js diff --git a/hippo4j-server/hippo4j-ui/src/icons/index.js b/hippo4j-ui/src/icons/index.js similarity index 100% rename from hippo4j-server/hippo4j-ui/src/icons/index.js rename to hippo4j-ui/src/icons/index.js diff --git a/hippo4j-server/hippo4j-ui/src/icons/svg/404.svg b/hippo4j-ui/src/icons/svg/404.svg similarity index 100% rename from hippo4j-server/hippo4j-ui/src/icons/svg/404.svg rename to hippo4j-ui/src/icons/svg/404.svg diff --git a/hippo4j-server/hippo4j-ui/src/icons/svg/audit.svg b/hippo4j-ui/src/icons/svg/audit.svg similarity index 100% rename from hippo4j-server/hippo4j-ui/src/icons/svg/audit.svg rename to hippo4j-ui/src/icons/svg/audit.svg diff --git a/hippo4j-server/hippo4j-ui/src/icons/svg/dashboard2.svg b/hippo4j-ui/src/icons/svg/dashboard2.svg similarity index 100% rename from hippo4j-server/hippo4j-ui/src/icons/svg/dashboard2.svg rename to hippo4j-ui/src/icons/svg/dashboard2.svg diff --git a/hippo4j-server/hippo4j-ui/src/icons/svg/item4.svg b/hippo4j-ui/src/icons/svg/item4.svg similarity index 100% rename from hippo4j-server/hippo4j-ui/src/icons/svg/item4.svg rename to hippo4j-ui/src/icons/svg/item4.svg diff --git a/hippo4j-server/hippo4j-ui/src/icons/svg/item_logo4.svg b/hippo4j-ui/src/icons/svg/item_logo4.svg similarity index 100% rename from hippo4j-server/hippo4j-ui/src/icons/svg/item_logo4.svg rename to hippo4j-ui/src/icons/svg/item_logo4.svg diff --git a/hippo4j-server/hippo4j-ui/src/icons/svg/json.svg b/hippo4j-ui/src/icons/svg/json.svg similarity index 100% rename from hippo4j-server/hippo4j-ui/src/icons/svg/json.svg rename to hippo4j-ui/src/icons/svg/json.svg diff --git a/hippo4j-server/hippo4j-ui/src/icons/svg/language.svg b/hippo4j-ui/src/icons/svg/language.svg similarity index 100% rename from hippo4j-server/hippo4j-ui/src/icons/svg/language.svg rename to hippo4j-ui/src/icons/svg/language.svg diff --git a/hippo4j-server/hippo4j-ui/src/icons/svg/lessee.svg b/hippo4j-ui/src/icons/svg/lessee.svg similarity index 100% rename from hippo4j-server/hippo4j-ui/src/icons/svg/lessee.svg rename to hippo4j-ui/src/icons/svg/lessee.svg diff --git a/hippo4j-server/hippo4j-ui/src/icons/svg/link3.svg b/hippo4j-ui/src/icons/svg/link3.svg similarity index 100% rename from hippo4j-server/hippo4j-ui/src/icons/svg/link3.svg rename to hippo4j-ui/src/icons/svg/link3.svg diff --git a/hippo4j-server/hippo4j-ui/src/icons/svg/log3.svg b/hippo4j-ui/src/icons/svg/log3.svg similarity index 100% rename from hippo4j-server/hippo4j-ui/src/icons/svg/log3.svg rename to hippo4j-ui/src/icons/svg/log3.svg diff --git a/hippo4j-server/hippo4j-ui/src/icons/svg/notify.svg b/hippo4j-ui/src/icons/svg/notify.svg similarity index 100% rename from hippo4j-server/hippo4j-ui/src/icons/svg/notify.svg rename to hippo4j-ui/src/icons/svg/notify.svg diff --git a/hippo4j-server/hippo4j-ui/src/icons/svg/other4.svg b/hippo4j-ui/src/icons/svg/other4.svg similarity index 100% rename from hippo4j-server/hippo4j-ui/src/icons/svg/other4.svg rename to hippo4j-ui/src/icons/svg/other4.svg diff --git a/hippo4j-server/hippo4j-ui/src/icons/svg/pool3.svg b/hippo4j-ui/src/icons/svg/pool3.svg similarity index 100% rename from hippo4j-server/hippo4j-ui/src/icons/svg/pool3.svg rename to hippo4j-ui/src/icons/svg/pool3.svg diff --git a/hippo4j-server/hippo4j-ui/src/icons/svg/tenant_logo2.svg b/hippo4j-ui/src/icons/svg/tenant_logo2.svg similarity index 100% rename from hippo4j-server/hippo4j-ui/src/icons/svg/tenant_logo2.svg rename to hippo4j-ui/src/icons/svg/tenant_logo2.svg diff --git a/hippo4j-server/hippo4j-ui/src/icons/svg/threadPool_logo1.svg b/hippo4j-ui/src/icons/svg/threadPool_logo1.svg similarity index 100% rename from hippo4j-server/hippo4j-ui/src/icons/svg/threadPool_logo1.svg rename to hippo4j-ui/src/icons/svg/threadPool_logo1.svg diff --git a/hippo4j-server/hippo4j-ui/src/icons/svg/threadPool_logo2.svg b/hippo4j-ui/src/icons/svg/threadPool_logo2.svg similarity index 100% rename from hippo4j-server/hippo4j-ui/src/icons/svg/threadPool_logo2.svg rename to hippo4j-ui/src/icons/svg/threadPool_logo2.svg diff --git a/hippo4j-server/hippo4j-ui/src/icons/svg/user6.svg b/hippo4j-ui/src/icons/svg/user6.svg similarity index 100% rename from hippo4j-server/hippo4j-ui/src/icons/svg/user6.svg rename to hippo4j-ui/src/icons/svg/user6.svg diff --git a/hippo4j-server/hippo4j-ui/src/icons/svg/vessel3.svg b/hippo4j-ui/src/icons/svg/vessel3.svg similarity index 100% rename from hippo4j-server/hippo4j-ui/src/icons/svg/vessel3.svg rename to hippo4j-ui/src/icons/svg/vessel3.svg diff --git a/hippo4j-server/hippo4j-ui/src/icons/svgo.yml b/hippo4j-ui/src/icons/svgo.yml similarity index 100% rename from hippo4j-server/hippo4j-ui/src/icons/svgo.yml rename to hippo4j-ui/src/icons/svgo.yml diff --git a/hippo4j-server/hippo4j-ui/src/layout/components/AppMain.vue b/hippo4j-ui/src/layout/components/AppMain.vue similarity index 100% rename from hippo4j-server/hippo4j-ui/src/layout/components/AppMain.vue rename to hippo4j-ui/src/layout/components/AppMain.vue diff --git a/hippo4j-server/hippo4j-ui/src/layout/components/Navbar.vue b/hippo4j-ui/src/layout/components/Navbar.vue similarity index 94% rename from hippo4j-server/hippo4j-ui/src/layout/components/Navbar.vue rename to hippo4j-ui/src/layout/components/Navbar.vue index 612126a8..283431ff 100755 --- a/hippo4j-server/hippo4j-ui/src/layout/components/Navbar.vue +++ b/hippo4j-ui/src/layout/components/Navbar.vue @@ -18,7 +18,7 @@ - +

@@ -32,7 +32,7 @@ Dashboard - Log Out + {{ $t('system.logOut') }} @@ -45,12 +45,14 @@ import Breadcrumb from '@/components/Breadcrumb' import Hamburger from '@/components/Hamburger' import ErrorLog from '@/components/ErrorLog' + import langChange from '@/locale/langChange' export default { components: { Breadcrumb, Hamburger, - ErrorLog + ErrorLog, + langChange }, computed: { ...mapGetters([ @@ -106,7 +108,7 @@ float: right; height: 100%; line-height: 50px; - + display: flex; &:focus { outline: none; } diff --git a/hippo4j-server/hippo4j-ui/src/layout/components/Sidebar/FixiOSBug.js b/hippo4j-ui/src/layout/components/Sidebar/FixiOSBug.js similarity index 100% rename from hippo4j-server/hippo4j-ui/src/layout/components/Sidebar/FixiOSBug.js rename to hippo4j-ui/src/layout/components/Sidebar/FixiOSBug.js diff --git a/hippo4j-server/hippo4j-ui/src/layout/components/Sidebar/Item.vue b/hippo4j-ui/src/layout/components/Sidebar/Item.vue similarity index 100% rename from hippo4j-server/hippo4j-ui/src/layout/components/Sidebar/Item.vue rename to hippo4j-ui/src/layout/components/Sidebar/Item.vue diff --git a/hippo4j-server/hippo4j-ui/src/layout/components/Sidebar/Link.vue b/hippo4j-ui/src/layout/components/Sidebar/Link.vue similarity index 100% rename from hippo4j-server/hippo4j-ui/src/layout/components/Sidebar/Link.vue rename to hippo4j-ui/src/layout/components/Sidebar/Link.vue diff --git a/hippo4j-server/hippo4j-ui/src/layout/components/Sidebar/Logo.vue b/hippo4j-ui/src/layout/components/Sidebar/Logo.vue similarity index 100% rename from hippo4j-server/hippo4j-ui/src/layout/components/Sidebar/Logo.vue rename to hippo4j-ui/src/layout/components/Sidebar/Logo.vue diff --git a/hippo4j-server/hippo4j-ui/src/layout/components/Sidebar/SidebarItem.vue b/hippo4j-ui/src/layout/components/Sidebar/SidebarItem.vue similarity index 100% rename from hippo4j-server/hippo4j-ui/src/layout/components/Sidebar/SidebarItem.vue rename to hippo4j-ui/src/layout/components/Sidebar/SidebarItem.vue diff --git a/hippo4j-server/hippo4j-ui/src/layout/components/Sidebar/index.vue b/hippo4j-ui/src/layout/components/Sidebar/index.vue similarity index 100% rename from hippo4j-server/hippo4j-ui/src/layout/components/Sidebar/index.vue rename to hippo4j-ui/src/layout/components/Sidebar/index.vue diff --git a/hippo4j-server/hippo4j-ui/src/layout/components/index.js b/hippo4j-ui/src/layout/components/index.js similarity index 100% rename from hippo4j-server/hippo4j-ui/src/layout/components/index.js rename to hippo4j-ui/src/layout/components/index.js diff --git a/hippo4j-server/hippo4j-ui/src/layout/index.vue b/hippo4j-ui/src/layout/index.vue similarity index 100% rename from hippo4j-server/hippo4j-ui/src/layout/index.vue rename to hippo4j-ui/src/layout/index.vue diff --git a/hippo4j-server/hippo4j-ui/src/layout/mixin/ResizeHandler.js b/hippo4j-ui/src/layout/mixin/ResizeHandler.js similarity index 100% rename from hippo4j-server/hippo4j-ui/src/layout/mixin/ResizeHandler.js rename to hippo4j-ui/src/layout/mixin/ResizeHandler.js diff --git a/hippo4j-ui/src/locale/config.js b/hippo4j-ui/src/locale/config.js new file mode 100644 index 00000000..3262ac6d --- /dev/null +++ b/hippo4j-ui/src/locale/config.js @@ -0,0 +1,30 @@ +// 导入elementUi默认中英文语言包 +import elZh from 'element-ui/lib/locale/lang/zh-CN' +import elEn from 'element-ui/lib/locale/lang/en' + +import zh from './lang/zh' +import en from './lang/en' + +const lang = localStorage.getItem('locale_lang') + +export const i18nConfig = { + locale: lang || 'en', // 默认语种 + messages: { + zh: { ...zh, ...elZh }, // 中文包 + en: { ...en, ...elEn } // 英文包 + } +} + + +export const langSelectList = () => { + return [ + { + lang: 'zh', + name: '中文' + }, + { + lang: 'en', + name: 'English' + } + ] +} diff --git a/hippo4j-ui/src/locale/index.js b/hippo4j-ui/src/locale/index.js new file mode 100644 index 00000000..408134bc --- /dev/null +++ b/hippo4j-ui/src/locale/index.js @@ -0,0 +1,10 @@ +import Vue from 'vue' +import VueI18n from 'vue-i18n' + +import { i18nConfig } from './config' + +Vue.use(VueI18n) + +const i18n = new VueI18n(i18nConfig) + +export default i18n diff --git a/hippo4j-ui/src/locale/lang/en.js b/hippo4j-ui/src/locale/lang/en.js new file mode 100644 index 00000000..f581c3bb --- /dev/null +++ b/hippo4j-ui/src/locale/lang/en.js @@ -0,0 +1,31 @@ +export default { + // 系统 + system: { + login: 'Login Form', + username: 'Username', + password: 'Password', + logOut: 'Log Out' + }, + + // 公共 + common: { + search: 'Search', + addition: 'Addition', + serialNumber: 'Serial Number', + operation: 'Operation', + edit: 'Edit', + delete: 'Delete', + cancel: 'Cancel', + confirm: 'Confirm' + }, + + // 线程池 + threadPool: { + tenant: 'Tenant', + project: 'Project', + threadPool: 'Thread Pool', + + + } + +} diff --git a/hippo4j-ui/src/locale/lang/zh.js b/hippo4j-ui/src/locale/lang/zh.js new file mode 100644 index 00000000..f12d91c6 --- /dev/null +++ b/hippo4j-ui/src/locale/lang/zh.js @@ -0,0 +1,28 @@ +export default { + // 系统 + system: { + login: '登 陆', + username: '用户名', + password: '密码', + logOut: '注销' + }, + + // 公共 + common: { + search: '搜索', + addition: '添加', + serialNumber: '序号', + operation: '操作', + edit: '编辑', + delete: '删除', + cancel: '取消', + confirm: '确认' + }, + + // 线程池 + threadPool: { + tenant: '租户', + project: '项目', + threadPool: '线程池', + } +} diff --git a/hippo4j-ui/src/locale/langChange.vue b/hippo4j-ui/src/locale/langChange.vue new file mode 100644 index 00000000..c14dbe3c --- /dev/null +++ b/hippo4j-ui/src/locale/langChange.vue @@ -0,0 +1,62 @@ + + + diff --git a/hippo4j-server/hippo4j-ui/src/main.js b/hippo4j-ui/src/main.js similarity index 92% rename from hippo4j-server/hippo4j-ui/src/main.js rename to hippo4j-ui/src/main.js index 28d415d5..44f539b8 100755 --- a/hippo4j-server/hippo4j-ui/src/main.js +++ b/hippo4j-ui/src/main.js @@ -17,6 +17,7 @@ import './icons'; // icon import './permission'; // permission control // import './utils/error-log' // error log +import i18n from '@/locale' import * as filters from './filters'; // global filters import echarts from 'echarts'; Vue.prototype.$echarts = echarts; @@ -25,6 +26,7 @@ Vue.prototype.$cookie = cookie; Vue.use(Element, { size: Cookies.get('size') || 'medium', // set element-ui default size + i18n: (key, value) => i18n.t(key, value) }); // register global utility filters @@ -38,5 +40,6 @@ new Vue({ el: '#app', router, store, + i18n, render: (h) => h(App), }); diff --git a/hippo4j-server/hippo4j-ui/src/permission.js b/hippo4j-ui/src/permission.js similarity index 100% rename from hippo4j-server/hippo4j-ui/src/permission.js rename to hippo4j-ui/src/permission.js diff --git a/hippo4j-server/hippo4j-ui/src/router/index.js b/hippo4j-ui/src/router/index.js similarity index 100% rename from hippo4j-server/hippo4j-ui/src/router/index.js rename to hippo4j-ui/src/router/index.js diff --git a/hippo4j-server/hippo4j-ui/src/router/modules/tool.js b/hippo4j-ui/src/router/modules/tool.js similarity index 100% rename from hippo4j-server/hippo4j-ui/src/router/modules/tool.js rename to hippo4j-ui/src/router/modules/tool.js diff --git a/hippo4j-server/hippo4j-ui/src/settings.js b/hippo4j-ui/src/settings.js similarity index 100% rename from hippo4j-server/hippo4j-ui/src/settings.js rename to hippo4j-ui/src/settings.js diff --git a/hippo4j-server/hippo4j-ui/src/store/getters.js b/hippo4j-ui/src/store/getters.js similarity index 100% rename from hippo4j-server/hippo4j-ui/src/store/getters.js rename to hippo4j-ui/src/store/getters.js diff --git a/hippo4j-server/hippo4j-ui/src/store/index.js b/hippo4j-ui/src/store/index.js similarity index 100% rename from hippo4j-server/hippo4j-ui/src/store/index.js rename to hippo4j-ui/src/store/index.js diff --git a/hippo4j-server/hippo4j-ui/src/store/modules/app.js b/hippo4j-ui/src/store/modules/app.js similarity index 100% rename from hippo4j-server/hippo4j-ui/src/store/modules/app.js rename to hippo4j-ui/src/store/modules/app.js diff --git a/hippo4j-server/hippo4j-ui/src/store/modules/errorLog.js b/hippo4j-ui/src/store/modules/errorLog.js similarity index 100% rename from hippo4j-server/hippo4j-ui/src/store/modules/errorLog.js rename to hippo4j-ui/src/store/modules/errorLog.js diff --git a/hippo4j-server/hippo4j-ui/src/store/modules/permission.js b/hippo4j-ui/src/store/modules/permission.js similarity index 100% rename from hippo4j-server/hippo4j-ui/src/store/modules/permission.js rename to hippo4j-ui/src/store/modules/permission.js diff --git a/hippo4j-server/hippo4j-ui/src/store/modules/settings.js b/hippo4j-ui/src/store/modules/settings.js similarity index 100% rename from hippo4j-server/hippo4j-ui/src/store/modules/settings.js rename to hippo4j-ui/src/store/modules/settings.js diff --git a/hippo4j-server/hippo4j-ui/src/store/modules/user.js b/hippo4j-ui/src/store/modules/user.js similarity index 100% rename from hippo4j-server/hippo4j-ui/src/store/modules/user.js rename to hippo4j-ui/src/store/modules/user.js diff --git a/hippo4j-server/hippo4j-ui/src/styles/btn.scss b/hippo4j-ui/src/styles/btn.scss similarity index 97% rename from hippo4j-server/hippo4j-ui/src/styles/btn.scss rename to hippo4j-ui/src/styles/btn.scss index e6ba1a8e..8f47f2c0 100755 --- a/hippo4j-server/hippo4j-ui/src/styles/btn.scss +++ b/hippo4j-ui/src/styles/btn.scss @@ -1,4 +1,4 @@ -@import './variables.scss'; +@import 'variables'; @mixin colorBtn($color) { background: $color; diff --git a/hippo4j-server/hippo4j-ui/src/styles/element-ui.scss b/hippo4j-ui/src/styles/element-ui.scss similarity index 100% rename from hippo4j-server/hippo4j-ui/src/styles/element-ui.scss rename to hippo4j-ui/src/styles/element-ui.scss diff --git a/hippo4j-server/hippo4j-ui/src/styles/element-variables.scss b/hippo4j-ui/src/styles/element-variables.scss similarity index 100% rename from hippo4j-server/hippo4j-ui/src/styles/element-variables.scss rename to hippo4j-ui/src/styles/element-variables.scss diff --git a/hippo4j-server/hippo4j-ui/src/styles/index.scss b/hippo4j-ui/src/styles/index.scss similarity index 94% rename from hippo4j-server/hippo4j-ui/src/styles/index.scss rename to hippo4j-ui/src/styles/index.scss index a111be42..1fa21ba7 100755 --- a/hippo4j-server/hippo4j-ui/src/styles/index.scss +++ b/hippo4j-ui/src/styles/index.scss @@ -1,9 +1,9 @@ -@import './variables.scss'; -@import './mixin.scss'; -@import './transition.scss'; -@import './element-ui.scss'; -@import './sidebar.scss'; -@import './btn.scss'; +@import 'variables'; +@import 'mixin'; +@import 'transition'; +@import 'element-ui'; +@import 'sidebar'; +@import 'btn'; * { padding: 0; diff --git a/hippo4j-server/hippo4j-ui/src/styles/mixin.scss b/hippo4j-ui/src/styles/mixin.scss similarity index 100% rename from hippo4j-server/hippo4j-ui/src/styles/mixin.scss rename to hippo4j-ui/src/styles/mixin.scss diff --git a/hippo4j-server/hippo4j-ui/src/styles/sidebar.scss b/hippo4j-ui/src/styles/sidebar.scss similarity index 100% rename from hippo4j-server/hippo4j-ui/src/styles/sidebar.scss rename to hippo4j-ui/src/styles/sidebar.scss diff --git a/hippo4j-server/hippo4j-ui/src/styles/transition.scss b/hippo4j-ui/src/styles/transition.scss similarity index 100% rename from hippo4j-server/hippo4j-ui/src/styles/transition.scss rename to hippo4j-ui/src/styles/transition.scss diff --git a/hippo4j-server/hippo4j-ui/src/styles/variables.scss b/hippo4j-ui/src/styles/variables.scss similarity index 100% rename from hippo4j-server/hippo4j-ui/src/styles/variables.scss rename to hippo4j-ui/src/styles/variables.scss diff --git a/hippo4j-server/hippo4j-ui/src/utils/auth.js b/hippo4j-ui/src/utils/auth.js similarity index 100% rename from hippo4j-server/hippo4j-ui/src/utils/auth.js rename to hippo4j-ui/src/utils/auth.js diff --git a/hippo4j-server/hippo4j-ui/src/utils/clipboard.js b/hippo4j-ui/src/utils/clipboard.js similarity index 100% rename from hippo4j-server/hippo4j-ui/src/utils/clipboard.js rename to hippo4j-ui/src/utils/clipboard.js diff --git a/hippo4j-server/hippo4j-ui/src/utils/error-log.js b/hippo4j-ui/src/utils/error-log.js similarity index 100% rename from hippo4j-server/hippo4j-ui/src/utils/error-log.js rename to hippo4j-ui/src/utils/error-log.js diff --git a/hippo4j-server/hippo4j-ui/src/utils/get-page-title.js b/hippo4j-ui/src/utils/get-page-title.js similarity index 100% rename from hippo4j-server/hippo4j-ui/src/utils/get-page-title.js rename to hippo4j-ui/src/utils/get-page-title.js diff --git a/hippo4j-server/hippo4j-ui/src/utils/index.js b/hippo4j-ui/src/utils/index.js similarity index 100% rename from hippo4j-server/hippo4j-ui/src/utils/index.js rename to hippo4j-ui/src/utils/index.js diff --git a/hippo4j-server/hippo4j-ui/src/utils/open-window.js b/hippo4j-ui/src/utils/open-window.js similarity index 100% rename from hippo4j-server/hippo4j-ui/src/utils/open-window.js rename to hippo4j-ui/src/utils/open-window.js diff --git a/hippo4j-server/hippo4j-ui/src/utils/permission.js b/hippo4j-ui/src/utils/permission.js similarity index 100% rename from hippo4j-server/hippo4j-ui/src/utils/permission.js rename to hippo4j-ui/src/utils/permission.js diff --git a/hippo4j-server/hippo4j-ui/src/utils/request.js b/hippo4j-ui/src/utils/request.js similarity index 100% rename from hippo4j-server/hippo4j-ui/src/utils/request.js rename to hippo4j-ui/src/utils/request.js diff --git a/hippo4j-server/hippo4j-ui/src/utils/scroll-to.js b/hippo4j-ui/src/utils/scroll-to.js similarity index 100% rename from hippo4j-server/hippo4j-ui/src/utils/scroll-to.js rename to hippo4j-ui/src/utils/scroll-to.js diff --git a/hippo4j-server/hippo4j-ui/src/utils/validate.js b/hippo4j-ui/src/utils/validate.js similarity index 100% rename from hippo4j-server/hippo4j-ui/src/utils/validate.js rename to hippo4j-ui/src/utils/validate.js diff --git a/hippo4j-server/hippo4j-ui/src/views/dashboard/admin/components/BarChart.vue b/hippo4j-ui/src/views/dashboard/admin/components/BarChart.vue similarity index 100% rename from hippo4j-server/hippo4j-ui/src/views/dashboard/admin/components/BarChart.vue rename to hippo4j-ui/src/views/dashboard/admin/components/BarChart.vue diff --git a/hippo4j-server/hippo4j-ui/src/views/dashboard/admin/components/BoxCard.vue b/hippo4j-ui/src/views/dashboard/admin/components/BoxCard.vue similarity index 100% rename from hippo4j-server/hippo4j-ui/src/views/dashboard/admin/components/BoxCard.vue rename to hippo4j-ui/src/views/dashboard/admin/components/BoxCard.vue diff --git a/hippo4j-server/hippo4j-ui/src/views/dashboard/admin/components/LineChart.vue b/hippo4j-ui/src/views/dashboard/admin/components/LineChart.vue similarity index 100% rename from hippo4j-server/hippo4j-ui/src/views/dashboard/admin/components/LineChart.vue rename to hippo4j-ui/src/views/dashboard/admin/components/LineChart.vue diff --git a/hippo4j-server/hippo4j-ui/src/views/dashboard/admin/components/PanelGroup.vue b/hippo4j-ui/src/views/dashboard/admin/components/PanelGroup.vue similarity index 100% rename from hippo4j-server/hippo4j-ui/src/views/dashboard/admin/components/PanelGroup.vue rename to hippo4j-ui/src/views/dashboard/admin/components/PanelGroup.vue diff --git a/hippo4j-server/hippo4j-ui/src/views/dashboard/admin/components/PieChart.vue b/hippo4j-ui/src/views/dashboard/admin/components/PieChart.vue similarity index 100% rename from hippo4j-server/hippo4j-ui/src/views/dashboard/admin/components/PieChart.vue rename to hippo4j-ui/src/views/dashboard/admin/components/PieChart.vue diff --git a/hippo4j-server/hippo4j-ui/src/views/dashboard/admin/components/RaddarChart.vue b/hippo4j-ui/src/views/dashboard/admin/components/RaddarChart.vue similarity index 100% rename from hippo4j-server/hippo4j-ui/src/views/dashboard/admin/components/RaddarChart.vue rename to hippo4j-ui/src/views/dashboard/admin/components/RaddarChart.vue diff --git a/hippo4j-server/hippo4j-ui/src/views/dashboard/admin/components/TodoList/Todo.vue b/hippo4j-ui/src/views/dashboard/admin/components/TodoList/Todo.vue similarity index 100% rename from hippo4j-server/hippo4j-ui/src/views/dashboard/admin/components/TodoList/Todo.vue rename to hippo4j-ui/src/views/dashboard/admin/components/TodoList/Todo.vue diff --git a/hippo4j-server/hippo4j-ui/src/views/dashboard/admin/components/TodoList/index.scss b/hippo4j-ui/src/views/dashboard/admin/components/TodoList/index.scss similarity index 100% rename from hippo4j-server/hippo4j-ui/src/views/dashboard/admin/components/TodoList/index.scss rename to hippo4j-ui/src/views/dashboard/admin/components/TodoList/index.scss diff --git a/hippo4j-server/hippo4j-ui/src/views/dashboard/admin/components/TodoList/index.vue b/hippo4j-ui/src/views/dashboard/admin/components/TodoList/index.vue similarity index 100% rename from hippo4j-server/hippo4j-ui/src/views/dashboard/admin/components/TodoList/index.vue rename to hippo4j-ui/src/views/dashboard/admin/components/TodoList/index.vue diff --git a/hippo4j-server/hippo4j-ui/src/views/dashboard/admin/components/TransactionTable.vue b/hippo4j-ui/src/views/dashboard/admin/components/TransactionTable.vue similarity index 100% rename from hippo4j-server/hippo4j-ui/src/views/dashboard/admin/components/TransactionTable.vue rename to hippo4j-ui/src/views/dashboard/admin/components/TransactionTable.vue diff --git a/hippo4j-server/hippo4j-ui/src/views/dashboard/admin/components/mixins/resize.js b/hippo4j-ui/src/views/dashboard/admin/components/mixins/resize.js similarity index 100% rename from hippo4j-server/hippo4j-ui/src/views/dashboard/admin/components/mixins/resize.js rename to hippo4j-ui/src/views/dashboard/admin/components/mixins/resize.js diff --git a/hippo4j-server/hippo4j-ui/src/views/dashboard/admin/index.vue b/hippo4j-ui/src/views/dashboard/admin/index.vue similarity index 100% rename from hippo4j-server/hippo4j-ui/src/views/dashboard/admin/index.vue rename to hippo4j-ui/src/views/dashboard/admin/index.vue diff --git a/hippo4j-server/hippo4j-ui/src/views/dashboard/index.vue b/hippo4j-ui/src/views/dashboard/index.vue similarity index 100% rename from hippo4j-server/hippo4j-ui/src/views/dashboard/index.vue rename to hippo4j-ui/src/views/dashboard/index.vue diff --git a/hippo4j-server/hippo4j-ui/src/views/error-page/401.vue b/hippo4j-ui/src/views/error-page/401.vue similarity index 100% rename from hippo4j-server/hippo4j-ui/src/views/error-page/401.vue rename to hippo4j-ui/src/views/error-page/401.vue diff --git a/hippo4j-server/hippo4j-ui/src/views/error-page/404.vue b/hippo4j-ui/src/views/error-page/404.vue similarity index 100% rename from hippo4j-server/hippo4j-ui/src/views/error-page/404.vue rename to hippo4j-ui/src/views/error-page/404.vue diff --git a/hippo4j-server/hippo4j-ui/src/views/hippo4j/instance/index.vue b/hippo4j-ui/src/views/hippo4j/instance/index.vue similarity index 100% rename from hippo4j-server/hippo4j-ui/src/views/hippo4j/instance/index.vue rename to hippo4j-ui/src/views/hippo4j/instance/index.vue diff --git a/hippo4j-server/hippo4j-ui/src/views/hippo4j/item/index.vue b/hippo4j-ui/src/views/hippo4j/item/index.vue similarity index 100% rename from hippo4j-server/hippo4j-ui/src/views/hippo4j/item/index.vue rename to hippo4j-ui/src/views/hippo4j/item/index.vue diff --git a/hippo4j-server/hippo4j-ui/src/views/hippo4j/log/index.vue b/hippo4j-ui/src/views/hippo4j/log/index.vue similarity index 100% rename from hippo4j-server/hippo4j-ui/src/views/hippo4j/log/index.vue rename to hippo4j-ui/src/views/hippo4j/log/index.vue diff --git a/hippo4j-server/hippo4j-ui/src/views/hippo4j/monitor/components/LineChart.vue b/hippo4j-ui/src/views/hippo4j/monitor/components/LineChart.vue similarity index 100% rename from hippo4j-server/hippo4j-ui/src/views/hippo4j/monitor/components/LineChart.vue rename to hippo4j-ui/src/views/hippo4j/monitor/components/LineChart.vue diff --git a/hippo4j-server/hippo4j-ui/src/views/hippo4j/monitor/components/PieChart.vue b/hippo4j-ui/src/views/hippo4j/monitor/components/PieChart.vue similarity index 100% rename from hippo4j-server/hippo4j-ui/src/views/hippo4j/monitor/components/PieChart.vue rename to hippo4j-ui/src/views/hippo4j/monitor/components/PieChart.vue diff --git a/hippo4j-server/hippo4j-ui/src/views/hippo4j/monitor/components/RaddarChart.vue b/hippo4j-ui/src/views/hippo4j/monitor/components/RaddarChart.vue similarity index 100% rename from hippo4j-server/hippo4j-ui/src/views/hippo4j/monitor/components/RaddarChart.vue rename to hippo4j-ui/src/views/hippo4j/monitor/components/RaddarChart.vue diff --git a/hippo4j-server/hippo4j-ui/src/views/hippo4j/monitor/components/mixins/resize.js b/hippo4j-ui/src/views/hippo4j/monitor/components/mixins/resize.js similarity index 100% rename from hippo4j-server/hippo4j-ui/src/views/hippo4j/monitor/components/mixins/resize.js rename to hippo4j-ui/src/views/hippo4j/monitor/components/mixins/resize.js diff --git a/hippo4j-server/hippo4j-ui/src/views/hippo4j/monitor/index.vue b/hippo4j-ui/src/views/hippo4j/monitor/index.vue similarity index 97% rename from hippo4j-server/hippo4j-ui/src/views/hippo4j/monitor/index.vue rename to hippo4j-ui/src/views/hippo4j/monitor/index.vue index 686ff773..58d14f69 100755 --- a/hippo4j-server/hippo4j-ui/src/views/hippo4j/monitor/index.vue +++ b/hippo4j-ui/src/views/hippo4j/monitor/index.vue @@ -84,7 +84,7 @@
- + @@ -288,10 +288,10 @@ export default { this.temp = res; }); - monitorApi.lastTaskCountFun(this.listQuery).then((res) => { - this.rejectCount = res.rejectCount; - this.lastTaskCount = res.completedTaskCount; - }); + // monitorApi.lastTaskCountFun(this.listQuery).then((res) => { + // this.rejectCount = res.rejectCount; + // this.lastTaskCount = res.completedTaskCount; + // }); this.initChart(); }, diff --git a/hippo4j-server/hippo4j-ui/src/views/hippo4j/notify/index.vue b/hippo4j-ui/src/views/hippo4j/notify/index.vue similarity index 100% rename from hippo4j-server/hippo4j-ui/src/views/hippo4j/notify/index.vue rename to hippo4j-ui/src/views/hippo4j/notify/index.vue diff --git a/hippo4j-server/hippo4j-ui/src/views/hippo4j/other/alibaba-dubbo/index.vue b/hippo4j-ui/src/views/hippo4j/other/alibaba-dubbo/index.vue similarity index 99% rename from hippo4j-server/hippo4j-ui/src/views/hippo4j/other/alibaba-dubbo/index.vue rename to hippo4j-ui/src/views/hippo4j/other/alibaba-dubbo/index.vue index 9cef3ce2..da1e1761 100755 --- a/hippo4j-server/hippo4j-ui/src/views/hippo4j/other/alibaba-dubbo/index.vue +++ b/hippo4j-ui/src/views/hippo4j/other/alibaba-dubbo/index.vue @@ -215,8 +215,6 @@ export default { runTimeTemp: {}, typeOptions: [ { key: 'Dubbo', display_name: 'Dubbo' }, - { key: 'Kafka', display_name: 'Kafka' }, - { key: 'KafkaSpringCloudStream', display_name: 'KafkaSpringCloudStream' }, { key: 'RocketMQ', display_name: 'RocketMQ' }, { key: 'RocketMQSpringCloudStream', display_name: 'RocketMQSpringCloudStream' }, { key: 'RabbitMQ', display_name: 'RabbitMQ' }, diff --git a/hippo4j-server/hippo4j-ui/src/views/hippo4j/other/dubbo/index.vue b/hippo4j-ui/src/views/hippo4j/other/dubbo/index.vue similarity index 99% rename from hippo4j-server/hippo4j-ui/src/views/hippo4j/other/dubbo/index.vue rename to hippo4j-ui/src/views/hippo4j/other/dubbo/index.vue index a7422930..530275f6 100755 --- a/hippo4j-server/hippo4j-ui/src/views/hippo4j/other/dubbo/index.vue +++ b/hippo4j-ui/src/views/hippo4j/other/dubbo/index.vue @@ -215,8 +215,6 @@ export default { runTimeTemp: {}, typeOptions: [ { key: 'Dubbo', display_name: 'Dubbo' }, - { key: 'Kafka', display_name: 'Kafka' }, - { key: 'KafkaSpringCloudStream', display_name: 'KafkaSpringCloudStream' }, { key: 'RocketMQ', display_name: 'RocketMQ' }, { key: 'RocketMQSpringCloudStream', display_name: 'RocketMQSpringCloudStream' }, { key: 'RabbitMQ', display_name: 'RabbitMQ' }, diff --git a/hippo4j-server/hippo4j-ui/src/views/hippo4j/other/hystrix/index.vue b/hippo4j-ui/src/views/hippo4j/other/hystrix/index.vue similarity index 99% rename from hippo4j-server/hippo4j-ui/src/views/hippo4j/other/hystrix/index.vue rename to hippo4j-ui/src/views/hippo4j/other/hystrix/index.vue index 4d9c41f9..1162ed67 100755 --- a/hippo4j-server/hippo4j-ui/src/views/hippo4j/other/hystrix/index.vue +++ b/hippo4j-ui/src/views/hippo4j/other/hystrix/index.vue @@ -215,8 +215,6 @@ export default { runTimeTemp: {}, typeOptions: [ { key: 'Dubbo', display_name: 'Dubbo' }, - { key: 'Kafka', display_name: 'Kafka' }, - { key: 'KafkaSpringCloudStream', display_name: 'KafkaSpringCloudStream' }, { key: 'RocketMQ', display_name: 'RocketMQ' }, { key: 'RocketMQSpringCloudStream', display_name: 'RocketMQSpringCloudStream' }, { key: 'RabbitMQ', display_name: 'RabbitMQ' }, diff --git a/hippo4j-server/hippo4j-ui/src/views/hippo4j/other/index.vue b/hippo4j-ui/src/views/hippo4j/other/index.vue similarity index 99% rename from hippo4j-server/hippo4j-ui/src/views/hippo4j/other/index.vue rename to hippo4j-ui/src/views/hippo4j/other/index.vue index ab6b6790..64cea308 100755 --- a/hippo4j-server/hippo4j-ui/src/views/hippo4j/other/index.vue +++ b/hippo4j-ui/src/views/hippo4j/other/index.vue @@ -227,8 +227,6 @@ export default { runTimeTemp: {}, typeOptions: [ { key: 'Dubbo', display_name: 'Dubbo' }, - { key: 'Kafka', display_name: 'Kafka' }, - { key: 'KafkaSpringCloudStream', display_name: 'KafkaSpringCloudStream' }, { key: 'RocketMQ', display_name: 'RocketMQ' }, { key: 'RocketMQSpringCloudStream', display_name: 'RocketMQSpringCloudStream' }, { key: 'RabbitMQ', display_name: 'RabbitMQ' }, diff --git a/hippo4j-server/hippo4j-ui/src/views/hippo4j/other/rabbitmq-stream/index.vue b/hippo4j-ui/src/views/hippo4j/other/rabbitmq-stream/index.vue similarity index 99% rename from hippo4j-server/hippo4j-ui/src/views/hippo4j/other/rabbitmq-stream/index.vue rename to hippo4j-ui/src/views/hippo4j/other/rabbitmq-stream/index.vue index 47384c5b..b2c4918c 100755 --- a/hippo4j-server/hippo4j-ui/src/views/hippo4j/other/rabbitmq-stream/index.vue +++ b/hippo4j-ui/src/views/hippo4j/other/rabbitmq-stream/index.vue @@ -214,8 +214,6 @@ export default { runTimeTemp: {}, typeOptions: [ { key: 'Dubbo', display_name: 'Dubbo' }, - { key: 'Kafka', display_name: 'Kafka' }, - { key: 'KafkaSpringCloudStream', display_name: 'KafkaSpringCloudStream' }, { key: 'RocketMQ', display_name: 'RocketMQ' }, { key: 'RocketMQSpringCloudStream', display_name: 'RocketMQSpringCloudStream' }, { key: 'RabbitMQ', display_name: 'RabbitMQ' }, diff --git a/hippo4j-server/hippo4j-ui/src/views/hippo4j/other/rabbitmq/index.vue b/hippo4j-ui/src/views/hippo4j/other/rabbitmq/index.vue similarity index 99% rename from hippo4j-server/hippo4j-ui/src/views/hippo4j/other/rabbitmq/index.vue rename to hippo4j-ui/src/views/hippo4j/other/rabbitmq/index.vue index 0579bfd7..9dabd398 100755 --- a/hippo4j-server/hippo4j-ui/src/views/hippo4j/other/rabbitmq/index.vue +++ b/hippo4j-ui/src/views/hippo4j/other/rabbitmq/index.vue @@ -215,8 +215,6 @@ export default { runTimeTemp: {}, typeOptions: [ { key: 'Dubbo', display_name: 'Dubbo' }, - { key: 'Kafka', display_name: 'Kafka' }, - { key: 'KafkaSpringCloudStream', display_name: 'KafkaSpringCloudStream' }, { key: 'RocketMQ', display_name: 'RocketMQ' }, { key: 'RocketMQSpringCloudStream', display_name: 'RocketMQSpringCloudStream' }, { key: 'RabbitMQ', display_name: 'RabbitMQ' }, diff --git a/hippo4j-server/hippo4j-ui/src/views/hippo4j/other/rocketmq-stream/index.vue b/hippo4j-ui/src/views/hippo4j/other/rocketmq-stream/index.vue similarity index 99% rename from hippo4j-server/hippo4j-ui/src/views/hippo4j/other/rocketmq-stream/index.vue rename to hippo4j-ui/src/views/hippo4j/other/rocketmq-stream/index.vue index f0dfb75b..f64b9c78 100755 --- a/hippo4j-server/hippo4j-ui/src/views/hippo4j/other/rocketmq-stream/index.vue +++ b/hippo4j-ui/src/views/hippo4j/other/rocketmq-stream/index.vue @@ -214,8 +214,6 @@ export default { runTimeTemp: {}, typeOptions: [ { key: 'Dubbo', display_name: 'Dubbo' }, - { key: 'Kafka', display_name: 'Kafka' }, - { key: 'KafkaSpringCloudStream', display_name: 'KafkaSpringCloudStream' }, { key: 'RocketMQ', display_name: 'RocketMQ' }, { key: 'RocketMQSpringCloudStream', display_name: 'RocketMQSpringCloudStream' }, { key: 'RabbitMQ', display_name: 'RabbitMQ' }, diff --git a/hippo4j-server/hippo4j-ui/src/views/hippo4j/other/rocketmq/index.vue b/hippo4j-ui/src/views/hippo4j/other/rocketmq/index.vue similarity index 99% rename from hippo4j-server/hippo4j-ui/src/views/hippo4j/other/rocketmq/index.vue rename to hippo4j-ui/src/views/hippo4j/other/rocketmq/index.vue index dfac0769..17c4fb9a 100755 --- a/hippo4j-server/hippo4j-ui/src/views/hippo4j/other/rocketmq/index.vue +++ b/hippo4j-ui/src/views/hippo4j/other/rocketmq/index.vue @@ -215,8 +215,6 @@ export default { runTimeTemp: {}, typeOptions: [ { key: 'Dubbo', display_name: 'Dubbo' }, - { key: 'Kafka', display_name: 'Kafka' }, - { key: 'KafkaSpringCloudStream', display_name: 'KafkaSpringCloudStream' }, { key: 'RocketMQ', display_name: 'RocketMQ' }, { key: 'RocketMQSpringCloudStream', display_name: 'RocketMQSpringCloudStream' }, { key: 'RabbitMQ', display_name: 'RabbitMQ' }, diff --git a/hippo4j-server/hippo4j-ui/src/views/hippo4j/server/index.vue b/hippo4j-ui/src/views/hippo4j/server/index.vue similarity index 100% rename from hippo4j-server/hippo4j-ui/src/views/hippo4j/server/index.vue rename to hippo4j-ui/src/views/hippo4j/server/index.vue diff --git a/hippo4j-server/hippo4j-ui/src/views/hippo4j/server/jetty/index.vue b/hippo4j-ui/src/views/hippo4j/server/jetty/index.vue similarity index 100% rename from hippo4j-server/hippo4j-ui/src/views/hippo4j/server/jetty/index.vue rename to hippo4j-ui/src/views/hippo4j/server/jetty/index.vue diff --git a/hippo4j-server/hippo4j-ui/src/views/hippo4j/server/tomcat/index.vue b/hippo4j-ui/src/views/hippo4j/server/tomcat/index.vue similarity index 100% rename from hippo4j-server/hippo4j-ui/src/views/hippo4j/server/tomcat/index.vue rename to hippo4j-ui/src/views/hippo4j/server/tomcat/index.vue diff --git a/hippo4j-server/hippo4j-ui/src/views/hippo4j/server/undertow/index.vue b/hippo4j-ui/src/views/hippo4j/server/undertow/index.vue similarity index 100% rename from hippo4j-server/hippo4j-ui/src/views/hippo4j/server/undertow/index.vue rename to hippo4j-ui/src/views/hippo4j/server/undertow/index.vue diff --git a/hippo4j-server/hippo4j-ui/src/views/hippo4j/tenant/index.vue b/hippo4j-ui/src/views/hippo4j/tenant/index.vue similarity index 100% rename from hippo4j-server/hippo4j-ui/src/views/hippo4j/tenant/index.vue rename to hippo4j-ui/src/views/hippo4j/tenant/index.vue diff --git a/hippo4j-server/hippo4j-ui/src/views/hippo4j/threadpool/index.vue b/hippo4j-ui/src/views/hippo4j/threadpool/index.vue similarity index 97% rename from hippo4j-server/hippo4j-ui/src/views/hippo4j/threadpool/index.vue rename to hippo4j-ui/src/views/hippo4j/threadpool/index.vue index 267cc30a..f6505f24 100755 --- a/hippo4j-server/hippo4j-ui/src/views/hippo4j/threadpool/index.vue +++ b/hippo4j-ui/src/views/hippo4j/threadpool/index.vue @@ -3,7 +3,7 @@
- 搜索 + {{ $t('common.search') }} - 添加 + {{ $t('common.addition') }}
- + @@ -129,16 +129,16 @@ @@ -327,9 +327,9 @@ diff --git a/hippo4j-server/hippo4j-ui/src/views/hippo4j/user/index.vue b/hippo4j-ui/src/views/hippo4j/user/index.vue similarity index 100% rename from hippo4j-server/hippo4j-ui/src/views/hippo4j/user/index.vue rename to hippo4j-ui/src/views/hippo4j/user/index.vue diff --git a/hippo4j-server/hippo4j-ui/src/views/hippo4j/verify/index.vue b/hippo4j-ui/src/views/hippo4j/verify/index.vue similarity index 100% rename from hippo4j-server/hippo4j-ui/src/views/hippo4j/verify/index.vue rename to hippo4j-ui/src/views/hippo4j/verify/index.vue diff --git a/hippo4j-server/hippo4j-ui/src/views/login/auth-redirect.vue b/hippo4j-ui/src/views/login/auth-redirect.vue similarity index 100% rename from hippo4j-server/hippo4j-ui/src/views/login/auth-redirect.vue rename to hippo4j-ui/src/views/login/auth-redirect.vue diff --git a/hippo4j-server/hippo4j-ui/src/views/login/components/SocialSignin.vue b/hippo4j-ui/src/views/login/components/SocialSignin.vue similarity index 100% rename from hippo4j-server/hippo4j-ui/src/views/login/components/SocialSignin.vue rename to hippo4j-ui/src/views/login/components/SocialSignin.vue diff --git a/hippo4j-server/hippo4j-ui/src/views/login/index.vue b/hippo4j-ui/src/views/login/index.vue similarity index 98% rename from hippo4j-server/hippo4j-ui/src/views/login/index.vue rename to hippo4j-ui/src/views/login/index.vue index 19fa52d5..7710cf18 100755 --- a/hippo4j-server/hippo4j-ui/src/views/login/index.vue +++ b/hippo4j-ui/src/views/login/index.vue @@ -9,7 +9,7 @@ label-position="left" >
-

Login Form

+

{{ $t('system.login') }}

@@ -19,7 +19,7 @@ chen.ma machen@apache.org - https://github.com/itmachen - OpenGoofy - https://github.com/opengoofy - - Project lead - + https://github.com/mageeric shining-stars-lk @@ -43,23 +38,25 @@ hippo4j-example hippo4j-message hippo4j-monitor + hippo4j-rpc hippo4j-server hippo4j-spring-boot - 1.4.3-SNAPSHOT + 1.5.0-SNAPSHOT 6.5.0 2.9.3 6.1.5.Final - 2.12.1 0.9.0 2.11.1 2.0.0 + 2.1.214 + 3.0.5 + 2.6.12 1.7.7 - 1.2.9 1.8.4 2.0.4 3.4.2 @@ -69,6 +66,7 @@ 1.7.2 2.2.2 4.1.56.Final + 6.8.17 9.0.55 5.1.0 2.2.6.RELEASE @@ -108,21 +106,6 @@ pom import - - cn.hippo4j - hippo4j-message - ${revision} - - - cn.hippo4j - hippo4j-core - ${revision} - - - cn.hippo4j - hippo4j-adapter-base - ${revision} - com.baomidou mybatis-plus-boot-starter @@ -133,47 +116,11 @@ dozer-core ${dozer.version} - - com.github.ben-manes.caffeine - caffeine - ${caffeine.version} - - - com.aliyun - alibaba-dingtalk-service-sdk - ${dingtalk-sdk.version} - - - com.alibaba - transmittable-thread-local - ${transmittable-thread-local.version} - - - org.hibernate.validator - hibernate-validator - ${hibernate-validator.version} - org.slf4j slf4j-api ${slf4j-api.version} - - ch.qos.logback - logback-core - ${logback.version} - - - ch.qos.logback - logback-classic - ${logback.version} - - - org.springframework.boot - spring-boot-starter-json - ${spring-boot.version} - compile - io.netty netty-all