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

pull/872/head
weihu 3 years ago
commit 1bd874dad2

@ -52,6 +52,6 @@ cn.hippo4j.example.core.handler.ErrorLogRejectedExecutionHandler
2022-08-01 21:27:49.515 ERROR 48928 --- [ateHandler.test] r$CustomErrorLogRejectedExecutionHandler : 线程池抛出拒绝策略
```
:::tip
:::note
具体参考 `hippo4j-example/hippo4j-spring-boot-starter-example` 模块。
:::

@ -10,7 +10,7 @@ sidebar_position: 3
需要注意,项目 ID 需要与配置文件 `{application.name}` 保持一致。
:::tip
:::note
租户、项目、线程池 ID 如果由多个词组成,建议以 - 进行分割。比如message-center。
:::
@ -107,7 +107,7 @@ public class ThreadPoolConfig {
通过 ThreadPoolBuilder 构建动态线程池,只有 threadFactory、threadPoolId 为必填项,其它参数会从 hippo4j-server 服务拉取。
:::tip
:::note
创建线程池时建议填充实际的参数。如果在连接 Hippo4J Server 端失败时,会使用填充配置创建线程池。
:::

@ -1 +1,40 @@
--- sidebar_position: 3 --- # 快速开始 ## 服务启动 使用 Docker 运行服务端,默认使用内置 H2 数据库,数据持久化到 Docker 容器存储卷中。 ```shell docker run -d -p 6691:6691 --name hippo4j-server hippo4j/hippo4j-server ``` > 如果没有 Docker可以使用源码编译的方式启动 [Hippo4J-Server/Hippo4J-Bootstrap](https://github.com/longtai-cn/hippo4j/tree/develop/hippo4j-server/hippo4j-bootstrap) 模块下 ServerApplication 应用类。 启动示例项目,[hippo4j-spring-boot-starter-example](https://github.com/opengoofy/hippo4j/tree/develop/hippo4j-example/hippo4j-spring-boot-starter-example) 模块下 Hippo4JServerExampleApplication 应用类。 访问 Server 控制台,路径 `http://localhost:6691/index.html`默认用户名密码admin / 123456 ## 配置变更 访问控制台动态线程池菜单下线程池实例,修改动态线程池相关参数。 ![](https://images-machen.oss-cn-beijing.aliyuncs.com/image-20220813173811668.png) 观察 Hippo4j-Example 控制台日志输出,日志输出包括不限于此信息即为成功。 ```tex 2022-09-10 00:23:29.783 INFO 50322 --- [change.config_0] c.h.s.s.c.ServerThreadPoolDynamicRefresh : [message-consume] Dynamic thread pool change parameter. corePoolSize: 2 => 4 maximumPoolSize: 6 => 12 capacity: 1024 => 2048 keepAliveTime: 9999 => 9999 executeTimeOut: 800 => 3000 rejectedType: SyncPutQueuePolicy => RunsOldestTaskPolicy allowCoreThreadTimeOut: true => true ``` 另外,当 Client 集群部署时,可以修改某一个实例,或选择 `全部修改` 按钮,修改所有实例线程池信息。
---
sidebar_position: 3
---
# 快速开始
## 服务启动
使用 Docker 运行服务端,默认使用内置 H2 数据库,数据持久化到 Docker 容器存储卷中。
```shell
docker run -d -p 6691:6691 --name hippo4j-server hippo4j/hippo4j-server
```
> 如果没有 Docker可以使用源码编译的方式启动 [Hippo4J-Server/Hippo4J-Bootstrap](https://github.com/longtai-cn/hippo4j/tree/develop/hippo4j-server/hippo4j-bootstrap) 模块下 ServerApplication 应用类。
启动示例项目,[hippo4j-spring-boot-starter-example](https://github.com/opengoofy/hippo4j/tree/develop/hippo4j-example/hippo4j-spring-boot-starter-example) 模块下 Hippo4JServerExampleApplication 应用类。
访问 Server 控制台,路径 `http://localhost:6691/index.html`默认用户名密码admin / 123456
## 配置变更
访问控制台动态线程池菜单下线程池实例,修改动态线程池相关参数。
![](https://images-machen.oss-cn-beijing.aliyuncs.com/image-20220813173811668.png)
观察 Hippo4j-Example 控制台日志输出,日志输出包括不限于此信息即为成功。
```tex
2022-09-10 00:23:29.783 INFO 50322 --- [change.config_0] c.h.s.s.c.ServerThreadPoolDynamicRefresh : [message-consume] Dynamic thread pool change parameter.
corePoolSize: 2 => 4
maximumPoolSize: 6 => 12
capacity: 1024 => 2048
keepAliveTime: 9999 => 9999
executeTimeOut: 800 => 3000
rejectedType: SyncPutQueuePolicy => RunsOldestTaskPolicy
allowCoreThreadTimeOut: true => true
```
另外,当 Client 集群部署时,可以修改某一个实例,或选择 `全部修改` 按钮,修改所有实例线程池信息。

@ -14,8 +14,8 @@
"write-heading-ids": "docusaurus write-heading-ids"
},
"dependencies": {
"@docusaurus/core": "2.0.0-beta.21",
"@docusaurus/preset-classic": "2.0.0-beta.21",
"@docusaurus/core": "2.1.0",
"@docusaurus/preset-classic": "2.1.0",
"@mdx-js/react": "^1.6.22",
"clsx": "^1.1.1",
"prism-react-renderer": "^1.3.3",
@ -23,7 +23,7 @@
"react-dom": "^17.0.2"
},
"devDependencies": {
"@docusaurus/module-type-aliases": "2.0.0-beta.21"
"@docusaurus/module-type-aliases": "2.1.0"
},
"browserslist": {
"production": [

@ -19,13 +19,11 @@ package cn.hippo4j.adapter.web;
import cn.hippo4j.common.model.ThreadPoolRunStateInfo;
import cn.hippo4j.common.toolkit.ByteConvertUtil;
import cn.hippo4j.common.toolkit.MemoryUtil;
import cn.hippo4j.common.toolkit.StringUtil;
import cn.hippo4j.core.executor.state.AbstractThreadPoolRuntime;
import lombok.extern.slf4j.Slf4j;
import java.lang.management.ManagementFactory;
import java.lang.management.MemoryMXBean;
import java.lang.management.MemoryUsage;
/**
* Web thread pool run state handler.
*/
@ -34,16 +32,13 @@ public class WebThreadPoolRunStateHandler extends AbstractThreadPoolRuntime {
@Override
public ThreadPoolRunStateInfo supplement(ThreadPoolRunStateInfo poolRunStateInfo) {
MemoryMXBean memoryMXBean = ManagementFactory.getMemoryMXBean();
MemoryUsage heapMemoryUsage = memoryMXBean.getHeapMemoryUsage();
long used = heapMemoryUsage.getUsed();
long max = heapMemoryUsage.getMax();
String memoryProportion = new StringBuilder()
.append("已分配: ")
.append(ByteConvertUtil.getPrintSize(used))
.append(" / 最大可用: ")
.append(ByteConvertUtil.getPrintSize(max))
.toString();
long used = MemoryUtil.heapMemoryUsed();
long max = MemoryUtil.heapMemoryMax();
String memoryProportion = StringUtil.newBuilder(
"已分配: ",
ByteConvertUtil.getPrintSize(used),
" / 最大可用: ",
ByteConvertUtil.getPrintSize(max));
poolRunStateInfo.setCurrentLoad(poolRunStateInfo.getCurrentLoad() + "%");
poolRunStateInfo.setPeakLoad(poolRunStateInfo.getPeakLoad() + "%");
poolRunStateInfo.setMemoryProportion(memoryProportion);

@ -22,7 +22,8 @@ import cn.hippo4j.common.function.Matcher;
import java.lang.reflect.Array;
/**
* Array util.
* Array util.<br>
* Refer to cn.hutool.core.util.ArrayUtil:<br>
*/
public class ArrayUtil {

@ -22,7 +22,6 @@ import com.github.dozermapper.core.DozerBeanMapperBuilder;
import com.github.dozermapper.core.Mapper;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import org.springframework.beans.BeanUtils;
import java.beans.IntrospectionException;
import java.beans.PropertyDescriptor;
@ -30,7 +29,8 @@ import java.lang.reflect.Method;
import java.util.*;
/**
* Bean util.
* Bean util.<br>
* use com.github.dozermapper
*/
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class BeanUtil {
@ -73,6 +73,13 @@ public class BeanUtil {
.orElse(null);
}
/**
* map to bean
*
* @param map source data
* @param clazz type
* @param toCamelCase key convert
*/
public static <T> T mapToBean(Map<String, Object> map, Class<T> clazz, boolean toCamelCase) {
if (clazz == null) {
return null;

@ -21,7 +21,8 @@ import java.util.*;
import java.util.stream.Collectors;
/**
* Collection util.
* Collection util.<br>
* Refer to cn.hutool.core.collection.CollUtil:<br>
*/
public class CollectionUtil {

@ -46,14 +46,13 @@ public class ContentUtil {
}
public static String getGroupKey(ThreadPoolParameter parameter) {
StringBuilder stringBuilder = new StringBuilder();
String resultStr = stringBuilder.append(parameter.getTpId())
return StringUtil.createBuilder()
.append(parameter.getTpId())
.append(Constants.GROUP_KEY_DELIMITER)
.append(parameter.getItemId())
.append(Constants.GROUP_KEY_DELIMITER)
.append(parameter.getTenantId())
.toString();
return resultStr;
}
public static String getGroupKey(String... parameters) {

@ -23,9 +23,7 @@ import lombok.NoArgsConstructor;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZoneOffset;
import java.util.Date;
import java.util.SimpleTimeZone;
import java.util.TimeZone;
/**

@ -23,7 +23,6 @@ import org.springframework.core.io.ClassPathResource;
import java.io.*;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.List;
@ -52,36 +51,24 @@ public class FileUtil {
return resultReadStr;
}
/**
* According to the line read
*
* @param path the path
* @param charset the charset
*/
public static List<String> readLines(String path, Charset charset) {
List<String> strList = new ArrayList<>();
InputStreamReader inputStreamReader = null;
BufferedReader bufferedReader = null;
ClassPathResource classPathResource = new ClassPathResource(path);
try {
inputStreamReader = new InputStreamReader(classPathResource.getInputStream(), charset);
bufferedReader = new BufferedReader(inputStreamReader);
try (
InputStreamReader in = new InputStreamReader(classPathResource.getInputStream(), charset);
BufferedReader reader = new BufferedReader(in)) {
String line;
while ((line = bufferedReader.readLine()) != null) {
while ((line = reader.readLine()) != null) {
strList.add(line);
}
} catch (IOException e) {
e.printStackTrace();
throw new IllegalException("file read error");
} finally {
if (inputStreamReader != null) {
try {
inputStreamReader.close();
} catch (IOException e) {
throw new IllegalException("file read error");
}
}
if (bufferedReader != null) {
try {
bufferedReader.close();
} catch (IOException e) {
throw new IllegalException("file read error");
}
}
throw new IllegalException("file read error", e);
}
return strList;
}

@ -24,6 +24,7 @@ import static cn.hippo4j.common.constant.Constants.GROUP_KEY_DELIMITER;
/**
* Group key.
* Refer to com.alibaba.nacos.client.config.common.GroupKey:<br>
*/
public class GroupKey {

@ -47,10 +47,28 @@ public class IdUtil {
}
/**
* toString
* Returns a {@code String} object representing this {@code UUID}.
*
* @param uuid UUID
* @return UUID String
* <p> The UUID string representation is as described by this BNF:
* <blockquote><pre>
* {@code
* UUID = <time_low> "-" <time_mid> "-"
* <time_high_and_version> "-"
* <variant_and_sequence> "-"
* <node>
* time_low = 4*<hexOctet>
* time_mid = 2*<hexOctet>
* time_high_and_version = 2*<hexOctet>
* variant_and_sequence = 2*<hexOctet>
* node = 6*<hexOctet>
* hexOctet = <hexDigit><hexDigit>
* hexDigit =
* "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9"
* | "a" | "b" | "c" | "d" | "e" | "f"
* | "A" | "B" | "C" | "D" | "E" | "F"
* }</pre></blockquote>
*
* @return A string representation of this {@code UUID}
*/
public static String toString(UUID uuid, boolean isSimple) {
long mostSigBits = uuid.getMostSignificantBits();

@ -23,7 +23,8 @@ import java.util.Iterator;
import java.util.Objects;
/**
* reference google guava
* reference google guava<br>
* com.google.common.base.Joiner
*/
public class Joiner {

@ -17,10 +17,7 @@
package cn.hippo4j.common.toolkit;
import java.util.Collection;
import java.util.Dictionary;
import java.util.Map;
import java.util.Objects;
import java.util.*;
import java.util.function.BiFunction;
import java.util.function.Predicate;
@ -151,6 +148,41 @@ public class MapUtil {
return val;
}
/**
* Fuzzy matching based on Key.
*
* @param sourceMap
* @param filters
* @return
*/
public static List<String> parseMapForFilter(Map<String, ?> sourceMap, String filters) {
List<String> resultList = new ArrayList<>();
if (CollectionUtil.isEmpty(sourceMap)) {
return resultList;
}
sourceMap.forEach((key, val) -> {
if (checkKey(key, filters)) {
resultList.add(key);
}
});
return resultList;
}
/**
* Match the characters you want to query.
*
* @param key
* @param filters
* @return
*/
private static boolean checkKey(String key, String filters) {
if (key.indexOf(filters) > -1) {
return true;
} else {
return false;
}
}
/**
* remove value, Thread safety depends on whether the Map is a thread-safe Map.
*

@ -28,6 +28,7 @@ import java.util.List;
/**
* MD5 util.
* Refer to com.alibaba.nacos.common.util.Md5Utils:<br>
*/
public class Md5Util {
@ -96,16 +97,12 @@ public class Md5Util {
sb.append(Constants.WORD_SEPARATOR);
sb.append(dataIdGroupId[1]);
// if have tenant, then set it
if (dataIdGroupId.length == DATA_ID_GROUP_ID_THREE_LEN) {
if (StringUtil.isNotBlank(dataIdGroupId[2])) {
sb.append(Constants.WORD_SEPARATOR);
sb.append(dataIdGroupId[2]);
}
} else if (dataIdGroupId.length == DATA_ID_GROUP_ID_FOUR_LEN) {
if (StringUtil.isNotBlank(dataIdGroupId[2])) {
sb.append(Constants.WORD_SEPARATOR);
sb.append(dataIdGroupId[2]);
}
boolean b = (dataIdGroupId.length == DATA_ID_GROUP_ID_THREE_LEN
|| dataIdGroupId.length == DATA_ID_GROUP_ID_FOUR_LEN)
&& StringUtil.isNotBlank(dataIdGroupId[2]);
if (b) {
sb.append(Constants.WORD_SEPARATOR);
sb.append(dataIdGroupId[2]);
}
sb.append(Constants.LINE_SEPARATOR);
}

@ -0,0 +1,94 @@
/*
* 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 lombok.AccessLevel;
import lombok.NoArgsConstructor;
import java.lang.management.ManagementFactory;
import java.lang.management.MemoryMXBean;
import java.lang.management.MemoryUsage;
/**
* memory util<br>
* the obtained information is not invalid, after a long wait, obtain it again
*
* @author liuwenhao
*/
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class MemoryUtil {
static MemoryMXBean memoryMXBean = ManagementFactory.getMemoryMXBean();
static MemoryUsage heapMemoryUsage = memoryMXBean.getHeapMemoryUsage();
static MemoryUsage noHeapMemoryUsage = memoryMXBean.getNonHeapMemoryUsage();
/**
* get used memory in heap
*
* @return long bytes
*/
public static long heapMemoryUsed() {
return heapMemoryUsage.getUsed();
}
/**
* get max memory in heap
*
* @return long bytes
*/
public static long heapMemoryMax() {
return heapMemoryUsage.getMax();
}
/**
* get free memory in heap
*
* @return long bytes
*/
public static long heapMemoryFree() {
return Math.subtractExact(heapMemoryMax(), heapMemoryUsed());
}
/**
* get used memory in no-heap
*
* @return long bytes
*/
public static long noHeapMemoryUsed() {
return noHeapMemoryUsage.getUsed();
}
/**
* get max memory in no-heap
*
* @return long bytes
*/
public static long noHeapMemoryMax() {
return noHeapMemoryUsage.getMax();
}
/**
* get free memory in no-heap
*
* @return long bytes
*/
public static long noHeapMemoryFree() {
return Math.subtractExact(noHeapMemoryMax(), noHeapMemoryUsed());
}
}

@ -29,10 +29,13 @@ import java.util.Arrays;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ThreadPoolExecutor;
/**
* Reflect util.
* Reflect util.<br>
* Refer to cn.hutool.core.util.ReflectUtil:<br>
* {@link this#getFieldsDirectly(Class, boolean)} <br>
* {@link this#setFieldValue(Object, Field, Object)} <br>
* {@link this#getDefaultValue(Class)} <br>
*/
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class ReflectUtil {

@ -21,7 +21,11 @@ import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* String util.
* String util.<br>
* Refer to cn.hutool.core.util.StrUtil:<br>
* {@link this#toSymbolCase(CharSequence, char)}<br>
* {@link this#toCamelCase(CharSequence, char)}<br>
* {@link this#subBefore(String, String)}<br>
*/
public class StringUtil {
@ -53,8 +57,9 @@ public class StringUtil {
/**
* Returns {@code true} if the given string is null or is the empty string.
*
* <p>
* this method has been deprecated, use isEmpty() instead.
*
* @param str
* @return
*/
@ -302,7 +307,8 @@ public class StringUtil {
* StringUtils.split("abc def", " ") = ["abc", "def"]
* StringUtils.split("ab:cd:ef", ":") = ["ab", "cd", "ef"]
* </pre>
* @param str the String to parse, may be null
*
* @param str the String to parse, may be null
* @param separatorChars the characters used as the delimiters,
* @return an array of parsed Strings
*/

@ -15,10 +15,8 @@
* limitations under the License.
*/
package cn.hippo4j.config.toolkit;
package cn.hippo4j.common.toolkit;
import cn.hippo4j.common.toolkit.Assert;
import cn.hippo4j.common.toolkit.CollectionUtil;
import org.junit.Test;
import java.util.HashMap;
@ -66,9 +64,9 @@ public class MapUtilTest {
@Test
public void computeIfAbsentNotExistKeyTest() {
Map<Object, Object> map = new HashMap<>();
Map<String, Object> map = new HashMap<>();
map.put("abc", "123");
BiFunction<String, String, String> mappingFunction = (a, b) -> a + b;
BiFunction<String, String, Object> mappingFunction = (a, b) -> a + b;
try {
MapUtil.computeIfAbsent(map, null, mappingFunction, "param1", "param2");
} catch (Exception e) {
@ -93,9 +91,9 @@ public class MapUtilTest {
@Test
public void computeIfAbsentNotExistParam1Test() {
Map<Object, Object> map = new HashMap<>();
Map<String, Object> map = new HashMap<>();
map.put("abc", "123");
BiFunction<String, String, String> mappingFunction = (a, b) -> a + b;
BiFunction<String, String, Object> mappingFunction = (a, b) -> a + b;
try {
MapUtil.computeIfAbsent(map, "abc", mappingFunction, null, "param2");
} catch (Exception e) {
@ -107,9 +105,9 @@ public class MapUtilTest {
@Test
public void computeIfAbsentNotExistParam2Test() {
Map<Object, Object> map = new HashMap<>();
Map<String, Object> map = new HashMap<>();
map.put("abc", "123");
BiFunction<String, String, String> mappingFunction = (a, b) -> a + b;
BiFunction<String, String, Object> mappingFunction = (a, b) -> a + b;
try {
MapUtil.computeIfAbsent(map, "abc", mappingFunction, "param1", null);
} catch (Exception e) {
@ -121,18 +119,18 @@ public class MapUtilTest {
@Test
public void computeIfAbsentValNotNullTest() {
Map<Object, Object> map = new HashMap<>();
Map<String, Object> map = new HashMap<>();
map.put("abc", "123");
BiFunction<String, String, String> mappingFunction = (a, b) -> a + b;
BiFunction<String, String, Object> mappingFunction = (a, b) -> a + b;
Object ret = MapUtil.computeIfAbsent(map, "abc", mappingFunction, "param1", "param2");
Assert.isTrue(Objects.equals("123", String.valueOf(ret)));
}
@Test
public void computeIfAbsentValIsNullTest() {
Map<Object, Object> map = new HashMap<>();
Map<String, Object> map = new HashMap<>();
map.put("abc", "123");
BiFunction<String, String, String> mappingFunction = (a, b) -> a + b;
BiFunction<String, String, Object> mappingFunction = (a, b) -> a + b;
Object ret = MapUtil.computeIfAbsent(map, "xyz", mappingFunction, "param1", "param2");
Assert.isTrue(Objects.equals("param1param2", String.valueOf(ret)));
}

@ -0,0 +1,60 @@
/*
* 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 org.junit.Assert;
import org.junit.Test;
public class MemoryUtilTest {
@Test
public void heapMemoryUsed() {
long memoryUsed = MemoryUtil.heapMemoryUsed();
Assert.assertNotEquals(0, memoryUsed);
}
@Test
public void heapMemoryMax() {
long memoryUsed = MemoryUtil.heapMemoryMax();
Assert.assertNotEquals(0, memoryUsed);
}
@Test
public void heapMemoryFree() {
long memoryUsed = MemoryUtil.heapMemoryFree();
Assert.assertNotEquals(0, memoryUsed);
}
@Test
public void noHeapMemoryUsed() {
long memoryUsed = MemoryUtil.noHeapMemoryUsed();
Assert.assertNotEquals(0, memoryUsed);
}
@Test
public void noHeapMemoryMax() {
long memoryUsed = MemoryUtil.noHeapMemoryMax();
Assert.assertNotEquals(0, memoryUsed);
}
@Test
public void noHeapMemoryFree() {
long memoryUsed = MemoryUtil.noHeapMemoryFree();
Assert.assertNotEquals(0, memoryUsed);
}
}

@ -72,14 +72,14 @@ public class HttpUtilsTest {
Assert.assertNotNull(data);
}
@Test
@Test(expected = SocketTimeoutException.class)
public void testRestApiPostTimeout() {
String loginUrl = postUrl + "auth/login";
LoginInfo loginInfo = new LoginInfo();
loginInfo.setPassword("hippo4j");
loginInfo.setUsername("hippo4j");
loginInfo.setRememberMe(1);
Assert.assertThrows(SocketTimeoutException.class, () -> HttpUtil.post(loginUrl, loginInfo, 1, Result.class));
HttpUtil.post(loginUrl, loginInfo, 1, Result.class);
}
@Test

@ -21,6 +21,8 @@ import cn.hippo4j.common.model.ManyThreadPoolRunStateInfo;
import cn.hippo4j.common.model.ThreadPoolRunStateInfo;
import cn.hippo4j.common.toolkit.BeanUtil;
import cn.hippo4j.common.toolkit.ByteConvertUtil;
import cn.hippo4j.common.toolkit.MemoryUtil;
import cn.hippo4j.common.toolkit.StringUtil;
import cn.hippo4j.core.executor.DynamicThreadPoolExecutor;
import cn.hippo4j.core.executor.DynamicThreadPoolWrapper;
import cn.hippo4j.core.executor.manage.GlobalThreadPoolManage;
@ -30,9 +32,6 @@ import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.env.ConfigurableEnvironment;
import java.lang.management.ManagementFactory;
import java.lang.management.MemoryMXBean;
import java.lang.management.MemoryUsage;
import java.util.concurrent.ThreadPoolExecutor;
import static cn.hippo4j.core.toolkit.IdentifyUtil.CLIENT_IDENTIFICATION_VALUE;
@ -50,16 +49,13 @@ public class ThreadPoolRunStateHandler extends AbstractThreadPoolRuntime {
@Override
public ThreadPoolRunStateInfo supplement(ThreadPoolRunStateInfo poolRunStateInfo) {
MemoryMXBean memoryMXBean = ManagementFactory.getMemoryMXBean();
MemoryUsage heapMemoryUsage = memoryMXBean.getHeapMemoryUsage();
long used = heapMemoryUsage.getUsed();
long max = heapMemoryUsage.getMax();
String memoryProportion = new StringBuilder()
.append("已分配: ")
.append(ByteConvertUtil.getPrintSize(used))
.append(" / 最大可用: ")
.append(ByteConvertUtil.getPrintSize(max))
.toString();
long used = MemoryUtil.heapMemoryUsed();
long max = MemoryUtil.heapMemoryMax();
String memoryProportion = StringUtil.newBuilder(
"已分配: ",
ByteConvertUtil.getPrintSize(used),
" / 最大可用: ",
ByteConvertUtil.getPrintSize(max));
poolRunStateInfo.setCurrentLoad(poolRunStateInfo.getCurrentLoad() + "%");
poolRunStateInfo.setPeakLoad(poolRunStateInfo.getPeakLoad() + "%");
String ipAddress = hippo4JInetUtils.findFirstNonLoopBackHostInfo().getIpAddress();

@ -112,6 +112,9 @@ public class ThreadPoolBuilder implements Builder<ThreadPoolExecutor> {
public ThreadPoolBuilder maxPoolNum(int maxPoolSize) {
this.maxPoolSize = maxPoolSize;
if (maxPoolSize < this.corePoolSize) {
this.corePoolSize = maxPoolSize;
}
return this;
}
@ -228,6 +231,7 @@ public class ThreadPoolBuilder implements Builder<ThreadPoolExecutor> {
/**
* Create dynamic thread pool by thread pool id
*
* @param threadPoolId threadPoolId
* @return ThreadPoolExecutor
*/

@ -17,6 +17,9 @@
package cn.hippo4j.core.proxy;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import java.lang.reflect.Proxy;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.atomic.AtomicLong;
@ -24,6 +27,7 @@ import java.util.concurrent.atomic.AtomicLong;
/**
* Rejected proxy util.
*/
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class RejectedProxyUtil {
/**
@ -35,11 +39,10 @@ public class RejectedProxyUtil {
* @return
*/
public static RejectedExecutionHandler createProxy(RejectedExecutionHandler rejectedExecutionHandler, String threadPoolId, AtomicLong rejectedNum) {
RejectedExecutionHandler rejectedProxy = (RejectedExecutionHandler) Proxy
return (RejectedExecutionHandler) Proxy
.newProxyInstance(
rejectedExecutionHandler.getClass().getClassLoader(),
new Class[]{RejectedExecutionHandler.class},
new RejectedProxyInvocationHandler(rejectedExecutionHandler, threadPoolId, rejectedNum));
return rejectedProxy;
}
}

@ -15,10 +15,11 @@
* limitations under the License.
*/
package cn.hippo4j.core.toolkit.inet;
package cn.hippo4j.core.toolkit;
import cn.hippo4j.common.config.ApplicationContextHolder;
import org.springframework.beans.factory.ListableBeanFactory;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.context.support.AbstractApplicationContext;
@ -28,35 +29,25 @@ import java.lang.annotation.Annotation;
import java.util.Optional;
/**
* {@link DynamicThreadPoolAnnotationUtil} SpringBoot.
*
* <p>Spring version >= 5.2.0 , SpringBoot version 2.2.0.RELEASE
* {@link ListableBeanFactory#findAnnotationOnBean(java.lang.String, java.lang.Class)}
*
* <p>, , Spring .
* , Spring version < 5.3.14 , SpringBoot version < 2.6.2
*
* @author chen.ma
* @date 2022/1/5 21:15
* Adapted to an earlier version of SpringBoot.
*/
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class DynamicThreadPoolAnnotationUtil {
/**
* {@param beanName} {@param annotationType} .
* Check for the existence of {@param annotationType} based on {@param beanName}.
*
* @param beanName
* @param annotationType
* @param <A>
* @return
* @param beanName bean name
* @param annotationType annotation class
* @param <A> the Annotation type
*/
public static <A extends Annotation> A findAnnotationOnBean(String beanName, Class<A> annotationType) {
AbstractApplicationContext context = (AbstractApplicationContext) ApplicationContextHolder.getInstance();
ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();
A annotation = Optional.ofNullable(beanFactory)
return Optional.of(beanFactory)
.map(each -> (RootBeanDefinition) beanFactory.getMergedBeanDefinition(beanName))
.map(definition -> definition.getResolvedFactoryMethod())
.map(RootBeanDefinition::getResolvedFactoryMethod)
.map(factoryMethod -> AnnotationUtils.getAnnotation(factoryMethod, annotationType))
.orElse(null);
return annotation;
}
}

@ -22,7 +22,8 @@ import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong;
/**
* System clock.
* System clock.<br>
* Refer to cn.hutool.core.date.SystemClock<br>
*/
public class SystemClock {

@ -35,7 +35,8 @@ import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
/**
* Inet utils.
* Inet utils.<br>
* Refer to org.springframework.cloud.commons.util.InetUtils<br>
*/
public class InetUtils implements Closeable {
@ -80,7 +81,7 @@ public class InetUtils implements Closeable {
this.log.trace("Testing interface: " + ifc.getDisplayName());
if (ifc.getIndex() < lowest || result == null) {
lowest = ifc.getIndex();
} else if (result != null) {
} else {
continue;
}
// @formatter:off

@ -0,0 +1,52 @@
# \u4EE5\u4E0B\u5185\u5BB9\u590D\u5236\u5230 apollo \u914D\u7F6E\u6587\u4EF6\u4E2D
# Copy the following to the apollo configuration file
spring.dynamic.thread-pool.tomcat.core-pool-size=64
spring.dynamic.thread-pool.tomcat.maximum-pool-size=128
spring.dynamic.thread-pool.tomcat.keep-alive-time=1000
spring.dynamic.thread-pool.tomcat.enable=true
spring.dynamic.thread-pool.default-executor.core-pool-size=1
spring.dynamic.thread-pool.default-executor.maximum-pool-size=2
spring.dynamic.thread-pool.default-executor.blocking-queue=ResizableCapacityLinkedBlockingQueue
spring.dynamic.thread-pool.default-executor.execute-time-out=100
spring.dynamic.thread-pool.default-executor.keep-alive-time=6691
spring.dynamic.thread-pool.default-executor.queue-capacity=1
spring.dynamic.thread-pool.default-executor.rejected-handler=AbortPolicy
spring.dynamic.thread-pool.default-executor.active-alarm=90
spring.dynamic.thread-pool.default-executor.capacity-alarm=85
spring.dynamic.thread-pool.default-executor.alarm=true
spring.dynamic.thread-pool.default-executor.allow-core-thread-time-out=true
spring.dynamic.thread-pool.default-executor.notify.interval=5
spring.dynamic.thread-pool.default-executor.notify.receives=chen.ma
spring.dynamic.thread-pool.notify-platforms[0].platform=WECHAT
spring.dynamic.thread-pool.notify-platforms[0].secret-key=ec3be378-6c99-45d2-a147-b400c7e94a08
spring.dynamic.thread-pool.executors[0].thread-pool-id=message-consume
spring.dynamic.thread-pool.executors[0].thread-name-prefix=message-consume
spring.dynamic.thread-pool.executors[0].core-pool-size=2
spring.dynamic.thread-pool.executors[0].maximum-pool-size=4
spring.dynamic.thread-pool.executors[0].queue-capacity=1024
spring.dynamic.thread-pool.executors[0].blocking-queue=ResizableCapacityLinkedBlockingQueue
spring.dynamic.thread-pool.executors[0].execute-time-out=800
spring.dynamic.thread-pool.executors[0].rejected-handler=AbortPolicy
spring.dynamic.thread-pool.executors[0].keep-alive-time=6691
spring.dynamic.thread-pool.executors[0].allow-core-thread-time-out=true
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=chen.ma
spring.dynamic.thread-pool.executors[1].thread-pool-id=message-produce
spring.dynamic.thread-pool.executors[1].thread-name-prefix=message-produce
spring.dynamic.thread-pool.executors[1].core-pool-size=2
spring.dynamic.thread-pool.executors[1].maximum-pool-size=4
spring.dynamic.thread-pool.executors[1].queue-capacity=1024
spring.dynamic.thread-pool.executors[1].blocking-queue=ResizableCapacityLinkedBlockingQueue
spring.dynamic.thread-pool.executors[1].execute-time-out=800
spring.dynamic.thread-pool.executors[1].rejected-handler=AbortPolicy
spring.dynamic.thread-pool.executors[1].keep-alive-time=6691
spring.dynamic.thread-pool.executors[1].allow-core-thread-time-out=true
spring.dynamic.thread-pool.executors[1].alarm=true
spring.dynamic.thread-pool.executors[1].active-alarm=80
spring.dynamic.thread-pool.executors[1].capacity-alarm=80
spring.dynamic.thread-pool.executors[1].notify.interval=8
spring.dynamic.thread-pool.executors[1].notify.receives=chen.ma

@ -9,7 +9,7 @@ apollo.bootstrap.namespaces=application
apollo.bootstrap.eagerLoad.enabled=true
spring.profiles.active=dev
spring.application.name=dynamic-threadpool-example
spring.application.name=hippo4j-config-apollo-spring-boot-1x-starter-example
management.security.enabled=false
management.context-path=/actuator
@ -17,7 +17,11 @@ management.context-path=/actuator
spring.dynamic.thread-pool.enable=true
spring.dynamic.thread-pool.banner=true
spring.dynamic.thread-pool.check-state-interval=5
spring.dynamic.thread-pool.collect-type=micrometer
spring.dynamic.thread-pool.monitor.enable=true
spring.dynamic.thread-pool.monitor.collect-types=micrometer
spring.dynamic.thread-pool.monitor.thread-pool-types=dynamic,web
spring.dynamic.thread-pool.monitor.initial-delay=10000
spring.dynamic.thread-pool.monitor.collect-interval=5000
spring.dynamic.thread-pool.notify-platforms[0].platform=WECHAT
spring.dynamic.thread-pool.notify-platforms[0].token=ac0426a5-c712-474c-9bff-72b8b8f5caff
@ -25,33 +29,33 @@ spring.dynamic.thread-pool.notify-platforms[0].token=ac0426a5-c712-474c-9bff-72b
spring.dynamic.thread-pool.apollo.namespace=application
spring.dynamic.thread-pool.config-file-type=properties
spring.dynamic.thread-pool.executors[0].active-alarm = 80
spring.dynamic.thread-pool.executors[0].alarm = true
spring.dynamic.thread-pool.executors[0].allow-core-thread-time-out = true
spring.dynamic.thread-pool.executors[0].blocking-queue = LinkedBlockingQueue
spring.dynamic.thread-pool.executors[0].capacity-alarm = 80
spring.dynamic.thread-pool.executors[0].core-pool-size = 1
spring.dynamic.thread-pool.executors[0].execute-time-out = 1000
spring.dynamic.thread-pool.executors[0].keep-alive-time = 6691
spring.dynamic.thread-pool.executors[0].maximum-pool-size = 1
spring.dynamic.thread-pool.executors[0].notify.interval = 8
spring.dynamic.thread-pool.executors[0].notify.receives = chen.ma
spring.dynamic.thread-pool.executors[0].queue-capacity = 1
spring.dynamic.thread-pool.executors[0].rejected-handler = AbortPolicy
spring.dynamic.thread-pool.executors[0].thread-name-prefix = message-consume
spring.dynamic.thread-pool.executors[0].thread-pool-id = message-consume
spring.dynamic.thread-pool.executors[1].active-alarm = 80
spring.dynamic.thread-pool.executors[1].alarm = true
spring.dynamic.thread-pool.executors[1].allow-core-thread-time-out = true
spring.dynamic.thread-pool.executors[1].blocking-queue = LinkedBlockingQueue
spring.dynamic.thread-pool.executors[1].capacity-alarm = 80
spring.dynamic.thread-pool.executors[1].core-pool-size = 1
spring.dynamic.thread-pool.executors[1].execute-time-out = 1000
spring.dynamic.thread-pool.executors[1].keep-alive-time = 6691
spring.dynamic.thread-pool.executors[1].maximum-pool-size = 1
spring.dynamic.thread-pool.executors[1].notify.interval = 8
spring.dynamic.thread-pool.executors[1].notify.receives = chen.ma
spring.dynamic.thread-pool.executors[1].queue-capacity = 1
spring.dynamic.thread-pool.executors[1].rejected-handler = AbortPolicy
spring.dynamic.thread-pool.executors[1].thread-name-prefix = message-produce
spring.dynamic.thread-pool.executors[1].thread-pool-id = message-produce
spring.dynamic.thread-pool.executors[0].thread-pool-id=message-consume
spring.dynamic.thread-pool.executors[0].thread-name-prefix=message-consume
spring.dynamic.thread-pool.executors[0].core-pool-size=2
spring.dynamic.thread-pool.executors[0].maximum-pool-size=4
spring.dynamic.thread-pool.executors[0].queue-capacity=1024
spring.dynamic.thread-pool.executors[0].blocking-queue=ResizableCapacityLinkedBlockingQueue
spring.dynamic.thread-pool.executors[0].execute-time-out=800
spring.dynamic.thread-pool.executors[0].rejected-handler=AbortPolicy
spring.dynamic.thread-pool.executors[0].keep-alive-time=6691
spring.dynamic.thread-pool.executors[0].allow-core-thread-time-out=true
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=chen.ma
spring.dynamic.thread-pool.executors[1].thread-pool-id=message-produce
spring.dynamic.thread-pool.executors[1].thread-name-prefix=message-produce
spring.dynamic.thread-pool.executors[1].core-pool-size=2
spring.dynamic.thread-pool.executors[1].maximum-pool-size=4
spring.dynamic.thread-pool.executors[1].queue-capacity=1024
spring.dynamic.thread-pool.executors[1].blocking-queue=ResizableCapacityLinkedBlockingQueue
spring.dynamic.thread-pool.executors[1].execute-time-out=800
spring.dynamic.thread-pool.executors[1].rejected-handler=AbortPolicy
spring.dynamic.thread-pool.executors[1].keep-alive-time=6691
spring.dynamic.thread-pool.executors[1].allow-core-thread-time-out=true
spring.dynamic.thread-pool.executors[1].alarm=true
spring.dynamic.thread-pool.executors[1].active-alarm=80
spring.dynamic.thread-pool.executors[1].capacity-alarm=80
spring.dynamic.thread-pool.executors[1].notify.interval=8
spring.dynamic.thread-pool.executors[1].notify.receives=chen.ma

@ -0,0 +1,52 @@
# \u4EE5\u4E0B\u5185\u5BB9\u590D\u5236\u5230 apollo \u914D\u7F6E\u6587\u4EF6\u4E2D
# Copy the following to the apollo configuration file
spring.dynamic.thread-pool.tomcat.core-pool-size=64
spring.dynamic.thread-pool.tomcat.maximum-pool-size=128
spring.dynamic.thread-pool.tomcat.keep-alive-time=1000
spring.dynamic.thread-pool.tomcat.enable=true
spring.dynamic.thread-pool.default-executor.core-pool-size=1
spring.dynamic.thread-pool.default-executor.maximum-pool-size=2
spring.dynamic.thread-pool.default-executor.blocking-queue=ResizableCapacityLinkedBlockingQueue
spring.dynamic.thread-pool.default-executor.execute-time-out=100
spring.dynamic.thread-pool.default-executor.keep-alive-time=6691
spring.dynamic.thread-pool.default-executor.queue-capacity=1
spring.dynamic.thread-pool.default-executor.rejected-handler=AbortPolicy
spring.dynamic.thread-pool.default-executor.active-alarm=90
spring.dynamic.thread-pool.default-executor.capacity-alarm=85
spring.dynamic.thread-pool.default-executor.alarm=true
spring.dynamic.thread-pool.default-executor.allow-core-thread-time-out=true
spring.dynamic.thread-pool.default-executor.notify.interval=5
spring.dynamic.thread-pool.default-executor.notify.receives=chen.ma
spring.dynamic.thread-pool.notify-platforms[0].platform=WECHAT
spring.dynamic.thread-pool.notify-platforms[0].secret-key=ec3be378-6c99-45d2-a147-b400c7e94a08
spring.dynamic.thread-pool.executors[0].thread-pool-id=message-consume
spring.dynamic.thread-pool.executors[0].thread-name-prefix=message-consume
spring.dynamic.thread-pool.executors[0].core-pool-size=2
spring.dynamic.thread-pool.executors[0].maximum-pool-size=4
spring.dynamic.thread-pool.executors[0].queue-capacity=1024
spring.dynamic.thread-pool.executors[0].blocking-queue=ResizableCapacityLinkedBlockingQueue
spring.dynamic.thread-pool.executors[0].execute-time-out=800
spring.dynamic.thread-pool.executors[0].rejected-handler=AbortPolicy
spring.dynamic.thread-pool.executors[0].keep-alive-time=6691
spring.dynamic.thread-pool.executors[0].allow-core-thread-time-out=true
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=chen.ma
spring.dynamic.thread-pool.executors[1].thread-pool-id=message-produce
spring.dynamic.thread-pool.executors[1].thread-name-prefix=message-produce
spring.dynamic.thread-pool.executors[1].core-pool-size=2
spring.dynamic.thread-pool.executors[1].maximum-pool-size=4
spring.dynamic.thread-pool.executors[1].queue-capacity=1024
spring.dynamic.thread-pool.executors[1].blocking-queue=ResizableCapacityLinkedBlockingQueue
spring.dynamic.thread-pool.executors[1].execute-time-out=800
spring.dynamic.thread-pool.executors[1].rejected-handler=AbortPolicy
spring.dynamic.thread-pool.executors[1].keep-alive-time=6691
spring.dynamic.thread-pool.executors[1].allow-core-thread-time-out=true
spring.dynamic.thread-pool.executors[1].alarm=true
spring.dynamic.thread-pool.executors[1].active-alarm=80
spring.dynamic.thread-pool.executors[1].capacity-alarm=80
spring.dynamic.thread-pool.executors[1].notify.interval=8
spring.dynamic.thread-pool.executors[1].notify.receives=chen.ma

@ -1,4 +1,3 @@
# Configuration reference: https://hippo4j.cn/pages/2f674h
server.port=8091
server.servlet.context-path=/example
@ -10,7 +9,7 @@ apollo.bootstrap.namespaces=application
apollo.bootstrap.eagerLoad.enabled=true
spring.profiles.active=dev
spring.application.name=dynamic-threadpool-example
spring.application.name=hippo4j-config-apollo-spring-boot-starter-example
management.metrics.export.prometheus.enabled=true
management.server.port=29998
@ -19,29 +18,49 @@ management.endpoints.web.exposure.include=*
spring.dynamic.thread-pool.enable=true
spring.dynamic.thread-pool.banner=true
spring.dynamic.thread-pool.check-state-interval=3
spring.dynamic.thread-pool.monitor.enable=true
spring.dynamic.thread-pool.monitor.collect-types=micrometer
spring.dynamic.thread-pool.monitor.thread-pool-types=dynamic,web
spring.dynamic.thread-pool.monitor.initial-delay=10000
spring.dynamic.thread-pool.monitor.collect-interval=5000
spring.dynamic.thread-pool.notify-platforms[0].platform=WECHAT
spring.dynamic.thread-pool.notify-platforms[0].secret-key=ac0426a5-c712-474c-9bff-72b8b8f5caff
spring.dynamic.thread-pool.notify-platforms[0].token=ac0426a5-c712-474c-9bff-72b8b8f5caff
spring.dynamic.thread-pool.notify-platforms[1].platform=DING
spring.dynamic.thread-pool.notify-platforms[1].secret-key=56417ebba6a27ca352f0de77a2ae9da66d01f39610b5ee8a6033c60ef9071c55
spring.dynamic.thread-pool.notify-platforms[1].token=56417ebba6a27ca352f0de77a2ae9da66d01f39610b5ee8a6033c60ef9071c55
spring.dynamic.thread-pool.notify-platforms[2].platform=LARK
spring.dynamic.thread-pool.notify-platforms[2].secret-key=2cbf2808-3839-4c26-a04d-fd201dd51f9e
spring.dynamic.thread-pool.notify-platforms[2].token=2cbf2808-3839-4c26-a04d-fd201dd51f9e
spring.dynamic.thread-pool.apollo.namespace=application
spring.dynamic.thread-pool.config-file-type=properties
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].thread-name-prefix=message-consume
spring.dynamic.thread-pool.executors[0].core-pool-size=2
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].queue-capacity=1024
spring.dynamic.thread-pool.executors[0].blocking-queue=ResizableCapacityLinkedBlockingQueue
spring.dynamic.thread-pool.executors[0].execute-time-out=800
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].keep-alive-time=6691
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=chen.ma
spring.dynamic.thread-pool.executors[1].thread-pool-id=message-produce
spring.dynamic.thread-pool.executors[1].thread-name-prefix=message-produce
spring.dynamic.thread-pool.executors[1].core-pool-size=2
spring.dynamic.thread-pool.executors[1].maximum-pool-size=4
spring.dynamic.thread-pool.executors[1].queue-capacity=1024
spring.dynamic.thread-pool.executors[1].blocking-queue=ResizableCapacityLinkedBlockingQueue
spring.dynamic.thread-pool.executors[1].execute-time-out=800
spring.dynamic.thread-pool.executors[1].rejected-handler=AbortPolicy
spring.dynamic.thread-pool.executors[1].keep-alive-time=6691
spring.dynamic.thread-pool.executors[1].allow-core-thread-time-out=true
spring.dynamic.thread-pool.executors[1].alarm=true
spring.dynamic.thread-pool.executors[1].active-alarm=80
spring.dynamic.thread-pool.executors[1].capacity-alarm=80
spring.dynamic.thread-pool.executors[1].notify.interval=8
spring.dynamic.thread-pool.executors[1].notify.receives=chen.ma

@ -3,21 +3,37 @@ 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].thread-name-prefix=message-consume
spring.dynamic.thread-pool.executors[0].core-pool-size=2
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].queue-capacity=1024
spring.dynamic.thread-pool.executors[0].blocking-queue=ResizableCapacityLinkedBlockingQueue
spring.dynamic.thread-pool.executors[0].execute-time-out=800
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].keep-alive-time=6691
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.executors[0].notify.receives=chen.ma
spring.dynamic.thread-pool.executors[1].thread-pool-id=message-produce
spring.dynamic.thread-pool.executors[1].thread-name-prefix=message-produce
spring.dynamic.thread-pool.executors[1].core-pool-size=2
spring.dynamic.thread-pool.executors[1].maximum-pool-size=4
spring.dynamic.thread-pool.executors[1].queue-capacity=1024
spring.dynamic.thread-pool.executors[1].blocking-queue=ResizableCapacityLinkedBlockingQueue
spring.dynamic.thread-pool.executors[1].execute-time-out=800
spring.dynamic.thread-pool.executors[1].rejected-handler=AbortPolicy
spring.dynamic.thread-pool.executors[1].keep-alive-time=6691
spring.dynamic.thread-pool.executors[1].allow-core-thread-time-out=true
spring.dynamic.thread-pool.executors[1].alarm=true
spring.dynamic.thread-pool.executors[1].active-alarm=80
spring.dynamic.thread-pool.executors[1].capacity-alarm=80
spring.dynamic.thread-pool.executors[1].notify.interval=8
spring.dynamic.thread-pool.executors[1].notify.receives=chen.ma
spring.dynamic.thread-pool.notify-platforms[0].platform=WECHAT
spring.dynamic.thread-pool.notify-platforms[0].secret-key=ac0426a5-c712-474c-9bff-72b8b8f5caff
spring.dynamic.thread-pool.notify-platforms[0].token=ac0426a5-c712-474c-9bff-72b8b8f5caff

@ -0,0 +1,52 @@
# \u4EE5\u4E0B\u5185\u5BB9\u590D\u5236\u5230 etcd \u914D\u7F6E\u6587\u4EF6\u4E2D
# Copy the following to the etcd configuration file
spring.dynamic.thread-pool.tomcat.core-pool-size=64
spring.dynamic.thread-pool.tomcat.maximum-pool-size=128
spring.dynamic.thread-pool.tomcat.keep-alive-time=1000
spring.dynamic.thread-pool.tomcat.enable=true
spring.dynamic.thread-pool.default-executor.core-pool-size=1
spring.dynamic.thread-pool.default-executor.maximum-pool-size=2
spring.dynamic.thread-pool.default-executor.blocking-queue=ResizableCapacityLinkedBlockingQueue
spring.dynamic.thread-pool.default-executor.execute-time-out=100
spring.dynamic.thread-pool.default-executor.keep-alive-time=6691
spring.dynamic.thread-pool.default-executor.queue-capacity=1
spring.dynamic.thread-pool.default-executor.rejected-handler=AbortPolicy
spring.dynamic.thread-pool.default-executor.active-alarm=90
spring.dynamic.thread-pool.default-executor.capacity-alarm=85
spring.dynamic.thread-pool.default-executor.alarm=true
spring.dynamic.thread-pool.default-executor.allow-core-thread-time-out=true
spring.dynamic.thread-pool.default-executor.notify.interval=5
spring.dynamic.thread-pool.default-executor.notify.receives=chen.ma
spring.dynamic.thread-pool.notify-platforms[0].platform=WECHAT
spring.dynamic.thread-pool.notify-platforms[0].secret-key=ec3be378-6c99-45d2-a147-b400c7e94a08
spring.dynamic.thread-pool.executors[0].thread-pool-id=message-consume
spring.dynamic.thread-pool.executors[0].thread-name-prefix=message-consume
spring.dynamic.thread-pool.executors[0].core-pool-size=2
spring.dynamic.thread-pool.executors[0].maximum-pool-size=4
spring.dynamic.thread-pool.executors[0].queue-capacity=1024
spring.dynamic.thread-pool.executors[0].blocking-queue=ResizableCapacityLinkedBlockingQueue
spring.dynamic.thread-pool.executors[0].execute-time-out=800
spring.dynamic.thread-pool.executors[0].rejected-handler=AbortPolicy
spring.dynamic.thread-pool.executors[0].keep-alive-time=6691
spring.dynamic.thread-pool.executors[0].allow-core-thread-time-out=true
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=chen.ma
spring.dynamic.thread-pool.executors[1].thread-pool-id=message-produce
spring.dynamic.thread-pool.executors[1].thread-name-prefix=message-produce
spring.dynamic.thread-pool.executors[1].core-pool-size=2
spring.dynamic.thread-pool.executors[1].maximum-pool-size=4
spring.dynamic.thread-pool.executors[1].queue-capacity=1024
spring.dynamic.thread-pool.executors[1].blocking-queue=ResizableCapacityLinkedBlockingQueue
spring.dynamic.thread-pool.executors[1].execute-time-out=800
spring.dynamic.thread-pool.executors[1].rejected-handler=AbortPolicy
spring.dynamic.thread-pool.executors[1].keep-alive-time=6691
spring.dynamic.thread-pool.executors[1].allow-core-thread-time-out=true
spring.dynamic.thread-pool.executors[1].alarm=true
spring.dynamic.thread-pool.executors[1].active-alarm=80
spring.dynamic.thread-pool.executors[1].capacity-alarm=80
spring.dynamic.thread-pool.executors[1].notify.interval=8
spring.dynamic.thread-pool.executors[1].notify.receives=chen.ma

@ -6,7 +6,7 @@ management.security.enabled=false
management.context-path=/actuator
spring.profiles.active=dev
spring.application.name=dynamic-threadpool-example
spring.application.name=hippo4j-config-nacos-spring-boot-1x-starter-example
spring.cloud.nacos.config.server-addr=127.0.0.1:8848
spring.cloud.nacos.config.ext-config[0].data-id=hippo4j-nacos.yaml
@ -15,17 +15,51 @@ spring.cloud.nacos.config.ext-config[0].refresh=true
spring.dynamic.thread-pool.enable=true
spring.dynamic.thread-pool.banner=true
spring.dynamic.thread-pool.collect=true
spring.dynamic.thread-pool.collect-type=micrometer
spring.dynamic.thread-pool.check-state-interval=5
spring.dynamic.thread-pool.monitor.enable=true
spring.dynamic.thread-pool.monitor.collect-types=micrometer
spring.dynamic.thread-pool.monitor.thread-pool-types=dynamic,web
spring.dynamic.thread-pool.monitor.initial-delay=10000
spring.dynamic.thread-pool.monitor.collect-interval=5000
spring.dynamic.thread-pool.notify-platforms[0].platform=WECHAT
spring.dynamic.thread-pool.notify-platforms[0].secret-key=ac0426a5-c712-474c-9bff-72b8b8f5caff
spring.dynamic.thread-pool.notify-platforms[0].token=ac0426a5-c712-474c-9bff-72b8b8f5caff
spring.dynamic.thread-pool.notify-platforms[1].platform=DING
spring.dynamic.thread-pool.notify-platforms[1].secret-key=56417ebba6a27ca352f0de77a2ae9da66d01f39610b5ee8a6033c60ef9071c55
spring.dynamic.thread-pool.notify-platforms[1].token=56417ebba6a27ca352f0de77a2ae9da66d01f39610b5ee8a6033c60ef9071c55
spring.dynamic.thread-pool.notify-platforms[2].platform=LARK
spring.dynamic.thread-pool.notify-platforms[2].secret-key=2cbf2808-3839-4c26-a04d-fd201dd51f9e
spring.dynamic.thread-pool.notify-platforms[2].token=2cbf2808-3839-4c26-a04d-fd201dd51f9e
spring.dynamic.thread-pool.nacos.data-id=hippo4j-nacos.yaml
spring.dynamic.thread-pool.nacos.group=DEFAULT_GROUP
spring.dynamic.thread-pool.config-file-type=yml
spring.dynamic.thread-pool.executors[0].thread-pool-id=message-consume
spring.dynamic.thread-pool.executors[0].thread-name-prefix=message-consume
spring.dynamic.thread-pool.executors[0].core-pool-size=2
spring.dynamic.thread-pool.executors[0].maximum-pool-size=4
spring.dynamic.thread-pool.executors[0].queue-capacity=1024
spring.dynamic.thread-pool.executors[0].blocking-queue=ResizableCapacityLinkedBlockingQueue
spring.dynamic.thread-pool.executors[0].execute-time-out=800
spring.dynamic.thread-pool.executors[0].rejected-handler=AbortPolicy
spring.dynamic.thread-pool.executors[0].keep-alive-time=6691
spring.dynamic.thread-pool.executors[0].allow-core-thread-time-out=true
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=chen.ma
spring.dynamic.thread-pool.executors[1].thread-pool-id=message-produce
spring.dynamic.thread-pool.executors[1].thread-name-prefix=message-produce
spring.dynamic.thread-pool.executors[1].core-pool-size=2
spring.dynamic.thread-pool.executors[1].maximum-pool-size=4
spring.dynamic.thread-pool.executors[1].queue-capacity=1024
spring.dynamic.thread-pool.executors[1].blocking-queue=ResizableCapacityLinkedBlockingQueue
spring.dynamic.thread-pool.executors[1].execute-time-out=800
spring.dynamic.thread-pool.executors[1].rejected-handler=AbortPolicy
spring.dynamic.thread-pool.executors[1].keep-alive-time=6691
spring.dynamic.thread-pool.executors[1].allow-core-thread-time-out=true
spring.dynamic.thread-pool.executors[1].alarm=true
spring.dynamic.thread-pool.executors[1].active-alarm=80
spring.dynamic.thread-pool.executors[1].capacity-alarm=80
spring.dynamic.thread-pool.executors[1].notify.interval=8
spring.dynamic.thread-pool.executors[1].notify.receives=chen.ma

@ -0,0 +1,52 @@
# \u4EE5\u4E0B\u5185\u5BB9\u590D\u5236\u5230 nacos \u914D\u7F6E\u6587\u4EF6\u4E2D
# Copy the following to the nacos configuration file
spring.dynamic.thread-pool.tomcat.core-pool-size=64
spring.dynamic.thread-pool.tomcat.maximum-pool-size=128
spring.dynamic.thread-pool.tomcat.keep-alive-time=1000
spring.dynamic.thread-pool.tomcat.enable=true
spring.dynamic.thread-pool.default-executor.core-pool-size=1
spring.dynamic.thread-pool.default-executor.maximum-pool-size=2
spring.dynamic.thread-pool.default-executor.blocking-queue=ResizableCapacityLinkedBlockingQueue
spring.dynamic.thread-pool.default-executor.execute-time-out=100
spring.dynamic.thread-pool.default-executor.keep-alive-time=6691
spring.dynamic.thread-pool.default-executor.queue-capacity=1
spring.dynamic.thread-pool.default-executor.rejected-handler=AbortPolicy
spring.dynamic.thread-pool.default-executor.active-alarm=90
spring.dynamic.thread-pool.default-executor.capacity-alarm=85
spring.dynamic.thread-pool.default-executor.alarm=true
spring.dynamic.thread-pool.default-executor.allow-core-thread-time-out=true
spring.dynamic.thread-pool.default-executor.notify.interval=5
spring.dynamic.thread-pool.default-executor.notify.receives=chen.ma
spring.dynamic.thread-pool.notify-platforms[0].platform=WECHAT
spring.dynamic.thread-pool.notify-platforms[0].secret-key=ec3be378-6c99-45d2-a147-b400c7e94a08
spring.dynamic.thread-pool.executors[0].thread-pool-id=message-consume
spring.dynamic.thread-pool.executors[0].thread-name-prefix=message-consume
spring.dynamic.thread-pool.executors[0].core-pool-size=2
spring.dynamic.thread-pool.executors[0].maximum-pool-size=4
spring.dynamic.thread-pool.executors[0].queue-capacity=1024
spring.dynamic.thread-pool.executors[0].blocking-queue=ResizableCapacityLinkedBlockingQueue
spring.dynamic.thread-pool.executors[0].execute-time-out=800
spring.dynamic.thread-pool.executors[0].rejected-handler=AbortPolicy
spring.dynamic.thread-pool.executors[0].keep-alive-time=6691
spring.dynamic.thread-pool.executors[0].allow-core-thread-time-out=true
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=chen.ma
spring.dynamic.thread-pool.executors[1].thread-pool-id=message-produce
spring.dynamic.thread-pool.executors[1].thread-name-prefix=message-produce
spring.dynamic.thread-pool.executors[1].core-pool-size=2
spring.dynamic.thread-pool.executors[1].maximum-pool-size=4
spring.dynamic.thread-pool.executors[1].queue-capacity=1024
spring.dynamic.thread-pool.executors[1].blocking-queue=ResizableCapacityLinkedBlockingQueue
spring.dynamic.thread-pool.executors[1].execute-time-out=800
spring.dynamic.thread-pool.executors[1].rejected-handler=AbortPolicy
spring.dynamic.thread-pool.executors[1].keep-alive-time=6691
spring.dynamic.thread-pool.executors[1].allow-core-thread-time-out=true
spring.dynamic.thread-pool.executors[1].alarm=true
spring.dynamic.thread-pool.executors[1].active-alarm=80
spring.dynamic.thread-pool.executors[1].capacity-alarm=80
spring.dynamic.thread-pool.executors[1].notify.interval=8
spring.dynamic.thread-pool.executors[1].notify.receives=chen.ma

@ -6,7 +6,7 @@ management.server.port=29999
management.endpoints.web.exposure.include=*
spring.profiles.active=dev
spring.application.name=dynamic-threadpool-example
spring.application.name=hippo4j-config-nacos-spring-boot-starter-example
spring.cloud.nacos.config.password=nacos
spring.cloud.nacos.config.server-addr=127.0.0.1:8848
@ -17,33 +17,51 @@ spring.cloud.nacos.config.extension-configs[0].refresh=true
spring.dynamic.thread-pool.enable=true
spring.dynamic.thread-pool.banner=true
spring.dynamic.thread-pool.collect=true
spring.dynamic.thread-pool.collect-type=micrometer
spring.dynamic.thread-pool.check-state-interval=5
spring.dynamic.thread-pool.monitor.enable=true
spring.dynamic.thread-pool.monitor.collect-types=micrometer
spring.dynamic.thread-pool.monitor.thread-pool-types=dynamic,web
spring.dynamic.thread-pool.monitor.initial-delay=10000
spring.dynamic.thread-pool.monitor.collect-interval=5000
spring.dynamic.thread-pool.notify-platforms[0].platform=WECHAT
spring.dynamic.thread-pool.notify-platforms[0].secret-key=ac0426a5-c712-474c-9bff-72b8b8f5caff
spring.dynamic.thread-pool.notify-platforms[0].token=ac0426a5-c712-474c-9bff-72b8b8f5caff
spring.dynamic.thread-pool.notify-platforms[1].platform=DING
spring.dynamic.thread-pool.notify-platforms[1].secret-key=56417ebba6a27ca352f0de77a2ae9da66d01f39610b5ee8a6033c60ef9071c55
spring.dynamic.thread-pool.notify-platforms[1].token=56417ebba6a27ca352f0de77a2ae9da66d01f39610b5ee8a6033c60ef9071c55
spring.dynamic.thread-pool.notify-platforms[2].platform=LARK
spring.dynamic.thread-pool.notify-platforms[2].secret-key=2cbf2808-3839-4c26-a04d-fd201dd51f9e
spring.dynamic.thread-pool.notify-platforms[2].token=2cbf2808-3839-4c26-a04d-fd201dd51f9e
spring.dynamic.thread-pool.nacos.data-id=hippo4j-nacos.yaml
spring.dynamic.thread-pool.nacos.group=DEFAULT_GROUP
spring.dynamic.thread-pool.config-file-type=yml
spring.dynamic.thread-pool.executors[0].thread-pool-id=message-consume
spring.dynamic.thread-pool.executors[0].core-pool-size=1
spring.dynamic.thread-pool.executors[0].maximum-pool-size=1
spring.dynamic.thread-pool.executors[0].queue-capacity=1
spring.dynamic.thread-pool.executors[0].blocking-queue=LinkedBlockingQueue
spring.dynamic.thread-pool.executors[0].execute-time-out=1000
spring.dynamic.thread-pool.executors[0].thread-name-prefix=message-consume
spring.dynamic.thread-pool.executors[0].core-pool-size=2
spring.dynamic.thread-pool.executors[0].maximum-pool-size=4
spring.dynamic.thread-pool.executors[0].queue-capacity=1024
spring.dynamic.thread-pool.executors[0].blocking-queue=ResizableCapacityLinkedBlockingQueue
spring.dynamic.thread-pool.executors[0].execute-time-out=800
spring.dynamic.thread-pool.executors[0].rejected-handler=AbortPolicy
spring.dynamic.thread-pool.executors[0].keep-alive-time=6691
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=chen.ma
spring.dynamic.thread-pool.executors[0].notify.receives=chen.ma
spring.dynamic.thread-pool.executors[1].thread-pool-id=message-produce
spring.dynamic.thread-pool.executors[1].thread-name-prefix=message-produce
spring.dynamic.thread-pool.executors[1].core-pool-size=2
spring.dynamic.thread-pool.executors[1].maximum-pool-size=4
spring.dynamic.thread-pool.executors[1].queue-capacity=1024
spring.dynamic.thread-pool.executors[1].blocking-queue=ResizableCapacityLinkedBlockingQueue
spring.dynamic.thread-pool.executors[1].execute-time-out=800
spring.dynamic.thread-pool.executors[1].rejected-handler=AbortPolicy
spring.dynamic.thread-pool.executors[1].keep-alive-time=6691
spring.dynamic.thread-pool.executors[1].allow-core-thread-time-out=true
spring.dynamic.thread-pool.executors[1].alarm=true
spring.dynamic.thread-pool.executors[1].active-alarm=80
spring.dynamic.thread-pool.executors[1].capacity-alarm=80
spring.dynamic.thread-pool.executors[1].notify.interval=8
spring.dynamic.thread-pool.executors[1].notify.receives=chen.ma

@ -0,0 +1,52 @@
# \u4EE5\u4E0B\u5185\u5BB9\u590D\u5236\u5230 nacos \u914D\u7F6E\u6587\u4EF6\u4E2D
# Copy the following to the nacos configuration file
spring.dynamic.thread-pool.tomcat.core-pool-size=64
spring.dynamic.thread-pool.tomcat.maximum-pool-size=128
spring.dynamic.thread-pool.tomcat.keep-alive-time=1000
spring.dynamic.thread-pool.tomcat.enable=true
spring.dynamic.thread-pool.default-executor.core-pool-size=1
spring.dynamic.thread-pool.default-executor.maximum-pool-size=2
spring.dynamic.thread-pool.default-executor.blocking-queue=ResizableCapacityLinkedBlockingQueue
spring.dynamic.thread-pool.default-executor.execute-time-out=100
spring.dynamic.thread-pool.default-executor.keep-alive-time=6691
spring.dynamic.thread-pool.default-executor.queue-capacity=1
spring.dynamic.thread-pool.default-executor.rejected-handler=AbortPolicy
spring.dynamic.thread-pool.default-executor.active-alarm=90
spring.dynamic.thread-pool.default-executor.capacity-alarm=85
spring.dynamic.thread-pool.default-executor.alarm=true
spring.dynamic.thread-pool.default-executor.allow-core-thread-time-out=true
spring.dynamic.thread-pool.default-executor.notify.interval=5
spring.dynamic.thread-pool.default-executor.notify.receives=chen.ma
spring.dynamic.thread-pool.notify-platforms[0].platform=WECHAT
spring.dynamic.thread-pool.notify-platforms[0].secret-key=ec3be378-6c99-45d2-a147-b400c7e94a08
spring.dynamic.thread-pool.executors[0].thread-pool-id=message-consume
spring.dynamic.thread-pool.executors[0].thread-name-prefix=message-consume
spring.dynamic.thread-pool.executors[0].core-pool-size=2
spring.dynamic.thread-pool.executors[0].maximum-pool-size=4
spring.dynamic.thread-pool.executors[0].queue-capacity=1024
spring.dynamic.thread-pool.executors[0].blocking-queue=ResizableCapacityLinkedBlockingQueue
spring.dynamic.thread-pool.executors[0].execute-time-out=800
spring.dynamic.thread-pool.executors[0].rejected-handler=AbortPolicy
spring.dynamic.thread-pool.executors[0].keep-alive-time=6691
spring.dynamic.thread-pool.executors[0].allow-core-thread-time-out=true
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=chen.ma
spring.dynamic.thread-pool.executors[1].thread-pool-id=message-produce
spring.dynamic.thread-pool.executors[1].thread-name-prefix=message-produce
spring.dynamic.thread-pool.executors[1].core-pool-size=2
spring.dynamic.thread-pool.executors[1].maximum-pool-size=4
spring.dynamic.thread-pool.executors[1].queue-capacity=1024
spring.dynamic.thread-pool.executors[1].blocking-queue=ResizableCapacityLinkedBlockingQueue
spring.dynamic.thread-pool.executors[1].execute-time-out=800
spring.dynamic.thread-pool.executors[1].rejected-handler=AbortPolicy
spring.dynamic.thread-pool.executors[1].keep-alive-time=6691
spring.dynamic.thread-pool.executors[1].allow-core-thread-time-out=true
spring.dynamic.thread-pool.executors[1].alarm=true
spring.dynamic.thread-pool.executors[1].active-alarm=80
spring.dynamic.thread-pool.executors[1].capacity-alarm=80
spring.dynamic.thread-pool.executors[1].notify.interval=8
spring.dynamic.thread-pool.executors[1].notify.receives=chen.ma

@ -3,7 +3,7 @@ server.port=8088
server.servlet.context-path=/example
spring.profiles.active=dev
spring.application.name=dynamic-threadpool-example
spring.application.name=hippo4j-spring-boot-starter-es-monitor-example
es.thread-pool-state.host = ip1:port,ip2:port
es.thread-pool-state.scheme = http
@ -14,8 +14,11 @@ es.thread-pool-state.index.name = thread-pool-state
spring.dynamic.thread-pool.item-id=test
spring.dynamic.thread-pool.enable=true
spring.dynamic.thread-pool.banner=false
spring.dynamic.thread-pool.collect=true
spring.dynamic.thread-pool.collect-type=es
spring.dynamic.thread-pool.monitor.enable=true
spring.dynamic.thread-pool.monitor.collect-types=elasticsearch
spring.dynamic.thread-pool.monitor.thread-pool-types=dynamic
spring.dynamic.thread-pool.monitor.initial-delay=10000
spring.dynamic.thread-pool.monitor.collect-interval=5000
spring.dynamic.thread-pool.notify-platforms[0].platform=DING
spring.dynamic.thread-pool.notify-platforms[0].token=xxx
spring.dynamic.thread-pool.notify-platforms[0].secret=xxx

@ -7,7 +7,7 @@ management.server.port=29901
management.endpoints.web.exposure.include=*
spring.profiles.active=dev
spring.application.name=dynamic-threadpool-example
spring.application.name=hippo4j-spring-boot-starter-example
spring.dynamic.thread-pool.server-addr=http://localhost:6691
### Use netty to report thread pool monitoring data. The default is http.
@ -19,4 +19,8 @@ spring.dynamic.thread-pool.username=admin
spring.dynamic.thread-pool.password=123456
# Enable server and micrometer monitoring at the same time
spring.dynamic.thread-pool.collect-type=server,micrometer
spring.dynamic.thread-pool.monitor.enable=true
spring.dynamic.thread-pool.monitor.collect-types=server,micrometer
spring.dynamic.thread-pool.monitor.thread-pool-types=dynamic,web
spring.dynamic.thread-pool.monitor.initial-delay=10000
spring.dynamic.thread-pool.monitor.collect-interval=5000

@ -17,9 +17,9 @@
package cn.hippo4j.message.service;
import cn.hippo4j.common.config.ApplicationContextHolder;
import cn.hippo4j.common.toolkit.CollectionUtil;
import cn.hippo4j.message.api.NotifyConfigBuilder;
import cn.hippo4j.common.config.ApplicationContextHolder;
import cn.hippo4j.message.dto.AlarmControlDTO;
import cn.hippo4j.message.dto.NotifyConfigDTO;
import cn.hippo4j.message.enums.NotifyTypeEnum;
@ -28,7 +28,7 @@ import cn.hippo4j.message.request.ChangeParameterNotifyRequest;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.CommandLineRunner;
import org.springframework.beans.factory.InitializingBean;
import java.util.HashMap;
import java.util.List;
@ -39,7 +39,7 @@ import java.util.Map;
*/
@Slf4j
@RequiredArgsConstructor
public class Hippo4jBaseSendMessageService implements Hippo4jSendMessageService, CommandLineRunner {
public class Hippo4jBaseSendMessageService implements Hippo4jSendMessageService, InitializingBean {
private final NotifyConfigBuilder notifyConfigBuilder;
@ -133,7 +133,7 @@ public class Hippo4jBaseSendMessageService implements Hippo4jSendMessageService,
}
@Override
public void run(String... args) throws Exception {
public void afterPropertiesSet() throws Exception {
Map<String, SendMessageHandler> sendMessageHandlerMap =
ApplicationContextHolder.getBeansOfType(SendMessageHandler.class);
sendMessageHandlerMap.values().forEach(each -> sendMessageHandlers.put(each.getType(), each));

@ -18,17 +18,51 @@
package cn.hippo4j.monitor.micrometer;
import cn.hippo4j.adapter.base.ThreadPoolAdapterState;
import cn.hippo4j.common.config.ApplicationContextHolder;
import cn.hippo4j.common.toolkit.BeanUtil;
import cn.hippo4j.common.toolkit.CollectionUtil;
import cn.hippo4j.monitor.base.AbstractAdapterThreadPoolMonitor;
import cn.hippo4j.monitor.base.MonitorTypeEnum;
import io.micrometer.core.instrument.Metrics;
import io.micrometer.core.instrument.Tag;
import org.springframework.core.env.Environment;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
* Adapter thread-pool micrometer monitor handler.
*/
public class AdapterThreadPoolMicrometerMonitorHandler extends AbstractAdapterThreadPoolMonitor {
private final static String METRIC_NAME_PREFIX = "adapter.thread-pool";
private final static String ADAPTER_THREAD_POOL_ID_TAG = METRIC_NAME_PREFIX + ".id";
private final static String APPLICATION_NAME_TAG = "application.name";
private final Map<String, ThreadPoolAdapterState> RUN_STATE_CACHE = new ConcurrentHashMap<>();
@Override
protected void execute(ThreadPoolAdapterState threadPoolAdapterState) {
ThreadPoolAdapterState stateInfo = RUN_STATE_CACHE.get(threadPoolAdapterState.getThreadPoolKey());
if (stateInfo == null) {
RUN_STATE_CACHE.put(threadPoolAdapterState.getThreadPoolKey(), threadPoolAdapterState);
} else {
BeanUtil.convert(threadPoolAdapterState, stateInfo);
}
Environment environment = ApplicationContextHolder.getInstance().getEnvironment();
String applicationName = environment.getProperty("spring.application.name", "application");
Iterable<Tag> tags = CollectionUtil.newArrayList(
Tag.of(ADAPTER_THREAD_POOL_ID_TAG, threadPoolAdapterState.getThreadPoolKey()),
Tag.of(APPLICATION_NAME_TAG, applicationName));
Metrics.gauge(metricName("core.size"), tags, threadPoolAdapterState, ThreadPoolAdapterState::getCoreSize);
Metrics.gauge(metricName("maximum.size"), tags, threadPoolAdapterState, ThreadPoolAdapterState::getMaximumSize);
Metrics.gauge(metricName("queue.capacity"), tags, threadPoolAdapterState, ThreadPoolAdapterState::getBlockingQueueCapacity);
}
private String metricName(String name) {
return String.join(".", METRIC_NAME_PREFIX, name);
}
@Override

@ -17,18 +17,56 @@
package cn.hippo4j.monitor.micrometer;
import cn.hippo4j.common.config.ApplicationContextHolder;
import cn.hippo4j.common.model.ThreadPoolRunStateInfo;
import cn.hippo4j.common.toolkit.BeanUtil;
import cn.hippo4j.common.toolkit.CollectionUtil;
import cn.hippo4j.monitor.base.AbstractWebThreadPoolMonitor;
import cn.hippo4j.monitor.base.MonitorTypeEnum;
import io.micrometer.core.instrument.Metrics;
import io.micrometer.core.instrument.Tag;
import org.springframework.core.env.Environment;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
* Web thread-pool micrometer monitor handler.
*/
public class WebThreadPoolMicrometerMonitorHandler extends AbstractWebThreadPoolMonitor {
private final static String METRIC_NAME_PREFIX = "web.thread-pool";
private final static String APPLICATION_NAME_TAG = "application.name";
private final Map<String, ThreadPoolRunStateInfo> RUN_STATE_CACHE = new ConcurrentHashMap<>();
@Override
protected void execute(ThreadPoolRunStateInfo webThreadPoolRunStateInfo) {
Environment environment = ApplicationContextHolder.getInstance().getEnvironment();
String applicationName = environment.getProperty("spring.application.name", "application");
ThreadPoolRunStateInfo stateInfo = RUN_STATE_CACHE.get(applicationName);
if (stateInfo == null) {
RUN_STATE_CACHE.put(applicationName, webThreadPoolRunStateInfo);
} else {
BeanUtil.convert(webThreadPoolRunStateInfo, stateInfo);
}
Iterable<Tag> tags = CollectionUtil.newArrayList(Tag.of(APPLICATION_NAME_TAG, applicationName));
Metrics.gauge(metricName("current.load"), tags, webThreadPoolRunStateInfo, ThreadPoolRunStateInfo::getSimpleCurrentLoad);
Metrics.gauge(metricName("peak.load"), tags, webThreadPoolRunStateInfo, ThreadPoolRunStateInfo::getSimplePeakLoad);
Metrics.gauge(metricName("core.size"), tags, webThreadPoolRunStateInfo, ThreadPoolRunStateInfo::getCoreSize);
Metrics.gauge(metricName("maximum.size"), tags, webThreadPoolRunStateInfo, ThreadPoolRunStateInfo::getMaximumSize);
Metrics.gauge(metricName("current.size"), tags, webThreadPoolRunStateInfo, ThreadPoolRunStateInfo::getPoolSize);
Metrics.gauge(metricName("largest.size"), tags, webThreadPoolRunStateInfo, ThreadPoolRunStateInfo::getLargestPoolSize);
Metrics.gauge(metricName("active.size"), tags, webThreadPoolRunStateInfo, ThreadPoolRunStateInfo::getActiveSize);
Metrics.gauge(metricName("queue.size"), tags, webThreadPoolRunStateInfo, ThreadPoolRunStateInfo::getQueueSize);
Metrics.gauge(metricName("queue.capacity"), tags, webThreadPoolRunStateInfo, ThreadPoolRunStateInfo::getQueueCapacity);
Metrics.gauge(metricName("queue.remaining.capacity"), tags, webThreadPoolRunStateInfo, ThreadPoolRunStateInfo::getQueueRemainingCapacity);
Metrics.gauge(metricName("completed.task.count"), tags, webThreadPoolRunStateInfo, ThreadPoolRunStateInfo::getCompletedTaskCount);
}
private String metricName(String name) {
return String.join(".", METRIC_NAME_PREFIX, name);
}
@Override

@ -20,7 +20,7 @@ JAVA_OPT="${JAVA_OPT} --server.tomcat.basedir=${BASE_DIR}/bin"
if [[ "${DATASOURCE_MODE}" == "mysql" ]]; then
JAVA_OPT="${JAVA_OPT} --spring.datasource.url=\"jdbc:mysql://${DATASOURCE_HOST}:${DATASOURCE_PORT}/${DATASOURCE_DB}?characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&transformedBitIsBoolean=true&serverTimezone=GMT%2B8\" "
JAVA_OPT="${JAVA_OPT} ---spring.datasource.username=${DATASOURCE_USERNAME} --spring.datasource.password=${DATASOURCE_PASSWORD} "
JAVA_OPT="${JAVA_OPT} --spring.datasource.username=${DATASOURCE_USERNAME} --spring.datasource.password=${DATASOURCE_PASSWORD} "
elif [[ "${DATASOURCE_MODE}" == "h2" ]]; then
JAVA_OPT="${JAVA_OPT} --spring.profiles.active=h2 --spring.datasource.url=jdbc:h2:file:${BASE_DIR}/h2_hippo4j;DB_CLOSE_DELAY=-1;DATABASE_TO_UPPER=false;MODE=MYSQL"
else

@ -17,12 +17,12 @@
package cn.hippo4j.config.notify;
import cn.hippo4j.common.toolkit.MapUtil;
import cn.hippo4j.config.event.AbstractEvent;
import cn.hippo4j.config.event.AbstractSlowEvent;
import cn.hippo4j.config.notify.listener.AbstractSmartSubscriber;
import cn.hippo4j.config.notify.listener.AbstractSubscriber;
import cn.hippo4j.config.toolkit.ClassUtil;
import cn.hippo4j.config.toolkit.MapUtil;
import cn.hippo4j.config.event.AbstractSlowEvent;
import lombok.extern.slf4j.Slf4j;
import java.util.Map;

@ -22,17 +22,12 @@ import cn.hippo4j.common.constant.Constants;
import cn.hippo4j.common.design.observer.AbstractSubjectCenter;
import cn.hippo4j.common.design.observer.Observer;
import cn.hippo4j.common.design.observer.ObserverMessage;
import cn.hippo4j.common.toolkit.CollectionUtil;
import cn.hippo4j.common.toolkit.JSONUtil;
import cn.hippo4j.common.toolkit.Joiner;
import cn.hippo4j.common.toolkit.Md5Util;
import cn.hippo4j.common.toolkit.StringUtil;
import cn.hippo4j.common.toolkit.*;
import cn.hippo4j.config.event.LocalDataChangeEvent;
import cn.hippo4j.config.model.CacheItem;
import cn.hippo4j.config.model.ConfigAllInfo;
import cn.hippo4j.config.notify.NotifyCenter;
import cn.hippo4j.config.service.biz.ConfigService;
import cn.hippo4j.config.toolkit.MapUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.StringUtils;

@ -17,17 +17,13 @@
package cn.hippo4j.config.service;
import cn.hippo4j.common.toolkit.CollectionUtil;
import cn.hippo4j.common.toolkit.JSONUtil;
import cn.hippo4j.common.toolkit.Md5Util;
import cn.hippo4j.common.toolkit.StringUtil;
import cn.hippo4j.common.toolkit.*;
import cn.hippo4j.common.web.base.Results;
import cn.hippo4j.config.event.AbstractEvent;
import cn.hippo4j.config.event.LocalDataChangeEvent;
import cn.hippo4j.config.notify.NotifyCenter;
import cn.hippo4j.config.notify.listener.AbstractSubscriber;
import cn.hippo4j.config.toolkit.ConfigExecutor;
import cn.hippo4j.config.toolkit.MapUtil;
import cn.hippo4j.config.toolkit.Md5ConfigUtil;
import cn.hippo4j.config.toolkit.RequestUtil;
import lombok.SneakyThrows;

@ -1,82 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package cn.hippo4j.config.toolkit;
import cn.hippo4j.common.toolkit.CollectionUtil;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.function.BiFunction;
/**
* Map util.
*/
public class MapUtil {
public static Object computeIfAbsent(Map target, Object key, BiFunction mappingFunction, Object param1, Object param2) {
Objects.requireNonNull(target, "target");
Objects.requireNonNull(key, "key");
Objects.requireNonNull(mappingFunction, "mappingFunction");
Objects.requireNonNull(param1, "param1");
Objects.requireNonNull(param2, "param2");
Object val = target.get(key);
if (val == null) {
Object ret = mappingFunction.apply(param1, param2);
target.put(key, ret);
return ret;
}
return val;
}
/**
* Fuzzy matching based on Key.
*
* @param sourceMap
* @param filters
* @return
*/
public static List<String> parseMapForFilter(Map<String, ?> sourceMap, String filters) {
List<String> resultList = new ArrayList<>();
if (CollectionUtil.isEmpty(sourceMap)) {
return resultList;
}
sourceMap.forEach((key, val) -> {
if (checkKey(key, filters)) {
resultList.add(key);
}
});
return resultList;
}
/**
* Match the characters you want to query.
*
* @param key
* @param filters
* @return
*/
private static boolean checkKey(String key, String filters) {
if (key.indexOf(filters) > -1) {
return true;
} else {
return false;
}
}
}

@ -88,7 +88,7 @@ public class Lease<T> {
}
public boolean isExpired(long additionalLeaseMs) {
return (evictionTimestamp > 0 || System.currentTimeMillis() > (lastUpdateTimestamp + duration + additionalLeaseMs));
return (evictionTimestamp > 0 || System.currentTimeMillis() > (lastUpdateTimestamp + additionalLeaseMs));
}
public long getRegistrationTimestamp() {

@ -18,7 +18,7 @@
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.monitor.ThreadPoolMonitorExecutor;
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;
@ -37,8 +37,6 @@ import cn.hippo4j.message.service.AlarmControlHandler;
import cn.hippo4j.message.service.Hippo4jBaseSendMessageService;
import cn.hippo4j.message.service.Hippo4jSendMessageService;
import cn.hippo4j.springboot.starter.adapter.web.WebAdapterConfiguration;
import cn.hippo4j.springboot.starter.monitor.local.log.LocalLogMonitorAutoConfiguration;
import cn.hippo4j.springboot.starter.monitor.micrometer.MicrometerMonitorAutoConfiguration;
import lombok.AllArgsConstructor;
import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
@ -88,8 +86,8 @@ public class DynamicThreadPoolAutoConfiguration {
}
@Bean
public DynamicThreadPoolMonitorExecutor hippo4jDynamicThreadPoolMonitorExecutor() {
return new DynamicThreadPoolMonitorExecutor(bootstrapConfigProperties);
public ThreadPoolMonitorExecutor hippo4jDynamicThreadPoolMonitorExecutor() {
return new ThreadPoolMonitorExecutor(bootstrapConfigProperties);
}
@Bean

@ -18,6 +18,7 @@
package cn.hippo4j.config.springboot.starter.config;
import cn.hippo4j.monitor.base.MonitorThreadPoolTypeEnum;
import cn.hippo4j.monitor.base.MonitorTypeEnum;
import lombok.Data;
/**
@ -32,9 +33,9 @@ public class MonitorProperties {
private Boolean enable = Boolean.TRUE;
/**
* Type of collection thread pool running data. eg: log,micrometer. Multiple can be used at the same time.
* Type of collection thread pool running data. eg: log,micrometer. Multiple can be used at the same time, default micrometer.
*/
private String collectTypes;
private String collectTypes = MonitorTypeEnum.MICROMETER.toString().toLowerCase();
/**
* Monitor the type of thread pool. eg: dynamic,web,adapter. Can be configured arbitrarily, default dynamic.

@ -21,6 +21,7 @@ import cn.hippo4j.common.config.ApplicationContextHolder;
import cn.hippo4j.common.spi.DynamicThreadPoolServiceLoader;
import cn.hippo4j.common.toolkit.StringUtil;
import cn.hippo4j.config.springboot.starter.config.BootstrapConfigProperties;
import cn.hippo4j.config.springboot.starter.config.MonitorProperties;
import cn.hippo4j.core.executor.manage.GlobalThreadPoolManage;
import cn.hippo4j.common.design.builder.ThreadFactoryBuilder;
import cn.hippo4j.monitor.base.DynamicThreadPoolMonitor;
@ -40,11 +41,11 @@ import java.util.concurrent.TimeUnit;
import static cn.hippo4j.core.executor.manage.GlobalThreadPoolManage.getThreadPoolNum;
/**
* Dynamic thread-pool monitor executor.
* Thread-pool monitor executor.
*/
@Slf4j
@RequiredArgsConstructor
public class DynamicThreadPoolMonitorExecutor implements ApplicationRunner {
public class ThreadPoolMonitorExecutor implements ApplicationRunner {
private final BootstrapConfigProperties properties;
@ -54,8 +55,11 @@ public class DynamicThreadPoolMonitorExecutor implements ApplicationRunner {
@Override
public void run(ApplicationArguments args) throws Exception {
String collectType = properties.getCollectType();
if (!properties.getCollect() || StringUtil.isBlank(collectType)) {
MonitorProperties monitor = properties.getMonitor();
if (monitor == null
|| !monitor.getEnable()
|| StringUtil.isBlank(monitor.getThreadPoolTypes())
|| StringUtil.isBlank(monitor.getCollectTypes())) {
return;
}
log.info("Start monitoring the running status of dynamic thread pool.");
@ -64,13 +68,8 @@ public class DynamicThreadPoolMonitorExecutor implements ApplicationRunner {
new Integer(1),
ThreadFactoryBuilder.builder().daemon(true).prefix("client.scheduled.collect.data").build());
// Get dynamic thread pool monitoring component.
List<String> collectTypes = Arrays.asList(collectType.split(","));
ApplicationContextHolder.getBeansOfType(ThreadPoolMonitor.class)
.forEach((key, val) -> {
if (collectTypes.contains(val.getType())) {
threadPoolMonitors.add(val);
}
});
List<String> collectTypes = Arrays.asList(monitor.getCollectTypes().split(","));
ApplicationContextHolder.getBeansOfType(ThreadPoolMonitor.class).forEach((beanName, bean) -> threadPoolMonitors.add(bean));
Collection<DynamicThreadPoolMonitor> dynamicThreadPoolMonitors =
DynamicThreadPoolServiceLoader.getSingletonServiceInstances(DynamicThreadPoolMonitor.class);
dynamicThreadPoolMonitors.stream().filter(each -> collectTypes.contains(each.getType())).forEach(each -> threadPoolMonitors.add(each));

@ -36,11 +36,7 @@ import java.util.concurrent.ExecutorService;
* Abstract core thread-pool dynamic refresh.
*/
@Slf4j
public abstract class AbstractConfigThreadPoolDynamicRefresh
implements
ThreadPoolDynamicRefresh,
ThreadPoolInitRefresh,
InitializingBean {
public abstract class AbstractConfigThreadPoolDynamicRefresh implements ThreadPoolDynamicRefresh, ThreadPoolInitRefresh, InitializingBean {
private final BootstrapConfigPropertiesBinderAdapt bootstrapConfigPropertiesBinderAdapt;

@ -68,7 +68,7 @@ public class DynamicThreadPoolConfigService extends AbstractDynamicThreadPoolSer
.allowCoreThreadTimeOut(BooleanUtil.toBoolean(String.valueOf(registerParameter.getAllowCoreThreadTimeOut())))
.keepAliveTime(registerParameter.getKeepAliveTime())
.blockingQueue(BlockingQueueTypeEnum.getBlockingQueueNameByType(registerParameter.getBlockingQueueType().getType()))
.capacityAlarm(registerParameter.getCapacity())
.queueCapacity(registerParameter.getCapacity())
.threadNamePrefix(registerParameter.getThreadNamePrefix())
.rejectedHandler(RejectedPolicyTypeEnum.getRejectedNameByType(registerParameter.getRejectedPolicyType().getType()))
.executeTimeOut(registerParameter.getExecuteTimeOut())

@ -32,7 +32,7 @@ import cn.hippo4j.core.executor.manage.GlobalThreadPoolManage;
import cn.hippo4j.core.executor.support.CommonDynamicThreadPool;
import cn.hippo4j.core.executor.support.ThreadPoolBuilder;
import cn.hippo4j.core.executor.support.adpter.DynamicThreadPoolAdapterChoose;
import cn.hippo4j.core.toolkit.inet.DynamicThreadPoolAnnotationUtil;
import cn.hippo4j.core.toolkit.DynamicThreadPoolAnnotationUtil;
import cn.hippo4j.message.service.ThreadPoolNotifyAlarm;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;

@ -20,6 +20,7 @@ package cn.hippo4j.springboot.starter.monitor.elasticsearch;
import cn.hippo4j.monitor.elasticsearch.AdapterThreadPoolElasticSearchMonitorHandler;
import cn.hippo4j.monitor.elasticsearch.DynamicThreadPoolElasticSearchMonitorHandler;
import cn.hippo4j.monitor.elasticsearch.WebThreadPoolElasticSearchMonitorHandler;
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@ -27,19 +28,23 @@ import org.springframework.context.annotation.Configuration;
* Elastic-search monitor auto configuration.
*/
@Configuration
@ConditionalOnExpression("'${spring.dynamic.thread-pool.monitor.collect-types:}'.contains('elasticsearch')")
public class ElasticSearchMonitorAutoConfiguration {
@Bean
@ConditionalOnExpression("'${spring.dynamic.thread-pool.monitor.thread-pool-types:}'.contains('dynamic')")
public DynamicThreadPoolElasticSearchMonitorHandler dynamicThreadPoolElasticSearchMonitorHandler() {
return new DynamicThreadPoolElasticSearchMonitorHandler();
}
@Bean
@ConditionalOnExpression("'${spring.dynamic.thread-pool.monitor.thread-pool-types:}'.contains('web')")
public WebThreadPoolElasticSearchMonitorHandler webThreadPoolElasticSearchMonitorHandler() {
return new WebThreadPoolElasticSearchMonitorHandler();
}
@Bean
@ConditionalOnExpression("'${spring.dynamic.thread-pool.monitor.thread-pool-types:}'.contains('adapter')")
public AdapterThreadPoolElasticSearchMonitorHandler adapterThreadPoolElasticSearchMonitorHandler() {
return new AdapterThreadPoolElasticSearchMonitorHandler();
}

@ -20,6 +20,7 @@ package cn.hippo4j.springboot.starter.monitor.local.log;
import cn.hippo4j.monitor.local.log.AdapterThreadPoolLocalLogMonitorHandler;
import cn.hippo4j.monitor.local.log.DynamicThreadPoolLocalLogMonitorHandler;
import cn.hippo4j.monitor.local.log.WebThreadPoolLocalLogMonitorHandler;
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@ -27,19 +28,23 @@ import org.springframework.context.annotation.Configuration;
* Local log monitor auto configuration.
*/
@Configuration
@ConditionalOnExpression("'${spring.dynamic.thread-pool.monitor.collect-types:}'.contains('log')")
public class LocalLogMonitorAutoConfiguration {
@Bean
@ConditionalOnExpression("'${spring.dynamic.thread-pool.monitor.thread-pool-types:}'.contains('dynamic')")
public DynamicThreadPoolLocalLogMonitorHandler dynamicThreadPoolLocalLogMonitorHandler() {
return new DynamicThreadPoolLocalLogMonitorHandler();
}
@Bean
@ConditionalOnExpression("'${spring.dynamic.thread-pool.monitor.thread-pool-types:}'.contains('web')")
public WebThreadPoolLocalLogMonitorHandler webThreadPoolLocalLogMonitorHandler() {
return new WebThreadPoolLocalLogMonitorHandler();
}
@Bean
@ConditionalOnExpression("'${spring.dynamic.thread-pool.monitor.thread-pool-types:}'.contains('adapter')")
public AdapterThreadPoolLocalLogMonitorHandler adapterThreadPoolLocalLogMonitorHandler() {
return new AdapterThreadPoolLocalLogMonitorHandler();
}

@ -20,6 +20,7 @@ package cn.hippo4j.springboot.starter.monitor.micrometer;
import cn.hippo4j.monitor.micrometer.AdapterThreadPoolMicrometerMonitorHandler;
import cn.hippo4j.monitor.micrometer.DynamicThreadPoolMicrometerMonitorHandler;
import cn.hippo4j.monitor.micrometer.WebThreadPoolMicrometerMonitorHandler;
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@ -27,19 +28,23 @@ import org.springframework.context.annotation.Configuration;
* Micrometer monitor auto configuration.
*/
@Configuration
@ConditionalOnExpression("'${spring.dynamic.thread-pool.monitor.collect-types:}'.contains('micrometer')")
public class MicrometerMonitorAutoConfiguration {
@Bean
@ConditionalOnExpression("'${spring.dynamic.thread-pool.monitor.thread-pool-types:}'.contains('dynamic')")
public DynamicThreadPoolMicrometerMonitorHandler dynamicThreadPoolMicrometerMonitorHandler() {
return new DynamicThreadPoolMicrometerMonitorHandler();
}
@Bean
@ConditionalOnExpression("'${spring.dynamic.thread-pool.monitor.thread-pool-types:}'.contains('web')")
public WebThreadPoolMicrometerMonitorHandler webThreadPoolMicrometerMonitorHandler() {
return new WebThreadPoolMicrometerMonitorHandler();
}
@Bean
@ConditionalOnExpression("'${spring.dynamic.thread-pool.monitor.thread-pool-types:}'.contains('adapter')")
public AdapterThreadPoolMicrometerMonitorHandler adapterThreadPoolMicrometerMonitorHandler() {
return new AdapterThreadPoolMicrometerMonitorHandler();
}

@ -80,27 +80,37 @@ public class BootstrapProperties implements BootstrapPropertiesInterface {
private Boolean banner = true;
/**
* Enable client data collect
* Thread pool monitoring related configuration.
*/
private Boolean collect = true;
private MonitorProperties monitor;
/**
* Type of collection thread pool running data. eg: server,micrometer. Multiple can be used at the same time.
/***
* Latest use {@link MonitorProperties#getEnable()}
*/
private String collectType;
@Deprecated
private Boolean collect = Boolean.TRUE;
/**
* Task buffer container capacity
* Latest use {@link MonitorProperties#getCollectTypes()}
*/
private Integer taskBufferSize = 4096;
@Deprecated
private String collectType;
/**
* Delay starting data acquisition task. unit: ms
* Latest use {@link MonitorProperties#getInitialDelay()}
*/
@Deprecated
private Long initialDelay = 10000L;
/**
* Time interval for client to collect monitoring data. unit: ms
* Latest use {@link MonitorProperties#getCollectInterval()}
*/
@Deprecated
private Long collectInterval = 5000L;
/**
* Latest use {@link MonitorProperties#getTaskBufferSize()}
*/
@Deprecated
private Integer taskBufferSize = 4096;
}

@ -0,0 +1,59 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package cn.hippo4j.springboot.starter.config;
import cn.hippo4j.monitor.base.MonitorThreadPoolTypeEnum;
import cn.hippo4j.monitor.base.MonitorTypeEnum;
import lombok.Data;
/**
* Thread pool monitoring properties.
*/
@Data
public class MonitorProperties {
/**
* Collect thread pool runtime indicators.
*/
private Boolean enable = Boolean.TRUE;
/**
* Type of collection thread pool running data. eg: log,micrometer. Multiple can be used at the same time, default micrometer.
*/
private String collectTypes = MonitorTypeEnum.SERVER.toString().toLowerCase();
/**
* Monitor the type of thread pool. eg: dynamic,web,adapter. Can be configured arbitrarily, default dynamic.
*/
private String threadPoolTypes = MonitorThreadPoolTypeEnum.DYNAMIC.toString().toLowerCase();
/**
* Delay starting data acquisition task. unit: ms
*/
private Long initialDelay = 10000L;
/**
* Collect interval. unit: ms
*/
private Long collectInterval = 5000L;
/**
* Task buffer container capacity
*/
private Integer taskBufferSize = 4096;
}

@ -154,6 +154,9 @@ public class ClientWorker {
}
public List<String> checkUpdateTpIds(String probeUpdateString, boolean isInitializingCacheList) {
if (StringUtils.isEmpty(probeUpdateString)) {
return Collections.emptyList();
}
Map<String, String> params = new HashMap(2);
params.put(PROBE_MODIFY_REQUEST, probeUpdateString);
params.put(WEIGHT_CONFIGS, IdUtil.simpleUUID());
@ -165,9 +168,6 @@ public class ClientWorker {
if (isInitializingCacheList) {
headers.put(LONG_PULLING_TIMEOUT_NO_HANGUP, "true");
}
if (StringUtils.isEmpty(probeUpdateString)) {
return Collections.emptyList();
}
try {
long readTimeoutMs = timeout + (long) Math.round(timeout >> 1);
Result result = agent.httpPostByConfig(LISTENER_PATH, headers, params, readTimeoutMs);

@ -18,17 +18,17 @@
package cn.hippo4j.springboot.starter.monitor;
import cn.hippo4j.common.config.ApplicationContextHolder;
import cn.hippo4j.common.design.builder.ThreadFactoryBuilder;
import cn.hippo4j.common.monitor.Message;
import cn.hippo4j.common.spi.DynamicThreadPoolServiceLoader;
import cn.hippo4j.common.toolkit.CollectionUtil;
import cn.hippo4j.common.toolkit.StringUtil;
import cn.hippo4j.common.toolkit.ThreadUtil;
import cn.hippo4j.core.executor.manage.GlobalThreadPoolManage;
import cn.hippo4j.common.design.builder.ThreadFactoryBuilder;
import cn.hippo4j.monitor.base.DynamicThreadPoolMonitor;
import cn.hippo4j.monitor.base.MonitorTypeEnum;
import cn.hippo4j.monitor.base.ThreadPoolMonitor;
import cn.hippo4j.springboot.starter.config.BootstrapProperties;
import cn.hippo4j.springboot.starter.config.MonitorProperties;
import cn.hippo4j.springboot.starter.monitor.collect.Collector;
import cn.hippo4j.springboot.starter.monitor.send.MessageSender;
import cn.hippo4j.springboot.starter.remote.ServerHealthCheck;
@ -39,7 +39,11 @@ import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.boot.CommandLineRunner;
import java.util.*;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ScheduledThreadPoolExecutor;
@ -102,24 +106,25 @@ public class ReportingEventExecutor implements Runnable, CommandLineRunner, Disp
@Override
public void run(String... args) {
if (!properties.getCollect()) {
MonitorProperties monitor = properties.getMonitor();
if (monitor == null
|| !monitor.getEnable()
|| StringUtil.isBlank(monitor.getThreadPoolTypes())
|| StringUtil.isBlank(monitor.getCollectTypes())) {
return;
}
threadPoolMonitors = new ArrayList<>();
String collectType = Optional.ofNullable(StringUtil.emptyToNull(properties.getCollectType())).orElse(MonitorTypeEnum.SERVER.name().toLowerCase());
String collectType = Optional.ofNullable(StringUtil.emptyToNull(monitor.getCollectTypes())).orElse(MonitorTypeEnum.SERVER.name().toLowerCase());
collectVesselExecutor = new ScheduledThreadPoolExecutor(
new Integer(collectType.split(",").length),
ThreadFactoryBuilder.builder().daemon(true).prefix("client.scheduled.collect.data").build());
Collection<DynamicThreadPoolMonitor> dynamicThreadPoolMonitors =
DynamicThreadPoolServiceLoader.getSingletonServiceInstances(DynamicThreadPoolMonitor.class);
boolean customerDynamicThreadPoolMonitorFlag = CollectionUtil.isNotEmpty(dynamicThreadPoolMonitors) || (collectType.contains(MonitorTypeEnum.MICROMETER.name().toLowerCase())
|| collectType.contains(MonitorTypeEnum.LOG.name().toLowerCase())
|| collectType.contains(MonitorTypeEnum.ELASTICSEARCH.name().toLowerCase()));
Collection<ThreadPoolMonitor> dynamicThreadPoolMonitors =
DynamicThreadPoolServiceLoader.getSingletonServiceInstances(ThreadPoolMonitor.class);
Map<String, ThreadPoolMonitor> threadPoolMonitorMap = ApplicationContextHolder.getBeansOfType(ThreadPoolMonitor.class);
boolean customerDynamicThreadPoolMonitorFlag = CollectionUtil.isNotEmpty(dynamicThreadPoolMonitors) || CollectionUtil.isNotEmpty(threadPoolMonitorMap);
if (customerDynamicThreadPoolMonitorFlag) {
// Get all dynamic thread pool monitoring components.
Map<String, ThreadPoolMonitor> threadPoolMonitorMap = ApplicationContextHolder.getBeansOfType(ThreadPoolMonitor.class);
threadPoolMonitorMap.forEach((beanName, monitor) -> threadPoolMonitors.add(monitor));
dynamicThreadPoolMonitors.stream().filter(each -> collectType.contains(each.getType())).forEach(each -> threadPoolMonitors.add(each));
threadPoolMonitorMap.forEach((beanName, bean) -> threadPoolMonitors.add(bean));
dynamicThreadPoolMonitors.forEach(each -> threadPoolMonitors.add(each));
collectVesselExecutor.scheduleWithFixedDelay(
() -> dynamicThreadPoolMonitor(),
properties.getInitialDelay(),

@ -35,7 +35,7 @@ import cn.hippo4j.core.executor.manage.GlobalNotifyAlarmManage;
import cn.hippo4j.core.executor.manage.GlobalThreadPoolManage;
import cn.hippo4j.core.executor.support.*;
import cn.hippo4j.core.executor.support.adpter.DynamicThreadPoolAdapterChoose;
import cn.hippo4j.core.toolkit.inet.DynamicThreadPoolAnnotationUtil;
import cn.hippo4j.core.toolkit.DynamicThreadPoolAnnotationUtil;
import cn.hippo4j.message.service.ThreadPoolNotifyAlarm;
import cn.hippo4j.springboot.starter.config.BootstrapProperties;
import cn.hippo4j.springboot.starter.core.DynamicThreadPoolSubscribeConfig;
@ -45,14 +45,12 @@ import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.core.task.TaskDecorator;
import org.springframework.util.ClassUtils;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

Loading…
Cancel
Save