Merge remote-tracking branch 'origin/develop' into develop

pull/659/head
shining-stars-lk 3 years ago
commit cf5027194a

@ -2,7 +2,7 @@
# 动态可观测线程池框架,提高线上运行保障能力
[![Gitee](https://gitee.com/agentart/hippo4j/badge/star.svg?theme=gvp)](https://gitee.com/agentart/hippo4j) [![GitHub](https://img.shields.io/github/stars/opengoofy/hippo4j)](https://github.com/opengoofy/hippo4j) [![OpenIssue](http://isitmaintained.com/badge/open/opengoofy/hippo4j.svg)](https://github.com/opengoofy/hippo4j/issues) [![Contributors](https://img.shields.io/github/contributors/opengoofy/hippo4j?color=3ba272)](https://github.com/opengoofy/hippo4j/graphs/contributors) [![License](https://img.shields.io/github/license/opengoofy/hippo4j?color=5470c6)](https://github.com/opengoofy/hippo4j/blob/develop/LICENSE)
[![Gitee](https://gitee.com/agentart/hippo4j/badge/star.svg?theme=gvp)](https://gitee.com/agentart/hippo4j) [![GitHub](https://img.shields.io/github/stars/opengoofy/hippo4j)](https://github.com/opengoofy/hippo4j) [![Docker Pulls](https://img.shields.io/docker/pulls/hippo4j/hippo4j-server.svg)](https://store.docker.com/community/images/hippo4j/hippo4j-server) [![Contributors](https://img.shields.io/github/contributors/opengoofy/hippo4j?color=3ba272)](https://github.com/opengoofy/hippo4j/graphs/contributors) [![License](https://img.shields.io/github/license/opengoofy/hippo4j?color=5470c6)](https://github.com/opengoofy/hippo4j/blob/develop/LICENSE)
-------
@ -32,7 +32,7 @@ Hippo-4J 通过对 JDK 线程池增强,以及扩展三方框架底层线程池
- 通知报警 - 内置四种报警通知策略,线程池活跃度、容量水位、拒绝策略以及任务执行时间超长;
- 运行监控 - 实时查看线程池运行时数据,最近半小时线程池运行数据图表展示;
- 功能扩展 - 支持线程池任务传递上下文;项目关闭时,支持等待线程池在指定时间内完成任务;
- 多种模式 - 内置两种使用模式:[依赖配置中心](https://hippo4j.cn/docs/user_docs/getting-started/hippo4j-core-start) 和 [无中间件依赖](https://hippo4j.cn/docs/user_docs/getting-started/hippo4j-server-start)
- 多种模式 - 内置两种使用模式:[依赖配置中心](https://hippo4j.cn/docs/user_docs/getting-started/config/hippo4j-core-start) 和 [无中间件依赖](https://hippo4j.cn/docs/user_docs/getting-started/server/hippo4j-server-start)
- 容器管理 - Tomcat、Jetty、Undertow 容器线程池运行时查看和线程数变更;
- 中间件适配 - Apache RocketMQ、Dubbo、RabbitMQ、Hystrix 消费线程池运行时数据查看和线程数变更。
@ -52,16 +52,14 @@ Hippo-4J 获得了一些宝贵的荣誉,肯定了 Hippo-4J 作为一款开源
<img align="center" width="680" alt="image" src="https://user-images.githubusercontent.com/77398366/187014905-b50bdc8b-ca0e-4137-9a02-1e6b06106191.jpg">
## 开发者
Hippo-4J 获得的成就属于每一位对 Hippo-4J 做出过贡献的成员,感谢各位的贡献
Hippo-4J 获得的成就属于每一位对 Hippo-4J 做出过贡献的成员,感谢各位的付出
如果屏幕前的同学有意提交 Hippo-4J请参考 [good first issue](https://github.com/opengoofy/hippo4j/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22) 或者 [good pro issue](https://github.com/opengoofy/hippo4j/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+pro+issue%22) 任务列表。
<a href="https://github.com/opengoofy/hippo4j/graphs/contributors"><img src="https://opencollective.com/hippo4j/contributors.svg?width=890&button=false" /></a>
## 友情链接
- [[ Sa-Token ]](https://github.com/dromara/sa-token):一个轻量级 java 权限认证框架,让鉴权变得简单、优雅!
@ -72,7 +70,6 @@ Hippo-4J 获得的成就属于每一位对 Hippo-4J 做出过贡献的成员,
- [[ toBeBetterJavaer ]](https://github.com/itwanger/toBeBetterJavaer):一份通俗易懂、风趣幽默的 Java 学习指南。
## 联系我
![image](https://user-images.githubusercontent.com/77398366/185774220-c11951f9-e130-4d60-8204-afb5c51d4401.png)

@ -6,7 +6,9 @@ sidebar_position: 1
Git Commit Log 尽量使用英文。
为了让您的 ID 显示在 Contributor 列表中,别忘了以下设置:
Pull Request 尽量保持单一,不同语义的代码贡献应拆分多个 Pull Request。
为了让您的 GitHub ID 显示在 Contributor 列表中,别忘了以下设置:
```shell
git config --global user.name "username"

@ -12,7 +12,7 @@ sidebar_position: 3
## 谁在使用 Hippo4J
共计 16+ 家公司生产接入 Hippo4J。按照公司登记时间排序。
共计 18+ 家公司生产接入 Hippo4J。按照公司登记时间排序。
- [身边云](https://serviceshare.com)
- [Medbanks](https://www.medbanks.cn)
@ -30,3 +30,5 @@ sidebar_position: 3
- [众合云科51社保](https://home.101hr.com/)
- [好货云店](https://pc.haohuoyundian.com/)
- [斗象科技](https://www.tophant.com/)
- [深圳航天信息有限公司](http://sz.aisino.com/)
- [新东方教育科技集团](https://www.xdf.cn/)

@ -12,8 +12,10 @@ sidebar_position: 4
感谢给予支持的朋友,您的支持是我前进的动力 🎉
| | ID | 赞赏金额 | 时间 | 备注 |
|-----| ------- | ---- | ---------- | ------------------------------------ |
| 1 | 六月飞雪 | 30.00 | 2021-12-30 | 代码设计很优雅的一款框架,继续加油! |
| 2 | 孙大圣 | 26.6 | 2022-03-23 | 学习一下😁😁 |
| 3 | Easy 点 | 66.00 | 2022-04-09 | 好货好技术当加赏 |
| | 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 | 👍 |

@ -0,0 +1,5 @@
{
"label": "依赖配置中心",
"position": 2,
"collapsed": true
}

@ -2,9 +2,9 @@
sidebar_position: 2
---
# hippo4j config 线程池监控
# 线程池监控
已完成 hippo4j-config 的 [接入工作](/docs/user_docs/getting-started/hippo4j-core-start) 。
已完成 hippo4j-config 的 [接入工作](/docs/user_docs/getting_started/config/hippo4j-config-start) 。
## 安装 Grafana + Prometheus
@ -51,7 +51,7 @@ management:
spring:
dynamic:
thread-pool:
collect-type: metric
collect-type: prometheus
```
Prometheus 配置任务,配置成功后需重启。
@ -76,7 +76,6 @@ Grafana DashBoard 配置。
![](https://images-machen.oss-cn-beijing.aliyuncs.com/43_65f6020ed111b6bb3808ec338576bd6b.png)
![](https://images-machen.oss-cn-beijing.aliyuncs.com/image-20220327171957444.png)
获取到 JSON 文件后,导入至 Grafana。

@ -2,9 +2,9 @@
sidebar_position: 1
---
# hippo4j config 接入
# 接入流程
Nacos、Apollo、Zookeeper 配置中心任选其一。
Nacos、Apollo、Zookeeper、ETCD 配置中心任选其一。
## hippo4j 配置
@ -191,56 +191,3 @@ private ThreadPoolExecutor messageProduceDynamicExecutor;
messageProduceDynamicExecutor.execute(() -> xxx);
```
## ThreadPoolTaskExecutor 适配
Spring 针对 JDK 线程池提供了增强版的 `ThreadPoolTaskExecutor`Hippo4J 对此进行了适配。
```java
package cn.hippo4j.example;
import cn.hippo4j.core.executor.DynamicThreadPool;
import cn.hippo4j.core.executor.support.ResizableCapacityLinkedBlockIngQueue;
import cn.hippo4j.core.executor.support.ThreadPoolBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
@Configuration
public class ThreadPoolConfig {
@Bean
@DynamicThreadPool
public ThreadPoolExecutor dynamicThreadPoolExecutor() {
String threadPoolId = "message-consume";
ThreadPoolExecutor dynamicExecutor = ThreadPoolBuilder.builder()
.threadFactory(threadPoolId)
.threadPoolId(threadPoolId)
.corePoolSize(5)
.maxPoolNum(10)
.workQueue(new ResizableCapacityLinkedBlockIngQueue(1024))
.rejected(new ThreadPoolExecutor.AbortPolicy())
.keepAliveTime(6000, TimeUnit.MILLISECONDS)
// 等待终止毫秒
.awaitTerminationMillis(5000)
// 线程任务装饰器
.taskDecorator((task) -> {
String placeholderVal = MDC.get("xxx");
return () -> {
try {
MDC.put("xxx", placeholderVal);
task.run();
} finally {
MDC.clear();
}
};
})
.dynamicPool()
.build();
return dynamicExecutor;
}
}
```

@ -2,7 +2,7 @@
sidebar_position: 0
---
# hippo4j 的两种使用模式
# 运行模式介绍
1.1.0 版本发布后Hippo-4J 分为两种使用模式:轻量级依赖配置中心以及无中间件依赖版本。
@ -12,7 +12,7 @@ sidebar_position: 0
**轻量级动态线程池管理**,依赖 Apollo、Nacos、Zookeeper 等三方配置中心(任选其一)完成线程池参数动态变更,支持运行时报警、监控等功能。
> 监控功能配置详见:[线程池监控](/docs/user_docs/getting-started/hippo4j-core-monitor)
> 监控功能配置详见:[线程池监控](/docs/user_docs/getting_started/config/hippo4j-config-monitor)
![](https://images-machen.oss-cn-beijing.aliyuncs.com/20220814_hippo4j_monitor.jpg)

@ -2,7 +2,7 @@
sidebar_position: 6
---
# hippo4j 三方框架线程池适配
# 三方框架线程池适配
Hippo4J 目前已支持的三方框架线程池列表:
@ -53,9 +53,9 @@ Hippo4J Server 仅需要引入上述 Jar 包,即可在 Hippo4J Server 的控
![](https://images-machen.oss-cn-beijing.aliyuncs.com/image-20220531194810047.png)
## Hippo4J Core
## Hippo4J Config
Hippo4J Core 除了依赖上述适配 Jar 包外,还需要在配置中心添加以下配置项。
Hippo4J Config 除了依赖上述适配 Jar 包外,还需要在配置中心添加以下配置项。
```yaml
spring:

@ -0,0 +1,5 @@
{
"label": "无中间件依赖",
"position": 3,
"collapsed": true
}

@ -2,7 +2,7 @@
sidebar_position: 4
---
# hippo4j server 服务端配置
# 服务端配置
`hippo4j.core.clean-history-data-enable`

@ -2,7 +2,7 @@
sidebar_position: 3
---
# hippo4j server 接入
# 接入流程
部署服务端,参考 [部署手册](/docs/user_docs/ops/hippo4j-server-deploy)。
@ -127,55 +127,3 @@ private ThreadPoolExecutor messageProduceDynamicExecutor;
messageProduceDynamicExecutor.execute(() -> xxx);
```
## ThreadPoolTaskExecutor 适配
Spring 针对 JDK 线程池提供了增强版的 `ThreadPoolTaskExecutor`Hippo4J 对此进行了适配。
```java
package cn.hippo4j.example;
import cn.hippo4j.core.executor.DynamicThreadPool;
import cn.hippo4j.core.executor.support.ResizableCapacityLinkedBlockIngQueue;
import cn.hippo4j.core.executor.support.ThreadPoolBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
@Configuration
public class ThreadPoolConfig {
@Bean
@DynamicThreadPool
public ThreadPoolExecutor dynamicThreadPoolExecutor() {
String threadPoolId = "message-consume";
ThreadPoolExecutor dynamicExecutor = ThreadPoolBuilder.builder()
.threadFactory(threadPoolId)
.threadPoolId(threadPoolId)
.corePoolSize(5)
.maxPoolNum(10)
.workQueue(new ResizableCapacityLinkedBlockIngQueue(1024))
.rejected(new ThreadPoolExecutor.AbortPolicy())
.keepAliveTime(6000, TimeUnit.MILLISECONDS)
// 等待终止毫秒
.awaitTerminationMillis(5000)
// 线程任务装饰器
.taskDecorator((task) -> {
String placeholderVal = MDC.get("xxx");
return () -> {
try {
MDC.put("xxx", placeholderVal);
task.run();
} finally {
MDC.clear();
}
};
})
.dynamicPool()
.build();
return dynamicExecutor;
}
}
```

@ -18,7 +18,7 @@ Hippo-4J 通过对 JDK 线程池增强,以及扩展三方框架底层线程池
- 👐 功能扩展 - 支持线程池任务传递上下文;项目关闭时,支持等待线程池在指定时间内完成任务;
- 👯‍♀️ 多种模式 - 内置两种使用模式:[依赖配置中心](https://hippo4j.cn/docs/user_docs/getting-started/hippo4j-core-start) 和 [无中间件依赖](https://hippo4j.cn/docs/user_docs/getting-started/hippo4j-server-start)
- 👯‍♀️ 多种模式 - 内置两种使用模式:[依赖配置中心](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 容器线程池运行时查看和线程数变更;
@ -28,7 +28,7 @@ Hippo-4J 通过对 JDK 线程池增强,以及扩展三方框架底层线程池
## 快速开始
对于本地演示目的,请参阅 [Quick start](getting-started/hippo4j-server-start)
对于本地演示目的,请参阅 [Quick start](docs/user_docs/getting_started/server/hippo4j-server-start)
演示环境:
- [http://console.hippo4j.cn/index.html](http://console.hippo4j.cn/index.html)

@ -2,7 +2,7 @@
sidebar_position: 2
---
# docker hippo4j server 构建
# hippo4j server docker 构建
可以通过以下命令快速构建 Hippo4J Server
@ -41,11 +41,11 @@ docker run -p 6691:6691 --name hippo4j-server -d hippo4j-server:{指定版本}
* 暂时只暴露以下参数
* MYSQL_HOST、MYSQL_PORT、MYSQL_DB、MYSQL_USERNAME、MYSQL_PASSWORD
*/
docker run -p 6691:6691 --name hippo4j-server \
docker run -d -p 6691:6691 --name hippo4j-server \
-e MYSQL_HOST=127.0.0.1 \
-e MYSQL_PORT=3306 \
-e MYSQL_DB=hippo4j_manager \
-e MYSQL_USERNAME=root \
-e MYSQL_PASSWORD=mysql \
-d hippo4j-server
-e MYSQL_PASSWORD=root \
hippo4j/hippo4j-server
```

@ -1,5 +1,5 @@
{
"label": "用户手册",
"label": "用户指南",
"position": 2,
"link": {
"type": "generated-index",

@ -2,7 +2,7 @@
sidebar_position: 1
---
# 为什么写这个框架
# 为什么写
[美团线程池文章](https://tech.meituan.com/2020/04/02/java-pooling-pratice-in-meituan.html "美团线程池文章") 介绍中,因为业务对线程池参数没有合理配置,触发过几起生产事故,进而引发了一系列思考。最终决定封装线程池动态参数调整,扩展线程池监控以及消息报警等功能。
@ -20,10 +20,21 @@ sidebar_position: 1
虽然线程池提供了我们许多便利,但也并非尽善尽美,比如下面这些问题就无法很好解决。
- **原生线程池创建时无法合理评估参数问题**。比如功能使用到线程池遇到突发流量洪峰频繁拒绝任务。Hippo4J 提供动态修改参数功能,**避免修改线程池参数后重启线上应用**
- 当线程池运行过程中无法再接受新的任务,此时你想知道 **线程池内线程都在做什么**Hippo4J 提供查看线程池堆栈功能;
- 某接口频繁超时,内部依赖线程池执行,想要 **查看过去一段时间线程池运行参数情况**。Hippo4J 提供历史数据图表查看功能;
- **原生线程池无任务报警策略**。Hippo4J 内置四种报警策略,分别是:活跃度报警、队列容量报警、拒绝策略报警和运行时间过长报警。
- 线程池随便定义,线程资源过多,造成服务器高负载。
- 线程池参数不易评估,随着业务的并发提升,业务面临出现故障的风险。
- 线程池任务执行时间超过平均执行周期,开发人员无法感知。
- 线程池任务堆积,触发拒绝策略,影响既有业务正常运行。
- 当业务出现超时、熔断等问题时,因为没有监控,无法确定是不是线程池引起。
- 原生线程池不支持运行时变量的传递,比如 MDC 上下文遇到线程池就 GG。
- 无法执行优雅关闭,当项目关闭时,大量正在运行的线程池任务被丢弃。
- 线程池运行中,任务执行停止,怀疑发生死锁或执行耗时操作,但是无从下手。
Hippo4J 很好解决了这些问题,它将业务中所有线程池统一管理,增强原生线程池系列功能。
@ -39,10 +50,11 @@ Hippo4J 除去动态修改线程池,还包含实时查看线程池运行时指
- `hippo4j-auth`:用户、角色、权限等;
- `hippo4j-common`:多个模块公用代码实现;
- `hippo4j-config`:提供线程池准实时参数更新功能;
- `hippo4j-console`:对接 Web 前端项目
- `hippo4j-console`:对接前端控制台
- `hippo4j-core`:核心的依赖,包括配置、核心包装类等;
- `hippo4j-discovery`:提供线程池项目实例注册、续约、下线等功能;
- `hippo4j-example` :示例工程;
- `hippo4j-server` :聚合 Server 端发布需要的模块;
- `hippo4j-spring-boot`:负责与 Server 端交互的依赖组件;
- `hippo4j-tool` :操作日志等组件代码。
- `hippo4j-message` :配置变更以及报警通知发送;
- `hippo4j-monitor` :线程池运行时监控;
- `hippo4j-server` Server 端发布需要的模块聚合;
- `hippo4j-spring-boot`SpringBoot Starter。

@ -2,7 +2,7 @@
sidebar_position: 2
---
# 架构设计介绍
# 架构设计
简单来说Hippo4J 从部署的角度上分为两种角色Server 端和 Client 端。
@ -20,7 +20,6 @@ Client 端指的是我们 SpringBoot 应用,通过引入 Hippo4J Starter Jar
代码设计基于 Nacos 1.x 版本的 **长轮询以及异步 Servlet 机制** 实现。
### 注册中心Discovery
负责管理 Client 端(单机或集群)注册到 Server 端的实例,包括不限于**实例注册、续约、过期剔除** 等操作,代码基于 Eureka 源码实现。
@ -31,7 +30,6 @@ Client 端指的是我们 SpringBoot 应用,通过引入 Hippo4J Starter Jar
目前的设计是如此,不排除后续基于 Discovery 做更多的扩展。
### 控制台Console
对接前端项目,包括不限于以下模块管理:
@ -44,7 +42,6 @@ Hippo4J 内置了很多需要通知的事件,比如:线程池参数变更通
目前 Notify 已经接入了钉钉、企业微信和飞书后续持续集成邮件、短信等通知渠道并且Notify 模块提供了消息事件的 SPI 方案,可以接受三方自定义的推送。
## Hippo4j-Spring-Boot-Starter
熟悉 SpringBoot 的小伙伴对 Starter 应该不会陌生。Hippo4J 提供以 Starter Jar 包的形式嵌套在应用内,负责与 Server 端完成交互。
@ -52,4 +49,3 @@ Hippo4J 内置了很多需要通知的事件,比如:线程池参数变更通
## 功能架构
![](https://images-machen.oss-cn-beijing.aliyuncs.com/image-20211105230953626.png)

@ -2,17 +2,11 @@
sidebar_position: 4
---
# 参数变更 & 报警通知
# 通知报警
:::tip
现阶段已集成钉钉、企业微信、飞书的消息推送,后续会持续接入邮箱、短信和自定义通知渠道。
:::
## 创建通知
![](https://images-machen.oss-cn-beijing.aliyuncs.com/image-20220109000449862.png)
![](https://images-machen.oss-cn-beijing.aliyuncs.com/image-20220904181527453.png)
**通知平台**
@ -47,27 +41,31 @@ 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)
## 企业微信
[企业微信创建群机器人](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)

@ -2,28 +2,40 @@
sidebar_position: 3
---
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
# 快速开始
:::tip
Hippo4J 支持两种运行模式依赖配置中心Hippo4J-Config或 Hippo4J Server下文描述接入 Hippo4J
Server[Hippo4J-Config 接入参考此处](/docs/user_docs/getting-started/hippo4j-core-start.md) 。
:::
## 服务启动
MySQL 创建名为 `hippo4j_manager` 的数据库,字符集选择 `utf8mb4`,并导入 [Hippo4J 初始化 SQL 语句](https://github.com/longtai-cn/hippo4j/blob/develop/hippo4j-server/conf/hippo4j_manager.sql)。
使用 Docker 运行服务端,可以灵活定制相关参数。如果 MySQL 非 Docker 部署,`MYSQL_HOST` 需要使用本地 IP。
## 如何运行 Demo
```shell
docker run -d -p 6691:6691 --name hippo4j-server \
-e MYSQL_HOST=127.0.0.1 \
-e MYSQL_PORT=3306 \
-e MYSQL_DB=hippo4j_manager \
-e MYSQL_USERNAME=root \
-e MYSQL_PASSWORD=root \
hippo4j/hippo4j-server
```
> 如果没有 Docker可以使用源码编译的方式启动 [Hippo4J-Server](https://github.com/longtai-cn/hippo4j/tree/develop/hippo4j-server) 模块下 ServerApplication 应用类。
Clone Hippo4J [源代码](https://github.com/longtai-cn/hippo4j),导入初始化 SQL 语句并运行示例程序。
启动示例项目,[hippo4j-spring-boot-starter-example](https://github.com/opengoofy/hippo4j/tree/develop/hippo4j-example/hippo4j-spring-boot-starter-example) 模块下 Hippo4JServerExampleApplication 应用类
1. 导入 [Hippo4J 初始化 SQL 语句](https://github.com/longtai-cn/hippo4j/blob/develop/hippo4j-server/conf/hippo4j_manager.sql)
2. 启动 [Hippo4J-Server](https://github.com/longtai-cn/hippo4j/tree/develop/hippo4j-server) 模块下 ServerApplication 应用类;
3. 启动 [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
通过 Server 控制台访问,路径:`http://localhost:6691/index.html#/hippo4j/dynamic/thread-pool/instance`。
## 配置变更
默认用户名密码admin / 123456
访问控制台动态线程池菜单下线程池实例,修改动态线程池相关参数。
![](https://images-machen.oss-cn-beijing.aliyuncs.com/image-20220813173811668.png)
修改相关参数, 观察 Hippo4j-Example 控制台日志输出,日志输出包括不限于此信息即为成功。
观察 Hippo4j-Example 控制台日志输出,日志输出包括不限于此信息即为成功。
```tex
2022-08-13 21:26:25.814 INFO 38972 --- [change.config-5] c.h.s.s.c.ServerThreadPoolDynamicRefresh : [message-consume] Dynamic thread pool change parameter.
@ -37,5 +49,3 @@ Clone Hippo4J [源代码](https://github.com/longtai-cn/hippo4j),导入初始
```
另外,当 Client 集群部署时,可以修改某一个实例,或选择 `全部修改` 按钮,修改所有实例线程池信息。
线程池参数动态变更通知,或线程池运行时报警,详情参考 [通知报警](/docs/user_docs/user_guide/alarm.md)。

@ -64,7 +64,7 @@ const config = {
// content: `<a target="_blank" rel="noopener noreferrer" href="https://xiaomage.info/knowledge-planet/">👉 《小马哥的代码实战课》官方知识星球来啦!!!</a>`,
},
navbar: {
title: 'hippoforjava',
title: 'HIPPO-4J',
logo: {
alt: 'HIPPO-4J 动态可观测线程池框架',
src: 'img/web.png',

@ -145,4 +145,11 @@ public enum BlockingQueueTypeEnum {
.findFirst();
return queueTypeEnum.map(each -> each.name).orElse("");
}
public static BlockingQueueTypeEnum getBlockingQueueTypeEnumByName(String name) {
Optional<BlockingQueueTypeEnum> queueTypeEnum = Arrays.stream(BlockingQueueTypeEnum.values())
.filter(each -> each.name.equals(name))
.findFirst();
return queueTypeEnum.orElse(LINKED_BLOCKING_QUEUE);
}
}

@ -99,4 +99,11 @@ public enum RejectedPolicyTypeEnum {
public static String getRejectedNameByType(int type) {
return createPolicy(type).getClass().getSimpleName();
}
public static RejectedPolicyTypeEnum getRejectedPolicyTypeEnumByName(String name) {
Optional<RejectedPolicyTypeEnum> rejectedTypeEnum = Stream.of(RejectedPolicyTypeEnum.values())
.filter(each -> each.name.equals(name))
.findFirst();
return rejectedTypeEnum.orElse(ABORT_POLICY);
}
}

@ -33,7 +33,6 @@ public class JSONUtil {
if (object == null) {
return null;
}
return JSON_FACADE.toJSONString(object);
}
@ -41,7 +40,6 @@ public class JSONUtil {
if (StringUtil.isBlank(text)) {
return null;
}
return JSON_FACADE.parseObject(text, clazz);
}
@ -49,7 +47,6 @@ public class JSONUtil {
if (StringUtil.isBlank(text)) {
return null;
}
return JSON_FACADE.parseObject(text, valueTypeRef);
}
@ -57,7 +54,6 @@ public class JSONUtil {
if (StringUtil.isBlank(text)) {
return null;
}
return JSON_FACADE.parseArray(text, clazz);
}
}

@ -19,11 +19,8 @@ package cn.hippo4j.common.toolkit;
import cn.hippo4j.common.function.Matcher;
import com.google.common.base.Strings;
import org.checkerframework.checker.units.qual.A;
import org.junit.Test;
import java.lang.reflect.Array;
public class ArrayUtilTest {
@Test
@ -41,13 +38,10 @@ public class ArrayUtilTest {
@Test
public void assertFirstMatch() {
Matcher<String> matcher = (str) -> "1".equalsIgnoreCase(str);
String[] array = new String[0];
Assert.isTrue(Strings.isNullOrEmpty(ArrayUtil.firstMatch(matcher, array)));
array = new String[]{"0"};
Assert.isTrue(Strings.isNullOrEmpty(ArrayUtil.firstMatch(matcher, array)));
array = new String[]{"1"};
Assert.isTrue(!Strings.isNullOrEmpty(ArrayUtil.firstMatch(matcher, array)));
}
@ -57,14 +51,12 @@ public class ArrayUtilTest {
String[] array = new String[]{"1"};
Assert.isTrue(ArrayUtil.addAll(array, null).length == 1);
Assert.isTrue(ArrayUtil.addAll(null, array).length == 1);
Assert.isTrue(ArrayUtil.addAll(array, new String[]{"1"}).length == 2);
}
@Test
public void assertClone() {
Assert.isNull(ArrayUtil.clone(null));
String[] array = new String[0];
Assert.isTrue(array != ArrayUtil.clone(array));
Assert.isTrue(array.length == ArrayUtil.clone(array).length);

@ -30,7 +30,6 @@ public class CollectionUtilTest {
@Test
public void assertGetFirst() {
Assert.isNull(CollectionUtil.getFirst(null));
String first = CollectionUtil.getFirst(Lists.newArrayList("1", "2"));
Assert.notEmpty(first);
}
@ -39,28 +38,20 @@ public class CollectionUtilTest {
public void assertIsEmpty() {
List list = null;
Assert.isTrue(CollectionUtil.isEmpty(list));
list = Lists.newArrayList();
Assert.isTrue(CollectionUtil.isEmpty(list));
list = Lists.newArrayList("1");
Assert.isTrue(!CollectionUtil.isEmpty(list));
Map map = null;
Assert.isTrue(CollectionUtil.isEmpty(map));
map = Maps.newHashMap();
Assert.isTrue(CollectionUtil.isEmpty(map));
map.put("key", "value");
Assert.isTrue(!CollectionUtil.isEmpty(map));
Iterator iterator = null;
Assert.isTrue(CollectionUtil.isEmpty(iterator));
iterator = Lists.emptyList().iterator();
Assert.isTrue(CollectionUtil.isEmpty(iterator));
iterator = Lists.newArrayList("1").iterator();
Assert.isTrue(!CollectionUtil.isEmpty(iterator));
}
@ -69,28 +60,20 @@ public class CollectionUtilTest {
public void assertIsNotEmpty() {
List list = null;
Assert.isTrue(!CollectionUtil.isNotEmpty(list));
list = Lists.newArrayList();
Assert.isTrue(!CollectionUtil.isNotEmpty(list));
list = Lists.newArrayList("1");
Assert.isTrue(CollectionUtil.isNotEmpty(list));
Map map = null;
Assert.isTrue(!CollectionUtil.isNotEmpty(map));
map = Maps.newHashMap();
Assert.isTrue(!CollectionUtil.isNotEmpty(map));
map.put("key", "value");
Assert.isTrue(CollectionUtil.isNotEmpty(map));
Iterator iterator = null;
Assert.isTrue(!CollectionUtil.isNotEmpty(iterator));
iterator = Lists.emptyList().iterator();
Assert.isTrue(!CollectionUtil.isNotEmpty(iterator));
iterator = Lists.newArrayList("1").iterator();
Assert.isTrue(CollectionUtil.isNotEmpty(iterator));
}

@ -0,0 +1,87 @@
/*
* 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.toolkit;
import com.fasterxml.jackson.core.type.TypeReference;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import org.junit.Assert;
import org.junit.Test;
import java.util.Arrays;
import java.util.List;
public class JSONUtilTest {
private static final Foo EXPECTED_FOO = new Foo(1, "foo1", new Foo(2, "foo2", null));
private static final List<Foo> EXPECTED_FOO_ARRAY = Arrays.asList(EXPECTED_FOO, EXPECTED_FOO);
private static final String EXPECTED_FOO_JSON = "{\"id\":1,\"name\":\"foo1\",\"foo\":{\"id\":2,\"name\":\"foo2\"}}";
private static final String EXPECTED_FOO_JSON_ARRAY = "[" + EXPECTED_FOO_JSON + "," + EXPECTED_FOO_JSON + "]";
@Test
public void assertToJSONString() {
Assert.assertNull(JSONUtil.toJSONString(null));
Assert.assertEquals(EXPECTED_FOO_JSON, JSONUtil.toJSONString(EXPECTED_FOO));
}
@Test
public void assertParseObject() {
Assert.assertNull(JSONUtil.parseObject(null, Foo.class));
Assert.assertNull(JSONUtil.parseObject(" ", Foo.class));
Assert.assertEquals(EXPECTED_FOO, JSONUtil.parseObject(EXPECTED_FOO_JSON, Foo.class));
}
@Test
public void assertParseObjectTypeReference() {
Assert.assertNull(JSONUtil.parseObject(null, new TypeReference<List<Foo>>() {
}));
Assert.assertNull(JSONUtil.parseObject(" ", new TypeReference<List<Foo>>() {
}));
Assert.assertEquals(
EXPECTED_FOO_ARRAY,
JSONUtil.parseObject(EXPECTED_FOO_JSON_ARRAY, new TypeReference<List<Foo>>() {
}));
}
@Test
public void assertParseArray() {
Assert.assertNull(JSONUtil.parseArray(null, Foo.class));
Assert.assertNull(JSONUtil.parseArray(" ", Foo.class));
Assert.assertEquals(
EXPECTED_FOO_ARRAY,
JSONUtil.parseArray(EXPECTED_FOO_JSON_ARRAY, Foo.class));
}
@EqualsAndHashCode
@AllArgsConstructor
@NoArgsConstructor
@Data
private static class Foo {
private Integer id;
private String name;
private Foo foo;
}
}

@ -0,0 +1,21 @@
/*
* 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.toolkit;
public class Md5UtilTest {
}

@ -0,0 +1,22 @@
/*
* 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.toolkit;
public class ReflectUtilTest {
}

@ -0,0 +1,21 @@
/*
* 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.toolkit;
public class SingletonTest {
}

@ -0,0 +1,21 @@
/*
* 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.toolkit;
public class StringUtilTest {
}

@ -0,0 +1,21 @@
/*
* 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.toolkit;
public class ThreadUtilTest {
}

@ -0,0 +1,21 @@
/*
* 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.toolkit;
public class UserContextTest {
}

@ -23,6 +23,7 @@ import cn.hippo4j.common.toolkit.JSONUtil;
import cn.hippo4j.common.toolkit.StringUtil;
import cn.hippo4j.common.web.base.Result;
import cn.hippo4j.common.web.base.Results;
import cn.hippo4j.common.web.exception.ErrorCodeEnum;
import cn.hippo4j.config.model.CacheItem;
import cn.hippo4j.config.model.biz.threadpool.ThreadPoolDelReqDTO;
import cn.hippo4j.config.model.biz.threadpool.ThreadPoolQueryReqDTO;
@ -84,6 +85,19 @@ public class ThreadPoolController {
@DeleteMapping("/delete")
public Result deletePool(@RequestBody ThreadPoolDelReqDTO reqDTO) {
List<Lease<InstanceInfo>> leases = baseInstanceRegistry.listInstance(reqDTO.getItemId());
Lease<InstanceInfo> first = CollUtil.getFirst(leases);
if (first == null) {
threadPoolService.deletePool(reqDTO);
return Results.success();
}
InstanceInfo holder = first.getHolder();
String itemTenantKey = holder.getGroupKey();
String groupKey = getGroupKey(reqDTO.getTpId(), itemTenantKey);
Map<String, CacheItem> content = ConfigCacheService.getContent(groupKey);
if (!content.isEmpty()) {
return Results.failure(ErrorCodeEnum.SERVICE_ERROR.getCode(), "this thread pool has instances running");
}
threadPoolService.deletePool(reqDTO);
return Results.success();
}

File diff suppressed because one or more lines are too long

@ -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}.pagination-container[data-v-df7d1fa0]{background:#fff;padding:32px 16px}.pagination-container.hidden[data-v-df7d1fa0]{display:none}[data-v-65a213ee]::-webkit-scrollbar{width:8px;height:8px}[data-v-65a213ee]::-webkit-scrollbar-track{border-radius:5px;background:rgba(0,0,0,.06);-webkit-box-shadow:inset 0 0 5px rgba(0,0,0,.08)}[data-v-65a213ee]::-webkit-scrollbar-thumb{border-radius:5px;background:rgba(0,0,0,.12);-webkit-box-shadow:inset 0 0 10px rgba(0,0,0,.2)}.stack-info[data-v-65a213ee]{height:400px;overflow:auto}.stack-info>li[data-v-65a213ee]{margin-bottom:24px}.stack-info>li p[data-v-65a213ee]:first-child{color:#06f;font-weight:600;margin-top:10px}.stack-info>li ul[data-v-65a213ee]{margin-left:30px}.stack-info>li ul li[data-v-65a213ee]{color:#fc5531;text-align:justify;margin:10px auto}
.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}.pagination-container[data-v-df7d1fa0]{background:#fff;padding:32px 16px}.pagination-container.hidden[data-v-df7d1fa0]{display:none}[data-v-2f9bac29]::-webkit-scrollbar{width:8px;height:8px}[data-v-2f9bac29]::-webkit-scrollbar-track{border-radius:5px;background:rgba(0,0,0,.06);-webkit-box-shadow:inset 0 0 5px rgba(0,0,0,.08)}[data-v-2f9bac29]::-webkit-scrollbar-thumb{border-radius:5px;background:rgba(0,0,0,.12);-webkit-box-shadow:inset 0 0 10px rgba(0,0,0,.2)}.stack-info[data-v-2f9bac29]{height:400px;overflow:auto}.stack-info>li[data-v-2f9bac29]{margin-bottom:24px}.stack-info>li p[data-v-2f9bac29]:first-child{color:#06f;font-weight:600;margin-top:10px}.stack-info>li ul[data-v-2f9bac29]{margin-left:30px}.stack-info>li ul li[data-v-2f9bac29]{color:#fc5531;text-align:justify;margin:10px auto}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -48,7 +48,7 @@ import java.util.concurrent.*;
public class ThreadPoolNotifyAlarmHandler implements Runnable, CommandLineRunner {
@NonNull
private final Hippo4jSendMessageService hippoSendMessageService;
private final Hippo4jSendMessageService hippo4jSendMessageService;
@Value("${spring.profiles.active:UNKNOWN}")
private String active;
@ -101,19 +101,19 @@ public class ThreadPoolNotifyAlarmHandler implements Runnable, CommandLineRunner
* @param threadPoolExecutor
*/
public void checkPoolCapacityAlarm(String threadPoolId, ThreadPoolExecutor threadPoolExecutor) {
if (hippoSendMessageService == null) {
ThreadPoolNotifyAlarm alarmConfig = GlobalNotifyAlarmManage.get(threadPoolId);
if (Objects.isNull(alarmConfig) || !alarmConfig.getAlarm() || alarmConfig.getCapacityAlarm() <= 0) {
return;
}
ThreadPoolNotifyAlarm threadPoolNotifyAlarm = GlobalNotifyAlarmManage.get(threadPoolId);
BlockingQueue blockingQueue = threadPoolExecutor.getQueue();
int queueSize = blockingQueue.size();
int capacity = queueSize + blockingQueue.remainingCapacity();
int divide = CalculateUtil.divide(queueSize, capacity);
boolean isSend = threadPoolNotifyAlarm.getAlarm() && divide > threadPoolNotifyAlarm.getCapacityAlarm();
boolean isSend = alarmConfig.getAlarm() && divide > alarmConfig.getCapacityAlarm();
if (isSend) {
AlarmNotifyRequest alarmNotifyRequest = buildAlarmNotifyReq(threadPoolExecutor);
AlarmNotifyRequest alarmNotifyRequest = buildAlarmNotifyRequest(threadPoolExecutor);
alarmNotifyRequest.setThreadPoolId(threadPoolId);
hippoSendMessageService.sendAlarmMessage(NotifyTypeEnum.CAPACITY, alarmNotifyRequest);
hippo4jSendMessageService.sendAlarmMessage(NotifyTypeEnum.CAPACITY, alarmNotifyRequest);
}
}
@ -124,15 +124,18 @@ public class ThreadPoolNotifyAlarmHandler implements Runnable, CommandLineRunner
* @param threadPoolExecutor
*/
public void checkPoolActivityAlarm(String threadPoolId, ThreadPoolExecutor threadPoolExecutor) {
ThreadPoolNotifyAlarm alarmConfig = GlobalNotifyAlarmManage.get(threadPoolId);
if (Objects.isNull(alarmConfig) || !alarmConfig.getAlarm() || alarmConfig.getCapacityAlarm() <= 0) {
return;
}
int activeCount = threadPoolExecutor.getActiveCount();
int maximumPoolSize = threadPoolExecutor.getMaximumPoolSize();
int divide = CalculateUtil.divide(activeCount, maximumPoolSize);
ThreadPoolNotifyAlarm threadPoolNotifyAlarm = GlobalNotifyAlarmManage.get(threadPoolId);
boolean isSend = threadPoolNotifyAlarm.getAlarm() && divide > threadPoolNotifyAlarm.getActiveAlarm();
boolean isSend = alarmConfig.getAlarm() && divide > alarmConfig.getActiveAlarm();
if (isSend) {
AlarmNotifyRequest alarmNotifyRequest = buildAlarmNotifyReq(threadPoolExecutor);
AlarmNotifyRequest alarmNotifyRequest = buildAlarmNotifyRequest(threadPoolExecutor);
alarmNotifyRequest.setThreadPoolId(threadPoolId);
hippoSendMessageService.sendAlarmMessage(NotifyTypeEnum.ACTIVITY, alarmNotifyRequest);
hippo4jSendMessageService.sendAlarmMessage(NotifyTypeEnum.ACTIVITY, alarmNotifyRequest);
}
}
@ -143,15 +146,15 @@ public class ThreadPoolNotifyAlarmHandler implements Runnable, CommandLineRunner
*/
public void asyncSendRejectedAlarm(String threadPoolId) {
Runnable checkPoolRejectedAlarmTask = () -> {
ThreadPoolNotifyAlarm threadPoolNotifyAlarm = GlobalNotifyAlarmManage.get(threadPoolId);
if (Objects.isNull(threadPoolNotifyAlarm) || !threadPoolNotifyAlarm.getAlarm()) {
ThreadPoolNotifyAlarm alarmConfig = GlobalNotifyAlarmManage.get(threadPoolId);
if (Objects.isNull(alarmConfig) || !alarmConfig.getAlarm()) {
return;
}
ThreadPoolExecutor threadPoolExecutor = GlobalThreadPoolManage.getExecutorService(threadPoolId).getExecutor();
if (threadPoolExecutor instanceof DynamicThreadPoolExecutor) {
AlarmNotifyRequest alarmNotifyRequest = buildAlarmNotifyReq(threadPoolExecutor);
AlarmNotifyRequest alarmNotifyRequest = buildAlarmNotifyRequest(threadPoolExecutor);
alarmNotifyRequest.setThreadPoolId(threadPoolId);
hippoSendMessageService.sendAlarmMessage(NotifyTypeEnum.REJECT, alarmNotifyRequest);
hippo4jSendMessageService.sendAlarmMessage(NotifyTypeEnum.REJECT, alarmNotifyRequest);
}
};
ASYNC_ALARM_NOTIFY_EXECUTOR.execute(checkPoolRejectedAlarmTask);
@ -166,13 +169,13 @@ public class ThreadPoolNotifyAlarmHandler implements Runnable, CommandLineRunner
* @param threadPoolExecutor
*/
public void asyncSendExecuteTimeOutAlarm(String threadPoolId, long executeTime, long executeTimeOut, ThreadPoolExecutor threadPoolExecutor) {
ThreadPoolNotifyAlarm threadPoolNotifyAlarm = GlobalNotifyAlarmManage.get(threadPoolId);
if (Objects.isNull(threadPoolNotifyAlarm) || !threadPoolNotifyAlarm.getAlarm()) {
ThreadPoolNotifyAlarm alarmConfig = GlobalNotifyAlarmManage.get(threadPoolId);
if (Objects.isNull(alarmConfig) || !alarmConfig.getAlarm()) {
return;
}
if (threadPoolExecutor instanceof DynamicThreadPoolExecutor) {
try {
AlarmNotifyRequest alarmNotifyRequest = buildAlarmNotifyReq(threadPoolExecutor);
AlarmNotifyRequest alarmNotifyRequest = buildAlarmNotifyRequest(threadPoolExecutor);
alarmNotifyRequest.setThreadPoolId(threadPoolId);
alarmNotifyRequest.setExecuteTime(executeTime);
alarmNotifyRequest.setExecuteTimeOut(executeTimeOut);
@ -180,7 +183,7 @@ public class ThreadPoolNotifyAlarmHandler implements Runnable, CommandLineRunner
if (StringUtil.isNotBlank(executeTimeoutTrace)) {
alarmNotifyRequest.setExecuteTimeoutTrace(executeTimeoutTrace);
}
Runnable task = () -> hippoSendMessageService.sendAlarmMessage(NotifyTypeEnum.TIMEOUT, alarmNotifyRequest);
Runnable task = () -> hippo4jSendMessageService.sendAlarmMessage(NotifyTypeEnum.TIMEOUT, alarmNotifyRequest);
ASYNC_ALARM_NOTIFY_EXECUTOR.execute(task);
} catch (Throwable ex) {
log.error("Send thread pool execution timeout alarm error.", ex);
@ -198,50 +201,40 @@ public class ThreadPoolNotifyAlarmHandler implements Runnable, CommandLineRunner
String appName = StrUtil.isBlank(itemId) ? applicationName : itemId;
request.setAppName(appName);
request.setIdentify(IdentifyUtil.getIdentify());
hippoSendMessageService.sendChangeMessage(request);
hippo4jSendMessageService.sendChangeMessage(request);
}
/**
* Build alarm notify req.
* Build alarm notify request.
*
* @param threadPoolExecutor
* @return
*/
public AlarmNotifyRequest buildAlarmNotifyReq(ThreadPoolExecutor threadPoolExecutor) {
AlarmNotifyRequest request = new AlarmNotifyRequest();
String appName = StrUtil.isBlank(itemId) ? applicationName : itemId;
request.setAppName(appName);
int corePoolSize = threadPoolExecutor.getCorePoolSize();
int maximumPoolSize = threadPoolExecutor.getMaximumPoolSize();
int poolSize = threadPoolExecutor.getPoolSize();
int activeCount = threadPoolExecutor.getActiveCount();
int largestPoolSize = threadPoolExecutor.getLargestPoolSize();
long completedTaskCount = threadPoolExecutor.getCompletedTaskCount();
request.setActive(active.toUpperCase());
request.setIdentify(IdentifyUtil.getIdentify());
request.setCorePoolSize(corePoolSize);
request.setMaximumPoolSize(maximumPoolSize);
request.setPoolSize(poolSize);
request.setActiveCount(activeCount);
request.setLargestPoolSize(largestPoolSize);
request.setCompletedTaskCount(completedTaskCount);
BlockingQueue<Runnable> queue = threadPoolExecutor.getQueue();
int queueSize = queue.size();
String queueType = queue.getClass().getSimpleName();
int remainingCapacity = queue.remainingCapacity();
int queueCapacity = queueSize + remainingCapacity;
request.setQueueName(queueType);
request.setCapacity(queueCapacity);
request.setQueueSize(queueSize);
request.setRemainingCapacity(remainingCapacity);
public AlarmNotifyRequest buildAlarmNotifyRequest(ThreadPoolExecutor threadPoolExecutor) {
BlockingQueue<Runnable> blockingQueue = threadPoolExecutor.getQueue();
RejectedExecutionHandler rejectedExecutionHandler = threadPoolExecutor instanceof DynamicThreadPoolExecutor
? ((DynamicThreadPoolExecutor) threadPoolExecutor).getRedundancyHandler()
: threadPoolExecutor.getRejectedExecutionHandler();
request.setRejectedExecutionHandlerName(rejectedExecutionHandler.getClass().getSimpleName());
long rejectCount = threadPoolExecutor instanceof DynamicThreadPoolExecutor
? ((DynamicThreadPoolExecutor) threadPoolExecutor).getRejectCountNum()
: -1L;
request.setRejectCountNum(rejectCount);
return request;
AlarmNotifyRequest alarmNotifyRequest = AlarmNotifyRequest.builder()
.appName(StrUtil.isBlank(itemId) ? applicationName : itemId)
.active(active.toUpperCase())
.identify(IdentifyUtil.getIdentify())
.corePoolSize(threadPoolExecutor.getCorePoolSize())
.maximumPoolSize(threadPoolExecutor.getMaximumPoolSize())
.poolSize(threadPoolExecutor.getPoolSize())
.activeCount(threadPoolExecutor.getActiveCount())
.largestPoolSize(threadPoolExecutor.getLargestPoolSize())
.completedTaskCount(threadPoolExecutor.getCompletedTaskCount())
.queueName(blockingQueue.getClass().getSimpleName())
.capacity(blockingQueue.size() + blockingQueue.remainingCapacity())
.queueSize(blockingQueue.size())
.remainingCapacity(blockingQueue.remainingCapacity())
.rejectedExecutionHandlerName(rejectedExecutionHandler.getClass().getSimpleName())
.rejectCountNum(rejectCount)
.build();
return alarmNotifyRequest;
}
}

@ -15,14 +15,14 @@
* limitations under the License.
*/
package cn.hippo4j.example.core.apollo;
package cn.hippo4j.example.config.apollo;
import cn.hippo4j.core.enable.EnableDynamicThreadPool;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@EnableDynamicThreadPool
@SpringBootApplication(scanBasePackages = "cn.hippo4j.example.core")
@SpringBootApplication(scanBasePackages = "cn.hippo4j.example.config")
public class ConfigApolloExampleApplication {
public static void main(String[] args) {

@ -0,0 +1,47 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>cn.hippo4j</groupId>
<artifactId>hippo4j-example</artifactId>
<version>${revision}</version>
</parent>
<artifactId>hippo4j-config-etcd-spring-boot-starter-example</artifactId>
<properties>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
<maven.deploy.skip>true</maven.deploy.skip>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</dependency>
<dependency>
<groupId>cn.hippo4j</groupId>
<artifactId>hippo4j-config-spring-boot-starter</artifactId>
<version>${revision}</version>
</dependency>
<dependency>
<groupId>io.etcd</groupId>
<artifactId>jetcd-core</artifactId>
<version>${jetcd.version}</version>
</dependency>
<dependency>
<groupId>cn.hippo4j</groupId>
<artifactId>hippo4j-example-core</artifactId>
<version>${revision}</version>
</dependency>
</dependencies>
</project>

@ -15,50 +15,23 @@
* limitations under the License.
*/
package cn.hippo4j.core.springboot.starter.common;
package cn.hippo4j.example.config.etcd;
/**
* Config file type enum.
*/
public enum ConfigFileTypeEnum {
/**
* PROPERTIES
*/
PROPERTIES {
@Override
public String type() {
return "properties";
}
},
import cn.hippo4j.core.enable.EnableDynamicThreadPool;
/***
* YML
*/
YML {
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@Override
public String type() {
return "yml";
}
},
/***
* YAML
*/
YAML {
@Override
public String type() {
return "yaml";
}
};
/**
* @author : wh
* @date : 2022/9/2 19:06
* @description:
*/
@EnableDynamicThreadPool
@SpringBootApplication(scanBasePackages = "cn.hippo4j.example.config")
public class ConfigEtcdExampleApplication {
/**
* Type.
*
* @return
*/
public abstract String type();
public static void main(String[] args) {
SpringApplication.run(ConfigEtcdExampleApplication.class, args);
}
}

@ -0,0 +1,46 @@
/*
* 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.example.config.etcd.config;
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;
/**
* @author : wh
* @date : 2022/9/2 19:26
* @description:
*/
@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;
}
}

@ -0,0 +1,43 @@
/*
* 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.example.config.etcd.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.concurrent.ThreadPoolExecutor;
/**
* @author : wh
* @date : 2022/9/2 19:18
* @description:
*/
@RestController
@RequestMapping
public class TestController {
@Autowired
private ThreadPoolExecutor messageConsumeDynamicExecutor;
@GetMapping("test")
public void test() {
System.out.println(messageConsumeDynamicExecutor.getMaximumPoolSize());
}
}

@ -0,0 +1,23 @@
server.port=8888
spring.application.name=etcd
spring.dynamic.thread-pool.etcd.endpoints= http://127.0.0.1:2379
spring.dynamic.thread-pool.etcd.key= /thread
spring.dynamic.thread-pool.executors[0].thread-pool-id=message-consume
spring.dynamic.thread-pool.executors[0].core-pool-size=3
spring.dynamic.thread-pool.executors[0].maximum-pool-size=4
spring.dynamic.thread-pool.executors[0].queue-capacity=4
spring.dynamic.thread-pool.executors[0].execute-time-out=1000
spring.dynamic.thread-pool.executors[0].blocking-queue=LinkedBlockingQueue
spring.dynamic.thread-pool.executors[0].rejected-handler=AbortPolicy
spring.dynamic.thread-pool.executors[0].keep-alive-time=1000
spring.dynamic.thread-pool.executors[0].allow-core-thread-time-out=true
spring.dynamic.thread-pool.executors[0].thread-name-prefix=message-consume
spring.dynamic.thread-pool.executors[0].alarm=true
spring.dynamic.thread-pool.executors[0].active-alarm=80
spring.dynamic.thread-pool.executors[0].capacity-alarm=80
spring.dynamic.thread-pool.executors[0].notify.interval=8
spring.dynamic.thread-pool.executors[0].notify.receives=111
spring.dynamic.thread-pool.notify-platforms[0].platform=WECHAT
spring.dynamic.thread-pool.notify-platforms[0].secret-key=ac0426a5-c712-474c-9bff-72b8b8f5caff

@ -15,14 +15,14 @@
* limitations under the License.
*/
package cn.hippo4j.example.core.nacos;
package cn.hippo4j.example.config.nacos;
import cn.hippo4j.core.enable.EnableDynamicThreadPool;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@EnableDynamicThreadPool
@SpringBootApplication(scanBasePackages = "cn.hippo4j.example.core")
@SpringBootApplication(scanBasePackages = "cn.hippo4j.example.config")
public class ConfigNacosExampleApplication {
public static void main(String[] args) {

@ -15,14 +15,14 @@
* limitations under the License.
*/
package cn.hippo4j.example.core.zookeeper;
package cn.hippo4j.example.config.zookeeper;
import cn.hippo4j.core.enable.EnableDynamicThreadPool;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@EnableDynamicThreadPool
@SpringBootApplication(scanBasePackages = "cn.hippo4j.example.core")
@SpringBootApplication(scanBasePackages = "cn.hippo4j.example.config")
public class ConfigZookeeperExampleApplication {
public static void main(String[] args) {

@ -45,8 +45,9 @@ public class RunStateHandlerTest {
@Resource
private ThreadPoolExecutor messageProduceDynamicThreadPool;
/*@Resource
private ThreadPoolTaskExecutor testSpringThreadPoolTaskExecutor;*/
/*
* @Resource private ThreadPoolTaskExecutor testSpringThreadPoolTaskExecutor;
*/
private final ThreadPoolExecutor runStateHandlerTestExecutor = new ThreadPoolExecutor(
4,

@ -29,12 +29,6 @@
<artifactId>spring-boot-starter-json</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.83</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>

@ -17,8 +17,8 @@
package cn.hippo4j.springboot.starter.adapter.springcloud.stream.rabbitmq.example;
import cn.hippo4j.common.toolkit.JSONUtil;
import cn.hippo4j.example.core.dto.SendMessageDTO;
import com.alibaba.fastjson.JSON;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.stream.function.StreamBridge;
@ -64,7 +64,7 @@ public class MessageProduce {
sendResult,
keys,
System.currentTimeMillis() - startTime,
JSON.toJSONString(payload));
JSONUtil.toJSONString(payload));
}
}
}

@ -17,8 +17,8 @@
package cn.hippo4j.springboot.starter.adapter.springcloud.stream.rabbitmq.example;
import cn.hippo4j.common.toolkit.JSONUtil;
import cn.hippo4j.core.enable.EnableDynamicThreadPool;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.support.AmqpHeaders;
import org.springframework.boot.SpringApplication;
@ -44,7 +44,7 @@ public class ServerAdapterSpringCloudStreamRabbitMQApplication {
MessageHeaders headers = message.getHeaders();
log.info("Input current thread name: {} ,{} received from partition {}",
Thread.currentThread().getName(),
JSON.toJSONString(message.getPayload()),
JSONUtil.toJSONString(message.getPayload()),
headers.get(AmqpHeaders.CONSUMER_QUEUE));
};
}

@ -17,8 +17,8 @@
package cn.hippo4j.springboot.starter.adapter.springcloud.stream.rocketmq.example;
import cn.hippo4j.common.toolkit.JSONUtil;
import cn.hippo4j.example.core.dto.SendMessageDTO;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.stream.annotation.StreamListener;
import org.springframework.messaging.handler.annotation.Headers;
@ -41,7 +41,7 @@ public class MessageConsume {
// ignore
} finally {
log.info("Keys: {}, Msg id: {}, Execute time: {} ms, Message: {}", headers.get("rocketmq_KEYS"), headers.get("rocketmq_MESSAGE_ID"), System.currentTimeMillis() - startTime,
JSON.toJSONString(message));
JSONUtil.toJSONString(message));
}
log.info("Input current thread name: {}", Thread.currentThread().getName());
}
@ -53,7 +53,7 @@ public class MessageConsume {
// ignore
} finally {
log.info("Keys: {}, Msg id: {}, Execute time: {} ms, Message: {}", headers.get("rocketmq_KEYS"), headers.get("rocketmq_MESSAGE_ID"), System.currentTimeMillis() - startTime,
JSON.toJSONString(message));
JSONUtil.toJSONString(message));
}
log.info("Input2 current thread name: {}", Thread.currentThread().getName());
}

@ -17,8 +17,8 @@
package cn.hippo4j.springboot.starter.adapter.springcloud.stream.rocketmq.example;
import cn.hippo4j.common.toolkit.JSONUtil;
import cn.hippo4j.example.core.dto.SendMessageDTO;
import com.alibaba.fastjson.JSON;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.rocketmq.common.message.MessageConst;
@ -61,7 +61,7 @@ public class MessageProduce {
.uid(keys)
.build();
Message<?> message = MessageBuilder
.withPayload(JSON.toJSONString(payload))
.withPayload(JSONUtil.toJSONString(payload))
.setHeader(MessageConst.PROPERTY_KEYS, keys)
.setHeader(MessageConst.PROPERTY_TAGS, tags)
.build();
@ -74,7 +74,7 @@ public class MessageProduce {
sendResult,
keys,
System.currentTimeMillis() - startTime,
JSON.toJSONString(payload));
JSONUtil.toJSONString(payload));
}
}
}

@ -22,6 +22,7 @@
<module>hippo4j-spring-boot-starter-adapter-spring-cloud-stream-rabbitmq-example</module>
<module>hippo4j-spring-boot-starter-adapter-spring-cloud-stream-rocketmq-example</module>
<module>hippo4j-spring-boot-starter-adapter-rocketmq-example</module>
<module>hippo4j-config-etcd-spring-boot-starter-example</module>
</modules>
<properties>

@ -19,13 +19,19 @@ package cn.hippo4j.message.request;
import cn.hippo4j.message.enums.NotifyTypeEnum;
import cn.hippo4j.message.request.base.BaseNotifyRequest;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
/**
* Alarm notify request.
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Accessors(chain = true)
public class AlarmNotifyRequest extends BaseNotifyRequest {

@ -61,20 +61,16 @@ public class PrometheusMonitorHandler extends AbstractDynamicThreadPoolMonitor {
Iterable<Tag> tags = Lists.newArrayList(
Tag.of(DYNAMIC_THREAD_POOL_ID_TAG, poolRunStateInfo.getTpId()),
Tag.of(APPLICATION_NAME_TAG, applicationName));
// load
Metrics.gauge(metricName("current.load"), tags, poolRunStateInfo, ThreadPoolRunStateInfo::getSimpleCurrentLoad);
Metrics.gauge(metricName("peak.load"), tags, poolRunStateInfo, ThreadPoolRunStateInfo::getSimplePeakLoad);
// thread pool
Metrics.gauge(metricName("core.size"), tags, poolRunStateInfo, ThreadPoolRunStateInfo::getCoreSize);
Metrics.gauge(metricName("maximum.size"), tags, poolRunStateInfo, ThreadPoolRunStateInfo::getMaximumSize);
Metrics.gauge(metricName("current.size"), tags, poolRunStateInfo, ThreadPoolRunStateInfo::getPoolSize);
Metrics.gauge(metricName("largest.size"), tags, poolRunStateInfo, ThreadPoolRunStateInfo::getLargestPoolSize);
Metrics.gauge(metricName("active.size"), tags, poolRunStateInfo, ThreadPoolRunStateInfo::getActiveSize);
// queue
Metrics.gauge(metricName("queue.size"), tags, poolRunStateInfo, ThreadPoolRunStateInfo::getQueueSize);
Metrics.gauge(metricName("queue.capacity"), tags, poolRunStateInfo, ThreadPoolRunStateInfo::getQueueCapacity);
Metrics.gauge(metricName("queue.remaining.capacity"), tags, poolRunStateInfo, ThreadPoolRunStateInfo::getQueueRemainingCapacity);
// other
Metrics.gauge(metricName("completed.task.count"), tags, poolRunStateInfo, ThreadPoolRunStateInfo::getCompletedTaskCount);
Metrics.gauge(metricName("reject.count"), tags, poolRunStateInfo, ThreadPoolRunStateInfo::getRejectCount);
}

@ -56,6 +56,14 @@
<optional>true</optional>
</dependency>
<dependency>
<groupId>io.etcd</groupId>
<artifactId>jetcd-core</artifactId>
<version>${jetcd.version}</version>
<scope>compile</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>

@ -15,16 +15,20 @@
* limitations under the License.
*/
package cn.hippo4j.core.springboot.starter.config;
package cn.hippo4j.config.springboot.starter.config;
import java.util.List;
import java.util.Map;
import java.util.List;
import java.util.Map;
import cn.hippo4j.core.config.BootstrapPropertiesInterface;
import cn.hippo4j.core.springboot.starter.parser.ConfigFileTypeEnum;
import cn.hippo4j.config.springboot.starter.parser.ConfigFileTypeEnum;
import lombok.Getter;
import lombok.Setter;
import org.springframework.boot.context.properties.ConfigurationProperties;
import java.util.List;
import java.util.Map;
import org.springframework.boot.context.properties.ConfigurationProperties;
/**
* Bootstrap core properties.
@ -86,6 +90,11 @@ public class BootstrapConfigProperties implements BootstrapPropertiesInterface {
*/
private Map<String, String> zookeeper;
/**
* etcd config
*/
private Map<String, String> etcd;
/**
* Tomcat thread pool config.
*/

@ -15,14 +15,16 @@
* limitations under the License.
*/
package cn.hippo4j.core.springboot.starter.config;
package cn.hippo4j.config.springboot.starter.config;
import cn.hippo4j.core.springboot.starter.refresher.ApolloRefresherHandler;
import cn.hippo4j.core.springboot.starter.refresher.NacosCloudRefresherHandler;
import cn.hippo4j.core.springboot.starter.refresher.NacosRefresherHandler;
import cn.hippo4j.core.springboot.starter.refresher.ZookeeperRefresherHandler;
import cn.hippo4j.config.springboot.starter.refresher.ApolloRefresherHandler;
import cn.hippo4j.config.springboot.starter.refresher.NacosCloudRefresherHandler;
import cn.hippo4j.config.springboot.starter.refresher.NacosRefresherHandler;
import cn.hippo4j.config.springboot.starter.refresher.ZookeeperRefresherHandler;
import cn.hippo4j.config.springboot.starter.refresher.EtcdRefresherHandler;
import com.alibaba.cloud.nacos.NacosConfigManager;
import com.alibaba.nacos.api.config.ConfigService;
import io.etcd.jetcd.Client;
import lombok.RequiredArgsConstructor;
import org.apache.curator.framework.CuratorFramework;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
@ -45,6 +47,8 @@ public class ConfigHandlerConfiguration {
private static final String ZOOKEEPER_CONNECT_STR_KEY = "zookeeper.zk-connect-str";
private static final String ETCD = "etcd.endpoints";
@RequiredArgsConstructor
@ConditionalOnClass(ConfigService.class)
@ConditionalOnMissingClass(NACOS_CONFIG_MANAGER_KEY)
@ -88,4 +92,15 @@ public class ConfigHandlerConfiguration {
return new ZookeeperRefresherHandler();
}
}
@ConditionalOnClass(Client.class)
@ConditionalOnProperty(prefix = BootstrapConfigProperties.PREFIX, name = ETCD)
static class EmbeddedEtcd {
@Bean
public EtcdRefresherHandler etcdRefresher() {
return new EtcdRefresherHandler();
}
}
}

@ -15,28 +15,29 @@
* limitations under the License.
*/
package cn.hippo4j.core.springboot.starter.config;
package cn.hippo4j.config.springboot.starter.config;
import cn.hippo4j.common.config.ApplicationContextHolder;
import cn.hippo4j.config.springboot.starter.monitor.DynamicThreadPoolMonitorExecutor;
import cn.hippo4j.config.springboot.starter.notify.CoreNotifyConfigBuilder;
import cn.hippo4j.config.springboot.starter.refresher.event.AdapterExecutorsRefreshListener;
import cn.hippo4j.config.springboot.starter.refresher.event.DynamicThreadPoolRefreshListener;
import cn.hippo4j.config.springboot.starter.refresher.event.PlatformsRefreshListener;
import cn.hippo4j.config.springboot.starter.refresher.event.WebExecutorRefreshListener;
import cn.hippo4j.config.springboot.starter.support.DynamicThreadPoolAdapterRegister;
import cn.hippo4j.config.springboot.starter.support.DynamicThreadPoolConfigService;
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.core.springboot.starter.monitor.DynamicThreadPoolMonitorExecutor;
import cn.hippo4j.core.springboot.starter.notify.CoreNotifyConfigBuilder;
import cn.hippo4j.core.springboot.starter.refresher.event.AdapterExecutorsRefreshListener;
import cn.hippo4j.core.springboot.starter.refresher.event.DynamicThreadPoolRefreshListener;
import cn.hippo4j.core.springboot.starter.refresher.event.PlatformsRefreshListener;
import cn.hippo4j.core.springboot.starter.refresher.event.WebExecutorRefreshListener;
import cn.hippo4j.core.springboot.starter.support.DynamicThreadPoolAdapterRegister;
import cn.hippo4j.core.springboot.starter.support.DynamicThreadPoolConfigService;
import cn.hippo4j.core.springboot.starter.support.DynamicThreadPoolPostProcessor;
import cn.hippo4j.message.api.NotifyConfigBuilder;
import cn.hippo4j.message.config.MessageConfiguration;
import cn.hippo4j.message.service.AlarmControlHandler;
import cn.hippo4j.message.service.Hippo4jBaseSendMessageService;
import cn.hippo4j.message.service.Hippo4jSendMessageService;
import lombok.AllArgsConstructor;
import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
@ -59,7 +60,8 @@ import org.springframework.core.annotation.Order;
@ConditionalOnProperty(prefix = BootstrapConfigProperties.PREFIX, value = "enable", matchIfMissing = true, havingValue = "true")
@Import({
ConfigHandlerConfiguration.EmbeddedNacos.class, ConfigHandlerConfiguration.EmbeddedNacosCloud.class,
ConfigHandlerConfiguration.EmbeddedApollo.class, ConfigHandlerConfiguration.EmbeddedZookeeper.class
ConfigHandlerConfiguration.EmbeddedApollo.class, ConfigHandlerConfiguration.EmbeddedZookeeper.class,
ConfigHandlerConfiguration.EmbeddedEtcd.class
})
public class DynamicThreadPoolCoreAutoConfiguration {
@ -78,8 +80,8 @@ public class DynamicThreadPoolCoreAutoConfiguration {
}
@Bean
public ThreadPoolNotifyAlarmHandler threadPoolNotifyAlarmHandler(Hippo4jSendMessageService hippoSendMessageService) {
return new ThreadPoolNotifyAlarmHandler(hippoSendMessageService);
public ThreadPoolNotifyAlarmHandler threadPoolNotifyAlarmHandler(Hippo4jSendMessageService hippo4jSendMessageService) {
return new ThreadPoolNotifyAlarmHandler(hippo4jSendMessageService);
}
@Bean

@ -15,7 +15,7 @@
* limitations under the License.
*/
package cn.hippo4j.core.springboot.starter.config;
package cn.hippo4j.config.springboot.starter.config;
import lombok.AllArgsConstructor;
import lombok.Builder;

@ -15,13 +15,13 @@
* limitations under the License.
*/
package cn.hippo4j.core.springboot.starter.monitor;
package cn.hippo4j.config.springboot.starter.monitor;
import cn.hippo4j.common.config.ApplicationContextHolder;
import cn.hippo4j.common.toolkit.StringUtil;
import cn.hippo4j.config.springboot.starter.config.BootstrapConfigProperties;
import cn.hippo4j.core.executor.support.ThreadFactoryBuilder;
import cn.hippo4j.common.spi.DynamicThreadPoolServiceLoader;
import cn.hippo4j.core.springboot.starter.config.BootstrapConfigProperties;
import cn.hippo4j.monitor.base.DynamicThreadPoolMonitor;
import cn.hippo4j.monitor.base.ThreadPoolMonitor;
import com.google.common.collect.Lists;

@ -15,13 +15,13 @@
* limitations under the License.
*/
package cn.hippo4j.core.springboot.starter.notify;
package cn.hippo4j.config.springboot.starter.notify;
import cn.hippo4j.common.toolkit.CollectionUtil;
import cn.hippo4j.common.toolkit.StringUtil;
import cn.hippo4j.core.springboot.starter.config.BootstrapConfigProperties;
import cn.hippo4j.core.springboot.starter.config.ExecutorProperties;
import cn.hippo4j.core.springboot.starter.config.NotifyPlatformProperties;
import cn.hippo4j.config.springboot.starter.config.BootstrapConfigProperties;
import cn.hippo4j.config.springboot.starter.config.ExecutorProperties;
import cn.hippo4j.config.springboot.starter.config.NotifyPlatformProperties;
import cn.hippo4j.message.service.AlarmControlHandler;
import cn.hippo4j.message.dto.NotifyConfigDTO;
import cn.hippo4j.message.api.NotifyConfigBuilder;

@ -15,7 +15,7 @@
* limitations under the License.
*/
package cn.hippo4j.core.springboot.starter.parser;
package cn.hippo4j.config.springboot.starter.parser;
import java.io.IOException;
import java.util.List;

@ -15,7 +15,7 @@
* limitations under the License.
*/
package cn.hippo4j.core.springboot.starter.parser;
package cn.hippo4j.config.springboot.starter.parser;
import com.google.common.collect.Lists;

@ -15,7 +15,7 @@
* limitations under the License.
*/
package cn.hippo4j.core.springboot.starter.parser;
package cn.hippo4j.config.springboot.starter.parser;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;

@ -15,15 +15,15 @@
* limitations under the License.
*/
package cn.hippo4j.core.springboot.starter.refresher;
package cn.hippo4j.config.springboot.starter.refresher;
import cn.hippo4j.common.api.ThreadPoolDynamicRefresh;
import cn.hippo4j.common.config.ApplicationContextHolder;
import cn.hippo4j.common.toolkit.CollectionUtil;
import cn.hippo4j.config.springboot.starter.config.BootstrapConfigProperties;
import cn.hippo4j.config.springboot.starter.parser.ConfigParserHandler;
import cn.hippo4j.config.springboot.starter.refresher.event.Hippo4jConfigDynamicRefreshEvent;
import cn.hippo4j.core.executor.support.ThreadPoolBuilder;
import cn.hippo4j.core.springboot.starter.config.BootstrapConfigProperties;
import cn.hippo4j.core.springboot.starter.parser.ConfigParserHandler;
import cn.hippo4j.core.springboot.starter.refresher.event.Hippo4jConfigDynamicRefreshEvent;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.InitializingBean;

@ -15,8 +15,9 @@
* limitations under the License.
*/
package cn.hippo4j.core.springboot.starter.refresher;
package cn.hippo4j.config.springboot.starter.refresher;
import cn.hippo4j.config.springboot.starter.config.BootstrapConfigProperties;
import com.ctrip.framework.apollo.Config;
import com.ctrip.framework.apollo.ConfigChangeListener;
import com.ctrip.framework.apollo.ConfigFile;
@ -29,8 +30,6 @@ import org.springframework.beans.factory.annotation.Value;
import java.util.Map;
import static cn.hippo4j.core.springboot.starter.config.BootstrapConfigProperties.PREFIX;
/**
* Apollo refresher handler.
*/
@ -52,7 +51,7 @@ public class ApolloRefresherHandler extends AbstractCoreThreadPoolDynamicRefresh
ConfigFileFormat configFileFormat = ConfigFileFormat.fromString(bootstrapConfigProperties.getConfigFileType().getValue());
ConfigFile configFile = ConfigService.getConfigFile(namespace, configFileFormat);
Map<String, Object> newChangeValueMap = Maps.newHashMap();
configChangeEvent.changedKeys().stream().filter(each -> each.contains(PREFIX)).forEach(each -> {
configChangeEvent.changedKeys().stream().filter(each -> each.contains(BootstrapConfigProperties.PREFIX)).forEach(each -> {
ConfigChange change = configChangeEvent.getChange(each);
String newValue = change.getNewValue();
newChangeValueMap.put(each, newValue);

@ -15,14 +15,14 @@
* limitations under the License.
*/
package cn.hippo4j.core.springboot.starter.refresher;
package cn.hippo4j.config.springboot.starter.refresher;
import cn.hippo4j.common.toolkit.CollectionUtil;
import cn.hippo4j.common.toolkit.StringUtil;
import cn.hippo4j.core.springboot.starter.config.BootstrapConfigProperties;
import cn.hippo4j.core.springboot.starter.config.DynamicThreadPoolNotifyProperties;
import cn.hippo4j.core.springboot.starter.config.ExecutorProperties;
import cn.hippo4j.core.springboot.starter.config.NotifyPlatformProperties;
import cn.hippo4j.config.springboot.starter.config.BootstrapConfigProperties;
import cn.hippo4j.config.springboot.starter.config.DynamicThreadPoolNotifyProperties;
import cn.hippo4j.config.springboot.starter.config.ExecutorProperties;
import cn.hippo4j.config.springboot.starter.config.NotifyPlatformProperties;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import com.google.common.collect.Lists;
@ -35,8 +35,6 @@ import org.springframework.boot.context.properties.source.MapConfigurationProper
import java.util.List;
import java.util.Map;
import static cn.hippo4j.core.springboot.starter.config.BootstrapConfigProperties.PREFIX;
/**
* Bootstrap core properties binder adapt.
*/
@ -54,7 +52,7 @@ public class BootstrapCorePropertiesBinderAdapt {
try {
ConfigurationPropertySource sources = new MapConfigurationPropertySource(configInfo);
Binder binder = new Binder(sources);
bindableCoreProperties = binder.bind(PREFIX, Bindable.ofInstance(bootstrapConfigProperties)).get();
bindableCoreProperties = binder.bind(BootstrapConfigProperties.PREFIX, Bindable.ofInstance(bootstrapConfigProperties)).get();
} catch (Exception ex) {
try {
Class.forName("org.springframework.boot.context.properties.bind.Binder");
@ -80,11 +78,11 @@ public class BootstrapCorePropertiesBinderAdapt {
configInfo.forEach((key, val) -> {
boolean containFlag = key != null
&& StringUtil.isNotBlank((String) key)
&& (((String) key).indexOf(PREFIX + ".executors") != -1
|| ((String) key).indexOf(PREFIX + ".notify-platforms") != -1
|| ((String) key).indexOf(PREFIX + ".notifyPlatforms") != -1);
&& (((String) key).indexOf(BootstrapConfigProperties.PREFIX + ".executors") != -1
|| ((String) key).indexOf(BootstrapConfigProperties.PREFIX + ".notify-platforms") != -1
|| ((String) key).indexOf(BootstrapConfigProperties.PREFIX + ".notifyPlatforms") != -1);
if (containFlag) {
String targetKey = key.toString().replace(PREFIX + ".", "");
String targetKey = key.toString().replace(BootstrapConfigProperties.PREFIX + ".", "");
targetMap.put(targetKey, val);
}
});

@ -0,0 +1,103 @@
/*
* 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.springboot.starter.refresher;
import cn.hippo4j.common.toolkit.JSONUtil;
import cn.hippo4j.common.toolkit.StringUtil;
import io.etcd.jetcd.*;
import io.etcd.jetcd.kv.GetResponse;
import io.etcd.jetcd.watch.WatchEvent;
import io.etcd.jetcd.watch.WatchResponse;
import lombok.extern.slf4j.Slf4j;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.Map;
import java.util.Objects;
/**
* @author : wh
* @date : 2022/8/30 17:59
* @description:
*/
@Slf4j
public class EtcdRefresherHandler extends AbstractCoreThreadPoolDynamicRefresh {
private Client client;
private static final String ENDPOINTS = "endpoints";
private static final String USER = "user";
private static final String PASSWORD = "password";
private static final String CHARSET = "charset";
private static final String AUTHORITY = "authority";
private static final String KEY = "key";
@Override
public void afterPropertiesSet() throws Exception {
Map<String, String> etcd = bootstrapConfigProperties.getEtcd();
String user = etcd.get(USER);
String password = etcd.get(PASSWORD);
String endpoints = etcd.get(ENDPOINTS);
String authority = etcd.get(AUTHORITY);
String key = etcd.get(KEY);
Charset charset = StringUtil.isBlank(etcd.get(CHARSET)) ? StandardCharsets.UTF_8 : Charset.forName(etcd.get(CHARSET));
ClientBuilder clientBuilder = Client.builder().endpoints(endpoints.split(","));
// todo
if (Objects.isNull(client)) {
client = StringUtil.isAllNotEmpty(user, password) ? clientBuilder.user(ByteSequence.from(user, charset))
.password(ByteSequence.from(password, charset)).authority(authority)
.build() : clientBuilder.build();
}
// todo Currently only supports json
GetResponse getResponse = client.getKVClient().get(ByteSequence.from(key, charset)).get();
KeyValue keyValue = getResponse.getKvs().get(0);
if (Objects.isNull(keyValue)) {
return;
}
client.getWatchClient().watch(ByteSequence.from(key, charset), new Watch.Listener() {
@Override
public void onNext(WatchResponse response) {
WatchEvent watchEvent = response.getEvents().get(0);
WatchEvent.EventType eventType = watchEvent.getEventType();
// todo Currently only supports json
if (Objects.equals(eventType, WatchEvent.EventType.PUT)) {
KeyValue keyValue1 = watchEvent.getKeyValue();
String value = keyValue1.getValue().toString(charset);
Map map = JSONUtil.parseObject(value, Map.class);
dynamicRefresh(keyValue1.getKey().toString(charset), map);
}
}
@Override
public void onError(Throwable throwable) {
log.error("Dynamic thread pool etcd config watcher exception ", throwable);
}
@Override
public void onCompleted() {
log.info("Dynamic thread pool etcd config key refreshed, config key {}", key);
}
});
}
}

@ -15,7 +15,7 @@
* limitations under the License.
*/
package cn.hippo4j.core.springboot.starter.refresher;
package cn.hippo4j.config.springboot.starter.refresher;
import cn.hippo4j.common.config.ApplicationContextHolder;
import com.alibaba.cloud.nacos.NacosConfigManager;

@ -15,9 +15,9 @@
* limitations under the License.
*/
package cn.hippo4j.core.springboot.starter.refresher;
package cn.hippo4j.config.springboot.starter.refresher;
import cn.hippo4j.core.springboot.starter.config.BootstrapConfigProperties;
import cn.hippo4j.config.springboot.starter.config.BootstrapConfigProperties;
import com.alibaba.nacos.api.annotation.NacosInjected;
import com.alibaba.nacos.api.config.ConfigService;
import com.alibaba.nacos.api.config.listener.Listener;

@ -15,7 +15,7 @@
* limitations under the License.
*/
package cn.hippo4j.core.springboot.starter.refresher;
package cn.hippo4j.config.springboot.starter.refresher;
import cn.hippo4j.core.executor.manage.GlobalNotifyAlarmManage;
import cn.hippo4j.message.service.ThreadPoolNotifyAlarm;

@ -15,13 +15,14 @@
* limitations under the License.
*/
package cn.hippo4j.core.springboot.starter.refresher.event;
package cn.hippo4j.config.springboot.starter.refresher.event;
import cn.hippo4j.adapter.base.ThreadPoolAdapter;
import cn.hippo4j.adapter.base.ThreadPoolAdapterParameter;
import cn.hippo4j.common.config.ApplicationContextHolder;
import cn.hippo4j.common.toolkit.CollectionUtil;
import cn.hippo4j.core.springboot.starter.config.AdapterExecutorProperties;
import cn.hippo4j.config.springboot.starter.config.AdapterExecutorProperties;
import cn.hippo4j.config.springboot.starter.support.DynamicThreadPoolAdapterRegister;
import cn.hutool.core.bean.BeanUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.ApplicationListener;
@ -32,8 +33,7 @@ import java.util.Map;
import java.util.Objects;
import static cn.hippo4j.common.constant.Constants.IDENTIFY_SLICER_SYMBOL;
import static cn.hippo4j.core.springboot.starter.refresher.event.Hippo4jConfigDynamicRefreshEventOrder.ADAPTER_EXECUTORS_LISTENER;
import static cn.hippo4j.core.springboot.starter.support.DynamicThreadPoolAdapterRegister.ADAPTER_EXECUTORS_MAP;
import static cn.hippo4j.config.springboot.starter.refresher.event.Hippo4jConfigDynamicRefreshEventOrder.ADAPTER_EXECUTORS_LISTENER;
/**
* Adapter executors refresh listener.
@ -51,7 +51,7 @@ public class AdapterExecutorsRefreshListener implements ApplicationListener<Hipp
}
for (AdapterExecutorProperties each : adapterExecutors) {
String buildKey = each.getMark() + IDENTIFY_SLICER_SYMBOL + each.getThreadPoolKey();
AdapterExecutorProperties adapterExecutorProperties = ADAPTER_EXECUTORS_MAP.get(buildKey);
AdapterExecutorProperties adapterExecutorProperties = DynamicThreadPoolAdapterRegister.ADAPTER_EXECUTORS_MAP.get(buildKey);
if (adapterExecutorProperties == null) {
continue;
}
@ -60,7 +60,7 @@ public class AdapterExecutorsRefreshListener implements ApplicationListener<Hipp
threadPoolAdapterMap.forEach((key, val) -> {
if (Objects.equals(val.mark(), each.getMark())) {
val.updateThreadPool(BeanUtil.toBean(each, ThreadPoolAdapterParameter.class));
ADAPTER_EXECUTORS_MAP.put(buildKey, each);
DynamicThreadPoolAdapterRegister.ADAPTER_EXECUTORS_MAP.put(buildKey, each);
}
});
}

@ -15,22 +15,22 @@
* limitations under the License.
*/
package cn.hippo4j.core.springboot.starter.refresher.event;
package cn.hippo4j.config.springboot.starter.refresher.event;
import cn.hippo4j.common.executor.support.BlockingQueueTypeEnum;
import cn.hippo4j.common.executor.support.RejectedPolicyTypeEnum;
import cn.hippo4j.common.executor.support.ResizableCapacityLinkedBlockingQueue;
import cn.hippo4j.common.toolkit.CollectionUtil;
import cn.hippo4j.config.springboot.starter.config.BootstrapConfigProperties;
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.core.executor.support.AbstractDynamicExecutorSupport;
import cn.hippo4j.core.proxy.RejectedProxyUtil;
import cn.hippo4j.core.springboot.starter.config.BootstrapConfigProperties;
import cn.hippo4j.core.springboot.starter.config.ExecutorProperties;
import cn.hippo4j.core.springboot.starter.notify.CoreNotifyConfigBuilder;
import cn.hippo4j.core.springboot.starter.support.GlobalCoreThreadPoolManage;
import cn.hippo4j.message.dto.NotifyConfigDTO;
import cn.hippo4j.message.request.ChangeParameterNotifyRequest;
import cn.hippo4j.message.service.Hippo4jBaseSendMessageService;
@ -52,7 +52,7 @@ import java.util.concurrent.atomic.AtomicLong;
import static cn.hippo4j.common.constant.ChangeThreadPoolConstants.CHANGE_DELIMITER;
import static cn.hippo4j.common.constant.ChangeThreadPoolConstants.CHANGE_THREAD_POOL_TEXT;
import static cn.hippo4j.core.springboot.starter.refresher.event.Hippo4jConfigDynamicRefreshEventOrder.EXECUTORS_LISTENER;
import static cn.hippo4j.config.springboot.starter.refresher.event.Hippo4jConfigDynamicRefreshEventOrder.EXECUTORS_LISTENER;
/**
* Dynamic thread-pool refresh listener.

@ -15,9 +15,9 @@
* limitations under the License.
*/
package cn.hippo4j.core.springboot.starter.refresher.event;
package cn.hippo4j.config.springboot.starter.refresher.event;
import cn.hippo4j.core.springboot.starter.config.BootstrapConfigProperties;
import cn.hippo4j.config.springboot.starter.config.BootstrapConfigProperties;
import lombok.Getter;
import lombok.Setter;
import org.springframework.context.ApplicationEvent;

@ -15,14 +15,14 @@
* limitations under the License.
*/
package cn.hippo4j.core.springboot.starter.refresher.event;
package cn.hippo4j.config.springboot.starter.refresher.event;
import cn.hippo4j.common.config.ApplicationContextHolder;
import cn.hippo4j.config.springboot.starter.config.BootstrapConfigProperties;
import cn.hippo4j.config.springboot.starter.config.ExecutorProperties;
import cn.hippo4j.config.springboot.starter.notify.CoreNotifyConfigBuilder;
import cn.hippo4j.core.executor.DynamicThreadPoolWrapper;
import cn.hippo4j.core.executor.manage.GlobalThreadPoolManage;
import cn.hippo4j.core.springboot.starter.config.BootstrapConfigProperties;
import cn.hippo4j.core.springboot.starter.config.ExecutorProperties;
import cn.hippo4j.core.springboot.starter.notify.CoreNotifyConfigBuilder;
import cn.hippo4j.message.dto.NotifyConfigDTO;
import cn.hippo4j.message.service.Hippo4jBaseSendMessageService;
import org.springframework.context.ApplicationListener;
@ -31,7 +31,7 @@ import org.springframework.core.annotation.Order;
import java.util.List;
import java.util.Map;
import static cn.hippo4j.core.springboot.starter.refresher.event.Hippo4jConfigDynamicRefreshEventOrder.PLATFORMS_LISTENER;
import static cn.hippo4j.config.springboot.starter.refresher.event.Hippo4jConfigDynamicRefreshEventOrder.PLATFORMS_LISTENER;
/**
* Platforms refresh listener.

@ -15,22 +15,22 @@
* limitations under the License.
*/
package cn.hippo4j.core.springboot.starter.refresher.event;
package cn.hippo4j.config.springboot.starter.refresher.event;
import cn.hippo4j.adapter.web.WebThreadPoolHandlerChoose;
import cn.hippo4j.adapter.web.WebThreadPoolService;
import cn.hippo4j.common.config.ApplicationContextHolder;
import cn.hippo4j.common.model.ThreadPoolParameter;
import cn.hippo4j.common.model.ThreadPoolParameterInfo;
import cn.hippo4j.core.springboot.starter.config.BootstrapConfigProperties;
import cn.hippo4j.core.springboot.starter.config.WebThreadPoolProperties;
import cn.hippo4j.config.springboot.starter.config.BootstrapConfigProperties;
import cn.hippo4j.config.springboot.starter.config.WebThreadPoolProperties;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.ApplicationListener;
import org.springframework.core.annotation.Order;
import java.util.Objects;
import static cn.hippo4j.core.springboot.starter.refresher.event.Hippo4jConfigDynamicRefreshEventOrder.WEB_EXECUTOR_LISTENER;
import static cn.hippo4j.config.springboot.starter.refresher.event.Hippo4jConfigDynamicRefreshEventOrder.WEB_EXECUTOR_LISTENER;
/**
* Web executor refresh listener.

@ -15,11 +15,11 @@
* limitations under the License.
*/
package cn.hippo4j.core.springboot.starter.support;
package cn.hippo4j.config.springboot.starter.support;
import cn.hippo4j.common.toolkit.CollectionUtil;
import cn.hippo4j.core.springboot.starter.config.AdapterExecutorProperties;
import cn.hippo4j.core.springboot.starter.config.BootstrapConfigProperties;
import cn.hippo4j.config.springboot.starter.config.BootstrapConfigProperties;
import cn.hippo4j.config.springboot.starter.config.AdapterExecutorProperties;
import com.google.common.collect.Maps;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;

@ -15,19 +15,19 @@
* limitations under the License.
*/
package cn.hippo4j.core.springboot.starter.support;
package cn.hippo4j.config.springboot.starter.support;
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.toolkit.BooleanUtil;
import cn.hippo4j.config.springboot.starter.config.ExecutorProperties;
import cn.hippo4j.core.executor.DynamicThreadPoolWrapper;
import cn.hippo4j.core.executor.manage.GlobalNotifyAlarmManage;
import cn.hippo4j.core.executor.manage.GlobalThreadPoolManage;
import cn.hippo4j.common.executor.support.BlockingQueueTypeEnum;
import cn.hippo4j.common.executor.support.RejectedPolicyTypeEnum;
import cn.hippo4j.core.executor.support.service.AbstractDynamicThreadPoolService;
import cn.hippo4j.core.springboot.starter.config.ExecutorProperties;
import cn.hippo4j.message.service.ThreadPoolNotifyAlarm;
import java.util.concurrent.ThreadPoolExecutor;

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save