Merge pull request #6 from longtai-cn/develop

merge
pull/198/head
skyemin 3 years ago committed by GitHub
commit 552d7f4019
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

3
.gitignore vendored

@ -31,3 +31,6 @@ build/
### VS Code ### ### VS Code ###
.vscode/ .vscode/
# maven plugin ignore
*.gpg

@ -1,14 +1,16 @@
![](https://images-machen.oss-cn-beijing.aliyuncs.com/hippo4j-logo-logoly.png) ![](https://images-machen.oss-cn-beijing.aliyuncs.com/hippo4j-logo-logoly.png)
<p> <p>
<a href="https://github.com/acmenlt/dynamic-threadpool" target="_blank"> <a href="https://gitee.com/longtai-cn/hippo4j" target="_blank">
<img alt="GitHub" src="https://img.shields.io/github/stars/acmenlt/dynamic-threadpool?label=Stars&style=flat-square&logo=GitHub"> <img alt="Gitee" src="https://gitee.com/longtai-cn/hippo4j/badge/star.svg?theme=gvp">
</a>
<a href="https://github.com/longtai-cn/hippo4j" target="_blank">
<img alt="GitHub" src="https://img.shields.io/github/stars/longtai-cn/hippo4j?label=Stars&style=flat-square&logo=GitHub">
</a> </a>
<a href="https://github.com/acmenlt/dynamic-threadpool/blob/develop/LICENSE"> <a href="https://github.com/longtai-cn/hippo4j/blob/develop/LICENSE">
<img src="https://img.shields.io/github/license/acmenlt/dynamic-threadpool?color=42b883&style=flat-square" alt="LICENSE"> <img src="https://img.shields.io/github/license/longtai-cn/hippo4j?color=42b883&style=flat-square" alt="LICENSE">
</a> </a>
<a title="Hits" target="_blank" href="https://github.com/acmenlt/dynamic-threadpool"> <a title="Hits" target="_blank" href="https://github.com/longtai-cn/hippo4j">
<img src="https://hits.b3log.org/acmenlt/dynamic-threadpool.svg"> <img src="https://hits.b3log.org/acmenlt/dynamic-threadpool.svg">
</a> </a>
</p> </p>
@ -21,15 +23,15 @@ Hippo4J 基于 **美团动态线程池** 设计理念开发,针对线程池增
按照租户、项目、线程池的维度划分,配合系统权限,让不同的开发、管理人员负责自己系统的线程池。 按照租户、项目、线程池的维度划分,配合系统权限,让不同的开发、管理人员负责自己系统的线程池。
1.1.0 版本发布后Hippo4J 分为两种使用模式,用一张图来说明两者的使用差别 1.1.0 版本发布后Hippo4J 分为两种使用模式:轻量级依赖配置中心以及无中间件依赖版本
![](https://images-machen.oss-cn-beijing.aliyuncs.com/image-20220319154626314.png) ![](https://images-machen.oss-cn-beijing.aliyuncs.com/image-20220319154626314.png)
### hippo4j-core ### hippo4j-core
**轻量级动态线程池管理**,依赖 Apollo、Nacos 等三方配置中心(任选其一)完成线程池参数动态变更,同样包含运行时报警、监控功能。 **轻量级动态线程池管理**,依赖 Apollo、Nacos、Zookeeper 等三方配置中心(任选其一)完成线程池参数动态变更,支持运行时报警、监控等功能。
> 监控功能配置详见:[线程池监控](https://hippox.cn/pages/2f67ll) > 监控功能配置详见:[线程池监控](https://hippo4j.cn/pages/2f67ll)
![](https://images-machen.oss-cn-beijing.aliyuncs.com/image-202203271737049821.png) ![](https://images-machen.oss-cn-beijing.aliyuncs.com/image-202203271737049821.png)
@ -37,14 +39,15 @@ Hippo4J 基于 **美团动态线程池** 设计理念开发,针对线程池增
**部署 hippo4j-server 服务**,通过可视化 Web 界面完成线程池的创建、变更以及查看,不依赖三方中间件。 **部署 hippo4j-server 服务**,通过可视化 Web 界面完成线程池的创建、变更以及查看,不依赖三方中间件。
相比较 hippo4j-core功能会更强大也引入了一定的复杂性。需要部署一个 Java 服务,以及 MySQL 数据库。 相比较 hippo4j-core功能会更强大同时也引入了一定的复杂性。需要部署一个 Java 服务,以及依赖 MySQL 数据库。
![](https://images-machen.oss-cn-beijing.aliyuncs.com/1644032018254-min.gif)
### 使用总结 ### 使用总结
| | hippo4j-core | hippo4j-server | | | hippo4j-core | hippo4j-server |
| ---- | ---------------------------------------------------- | ------------------------------------------------------------ | | ---- | ---------------------------------------------------- | ------------------------------------------------------------ |
| 依赖 | Nacos、Apollo 等配置中心(任选其一) | 部署 Hippo4J Server内部无依赖中间件 | | 依赖 | Nacos、Apollo、Zookeeper 等配置中心(任选其一) | 部署 Hippo4J Server内部无依赖中间件 |
| 使用 | 配置中心补充线程池相关参数 | Hippo4J Server Web 控制台添加线程池记录 | | 使用 | 配置中心补充线程池相关参数 | Hippo4J Server Web 控制台添加线程池记录 |
| 功能 | 包含基础功能:参数动态化、运行时监控、报警等 | 基础功能之外扩展控制台界面、线程池堆栈查看、线程池运行信息实时查看、历史运行信息查看、线程池配置集群个性化等 | | 功能 | 包含基础功能:参数动态化、运行时监控、报警等 | 基础功能之外扩展控制台界面、线程池堆栈查看、线程池运行信息实时查看、历史运行信息查看、线程池配置集群个性化等 |
@ -52,8 +55,6 @@ Hippo4J 基于 **美团动态线程池** 设计理念开发,针对线程池增
**两者在进行替换的时候,无需修改业务代码**。 **两者在进行替换的时候,无需修改业务代码**。
## 解决什么问题 ## 解决什么问题
简单来说Hippo4J 主要为我们解决了下面这些使用原生线程池存在的问题: 简单来说Hippo4J 主要为我们解决了下面这些使用原生线程池存在的问题:
@ -70,13 +71,13 @@ Hippo4J 已接入钉钉、企业微信以及飞书平台,提供了 **线程池
<table> <table>
<tr> <tr>
<td align="center" style="width: 400px;"> <td align="center" style="width: 400px;">
<a href="https://github.com/acmenlt"> <a href="https://github.com/longtai-cn">
<img src="https://images-machen.oss-cn-beijing.aliyuncs.com/image-20211203213443242.png" style="width: 400px;"><br> <img src="https://images-machen.oss-cn-beijing.aliyuncs.com/image-20211203213443242.png" style="width: 400px;"><br>
<sub>配置变更</sub> <sub>配置变更</sub>
</a><br> </a><br>
</td> </td>
<td align="center" style="width: 400px;"> <td align="center" style="width: 400px;">
<a href="https://github.com/acmenlt"> <a href="https://github.com/longtai-cn">
<img src="https://images-machen.oss-cn-beijing.aliyuncs.com/image-20211203213512019.png" style="width: 400px;"><br> <img src="https://images-machen.oss-cn-beijing.aliyuncs.com/image-20211203213512019.png" style="width: 400px;"><br>
<sub>报警通知</sub> <sub>报警通知</sub>
</a><br> </a><br>
@ -86,14 +87,15 @@ Hippo4J 已接入钉钉、企业微信以及飞书平台,提供了 **线程池
## 快速开始 ## 快速开始
[运行 Hippo4J 自带 Demo 参考文档](https://hippox.cn/pages/793dcb/) [运行 Hippo4J 自带 Demo 参考文档](https://hippo4j.cn/pages/793dcb/)
[在线体验地址](http://console.hippox.cn:6691/index.html) 用户名密码hippo4j / hippo4j [在线体验地址](http://console.hippox.cn:6691/index.html) 用户名密码hippo4j / hippo4j
## 联系我 ## 联系我
对于这个项目,是否有什么不一样看法,同 [作者](https://hippox.cn/pages/dd137d/) 或者创建 [Issues](https://github.com/acmenlt/dynamic-threadpool/issues) 沟通。 对于这个项目,是否有什么不一样看法,同 [作者](https://hippo4j.cn/pages/dd137d/) 或者创建 [Issues](https://github.com/longtai-cn/hippo4j/issues) 沟通。
![](https://images-machen.oss-cn-beijing.aliyuncs.com/64E583A0-B1DD-49A3-9AEC-8D246E9D5C12-mini.png)
## 公众号 ## 公众号
@ -103,8 +105,7 @@ Hippo4J 已接入钉钉、企业微信以及飞书平台,提供了 **线程池
## Stars 趋势 ## Stars 趋势
[![Stargazers over time](https://starchart.cc/acmenlt/dynamic-threadpool.svg)](https://starchart.cc/acmenlt/dynamic-threadpool) [![Stargazers over time](https://starchart.cc/longtai-cn/hippo4j.svg)](https://starchart.cc/longtai-cn/hippo4j)
## 友情链接 ## 友情链接
@ -115,7 +116,6 @@ Hippo4J 已接入钉钉、企业微信以及飞书平台,提供了 **线程池
## 鸣谢 ## 鸣谢
Hippo4J 项目基于或参考以下项目:[**Nacos**](https://github.com/alibaba/nacos)、[**Eureka**](https://github.com/Netflix/Eureka)、[**Mzt-Biz-Log**](https://github.com/mouzt/mzt-biz-log)、[**Equator**](https://github.com/dadiyang/equator)。 Hippo4J 项目基于或参考以下项目:[**Nacos**](https://github.com/alibaba/nacos)、[**Eureka**](https://github.com/Netflix/Eureka)、[**Mzt-Biz-Log**](https://github.com/mouzt/mzt-biz-log)、[**Equator**](https://github.com/dadiyang/equator)。
感谢 JetBrains 提供的免费开源 License 感谢 JetBrains 提供的免费开源 License

@ -53,6 +53,12 @@
</exclusions> </exclusions>
<optional>true</optional> <optional>true</optional>
</dependency> </dependency>
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.14</version>
</dependency>
</dependencies> </dependencies>
<build> <build>

@ -43,6 +43,11 @@ public class NotifyConfigDTO {
*/ */
private String secretKey; private String secretKey;
/**
*
*/
private String secret;
/** /**
* *
*/ */

@ -1,6 +1,9 @@
package cn.hippo4j.common.notify.platform; package cn.hippo4j.common.notify.platform;
import cn.hippo4j.common.notify.*; import cn.hippo4j.common.notify.NotifyConfigDTO;
import cn.hippo4j.common.notify.NotifyPlatformEnum;
import cn.hippo4j.common.notify.NotifyTypeEnum;
import cn.hippo4j.common.notify.SendMessageHandler;
import cn.hippo4j.common.notify.request.AlarmNotifyRequest; import cn.hippo4j.common.notify.request.AlarmNotifyRequest;
import cn.hippo4j.common.notify.request.ChangeParameterNotifyRequest; import cn.hippo4j.common.notify.request.ChangeParameterNotifyRequest;
import cn.hippo4j.common.toolkit.StringUtil; import cn.hippo4j.common.toolkit.StringUtil;
@ -13,7 +16,12 @@ import com.google.common.base.Joiner;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import com.taobao.api.ApiException; import com.taobao.api.ApiException;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.binary.Base64;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.List; import java.util.List;
import java.util.Objects; import java.util.Objects;
@ -102,7 +110,7 @@ public class DingSendMessageHandler implements SendMessageHandler<AlarmNotifyReq
DateUtil.now() DateUtil.now()
); );
execute(notifyConfig.getSecretKey(), DingAlarmConstants.DING_ALARM_TITLE, text, Lists.newArrayList(receives)); execute(notifyConfig, DingAlarmConstants.DING_ALARM_TITLE, text, Lists.newArrayList(receives));
} }
@Override @Override
@ -148,25 +156,35 @@ public class DingSendMessageHandler implements SendMessageHandler<AlarmNotifyReq
DateUtil.now() DateUtil.now()
); );
execute(notifyConfig.getSecretKey(), DingAlarmConstants.DING_NOTICE_TITLE, text, Lists.newArrayList(receives)); execute(notifyConfig, DingAlarmConstants.DING_NOTICE_TITLE, text, Lists.newArrayList(receives));
} }
private void execute(String secretKey, String title, String text, List<String> mobiles) { private void execute(NotifyConfigDTO notifyConfig, String title, String text, List<String> mobiles) {
String serverUrl = DingAlarmConstants.DING_ROBOT_SERVER_URL + secretKey; String serverUrl = DingAlarmConstants.DING_ROBOT_SERVER_URL + notifyConfig.getSecretKey();
String secret = notifyConfig.getSecret();
if (StringUtil.isNotBlank(secret)) {
long timestamp = System.currentTimeMillis();
String stringToSign = timestamp + "\n" + secret;
try {
Mac mac = Mac.getInstance("HmacSHA256");
mac.init(new SecretKeySpec(secret.getBytes(StandardCharsets.UTF_8), "HmacSHA256"));
byte[] signData = mac.doFinal(stringToSign.getBytes(StandardCharsets.UTF_8));
String sign = URLEncoder.encode(new String(Base64.encodeBase64(signData)), StandardCharsets.UTF_8.name());
serverUrl = serverUrl + "&timestamp=" + timestamp + "&sign=" + sign;
} catch (Exception ex) {
log.error("Failed to sign the message sent by nailing.", ex);
}
}
DingTalkClient dingTalkClient = new DefaultDingTalkClient(serverUrl); DingTalkClient dingTalkClient = new DefaultDingTalkClient(serverUrl);
OapiRobotSendRequest request = new OapiRobotSendRequest(); OapiRobotSendRequest request = new OapiRobotSendRequest();
request.setMsgtype("markdown"); request.setMsgtype("markdown");
OapiRobotSendRequest.Markdown markdown = new OapiRobotSendRequest.Markdown(); OapiRobotSendRequest.Markdown markdown = new OapiRobotSendRequest.Markdown();
markdown.setTitle(title); markdown.setTitle(title);
markdown.setText(text); markdown.setText(text);
OapiRobotSendRequest.At at = new OapiRobotSendRequest.At(); OapiRobotSendRequest.At at = new OapiRobotSendRequest.At();
at.setAtMobiles(mobiles); at.setAtMobiles(mobiles);
request.setAt(at); request.setAt(at);
request.setMarkdown(markdown); request.setMarkdown(markdown);
try { try {
dingTalkClient.execute(request); dingTalkClient.execute(request);
} catch (ApiException ex) { } catch (ApiException ex) {

@ -167,7 +167,7 @@ public class ThreadPoolNotifyAlarmHandler implements Runnable, CommandLineRunner
*/ */
public void asyncSendExecuteTimeOutAlarm(String threadPoolId, long executeTime, long executeTimeOut, ThreadPoolExecutor threadPoolExecutor) { public void asyncSendExecuteTimeOutAlarm(String threadPoolId, long executeTime, long executeTimeOut, ThreadPoolExecutor threadPoolExecutor) {
ThreadPoolNotifyAlarm threadPoolNotifyAlarm = GlobalNotifyAlarmManage.get(threadPoolId); ThreadPoolNotifyAlarm threadPoolNotifyAlarm = GlobalNotifyAlarmManage.get(threadPoolId);
if (!threadPoolNotifyAlarm.getIsAlarm()) { if (Objects.isNull(threadPoolNotifyAlarm) || !threadPoolNotifyAlarm.getIsAlarm()) {
return; return;
} }

@ -24,9 +24,9 @@ public class DynamicThreadPoolBannerHandler implements InitializingBean {
private final String DYNAMIC_THREAD_POOL = " :: Dynamic ThreadPool :: "; private final String DYNAMIC_THREAD_POOL = " :: Dynamic ThreadPool :: ";
private final String HIPPO4J_GITHUB = "GitHub: https://github.com/acmenlt/dynamic-threadpool"; private final String HIPPO4J_GITHUB = "GitHub: https://github.com/longtai-cn/hippo4j";
private final String HIPPO4J_SITE = "Site: https://hippox.cn"; private final String HIPPO4J_SITE = "Site: https://hippo4j.cn";
private final int STRAP_LINE_SIZE = 50; private final int STRAP_LINE_SIZE = 50;

@ -26,22 +26,22 @@ import static cn.hippo4j.common.constant.Constants.BASE_PATH;
@RequestMapping(BASE_PATH + "/apps") @RequestMapping(BASE_PATH + "/apps")
public class ApplicationController { public class ApplicationController {
private final InstanceRegistry instanceRegistry; private final InstanceRegistry<InstanceInfo> instanceRegistry;
@GetMapping("/{appName}") @GetMapping("/{appName}")
public Result applications(@PathVariable String appName) { public Result<List<Lease<InstanceInfo>>> applications(@PathVariable String appName) {
List<Lease<InstanceInfo>> resultInstanceList = instanceRegistry.listInstance(appName); List<Lease<InstanceInfo>> resultInstanceList = instanceRegistry.listInstance(appName);
return Results.success(resultInstanceList); return Results.success(resultInstanceList);
} }
@PostMapping("/register") @PostMapping("/register")
public Result addInstance(@RequestBody InstanceInfo instanceInfo) { public Result<Void> addInstance(@RequestBody InstanceInfo instanceInfo) {
instanceRegistry.register(instanceInfo); instanceRegistry.register(instanceInfo);
return Results.success(); return Results.success();
} }
@PostMapping("/renew") @PostMapping("/renew")
public Result renew(@RequestBody InstanceInfo.InstanceRenew instanceRenew) { public Result<Void> renew(@RequestBody InstanceInfo.InstanceRenew instanceRenew) {
boolean isSuccess = instanceRegistry.renew(instanceRenew); boolean isSuccess = instanceRegistry.renew(instanceRenew);
if (!isSuccess) { if (!isSuccess) {
log.warn("Not Found (Renew) :: {} - {}", instanceRenew.getAppName(), instanceRenew.getInstanceId()); log.warn("Not Found (Renew) :: {} - {}", instanceRenew.getAppName(), instanceRenew.getInstanceId());
@ -51,7 +51,7 @@ public class ApplicationController {
} }
@PostMapping("/remove") @PostMapping("/remove")
public Result remove(@RequestBody InstanceInfo instanceInfo) { public Result<Void> remove(@RequestBody InstanceInfo instanceInfo) {
instanceRegistry.remove(instanceInfo); instanceRegistry.remove(instanceInfo);
return Results.success(); return Results.success();
} }

@ -1,4 +1,4 @@
# Configuration reference: https://hippox.cn/pages/2f674h # Configuration reference: https://hippo4j.cn/pages/2f674h
server.port=8091 server.port=8091
server.servlet.context-path=/example server.servlet.context-path=/example

@ -47,7 +47,7 @@ public class RunStateHandlerTest {
/** /**
* 线, MDC Trace , . * 线, MDC Trace , .
*/ */
MDC.put(EXECUTE_TIMEOUT_TRACE, "https://github.com/acmenlt/dynamic-threadpool 感觉不错来个 Star."); MDC.put(EXECUTE_TIMEOUT_TRACE, "https://github.com/longtai-cn/hippo4j 感觉不错来个 Star.");
ThreadUtil.sleep(5000); ThreadUtil.sleep(5000);
for (int i = 0; i < Integer.MAX_VALUE; i++) { for (int i = 0; i < Integer.MAX_VALUE; i++) {
try { try {

@ -5,7 +5,7 @@
,---.'| : ',--.'| \ / \ \ / \ ,---. ,---.'| : ' : ; | PID: ${pid} ,---.'| : ',--.'| \ / \ \ / \ ,---. ,---.'| : ' : ; | PID: ${pid}
| | : _' || |, | : || : | ' ,'\ ; : | | ; : | Console: http://127.0.0.1:${server.port}/index.html | | : _' || |, | : || : | ' ,'\ ; : | | ; : | Console: http://127.0.0.1:${server.port}/index.html
: : |.' |`--'_ | | .\ :| | .\ : / / || | : _' | | : : : : |.' |`--'_ | | .\ :| | .\ : / / || | : _' | | : :
| ' ' ; :,' ,'| . : |: |. : |: |. ; ,. :: : |.' | : https://hippox.cn | ' ' ; :,' ,'| . : |: |. : |: |. ; ,. :: : |.' | : https://hippo4j.cn
' | .'. |' | | | | \ :| | \ :' | |: :| ' ' ; : | ; | ' | .'. |' | | | | \ :| | \ :' | |: :| ' ' ; : | ; |
| | : | '| | : | : . || : . |' | .; :\ \ .'. | ___ l | | : | '| | : | : . || : . |' | .; :\ \ .'. | ___ l
' : | : ;' : |__ : |`-': |`-'| : | `---`: | ' / /\ J : ' : | : ;' : |__ : |`-': |`-'| : | `---`: | ' / /\ J :

@ -18,7 +18,19 @@ public class NotifyPlatformProperties {
/** /**
* Secret key. * Secret key.
* {@link NotifyPlatformProperties#token}
*/ */
@Deprecated
private String secretKey; private String secretKey;
/**
* Token.
*/
private String token;
/**
* Secret.
*/
private String secret;
} }

@ -3,6 +3,7 @@ package cn.hippo4j.core.starter.notify;
import cn.hippo4j.common.api.NotifyConfigBuilder; import cn.hippo4j.common.api.NotifyConfigBuilder;
import cn.hippo4j.common.notify.AlarmControlHandler; import cn.hippo4j.common.notify.AlarmControlHandler;
import cn.hippo4j.common.notify.NotifyConfigDTO; import cn.hippo4j.common.notify.NotifyConfigDTO;
import cn.hippo4j.common.toolkit.StringUtil;
import cn.hippo4j.core.starter.config.BootstrapCoreProperties; import cn.hippo4j.core.starter.config.BootstrapCoreProperties;
import cn.hippo4j.core.starter.config.ExecutorProperties; import cn.hippo4j.core.starter.config.ExecutorProperties;
import cn.hippo4j.core.starter.config.NotifyPlatformProperties; import cn.hippo4j.core.starter.config.NotifyPlatformProperties;
@ -60,7 +61,8 @@ public class CoreNotifyConfigBuilder implements NotifyConfigBuilder {
notifyConfig.setPlatform(platformProperties.getPlatform()); notifyConfig.setPlatform(platformProperties.getPlatform());
notifyConfig.setTpId(threadPoolId); notifyConfig.setTpId(threadPoolId);
notifyConfig.setType("ALARM"); notifyConfig.setType("ALARM");
notifyConfig.setSecretKey(platformProperties.getSecretKey()); notifyConfig.setSecret(platformProperties.getSecret());
notifyConfig.setSecretKey(getToken(platformProperties));
int interval = Optional.ofNullable(executor.getNotify()) int interval = Optional.ofNullable(executor.getNotify())
.map(each -> each.getInterval()) .map(each -> each.getInterval())
.orElseGet(() -> bootstrapCoreProperties.getAlarmInterval() != null ? bootstrapCoreProperties.getAlarmInterval() : 5); .orElseGet(() -> bootstrapCoreProperties.getAlarmInterval() != null ? bootstrapCoreProperties.getAlarmInterval() : 5);
@ -78,7 +80,8 @@ public class CoreNotifyConfigBuilder implements NotifyConfigBuilder {
notifyConfig.setPlatform(platformProperties.getPlatform()); notifyConfig.setPlatform(platformProperties.getPlatform());
notifyConfig.setTpId(threadPoolId); notifyConfig.setTpId(threadPoolId);
notifyConfig.setType("CONFIG"); notifyConfig.setType("CONFIG");
notifyConfig.setSecretKey(platformProperties.getSecretKey()); notifyConfig.setSecretKey(getToken(platformProperties));
notifyConfig.setSecret(platformProperties.getSecret());
notifyConfig.setReceives(buildReceive(executor, platformProperties)); notifyConfig.setReceives(buildReceive(executor, platformProperties));
changeNotifyConfigs.add(notifyConfig); changeNotifyConfigs.add(notifyConfig);
} }
@ -115,4 +118,8 @@ public class CoreNotifyConfigBuilder implements NotifyConfigBuilder {
return receive; return receive;
} }
private String getToken(NotifyPlatformProperties platformProperties) {
return StringUtil.isNotBlank(platformProperties.getToken()) ? platformProperties.getToken() : platformProperties.getSecretKey();
}
} }

@ -68,7 +68,6 @@ public abstract class AbstractCoreThreadPoolDynamicRefresh implements ThreadPool
} }
BootstrapCoreProperties bindableCoreProperties = BootstrapCorePropertiesBinderAdapt.bootstrapCorePropertiesBinder(configInfo, bootstrapCoreProperties); BootstrapCoreProperties bindableCoreProperties = BootstrapCorePropertiesBinderAdapt.bootstrapCorePropertiesBinder(configInfo, bootstrapCoreProperties);
// web pool // web pool
refreshWebExecutor(bindableCoreProperties); refreshWebExecutor(bindableCoreProperties);
// platforms // platforms
@ -87,7 +86,6 @@ public abstract class AbstractCoreThreadPoolDynamicRefresh implements ThreadPool
executorProperties.getNotify().getCapacityAlarm(), executorProperties.getNotify().getCapacityAlarm(),
executorProperties.getNotify().getActiveAlarm() executorProperties.getNotify().getActiveAlarm()
); );
threadPoolNotifyAlarm.setInterval(executorProperties.getNotify().getInterval()); threadPoolNotifyAlarm.setInterval(executorProperties.getNotify().getInterval());
threadPoolNotifyAlarm.setReceives(executorProperties.receives()); threadPoolNotifyAlarm.setReceives(executorProperties.receives());
GlobalNotifyAlarmManage.put(executorProperties.getThreadPoolId(), threadPoolNotifyAlarm); GlobalNotifyAlarmManage.put(executorProperties.getThreadPoolId(), threadPoolNotifyAlarm);
@ -106,7 +104,6 @@ public abstract class AbstractCoreThreadPoolDynamicRefresh implements ThreadPool
if (isNullFlag) { if (isNullFlag) {
return; return;
} }
try { try {
PoolParameterInfo nowParameter = buildWebPoolParameter(bindableCoreProperties); PoolParameterInfo nowParameter = buildWebPoolParameter(bindableCoreProperties);
if (nowParameter != null) { if (nowParameter != null) {
@ -116,7 +113,7 @@ public abstract class AbstractCoreThreadPoolDynamicRefresh implements ThreadPool
PoolParameter beforeParameter = webThreadPoolService.getWebThreadPoolParameter(); PoolParameter beforeParameter = webThreadPoolService.getWebThreadPoolParameter();
if (!Objects.equals(beforeParameter.getCoreSize(), nowParameter.getCoreSize()) if (!Objects.equals(beforeParameter.getCoreSize(), nowParameter.getCoreSize())
|| !Objects.equals(beforeParameter.getMaxSize(), nowParameter.getMaxSize()) || !Objects.equals(beforeParameter.getMaxSize(), nowParameter.getMaxSize())
|| !Objects.equals(beforeParameter.getMaxSize(), nowParameter.getMaxSize())) { || !Objects.equals(beforeParameter.getKeepAliveTime(), nowParameter.getKeepAliveTime())) {
webThreadPoolService.updateWebThreadPool(nowParameter); webThreadPoolService.updateWebThreadPool(nowParameter);
} }
} }
@ -140,7 +137,6 @@ public abstract class AbstractCoreThreadPoolDynamicRefresh implements ThreadPool
CoreNotifyConfigBuilder configBuilder = ApplicationContextHolder.getBean(CoreNotifyConfigBuilder.class); CoreNotifyConfigBuilder configBuilder = ApplicationContextHolder.getBean(CoreNotifyConfigBuilder.class);
Map<String, List<NotifyConfigDTO>> notifyConfig = configBuilder.buildSingleNotifyConfig(executor); Map<String, List<NotifyConfigDTO>> notifyConfig = configBuilder.buildSingleNotifyConfig(executor);
sendMessageService.putPlatform(notifyConfig); sendMessageService.putPlatform(notifyConfig);
wrapper.setInitFlag(Boolean.TRUE); wrapper.setInitFlag(Boolean.TRUE);
} }
} }
@ -158,29 +154,11 @@ public abstract class AbstractCoreThreadPoolDynamicRefresh implements ThreadPool
if (!checkConsistency(threadPoolId, properties)) { if (!checkConsistency(threadPoolId, properties)) {
continue; continue;
} }
// refresh executor pool
dynamicRefreshPool(threadPoolId, properties); dynamicRefreshPool(threadPoolId, properties);
// old properties
ExecutorProperties beforeProperties = GlobalCoreThreadPoolManage.getProperties(properties.getThreadPoolId()); ExecutorProperties beforeProperties = GlobalCoreThreadPoolManage.getProperties(properties.getThreadPoolId());
ChangeParameterNotifyRequest changeRequest = new ChangeParameterNotifyRequest(); // refresh executor properties
changeRequest.setBeforeCorePoolSize(beforeProperties.getCorePoolSize());
changeRequest.setBeforeMaximumPoolSize(beforeProperties.getMaximumPoolSize());
changeRequest.setBeforeAllowsCoreThreadTimeOut(beforeProperties.getAllowCoreThreadTimeOut());
changeRequest.setBeforeKeepAliveTime(beforeProperties.getKeepAliveTime());
changeRequest.setBlockingQueueName(beforeProperties.getBlockingQueue());
changeRequest.setBeforeQueueCapacity(beforeProperties.getQueueCapacity());
changeRequest.setBeforeRejectedName(beforeProperties.getRejectedHandler());
changeRequest.setBeforeExecuteTimeOut(beforeProperties.getExecuteTimeOut());
changeRequest.setThreadPoolId(beforeProperties.getThreadPoolId());
changeRequest.setNowCorePoolSize(properties.getCorePoolSize());
changeRequest.setNowMaximumPoolSize(properties.getMaximumPoolSize());
changeRequest.setNowAllowsCoreThreadTimeOut(properties.getAllowCoreThreadTimeOut());
changeRequest.setNowKeepAliveTime(properties.getKeepAliveTime());
changeRequest.setNowQueueCapacity(properties.getQueueCapacity());
changeRequest.setNowRejectedName(properties.getRejectedHandler());
changeRequest.setNowExecuteTimeOut(properties.getExecuteTimeOut());
GlobalCoreThreadPoolManage.refresh(threadPoolId, properties); GlobalCoreThreadPoolManage.refresh(threadPoolId, properties);
log.info( log.info(
"[{}] Changed thread pool. " + "[{}] Changed thread pool. " +
@ -204,13 +182,41 @@ public abstract class AbstractCoreThreadPoolDynamicRefresh implements ThreadPool
); );
try { try {
threadPoolNotifyAlarmHandler.sendPoolConfigChange(changeRequest); threadPoolNotifyAlarmHandler.sendPoolConfigChange(newChangeRequest(beforeProperties, properties));
} catch (Throwable ex) { } catch (Throwable ex) {
log.error("Failed to send change notice. Message :: {}", ex.getMessage()); log.error("Failed to send change notice. Message :: {}", ex.getMessage());
} }
} }
} }
/**
* Construct ChangeParameterNotifyRequest instance
*
* @param beforeProperties old properties
* @param properties new properties
* @return instance
*/
private ChangeParameterNotifyRequest newChangeRequest(ExecutorProperties beforeProperties, ExecutorProperties properties) {
ChangeParameterNotifyRequest changeRequest = new ChangeParameterNotifyRequest();
changeRequest.setBeforeCorePoolSize(beforeProperties.getCorePoolSize());
changeRequest.setBeforeMaximumPoolSize(beforeProperties.getMaximumPoolSize());
changeRequest.setBeforeAllowsCoreThreadTimeOut(beforeProperties.getAllowCoreThreadTimeOut());
changeRequest.setBeforeKeepAliveTime(beforeProperties.getKeepAliveTime());
changeRequest.setBlockingQueueName(beforeProperties.getBlockingQueue());
changeRequest.setBeforeQueueCapacity(beforeProperties.getQueueCapacity());
changeRequest.setBeforeRejectedName(beforeProperties.getRejectedHandler());
changeRequest.setBeforeExecuteTimeOut(beforeProperties.getExecuteTimeOut());
changeRequest.setThreadPoolId(beforeProperties.getThreadPoolId());
changeRequest.setNowCorePoolSize(properties.getCorePoolSize());
changeRequest.setNowMaximumPoolSize(properties.getMaximumPoolSize());
changeRequest.setNowAllowsCoreThreadTimeOut(properties.getAllowCoreThreadTimeOut());
changeRequest.setNowKeepAliveTime(properties.getKeepAliveTime());
changeRequest.setNowQueueCapacity(properties.getQueueCapacity());
changeRequest.setNowRejectedName(properties.getRejectedHandler());
changeRequest.setNowExecuteTimeOut(properties.getExecuteTimeOut());
return changeRequest;
}
/** /**
* Check consistency. * Check consistency.
* *
@ -232,7 +238,6 @@ public abstract class AbstractCoreThreadPoolDynamicRefresh implements ThreadPool
!Objects.equals(beforeProperties.getQueueCapacity(), properties.getQueueCapacity()) !Objects.equals(beforeProperties.getQueueCapacity(), properties.getQueueCapacity())
&& Objects.equals(QueueTypeEnum.RESIZABLE_LINKED_BLOCKING_QUEUE.name, executor.getQueue().getClass().getSimpleName()) && Objects.equals(QueueTypeEnum.RESIZABLE_LINKED_BLOCKING_QUEUE.name, executor.getQueue().getClass().getSimpleName())
); );
return result; return result;
} }
@ -244,26 +249,21 @@ public abstract class AbstractCoreThreadPoolDynamicRefresh implements ThreadPool
*/ */
private void dynamicRefreshPool(String threadPoolId, ExecutorProperties properties) { private void dynamicRefreshPool(String threadPoolId, ExecutorProperties properties) {
ExecutorProperties beforeProperties = GlobalCoreThreadPoolManage.getProperties(properties.getThreadPoolId()); ExecutorProperties beforeProperties = GlobalCoreThreadPoolManage.getProperties(properties.getThreadPoolId());
ThreadPoolExecutor executor = GlobalThreadPoolManage.getExecutorService(threadPoolId).getExecutor(); ThreadPoolExecutor executor = GlobalThreadPoolManage.getExecutorService(threadPoolId).getExecutor();
if (!Objects.equals(beforeProperties.getCorePoolSize(), properties.getCorePoolSize())) {
executor.setCorePoolSize(properties.getCorePoolSize());
}
if (!Objects.equals(beforeProperties.getMaximumPoolSize(), properties.getMaximumPoolSize())) { if (!Objects.equals(beforeProperties.getMaximumPoolSize(), properties.getMaximumPoolSize())) {
executor.setMaximumPoolSize(properties.getMaximumPoolSize()); executor.setMaximumPoolSize(properties.getMaximumPoolSize());
} }
if (!Objects.equals(beforeProperties.getCorePoolSize(), properties.getCorePoolSize())) {
executor.setCorePoolSize(properties.getCorePoolSize());
}
if (!Objects.equals(beforeProperties.getAllowCoreThreadTimeOut(), properties.getAllowCoreThreadTimeOut())) { if (!Objects.equals(beforeProperties.getAllowCoreThreadTimeOut(), properties.getAllowCoreThreadTimeOut())) {
executor.allowCoreThreadTimeOut(properties.getAllowCoreThreadTimeOut()); executor.allowCoreThreadTimeOut(properties.getAllowCoreThreadTimeOut());
} }
if (!Objects.equals(beforeProperties.getExecuteTimeOut(), properties.getExecuteTimeOut())) { if (!Objects.equals(beforeProperties.getExecuteTimeOut(), properties.getExecuteTimeOut())) {
if (executor instanceof AbstractDynamicExecutorSupport) { if (executor instanceof AbstractDynamicExecutorSupport) {
((DynamicThreadPoolExecutor) executor).setExecuteTimeOut(properties.getExecuteTimeOut()); ((DynamicThreadPoolExecutor) executor).setExecuteTimeOut(properties.getExecuteTimeOut());
} }
} }
if (!Objects.equals(beforeProperties.getRejectedHandler(), properties.getRejectedHandler())) { if (!Objects.equals(beforeProperties.getRejectedHandler(), properties.getRejectedHandler())) {
RejectedExecutionHandler rejectedExecutionHandler = RejectedTypeEnum.createPolicy(properties.getRejectedHandler()); RejectedExecutionHandler rejectedExecutionHandler = RejectedTypeEnum.createPolicy(properties.getRejectedHandler());
if (executor instanceof AbstractDynamicExecutorSupport) { if (executor instanceof AbstractDynamicExecutorSupport) {
@ -272,14 +272,11 @@ public abstract class AbstractCoreThreadPoolDynamicRefresh implements ThreadPool
AtomicLong rejectCount = dynamicExecutor.getRejectCount(); AtomicLong rejectCount = dynamicExecutor.getRejectCount();
rejectedExecutionHandler = RejectedProxyUtil.createProxy(rejectedExecutionHandler, threadPoolId, rejectCount); rejectedExecutionHandler = RejectedProxyUtil.createProxy(rejectedExecutionHandler, threadPoolId, rejectCount);
} }
executor.setRejectedExecutionHandler(rejectedExecutionHandler); executor.setRejectedExecutionHandler(rejectedExecutionHandler);
} }
if (!Objects.equals(beforeProperties.getKeepAliveTime(), properties.getKeepAliveTime())) { if (!Objects.equals(beforeProperties.getKeepAliveTime(), properties.getKeepAliveTime())) {
executor.setKeepAliveTime(properties.getKeepAliveTime(), TimeUnit.SECONDS); executor.setKeepAliveTime(properties.getKeepAliveTime(), TimeUnit.SECONDS);
} }
if (!Objects.equals(beforeProperties.getQueueCapacity(), properties.getQueueCapacity()) if (!Objects.equals(beforeProperties.getQueueCapacity(), properties.getQueueCapacity())
&& Objects.equals(QueueTypeEnum.RESIZABLE_LINKED_BLOCKING_QUEUE.name, executor.getQueue().getClass().getSimpleName())) { && Objects.equals(QueueTypeEnum.RESIZABLE_LINKED_BLOCKING_QUEUE.name, executor.getQueue().getClass().getSimpleName())) {
if (executor.getQueue() instanceof ResizableCapacityLinkedBlockIngQueue) { if (executor.getQueue() instanceof ResizableCapacityLinkedBlockIngQueue) {
@ -307,15 +304,12 @@ public abstract class AbstractCoreThreadPoolDynamicRefresh implements ThreadPool
} else if (bindableCoreProperties.getJetty() != null) { } else if (bindableCoreProperties.getJetty() != null) {
poolProperties = bindableCoreProperties.getJetty(); poolProperties = bindableCoreProperties.getJetty();
} }
if (poolProperties != null) { if (poolProperties != null) {
parameterInfo = new PoolParameterInfo(); parameterInfo = new PoolParameterInfo();
parameterInfo.setCoreSize(poolProperties.getCorePoolSize()); parameterInfo.setCoreSize(poolProperties.getCorePoolSize());
parameterInfo.setMaxSize(poolProperties.getMaximumPoolSize()); parameterInfo.setMaxSize(poolProperties.getMaximumPoolSize());
parameterInfo.setKeepAliveTime(poolProperties.getKeepAliveTime()); parameterInfo.setKeepAliveTime(poolProperties.getKeepAliveTime());
} }
return parameterInfo; return parameterInfo;
} }
} }

@ -35,7 +35,7 @@ public class ApolloRefresherHandler extends AbstractCoreThreadPoolDynamicRefresh
ConfigChangeListener configChangeListener = configChangeEvent -> { ConfigChangeListener configChangeListener = configChangeEvent -> {
ConfigFile configFile = ConfigService.getConfigFile( ConfigFile configFile = ConfigService.getConfigFile(
namespace, this.namespace.replaceAll("." + bootstrapCoreProperties.getConfigFileType().getValue(), ""),
ConfigFileFormat.fromString(bootstrapCoreProperties.getConfigFileType().getValue()) ConfigFileFormat.fromString(bootstrapCoreProperties.getConfigFileType().getValue())
); );

@ -124,7 +124,7 @@ public final class DynamicThreadPoolPostProcessor implements BeanPostProcessor {
if (dynamicThreadPoolWrap.getExecutor() instanceof AbstractDynamicExecutorSupport) { if (dynamicThreadPoolWrap.getExecutor() instanceof AbstractDynamicExecutorSupport) {
// 设置动态线程池增强参数 // 设置动态线程池增强参数
ThreadPoolNotifyAlarm notify = executorProperties.getNotify(); ThreadPoolNotifyAlarm notify = Optional.ofNullable(executorProperties).map(ExecutorProperties::getNotify).orElse(null);
boolean isAlarm = Optional.ofNullable(notify) boolean isAlarm = Optional.ofNullable(notify)
.map(each -> each.getIsAlarm()) .map(each -> each.getIsAlarm())
.orElseGet(() -> bootstrapCoreProperties.getAlarm() != null ? bootstrapCoreProperties.getAlarm() : true); .orElseGet(() -> bootstrapCoreProperties.getAlarm() != null ? bootstrapCoreProperties.getAlarm() : true);
@ -194,5 +194,4 @@ public final class DynamicThreadPoolPostProcessor implements BeanPostProcessor {
return executorProperties; return executorProperties;
} }
} }

@ -51,7 +51,6 @@ public class DiscoveryConfiguration {
instanceInfo.setInstanceId(instanceId) instanceInfo.setInstanceId(instanceId)
.setIpApplicationName(getIpApplicationName(environment, hippo4JInetUtils)) .setIpApplicationName(getIpApplicationName(environment, hippo4JInetUtils))
.setHostName(InetAddress.getLocalHost().getHostAddress()) .setHostName(InetAddress.getLocalHost().getHostAddress())
.setGroupKey(itemId + GROUP_KEY_DELIMITER + namespace)
.setAppName(applicationName) .setAppName(applicationName)
.setPort(port) .setPort(port)
.setClientBasePath(contextPath) .setClientBasePath(contextPath)

@ -123,12 +123,21 @@ public class ServerThreadPoolDynamicRefresh implements ThreadPoolDynamicRefresh
* @param parameter * @param parameter
*/ */
public void changePoolInfo(ThreadPoolExecutor executor, PoolParameter parameter) { public void changePoolInfo(ThreadPoolExecutor executor, PoolParameter parameter) {
if (parameter.getCoreSize() != null) { if (parameter.getCoreSize() != null && parameter.getMaxSize() != null) {
executor.setCorePoolSize(parameter.getCoreSize()); if (parameter.getMaxSize() < executor.getMaximumPoolSize()) {
} executor.setCorePoolSize(parameter.getCoreSize());
executor.setMaximumPoolSize(parameter.getMaxSize());
if (parameter.getMaxSize() != null) { } else {
executor.setMaximumPoolSize(parameter.getMaxSize()); executor.setMaximumPoolSize(parameter.getMaxSize());
executor.setCorePoolSize(parameter.getCoreSize());
}
} else {
if (parameter.getMaxSize() != null) {
executor.setMaximumPoolSize(parameter.getMaxSize());
}
if (parameter.getCoreSize() != null) {
executor.setCorePoolSize(parameter.getCoreSize());
}
} }
if (parameter.getCapacity() != null if (parameter.getCapacity() != null

@ -9,7 +9,7 @@
<packaging>pom</packaging> <packaging>pom</packaging>
<name>${project.artifactId}</name> <name>${project.artifactId}</name>
<url>https://github.com/acmenlt/dynamic-threadpool</url> <url>https://github.com/longtai-cn/hippo4j</url>
<description>动态可观测线程池框架, 为业务系统提高线上运行保障能力.</description> <description>动态可观测线程池框架, 为业务系统提高线上运行保障能力.</description>
<modules> <modules>
@ -26,7 +26,7 @@
</modules> </modules>
<properties> <properties>
<revision>1.2.0</revision> <revision>1.2.0-RC4</revision>
<java.version>1.8</java.version> <java.version>1.8</java.version>
<dozer.version>6.5.0</dozer.version> <dozer.version>6.5.0</dozer.version>
@ -138,12 +138,6 @@
<version>${revision}</version> <version>${revision}</version>
</dependency> </dependency>
<dependency>
<groupId>cn.hippo4j</groupId>
<artifactId>open-change-tool</artifactId>
<version>${revision}</version>
</dependency>
<dependency> <dependency>
<groupId>com.baomidou</groupId> <groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId> <artifactId>mybatis-plus-boot-starter</artifactId>
@ -232,7 +226,7 @@
<issueManagement> <issueManagement>
<system>Github Issue</system> <system>Github Issue</system>
<url>https://github.com/acmenlt/dynamic-threadpool/issues</url> <url>https://github.com/longtai-cn/hippo4j/issues</url>
</issueManagement> </issueManagement>
<build> <build>
@ -351,9 +345,9 @@
</profiles> </profiles>
<scm> <scm>
<connection>scm:git@github.com:acmenlt/dynamic-threadpool</connection> <connection>scm:git@github.com:longtai-cn/hippo4j</connection>
<developerConnection>scm:git@github.com:acmenlt/dynamic-threadpool.git</developerConnection> <developerConnection>scm:git@github.com:longtai-cn/hippo4j.git</developerConnection>
<url>git@github.com:acmenlt/dynamic-threadpool.git</url> <url>git@github.com:longtai-cn/hippo4j.git</url>
</scm> </scm>
<distributionManagement> <distributionManagement>

Loading…
Cancel
Save