Merge branch 'opengoofy:develop' into develop

pull/883/head
黄成兴 3 years ago committed by GitHub
commit ea729ad2cf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

2
.gitignore vendored

@ -39,4 +39,4 @@ build/
### Docs ###
docs/node_modules
docs/build
docs/.docusaurus
docs/.docusaurus

@ -0,0 +1,56 @@
<img align="center" width="400" alt="image" src="https://user-images.githubusercontent.com/77398366/181906454-b46f6a14-7c2c-4b8f-8b0a-40432521bed8.png">
# Dynamic and observable thread pool framework
[![Gitee](https://gitee.com/itmachen/hippo4j/badge/star.svg?theme=gvp)](https://gitee.com/itmachen/hippo4j) [![GitHub](https://img.shields.io/github/stars/opengoofy/hippo4j)](https://github.com/opengoofy/hippo4j) [![Docker Pulls](https://img.shields.io/docker/pulls/hippo4j/hippo4j-server.svg)](https://store.docker.com/community/images/hippo4j/hippo4j-server) [![Contributors](https://img.shields.io/github/contributors/opengoofy/hippo4j?color=3ba272)](https://github.com/opengoofy/hippo4j/graphs/contributors) [![License](https://img.shields.io/github/license/opengoofy/hippo4j?color=5470c6)](https://github.com/opengoofy/hippo4j/blob/develop/LICENSE)
-------
## Thread pool pain points
A thread pool is a tool for managing threads based on the idea of pooling.
Using a thread pool reduces the overhead of creating and destroying threads and avoids running out of system resources due to too many threads.
The use of thread pools is essential in highly concurrent and high-volume task processing scenarios.
If you have actually used thread pools in your projects, I believe you may have encountered the following pain points:
- Thread pools are defined randomly, with too many thread resources, causing high server load.
- The thread pool parameters are not easily evaluated and the business is at risk of failure.
- Thread pool task execution time exceeds the average execution cycle and developers are not informed.
- Thread pool tasks pile up and affect business operations.
- Wireless process pool monitoring when the service has timeouts, meltdowns, and other problems.
- Thread pools do not support the passing of runtime variables, such as MDC contexts.
- When a project is closed, a large number of running thread pool tasks are discarded.
- Thread pool running, task execution stopped, don't know the problem.
## What is Hippo-4J
Hippo-4J through the JDK thread pool enhancements, as well as extending the three-party framework underlying thread pools and other features for business systems to improve online operational security capabilities.
The following functional support is provided:
- Global Control - Managing Application Thread Pool Instances.
- Dynamic changes - dynamically changing thread pool parameters at application runtime.
- Notify alarms - Four built-in alarm notification policies.
- Run Monitoring - Real-time view of thread pool runtime data.
- Feature extensions - support for thread pooling task passing contexts, etc.
- Multiple Modes - Two built-in usage modes: Configuration Center Mode and No Middleware Mode.
- Container Management - Tomcat, Jetty, Undertow container thread pool runtime view and thread count changes.
- Framework adaptation - Dubbo, Hystrix, Polaris, RabbitMQ, RocketMQ and other consumer thread pool runtime data view and thread count changes.
## Quick Start
For local presentation purposes, see [Quick start](https://hippo4j.cn/docs/user_docs/user_guide/quick-start).
Demo Environment: [http://console.hippo4j.cn/index.html](http://console.hippo4j.cn/index.html).
## Who is using
More companies with access are welcome to register at [registration address](https://github.com/opengoofy/hippo4j/issues/13), registration is only for product promotion.
## Contributors
Thanks to all the developers who contributed to the project. If interested in contributing, refer to [good first issue](https://github.com/opengoofy/hippo4j/issues?q=is%3Aopen+is%3Aissue+label%3A%22good+first+issue%22).

@ -1,5 +1,7 @@
<img align="center" width="400" alt="image" src="https://user-images.githubusercontent.com/77398366/181906454-b46f6a14-7c2c-4b8f-8b0a-40432521bed8.png">
中文 | [English](https://github.com/opengoofy/hippo4j/blob/develop/README-EN.md)
# 动态可观测线程池框架,提高线上运行保障能力
[![Gitee](https://gitee.com/itmachen/hippo4j/badge/star.svg?theme=gvp)](https://gitee.com/itmachen/hippo4j) [![GitHub](https://img.shields.io/github/stars/opengoofy/hippo4j)](https://github.com/opengoofy/hippo4j) [![Docker Pulls](https://img.shields.io/docker/pulls/hippo4j/hippo4j-server.svg)](https://store.docker.com/community/images/hippo4j/hippo4j-server) [![Contributors](https://img.shields.io/github/contributors/opengoofy/hippo4j?color=3ba272)](https://github.com/opengoofy/hippo4j/graphs/contributors) [![License](https://img.shields.io/github/license/opengoofy/hippo4j?color=5470c6)](https://github.com/opengoofy/hippo4j/blob/develop/LICENSE)
@ -36,7 +38,7 @@ Hippo-4J 通过对 JDK 线程池增强,以及扩展三方框架底层线程池
- 功能扩展 - 支持线程池任务传递上下文;项目关闭时,支持等待线程池在指定时间内完成任务。
- 多种模式 - 内置两种使用模式:[依赖配置中心](https://hippo4j.cn/docs/user_docs/getting_started/config/hippo4j-config-start) 和 [无中间件依赖](https://hippo4j.cn/docs/user_docs/getting_started/server/hippo4j-server-start)。
- 容器管理 - Tomcat、Jetty、Undertow 容器线程池运行时查看和线程数变更。
- 中间件适配 - Dubbo、Hystrix、Polaris、RabbitMQ、RocketMQ 等消费线程池运行时数据查看和线程数变更。
- 框架适配 - Dubbo、Hystrix、RabbitMQ、RocketMQ 等消费线程池运行时数据查看和线程数变更。
## 快速开始

@ -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 端失败时,会使用填充配置创建线程池。
:::

@ -21,7 +21,7 @@ docker run -d -p 6691:6691 --name hippo4j-server \
-e DATASOURCE_DB=hippo4j_manager \
-e DATASOURCE_USERNAME=root \
-e DATASOURCE_PASSWORD=root \
hippo4j/hippo4j-server
hippo4j/hippo4j-server
```
访问 Server 控制台,路径 `http://localhost:6691/index.html` 默认用户名密码admin / 123456
@ -33,10 +33,10 @@ hippo4j/hippo4j-server
方式一:
```shell
# 进入到 hippo4j-server 工程路径下
# 进入到 hippo4j-server/hippo4j-bootstrap 工程路径下
mvn clean package -Dskip.spotless.apply=true
# 默认打包是打包的 tag 是 latest
docker build -t hippo4j/hippo4j-server ../hippo4j-server
docker build -t hippo4j/hippo4j-server ../hippo4j-bootstrap
```
方式二:

@ -12,7 +12,7 @@ sidebar_position: 3
docker run -d -p 6691:6691 --name hippo4j-server hippo4j/hippo4j-server
```
> 如果没有 Docker可以使用源码编译的方式启动 [Hippo4J-Server](https://github.com/longtai-cn/hippo4j/tree/develop/hippo4j-server) 模块下 ServerApplication 应用类。
> 如果没有 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 应用类。

@ -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,87 +22,202 @@ package cn.hippo4j.common.constant;
*
* @author Rongzhen Yan
*/
public interface HttpResponseCode {
int SC_CONTINUE = 100;
int SC_SWITCHING_PROTOCOLS = 101;
int SC_OK = 200;
int SC_CREATED = 201;
int SC_ACCEPTED = 202;
int SC_NON_AUTHORITATIVE_INFORMATION = 203;
int SC_NO_CONTENT = 204;
int SC_RESET_CONTENT = 205;
int SC_PARTIAL_CONTENT = 206;
int SC_MULTIPLE_CHOICES = 300;
int SC_MOVED_PERMANENTLY = 301;
int SC_MOVED_TEMPORARILY = 302;
int SC_FOUND = 302;
int SC_SEE_OTHER = 303;
int SC_NOT_MODIFIED = 304;
int SC_USE_PROXY = 305;
int SC_TEMPORARY_REDIRECT = 307;
int SC_BAD_REQUEST = 400;
int SC_UNAUTHORIZED = 401;
int SC_PAYMENT_REQUIRED = 402;
int SC_FORBIDDEN = 403;
int SC_NOT_FOUND = 404;
int SC_METHOD_NOT_ALLOWED = 405;
int SC_NOT_ACCEPTABLE = 406;
int SC_PROXY_AUTHENTICATION_REQUIRED = 407;
int SC_REQUEST_TIMEOUT = 408;
int SC_CONFLICT = 409;
int SC_GONE = 410;
int SC_LENGTH_REQUIRED = 411;
int SC_PRECONDITION_FAILED = 412;
int SC_REQUEST_ENTITY_TOO_LARGE = 413;
int SC_REQUEST_URI_TOO_LONG = 414;
int SC_UNSUPPORTED_MEDIA_TYPE = 415;
int SC_REQUESTED_RANGE_NOT_SATISFIABLE = 416;
int SC_EXPECTATION_FAILED = 417;
int SC_INTERNAL_SERVER_ERROR = 500;
int SC_NOT_IMPLEMENTED = 501;
int SC_BAD_GATEWAY = 502;
int SC_SERVICE_UNAVAILABLE = 503;
int SC_GATEWAY_TIMEOUT = 504;
int SC_HTTP_VERSION_NOT_SUPPORTED = 505;
public class HttpResponseCode {
/* 2XX: generally "OK" */
/**
* HTTP Status-Code 200: OK.
*/
public static final int SC_OK = 200;
/**
* HTTP Status-Code 201: Created.
*/
public static final int SC_HTTP_CREATED = 201;
/**
* HTTP Status-Code 202: Accepted.
*/
public static final int SC_HTTP_ACCEPTED = 202;
/**
* HTTP Status-Code 203: Non-Authoritative Information.
*/
public static final int SC_HTTP_NOT_AUTHORITATIVE = 203;
/**
* HTTP Status-Code 204: No Content.
*/
public static final int SC_HTTP_NO_CONTENT = 204;
/**
* HTTP Status-Code 205: Reset Content.
*/
public static final int SC_HTTP_RESET = 205;
/**
* HTTP Status-Code 206: Partial Content.
*/
public static final int SC_HTTP_PARTIAL = 206;
/* 3XX: relocation/redirect */
/**
* HTTP Status-Code 300: Multiple Choices.
*/
public static final int SC_HTTP_MULT_CHOICE = 300;
/**
* HTTP Status-Code 301: Moved Permanently.
*/
public static final int SC_HTTP_MOVED_PERM = 301;
/**
* HTTP Status-Code 302: Temporary Redirect.
*/
public static final int SC_HTTP_MOVED_TEMP = 302;
/**
* HTTP Status-Code 303: See Other.
*/
public static final int SC_HTTP_SEE_OTHER = 303;
/**
* HTTP Status-Code 304: Not Modified.
*/
public static final int SC_HTTP_NOT_MODIFIED = 304;
/**
* HTTP Status-Code 305: Use Proxy.
*/
public static final int SC_HTTP_USE_PROXY = 305;
/**
* HTTP 1.1 Status-Code 307: Temporary Redirect.
*/
public static final int SC_HTTP_TEMP_REDIRECT = 307;
/**
* HTTP 1.1 Status-Code 308: Permanent Redirect
*/
public static final int SC_HTTP_PERMANENT_REDIRECT = 308;
/* 4XX: client error */
/**
* HTTP Status-Code 400: Bad Request.
*/
public static final int SC_HTTP_BAD_REQUEST = 400;
/**
* HTTP Status-Code 401: Unauthorized.
*/
public static final int SC_HTTP_UNAUTHORIZED = 401;
/**
* HTTP Status-Code 402: Payment Required.
*/
public static final int SC_HTTP_PAYMENT_REQUIRED = 402;
/**
* HTTP Status-Code 403: Forbidden.
*/
public static final int SC_HTTP_FORBIDDEN = 403;
/**
* HTTP Status-Code 404: Not Found.
*/
public static final int SC_HTTP_NOT_FOUND = 404;
/**
* HTTP Status-Code 405: Method Not Allowed.
*/
public static final int SC_HTTP_BAD_METHOD = 405;
/**
* HTTP Status-Code 406: Not Acceptable.
*/
public static final int SC_HTTP_NOT_ACCEPTABLE = 406;
/**
* HTTP Status-Code 407: Proxy Authentication Required.
*/
public static final int SC_HTTP_PROXY_AUTH = 407;
/**
* HTTP Status-Code 408: Request Time-Out.
*/
public static final int SC_HTTP_CLIENT_TIMEOUT = 408;
/**
* HTTP Status-Code 409: Conflict.
*/
public static final int SC_HTTP_CONFLICT = 409;
/**
* HTTP Status-Code 410: Gone.
*/
public static final int SC_HTTP_GONE = 410;
/**
* HTTP Status-Code 411: Length Required.
*/
public static final int SC_HTTP_LENGTH_REQUIRED = 411;
/**
* HTTP Status-Code 412: Precondition Failed.
*/
public static final int SC_HTTP_PRECON_FAILED = 412;
/**
* HTTP Status-Code 413: Request Entity Too Large.
*/
public static final int SC_HTTP_ENTITY_TOO_LARGE = 413;
/**
* HTTP Status-Code 414: Request-URI Too Large.
*/
public static final int SC_HTTP_REQ_TOO_LONG = 414;
/**
* HTTP Status-Code 415: Unsupported Media Type.
*/
public static final int SC_HTTP_UNSUPPORTED_TYPE = 415;
/* 5XX: server error */
/**
* HTTP Status-Code 500: Internal Server Error.
*/
public static final int SC_HTTP_INTERNAL_ERROR = 500;
/**
* HTTP Status-Code 501: Not Implemented.
*/
public static final int SC_HTTP_NOT_IMPLEMENTED = 501;
/**
* HTTP Status-Code 502: Bad Gateway.
*/
public static final int SC_HTTP_BAD_GATEWAY = 502;
/**
* HTTP Status-Code 503: Service Unavailable.
*/
public static final int SC_HTTP_UNAVAILABLE = 503;
/**
* HTTP Status-Code 504: Gateway Timeout.
*/
public static final int SC_HTTP_GATEWAY_TIMEOUT = 504;
/**
* HTTP Status-Code 505: HTTP Version Not Supported.
*/
public static final int SC_HTTP_VERSION = 505;
public static boolean isOk(int code) {
return (code >= SC_OK && code < SC_HTTP_MULT_CHOICE) || code == SC_HTTP_NOT_MODIFIED;
}
}

@ -17,30 +17,39 @@
package cn.hippo4j.common.enums;
/**
* Enumeration of thread pool audit status.
*/
public enum VerifyEnum {
/**
* unVerify
* To verify
*/
TO_VERIFY(0, "待审核"),
/**
* accept
* Verify accept
*/
VERIFY_ACCEPT(1, "审核通过"),
/**
* reject
* Verify reject
*/
VERIFY_REJECT(2, "审核拒绝"),
/**
* invalid
* Verify invalid
*/
VERIFY_INVALID(3, "失效");
/**
* Verify status
*/
private final Integer verifyStatus;
/**
* Desc
*/
private final String desc;
VerifyEnum(Integer verifyStatus, String desc) {

@ -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
*/

@ -319,7 +319,7 @@ public class HttpUtil {
}
connection.connect();
JdkHttpClientResponse response = new JdkHttpClientResponse(connection);
if (HttpResponseCode.SC_OK != response.getStatusCode()) {
if (!HttpResponseCode.isOk(response.getStatusCode())) {
String msg = String.format("HttpPost response code error. [code] %s [url] %s [body] %s", response.getStatusCode(), connection.getURL(), response.getBodyString());
throw new ServiceException(msg);
}

@ -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

@ -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;
}
}
}

File diff suppressed because one or more lines are too long

@ -1 +0,0 @@
.editor-container[data-v-7505e034]{height:82vh;overflow:auto}

File diff suppressed because one or more lines are too long

@ -1,893 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="216"
height="144"
id="svg4136"
version="1.1"
inkscape:version="0.91 r"
sodipodi:docname="jsoneditor-icons.svg">
<title
id="title6512">JSON Editor Icons</title>
<metadata
id="metadata4148">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title>JSON Editor Icons</dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<defs
id="defs4146" />
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1920"
inkscape:window-height="1028"
id="namedview4144"
showgrid="true"
inkscape:zoom="4"
inkscape:cx="97.217248"
inkscape:cy="59.950227"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="svg4136"
showguides="false"
borderlayer="false"
inkscape:showpageshadow="true"
showborder="true">
<inkscape:grid
type="xygrid"
id="grid4640"
empspacing="24" />
</sodipodi:namedview>
<!-- Created with SVG-edit - http://svg-edit.googlecode.com/ -->
<g
id="g4394">
<rect
x="4"
y="4"
width="16"
height="16"
id="svg_1"
style="fill:#1aae1c;fill-opacity:1;stroke:none;stroke-width:0" />
<rect
style="fill:#ec3f29;fill-opacity:0.94117647;stroke:none;stroke-width:0"
x="28.000006"
y="3.999995"
width="16"
height="16"
id="svg_1-7" />
<rect
id="rect4165"
height="16"
width="16"
y="3.999995"
x="52.000004"
style="fill:#4c4c4c;fill-opacity:1;stroke:none;stroke-width:0" />
<rect
style="fill:#4c4c4c;fill-opacity:1;stroke:none;stroke-width:0"
x="172.00002"
y="3.9999852"
width="16"
height="16"
id="rect4175" />
<rect
style="fill:#4c4c4c;fill-opacity:1;stroke:none;stroke-width:0"
x="196"
y="3.999995"
width="16"
height="16"
id="rect4175-3" />
<g
style="stroke:none"
id="g4299">
<rect
style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0"
id="svg_1-1"
height="1.9999986"
width="9.9999924"
y="10.999998"
x="7.0000048" />
<rect
style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0"
id="svg_1-1-1"
height="9.9999838"
width="1.9999955"
y="7.0000114"
x="11.000005" />
</g>
<g
style="stroke:none"
transform="matrix(0.70710678,-0.70710678,0.70710678,0.70710678,19.029435,12.000001)"
id="g4299-3">
<rect
style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0"
id="svg_1-1-0"
height="1.9999986"
width="9.9999924"
y="10.999998"
x="7.0000048" />
<rect
style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0"
id="svg_1-1-1-9"
height="9.9999838"
width="1.9999955"
y="7.0000114"
x="11.000005" />
</g>
<rect
style="fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:0"
x="55.000004"
y="7.0000048"
width="6.9999909"
height="6.9999905"
id="svg_1-7-5" />
<rect
id="rect4354"
height="6.9999905"
width="6.9999909"
y="10.00001"
x="58"
style="fill:#ffffff;fill-opacity:1;stroke:#4c4c4c;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<rect
style="fill:#ffffff;fill-opacity:1;stroke:#3c80df;stroke-width:0;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.94117647"
x="58.000004"
y="10.000005"
width="6.9999909"
height="6.9999905"
id="svg_1-7-5-7" />
<g
id="g4378">
<rect
id="svg_1-7-5-3"
height="1.9999965"
width="7.9999909"
y="10.999999"
x="198"
style="fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:0" />
<rect
style="fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:0"
x="198"
y="7.0000005"
width="11.999995"
height="1.9999946"
id="rect4374" />
<rect
style="fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:0"
x="198"
y="14.999996"
width="3.9999928"
height="1.9999995"
id="rect4376" />
</g>
<g
id="g4383"
transform="matrix(1,0,0,-1,-23.999995,23.999995)">
<rect
style="fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:0"
x="198"
y="10.999999"
width="7.9999909"
height="1.9999965"
id="rect4385" />
<rect
id="rect4387"
height="1.9999946"
width="11.999995"
y="7.0000005"
x="198"
style="fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:0" />
<rect
id="rect4389"
height="1.9999995"
width="3.9999928"
y="14.999996"
x="198"
style="fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:0" />
</g>
<rect
y="3.9999199"
x="76"
height="16"
width="16"
id="rect3754-4"
style="fill:#4c4c4c;fill-opacity:1;stroke:none" />
<path
sodipodi:nodetypes="cccccccc"
inkscape:connector-curvature="0"
id="path4351"
d="m 85.10447,6.0157384 -0.0156,1.4063 c 3.02669,-0.2402 0.33008,3.6507996 2.48438,4.5780996 -2.18694,1.0938 0.49191,4.9069 -2.45313,4.5781 l -0.0156,1.4219 c 5.70828,0.559 1.03264,-5.1005 4.70313,-5.2656 l 0,-1.4063 c -3.61303,-0.027 1.11893,-5.7069996 -4.70313,-5.3124996 z"
style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:0.2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
sodipodi:nodetypes="cccccccc"
inkscape:connector-curvature="0"
id="path4351-9"
d="m 82.78125,5.9984384 0.0156,1.4063 c -3.02668,-0.2402 -0.33007,3.6506996 -2.48437,4.5780996 2.18694,1.0938 -0.49192,4.9069 2.45312,4.5781 l 0.0156,1.4219 c -5.70827,0.559 -1.03263,-5.1004 -4.70312,-5.2656 l 0,-1.4063 c 3.61303,-0.027 -1.11894,-5.7070996 4.70312,-5.3124996 z"
style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:0.2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<rect
y="3.9999199"
x="100"
height="16"
width="16"
id="rect3754-25"
style="fill:#4c4c4c;fill-opacity:1;stroke:none" />
<path
inkscape:connector-curvature="0"
id="path2987"
d="m 103.719,5.6719384 0,12.7187996 3.03125,0 0,-1.5313 -1.34375,0 0,-9.6249996 1.375,0 0,-1.5625 z"
style="fill:#ffffff;fill-opacity:1;stroke:none" />
<path
inkscape:connector-curvature="0"
id="path2987-1"
d="m 112.2185,5.6721984 0,12.7187996 -3.03125,0 0,-1.5313 1.34375,0 0,-9.6249996 -1.375,0 0,-1.5625 z"
style="fill:#ffffff;fill-opacity:1;stroke:none" />
<rect
y="3.9999199"
x="124"
height="16"
width="16"
id="rect3754-73"
style="fill:#4c4c4c;fill-opacity:1;stroke:none" />
<path
sodipodi:nodetypes="ccccccccc"
inkscape:connector-curvature="0"
id="path3780"
d="m 126.2824,17.602938 1.78957,0 1.14143,-2.8641 5.65364,0 1.14856,2.8641 1.76565,0 -4.78687,-11.1610996 -1.91903,0 z"
style="fill:#ffffff;fill-opacity:1;stroke:none" />
<path
inkscape:connector-curvature="0"
id="path3782"
d="m 129.72704,13.478838 4.60852,0.01 -2.30426,-5.5497996 z"
style="fill:#4c4c4c;fill-opacity:1;stroke:none" />
<rect
y="3.9999199"
x="148"
height="16"
width="16"
id="rect3754-35"
style="fill:#4c4c4c;fill-opacity:1;stroke:none" />
<path
sodipodi:nodetypes="ccccccc"
inkscape:connector-curvature="0"
id="path5008-2"
d="m 156.47655,5.8917384 0,2.1797 0.46093,2.3983996 1.82813,0 0.39844,-2.3983996 0,-2.1797 z"
style="fill:#ffffff;fill-opacity:1;stroke:none" />
<path
sodipodi:nodetypes="ccccccc"
inkscape:connector-curvature="0"
id="path5008-2-8"
d="m 152.51561,5.8906384 0,2.1797 0.46094,2.3983996 1.82812,0 0.39844,-2.3983996 0,-2.1797 z"
style="fill:#ffffff;fill-opacity:1;stroke:none" />
</g>
<rect
x="4"
y="27.999994"
width="16"
height="16"
id="rect4432"
style="fill:#d3d3d3;fill-opacity:1;stroke:none;stroke-width:0" />
<rect
style="fill:#d3d3d3;fill-opacity:1;stroke:none;stroke-width:0"
x="28.000006"
y="27.99999"
width="16"
height="16"
id="rect4434" />
<rect
id="rect4436"
height="16"
width="16"
y="27.99999"
x="52.000004"
style="fill:#d3d3d3;fill-opacity:1;stroke:#000000;stroke-width:0" />
<rect
style="fill:#d3d3d3;stroke:#000000;stroke-width:0"
x="172.00002"
y="27.999981"
width="16"
height="16"
id="rect4446" />
<rect
style="fill:#d3d3d3;stroke:#000000;stroke-width:0"
x="196"
y="27.99999"
width="16"
height="16"
id="rect4448" />
<g
id="g4466"
style="stroke:none"
transform="translate(0,23.999995)">
<rect
style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0"
id="rect4468"
height="1.9999986"
width="9.9999924"
y="10.999998"
x="7.0000048" />
<rect
style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0"
id="rect4470"
height="9.9999838"
width="1.9999955"
y="7.0000114"
x="11.000005" />
</g>
<g
transform="matrix(0.70710678,-0.70710678,0.70710678,0.70710678,19.029435,35.999996)"
id="g4472"
style="stroke:none">
<rect
style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0"
id="rect4474"
height="1.9999986"
width="9.9999924"
y="10.999998"
x="7.0000048" />
<rect
style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0"
id="rect4476"
height="9.9999838"
width="1.9999955"
y="7.0000114"
x="11.000005" />
</g>
<rect
style="fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:0"
x="55.000004"
y="31"
width="6.9999909"
height="6.9999905"
id="rect4478" />
<rect
id="rect4480"
height="6.9999905"
width="6.9999909"
y="34.000008"
x="58"
style="fill:#ffffff;fill-opacity:1;stroke:#d3d3d3;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none" />
<rect
style="fill:#ffffff;fill-opacity:1;stroke:#d3d3d3;stroke-width:0;stroke-miterlimit:4;stroke-dasharray:none"
x="58.000004"
y="34.000004"
width="6.9999909"
height="6.9999905"
id="rect4482" />
<g
id="g4484"
transform="translate(0,23.999995)">
<rect
id="rect4486"
height="1.9999965"
width="7.9999909"
y="10.999999"
x="198"
style="fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:0" />
<rect
style="fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:0"
x="198"
y="7.0000005"
width="11.999995"
height="1.9999946"
id="rect4488" />
<rect
style="fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:0"
x="198"
y="14.999996"
width="3.9999928"
height="1.9999995"
id="rect4490" />
</g>
<g
id="g4492"
transform="matrix(1,0,0,-1,-23.999995,47.99999)">
<rect
style="fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:0"
x="198"
y="10.999999"
width="7.9999909"
height="1.9999965"
id="rect4494" />
<rect
id="rect4496"
height="1.9999946"
width="11.999995"
y="7.0000005"
x="198"
style="fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:0" />
<rect
id="rect4498"
height="1.9999995"
width="3.9999928"
y="14.999996"
x="198"
style="fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:0" />
</g>
<rect
style="fill:#d3d3d3;fill-opacity:1;stroke:none"
id="rect3754-8"
width="16"
height="16"
x="76"
y="27.99992" />
<path
style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:0.2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 85.10448,30.015537 -0.0156,1.4063 c 3.02668,-0.2402 0.33007,3.6508 2.48438,4.5781 -2.18695,1.0938 0.49191,4.90688 -2.45313,4.57808 l -0.0156,1.4219 c 5.70827,0.559 1.03263,-5.10048 4.70313,-5.26558 l 0,-1.4063 c -3.61304,-0.027 1.11893,-5.707 -4.70313,-5.3125 z"
id="path4351-1"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccccccc" />
<path
style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:0.2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 82.78126,29.998237 0.0156,1.4063 c -3.02668,-0.2402 -0.33008,3.6507 -2.48438,4.5781 2.18694,1.0938 -0.49191,4.90688 2.45313,4.57808 l 0.0156,1.4219 c -5.70828,0.559 -1.03264,-5.10038 -4.70313,-5.26558 l 0,-1.4063 c 3.61303,-0.027 -1.11893,-5.7071 4.70313,-5.3125 z"
id="path4351-9-5"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccccccc" />
<rect
style="fill:#d3d3d3;fill-opacity:1;stroke:none"
id="rect3754-65"
width="16"
height="16"
x="100"
y="27.99992" />
<path
style="fill:#ffffff;fill-opacity:1;stroke:none"
d="m 103.719,29.671937 0,12.71878 3.03125,0 0,-1.5313 -1.34375,0 0,-9.62498 1.375,0 0,-1.5625 z"
id="path2987-8"
inkscape:connector-curvature="0" />
<path
style="fill:#ffffff;fill-opacity:1;stroke:none"
d="m 112.2185,29.671937 0,12.71878 -3.03125,0 0,-1.5313 1.34375,0 0,-9.62498 -1.375,0 0,-1.5625 z"
id="path2987-1-9"
inkscape:connector-curvature="0" />
<rect
style="fill:#d3d3d3;fill-opacity:1;stroke:none"
id="rect3754-92"
width="16"
height="16"
x="124"
y="27.99992" />
<path
style="fill:#ffffff;fill-opacity:1;stroke:none"
d="m 126.2824,41.602917 1.78957,0 1.14143,-2.86408 5.65364,0 1.14856,2.86408 1.76565,0 -4.78687,-11.16108 -1.91902,0 z"
id="path3780-9"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccccccccc" />
<path
style="fill:#d3d3d3;fill-opacity:1;stroke:none"
d="m 129.72704,37.478837 4.60852,0.01 -2.30426,-5.5498 z"
id="path3782-2"
inkscape:connector-curvature="0" />
<rect
style="fill:#d3d3d3;fill-opacity:1;stroke:none"
id="rect3754-47"
width="16"
height="16"
x="148"
y="27.99992" />
<path
style="fill:#ffffff;fill-opacity:1;stroke:none"
d="m 156.47656,29.891737 0,2.1797 0.46093,2.3984 1.82813,0 0.39844,-2.3984 0,-2.1797 z"
id="path5008-2-1"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccccccc" />
<path
style="fill:#ffffff;fill-opacity:1;stroke:none"
d="m 152.51562,29.890637 0,2.1797 0.46094,2.3984 1.82812,0 0.39844,-2.3984 0,-2.1797 z"
id="path5008-2-8-8"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccccccc" />
<rect
id="svg_1-7-2"
height="1.9999961"
width="11.999996"
y="64"
x="54"
style="fill:#4c4c4c;fill-opacity:0.98431373;stroke:none;stroke-width:0" />
<rect
id="svg_1-7-2-2"
height="2.9999905"
width="2.9999907"
y="52"
x="80.000008"
style="fill:#4c4c4c;fill-opacity:0.98431373;stroke:none;stroke-width:0" />
<rect
style="fill:#4c4c4c;fill-opacity:0.98431373;stroke:none;stroke-width:0"
x="85.000008"
y="52"
width="2.9999907"
height="2.9999905"
id="rect4561" />
<rect
style="fill:#4c4c4c;fill-opacity:0.98431373;stroke:none;stroke-width:0"
x="80.000008"
y="58"
width="2.9999907"
height="2.9999905"
id="rect4563" />
<rect
id="rect4565"
height="2.9999905"
width="2.9999907"
y="58"
x="85.000008"
style="fill:#4c4c4c;fill-opacity:0.98431373;stroke:none;stroke-width:0" />
<rect
id="rect4567"
height="2.9999905"
width="2.9999907"
y="64"
x="80.000008"
style="fill:#4c4c4c;fill-opacity:0.98431373;stroke:none;stroke-width:0" />
<rect
style="fill:#4c4c4c;fill-opacity:0.98431373;stroke:none;stroke-width:0"
x="85.000008"
y="64"
width="2.9999907"
height="2.9999905"
id="rect4569" />
<circle
style="opacity:1;fill:none;fill-opacity:1;stroke:#4c4c4c;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none"
id="path4571"
cx="110.06081"
cy="57.939209"
r="4.7438836" />
<rect
style="fill:#4c4c4c;fill-opacity:0.98431373;stroke:none;stroke-width:0"
x="116.64566"
y="-31.79752"
width="4.229713"
height="6.4053884"
id="rect4563-2"
transform="matrix(0.70710678,0.70710678,-0.70710678,0.70710678,0,0)" />
<path
style="fill:#4c4c4c;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M 125,56 138.77027,56.095 132,64 Z"
id="path4613"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccc" />
<path
sodipodi:nodetypes="cccc"
inkscape:connector-curvature="0"
id="path4615"
d="M 149,64 162.77027,63.905 156,56 Z"
style="fill:#4c4c4c;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<rect
style="fill:#4c4c4c;fill-opacity:0.98431373;stroke:none;stroke-width:0"
x="54"
y="53"
width="11.999996"
height="1.9999961"
id="rect4638" />
<rect
id="svg_1-7-2-24"
height="1.9999957"
width="12.99999"
y="-56"
x="53"
style="fill:#4c4c4c;fill-opacity:0.98431373;stroke:none;stroke-width:0"
transform="matrix(0,1,-1,0,0,0)" />
<rect
transform="matrix(0,1,-1,0,0,0)"
style="fill:#4c4c4c;fill-opacity:0.98431373;stroke:none;stroke-width:0"
x="53"
y="-66"
width="12.99999"
height="1.9999957"
id="rect4657" />
<rect
id="rect4659"
height="0.99999291"
width="11.999999"
y="57"
x="54"
style="fill:#4c4c4c;fill-opacity:0.98431373;stroke:none;stroke-width:0" />
<rect
style="fill:#d3d3d3;fill-opacity:1;stroke:none;stroke-width:0;stroke-opacity:1"
x="54"
y="88.000122"
width="11.999996"
height="1.9999961"
id="rect4661" />
<rect
style="fill:#d3d3d3;fill-opacity:1;stroke:none;stroke-width:0;stroke-opacity:1"
x="80.000008"
y="76.000122"
width="2.9999907"
height="2.9999905"
id="rect4663" />
<rect
id="rect4665"
height="2.9999905"
width="2.9999907"
y="76.000122"
x="85.000008"
style="fill:#d3d3d3;fill-opacity:1;stroke:none;stroke-width:0;stroke-opacity:1" />
<rect
id="rect4667"
height="2.9999905"
width="2.9999907"
y="82.000122"
x="80.000008"
style="fill:#d3d3d3;fill-opacity:1;stroke:none;stroke-width:0;stroke-opacity:1" />
<rect
style="fill:#d3d3d3;fill-opacity:1;stroke:none;stroke-width:0;stroke-opacity:1"
x="85.000008"
y="82.000122"
width="2.9999907"
height="2.9999905"
id="rect4669" />
<rect
style="fill:#d3d3d3;fill-opacity:1;stroke:none;stroke-width:0;stroke-opacity:1"
x="80.000008"
y="88.000122"
width="2.9999907"
height="2.9999905"
id="rect4671" />
<rect
id="rect4673"
height="2.9999905"
width="2.9999907"
y="88.000122"
x="85.000008"
style="fill:#d3d3d3;fill-opacity:1;stroke:none;stroke-width:0;stroke-opacity:1" />
<circle
r="4.7438836"
cy="81.939331"
cx="110.06081"
id="circle4675"
style="opacity:1;fill:none;fill-opacity:1;stroke:#d3d3d3;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<rect
transform="matrix(0.70710678,0.70710678,-0.70710678,0.70710678,0,0)"
id="rect4677"
height="6.4053884"
width="4.229713"
y="-14.826816"
x="133.6163"
style="fill:#d3d3d3;fill-opacity:1;stroke:#d3d3d3;stroke-width:0;stroke-opacity:1" />
<path
sodipodi:nodetypes="cccc"
inkscape:connector-curvature="0"
id="path4679"
d="m 125,80.000005 13.77027,0.09499 L 132,87.999992 Z"
style="fill:#d3d3d3;fill-opacity:1;fill-rule:evenodd;stroke:#d3d3d3;stroke-width:0;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
style="fill:#d3d3d3;fill-opacity:1;fill-rule:evenodd;stroke:#d3d3d3;stroke-width:0;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M 149,88.0002 162.77027,87.9052 156,80.0002 Z"
id="path4681"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccc" />
<rect
id="rect4683"
height="1.9999961"
width="11.999996"
y="77.000122"
x="54"
style="fill:#d3d3d3;fill-opacity:1;stroke:none;stroke-width:0;stroke-opacity:1" />
<rect
transform="matrix(0,1,-1,0,0,0)"
style="fill:#d3d3d3;fill-opacity:1;stroke:none;stroke-width:0;stroke-opacity:1"
x="77.000122"
y="-56"
width="12.99999"
height="1.9999957"
id="rect4685" />
<rect
id="rect4687"
height="1.9999957"
width="12.99999"
y="-66"
x="77.000122"
style="fill:#d3d3d3;fill-opacity:1;stroke:none;stroke-width:0;stroke-opacity:1"
transform="matrix(0,1,-1,0,0,0)" />
<rect
style="fill:#d3d3d3;fill-opacity:1;stroke:none;stroke-width:0;stroke-opacity:1"
x="54"
y="81.000122"
width="11.999999"
height="0.99999291"
id="rect4689" />
<rect
id="rect4761-1"
height="1.9999945"
width="15.99999"
y="101"
x="76.000008"
style="fill:#ffffff;fill-opacity:0.80000007;stroke:none;stroke-width:0" />
<rect
id="rect4761-0"
height="1.9999945"
width="15.99999"
y="105"
x="76.000008"
style="fill:#ffffff;fill-opacity:0.80000007;stroke:none;stroke-width:0" />
<rect
id="rect4761-7"
height="1.9999945"
width="9"
y="109"
x="76.000008"
style="fill:#ffffff;fill-opacity:0.80000007;stroke:none;stroke-width:0" />
<rect
id="rect4761-1-1"
height="1.9999945"
width="12"
y="125"
x="76.000008"
style="fill:#ffffff;fill-opacity:0.80000007;stroke:none;stroke-width:0" />
<rect
id="rect4761-1-1-4"
height="1.9999945"
width="10"
y="137"
x="76.000008"
style="fill:#ffffff;fill-opacity:0.80000007;stroke:none;stroke-width:0" />
<rect
id="rect4761-1-1-4-4"
height="1.9999945"
width="10"
y="129"
x="82"
style="fill:#ffffff;fill-opacity:0.80000007;stroke:none;stroke-width:0" />
<rect
id="rect4761-1-1-4-4-3"
height="1.9999945"
width="9"
y="133"
x="82"
style="fill:#ffffff;fill-opacity:0.80000007;stroke:none;stroke-width:0" />
<path
inkscape:connector-curvature="0"
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;baseline-shift:baseline;text-anchor:start;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:0.8;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2.66157866;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
d="m 36.398438,100.0254 c -0.423362,-0.013 -0.846847,0.01 -1.265626,0.062 -1.656562,0.2196 -3.244567,0.9739 -4.507812,2.2266 L 29,100.5991 l -2.324219,7.7129 7.826172,-1.9062 -1.804687,-1.9063 c 1.597702,-1.5308 4.048706,-1.8453 5.984375,-0.7207 1.971162,1.1452 2.881954,3.3975 2.308593,5.5508 -0.573361,2.1533 -2.533865,3.6953 -4.830078,3.6953 l 0,3.0742 c 3.550756,0 6.710442,-2.4113 7.650391,-5.9414 0.939949,-3.5301 -0.618463,-7.2736 -3.710938,-9.0703 -1.159678,-0.6738 -2.431087,-1.0231 -3.701171,-1.0625 z"
id="path4138" />
<path
inkscape:connector-curvature="0"
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;baseline-shift:baseline;text-anchor:start;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:0.8;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2.66157866;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
d="m 59.722656,99.9629 c -1.270084,0.039 -2.541493,0.3887 -3.701172,1.0625 -3.092475,1.7967 -4.650886,5.5402 -3.710937,9.0703 0.939949,3.5301 4.09768,5.9414 7.648437,5.9414 l 0,-3.0742 c -2.296214,0 -4.256717,-1.542 -4.830078,-3.6953 -0.573361,-2.1533 0.337432,-4.4056 2.308594,-5.5508 1.935731,-1.1246 4.38863,-0.8102 5.986326,0.7207 l -1.806638,1.9063 7.828128,1.9062 -2.32422,-7.7129 -1.62696,1.7168 c -1.26338,-1.2531 -2.848917,-2.0088 -4.505855,-2.2285 -0.418778,-0.055 -0.842263,-0.076 -1.265625,-0.062 z"
id="path4138-1" />
<path
inkscape:connector-curvature="0"
style="opacity:0.8;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1.966;stroke-miterlimit:4;stroke-dasharray:none"
d="m 10.5,100 0,2 -2.4999996,0 L 12,107 l 4,-5 -2.5,0 0,-2 -3,0 z"
id="path3055-0-77" />
<path
style="opacity:0.8;fill:none;stroke:#ffffff;stroke-width:1.966;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 4.9850574,108.015 14.0298856,-0.03"
id="path5244-5-0-5"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<path
style="opacity:0.8;fill:none;stroke:#ffffff;stroke-width:1.966;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 4.9849874,132.015 14.0298866,-0.03"
id="path5244-5-0-5-8"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<path
inkscape:connector-curvature="0"
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;baseline-shift:baseline;text-anchor:start;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:0.4;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#4d4d4d;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2.66157866;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
d="m 36.398438,123.9629 c -0.423362,-0.013 -0.846847,0.01 -1.265626,0.062 -1.656562,0.2196 -3.244567,0.9739 -4.507812,2.2266 L 29,124.5366 l -2.324219,7.7129 7.826172,-1.9062 -1.804687,-1.9063 c 1.597702,-1.5308 4.048706,-1.8453 5.984375,-0.7207 1.971162,1.1453 2.881954,3.3975 2.308593,5.5508 -0.573361,2.1533 -2.533864,3.6953 -4.830078,3.6953 l 0,3.0742 c 3.550757,0 6.710442,-2.4093 7.650391,-5.9394 0.939949,-3.5301 -0.618463,-7.2756 -3.710938,-9.0723 -1.159678,-0.6737 -2.431087,-1.0231 -3.701171,-1.0625 z"
id="path4138-12" />
<path
inkscape:connector-curvature="0"
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;baseline-shift:baseline;text-anchor:start;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:0.4;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#4d4d4d;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2.66157866;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
d="m 59.722656,123.9629 c -1.270084,0.039 -2.541493,0.3888 -3.701172,1.0625 -3.092475,1.7967 -4.650886,5.5422 -3.710937,9.0723 0.939949,3.5301 4.09768,5.9394 7.648437,5.9394 l 0,-3.0742 c -2.296214,0 -4.256717,-1.542 -4.830078,-3.6953 -0.573361,-2.1533 0.337432,-4.4055 2.308594,-5.5508 1.935731,-1.1246 4.38863,-0.8102 5.986326,0.7207 l -1.806638,1.9063 7.828128,1.9062 -2.32422,-7.7129 -1.62696,1.7168 c -1.26338,-1.2531 -2.848917,-2.0088 -4.505855,-2.2285 -0.418778,-0.055 -0.842263,-0.076 -1.265625,-0.062 z"
id="path4138-1-3" />
<path
id="path6191"
d="m 10.5,116 0,-2 -2.4999996,0 L 12,109 l 4,5 -2.5,0 0,2 -3,0 z"
style="opacity:0.8;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1.966;stroke-miterlimit:4;stroke-dasharray:none"
inkscape:connector-curvature="0" />
<path
inkscape:connector-curvature="0"
style="opacity:0.8;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1.966;stroke-miterlimit:4;stroke-dasharray:none"
d="m 10.5,129 0,-2 -2.4999996,0 L 12,122 l 4,5 -2.5,0 0,2 -3,0 z"
id="path6193" />
<path
id="path6195"
d="m 10.5,135 0,2 -2.4999996,0 L 12,142 l 4,-5 -2.5,0 0,-2 -3,0 z"
style="opacity:0.8;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1.966;stroke-miterlimit:4;stroke-dasharray:none"
inkscape:connector-curvature="0" />
<path
sodipodi:type="star"
style="fill:#4d4d4d;fill-opacity:0.90196078;stroke:#d3d3d3;stroke-width:0;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none"
id="path4500"
sodipodi:sides="3"
sodipodi:cx="11.55581"
sodipodi:cy="60.073242"
sodipodi:r1="5.1116104"
sodipodi:r2="2.5558052"
sodipodi:arg1="0"
sodipodi:arg2="1.0471976"
inkscape:flatsided="false"
inkscape:rounded="0"
inkscape:randomized="0"
d="m 16.66742,60.073242 -3.833708,2.213392 -3.8337072,2.213393 0,-4.426785 0,-4.426784 3.8337082,2.213392 z"
inkscape:transform-center-x="-1.2779026" />
<path
inkscape:transform-center-x="1.277902"
d="m -31.500004,60.073242 -3.833708,2.213392 -3.833707,2.213393 0,-4.426785 0,-4.426784 3.833707,2.213392 z"
inkscape:randomized="0"
inkscape:rounded="0"
inkscape:flatsided="false"
sodipodi:arg2="1.0471976"
sodipodi:arg1="0"
sodipodi:r2="2.5558052"
sodipodi:r1="5.1116104"
sodipodi:cy="60.073242"
sodipodi:cx="-36.611614"
sodipodi:sides="3"
id="path4502"
style="fill:#4d4d4d;fill-opacity:0.90196078;stroke:#d3d3d3;stroke-width:0;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none"
sodipodi:type="star"
transform="scale(-1,1)" />
<path
d="m 16.66742,60.073212 -3.833708,2.213392 -3.8337072,2.213392 0,-4.426784 0,-4.426785 3.8337082,2.213392 z"
inkscape:randomized="0"
inkscape:rounded="0"
inkscape:flatsided="false"
sodipodi:arg2="1.0471976"
sodipodi:arg1="0"
sodipodi:r2="2.5558052"
sodipodi:r1="5.1116104"
sodipodi:cy="60.073212"
sodipodi:cx="11.55581"
sodipodi:sides="3"
id="path4504"
style="fill:#4d4d4d;fill-opacity:0.90196078;stroke:#d3d3d3;stroke-width:0;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none"
sodipodi:type="star"
transform="matrix(0,1,-1,0,72.0074,71.7877)"
inkscape:transform-center-y="1.2779029" />
<path
inkscape:transform-center-y="-1.2779026"
transform="matrix(0,-1,-1,0,96,96)"
sodipodi:type="star"
style="fill:#4d4d4d;fill-opacity:0.90196078;stroke:#d3d3d3;stroke-width:0;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none"
id="path4506"
sodipodi:sides="3"
sodipodi:cx="11.55581"
sodipodi:cy="60.073212"
sodipodi:r1="5.1116104"
sodipodi:r2="2.5558052"
sodipodi:arg1="0"
sodipodi:arg2="1.0471976"
inkscape:flatsided="false"
inkscape:rounded="0"
inkscape:randomized="0"
d="m 16.66742,60.073212 -3.833708,2.213392 -3.8337072,2.213392 0,-4.426784 0,-4.426785 3.8337082,2.213392 z" />
<path
sodipodi:nodetypes="cccc"
inkscape:connector-curvature="0"
id="path4615-5"
d="m 171.82574,65.174193 16.34854,0 -8.17427,-13.348454 z"
style="fill:#fbb917;fill-opacity:1;fill-rule:evenodd;stroke:#fbb917;stroke-width:1.65161395;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
style="opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 179,55 0,6 2,0 0,-6"
id="path4300"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccc" />
<path
style="opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 179,62 0,2 2,0 0,-2"
id="path4300-6"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccc" />
</svg>

Before

Width:  |  Height:  |  Size: 35 KiB

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -1 +0,0 @@
(window["webpackJsonp"]=window["webpackJsonp"]||[]).push([["chunk-2fd02e04"],{"64b7":function(e,t,n){"use strict";n("de5f")},ab3b:function(e,t,n){"use strict";n.r(t);var a=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("div",{staticClass:"app-container"},[n("split-pane",{attrs:{split:"vertical"},on:{resize:e.resize}},[n("template",{slot:"paneL"},[n("el-input",{attrs:{type:"textarea",rows:36,placeholder:"请输入内容",clearable:""},on:{change:e.originChange},model:{value:e.originText,callback:function(t){e.originText=t},expression:"originText"}})],1),e._v(" "),n("template",{slot:"paneR"},[n("div",{staticClass:"editor-container"},[n("JSONEditor",{attrs:{json:e.formatedValue}})],1)])],2)],1)},i=[],o=n("19ab"),r=n.n(o),s=n("33c3"),c={name:"JsonFormat",components:{splitPane:r.a,JSONEditor:s["a"]},data:function(){return{originText:"",formatedValue:""}},watch:{originText:function(e){try{this.formatedValue=JSON.parse(e)}catch(t){}}},methods:{resize:function(){},originChange:function(e){}}},l=c,u=(n("64b7"),n("2877")),p=Object(u["a"])(l,a,i,!1,null,"7505e034",null);t["default"]=p.exports},de5f:function(e,t,n){}}]);

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -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

@ -18,7 +18,6 @@
package cn.hippo4j.example.core.inittest;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.MDC;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
@ -29,8 +28,6 @@ import java.util.concurrent.SynchronousQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import static cn.hippo4j.common.constant.Constants.EXECUTE_TIMEOUT_TRACE;
/**
* Run state handler test.
*/
@ -81,7 +78,7 @@ public class RunStateHandlerTest {
/**
* When the execution of the thread pool task times out, the Trace flag is put into the MDC, and it is printed out when an alarm occurs.
*/
MDC.put(EXECUTE_TIMEOUT_TRACE, "39948722194639841.251.16612352194691531");
// MDC.put(EXECUTE_TIMEOUT_TRACE, "39948722194639841.251.16612352194691531");
try {
Thread.sleep(5000);
} catch (InterruptedException e) {

@ -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

@ -30,7 +30,7 @@ public interface NotifyConfigBuilder {
/**
* Build notify.
*
* @return
* @return notify info
*/
Map<String, List<NotifyConfigDTO>> buildNotify();
}

@ -60,8 +60,8 @@ public class DingSendMessageHandler extends AbstractRobotSendMessageHandler {
RobotMessageActualContent robotMessageActualContent = RobotMessageActualContent.builder()
.receiveSeparator(", @")
.changeSeparator(" -> ")
.replaceTxt(DING_ALARM_TIMOUT_REPLACE_TXT)
.traceReplaceTxt(DING_ALARM_TIMOUT_TRACE_REPLACE_TXT)
.replaceTxt(DING_ALARM_TIMEOUT_REPLACE_TXT)
.traceReplaceTxt(DING_ALARM_TIMEOUT_TRACE_REPLACE_TXT)
.alarmMessageContent(Singleton.get(dingAlarmTxtKey, () -> FileUtil.readUtf8String(dingAlarmTxtKey)))
.configMessageContent(Singleton.get(dingConfigTxtKey, () -> FileUtil.readUtf8String(dingConfigTxtKey)))
.build();

@ -55,66 +55,46 @@ public class LarkSendMessageHandler implements SendMessageHandler<AlarmNotifyReq
@SneakyThrows
public void sendAlarmMessage(NotifyConfigDTO notifyConfig, AlarmNotifyRequest alarmNotifyRequest) {
String afterReceives = getReceives(notifyConfig.getReceives());
String larkAlarmTimoutReplaceTxt;
String larkAlarmTimeoutReplaceTxt;
String larkAlarmTxtKey = "message/robot/dynamic-thread-pool/lark-alarm.json";
String larkAlarmTxt = Singleton.get(larkAlarmTxtKey, () -> FileUtil.readUtf8String(larkAlarmTxtKey));
String larkAlarmTimoutReplaceJsonKey = "message/robot/dynamic-thread-pool/lark-alarm-timeout-replace.json";
String larkAlarmTimoutReplaceJson = Singleton.get(larkAlarmTimoutReplaceJsonKey, () -> FileUtil.readUtf8String(larkAlarmTimoutReplaceJsonKey));
String larkAlarmTimeoutReplaceJsonKey = "message/robot/dynamic-thread-pool/lark-alarm-timeout-replace.json";
String larkAlarmTimeoutReplaceJson = Singleton.get(larkAlarmTimeoutReplaceJsonKey, () -> FileUtil.readUtf8String(larkAlarmTimeoutReplaceJsonKey));
if (Objects.equals(alarmNotifyRequest.getNotifyTypeEnum(), NotifyTypeEnum.TIMEOUT)) {
String executeTimeoutTrace = alarmNotifyRequest.getExecuteTimeoutTrace();
String larkAlarmTimoutTraceReplaceJsonKey = "message/robot/dynamic-thread-pool/lark-alarm-trace-replace.json";
String larkAlarmTimoutTraceReplaceJson = Singleton.get(larkAlarmTimoutTraceReplaceJsonKey, () -> FileUtil.readUtf8String(larkAlarmTimoutTraceReplaceJsonKey));
if (StringUtil.isNotBlank(executeTimeoutTrace)) {
String larkAlarmTimoutTraceReplaceTxt = String.format(larkAlarmTimoutTraceReplaceJson, executeTimeoutTrace);
larkAlarmTimoutReplaceTxt = StringUtil.replace(larkAlarmTimoutReplaceJson, larkAlarmTimoutTraceReplaceJson, larkAlarmTimoutTraceReplaceTxt);
larkAlarmTimeoutReplaceTxt = StringUtil.replace(larkAlarmTimeoutReplaceJson, larkAlarmTimoutTraceReplaceJson, larkAlarmTimoutTraceReplaceTxt);
} else {
larkAlarmTimoutReplaceTxt = StringUtil.replace(larkAlarmTimoutReplaceJson, larkAlarmTimoutTraceReplaceJson, "");
larkAlarmTimeoutReplaceTxt = StringUtil.replace(larkAlarmTimeoutReplaceJson, larkAlarmTimoutTraceReplaceJson, "");
}
larkAlarmTimoutReplaceTxt = String.format(larkAlarmTimoutReplaceTxt, alarmNotifyRequest.getExecuteTime(), alarmNotifyRequest.getExecuteTimeOut());
larkAlarmTxt = StringUtil.replace(larkAlarmTxt, larkAlarmTimoutReplaceJson, larkAlarmTimoutReplaceTxt);
larkAlarmTimeoutReplaceTxt = String.format(larkAlarmTimeoutReplaceTxt, alarmNotifyRequest.getExecuteTime(), alarmNotifyRequest.getExecuteTimeOut());
larkAlarmTxt = StringUtil.replace(larkAlarmTxt, larkAlarmTimeoutReplaceJson, larkAlarmTimeoutReplaceTxt);
} else {
larkAlarmTxt = StringUtil.replace(larkAlarmTxt, larkAlarmTimoutReplaceJson, "");
larkAlarmTxt = StringUtil.replace(larkAlarmTxt, larkAlarmTimeoutReplaceJson, "");
}
String text = String.format(larkAlarmTxt,
// 环境
alarmNotifyRequest.getActive(),
// 报警类型
alarmNotifyRequest.getNotifyTypeEnum(),
// 线程池ID
alarmNotifyRequest.getThreadPoolId(),
// 应用名称
alarmNotifyRequest.getAppName(),
// 实例信息
alarmNotifyRequest.getIdentify(),
// 核心线程数
alarmNotifyRequest.getCorePoolSize(),
// 最大线程数
alarmNotifyRequest.getMaximumPoolSize(),
// 当前线程数
alarmNotifyRequest.getPoolSize(),
// 活跃线程数
alarmNotifyRequest.getActiveCount(),
// 最大任务数
alarmNotifyRequest.getLargestPoolSize(),
// 线程池任务总量
alarmNotifyRequest.getCompletedTaskCount(),
// 队列类型名称
alarmNotifyRequest.getQueueName(),
// 队列容量
alarmNotifyRequest.getCapacity(),
// 队列元素个数
alarmNotifyRequest.getQueueSize(),
// 队列剩余个数
alarmNotifyRequest.getRemainingCapacity(),
// 拒绝策略名称
alarmNotifyRequest.getRejectedExecutionHandlerName(),
// 拒绝策略次数
alarmNotifyRequest.getRejectCountNum(),
// 告警手机号
afterReceives,
// 当前时间
LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")),
// 报警频率
notifyConfig.getInterval());
execute(notifyConfig.getSecretKey(), text);
}
@ -127,34 +107,20 @@ public class LarkSendMessageHandler implements SendMessageHandler<AlarmNotifyReq
String larkNoticeJsonKey = "message/robot/dynamic-thread-pool/lark-config.json";
String larkNoticeJson = Singleton.get(larkNoticeJsonKey, () -> FileUtil.readUtf8String(larkNoticeJsonKey));
String text = String.format(larkNoticeJson,
// 环境
changeParameterNotifyRequest.getActive(),
// 线程池名称
threadPoolId,
// 应用名称
changeParameterNotifyRequest.getAppName(),
// 实例信息
changeParameterNotifyRequest.getIdentify(),
// 核心线程数
changeParameterNotifyRequest.getBeforeCorePoolSize() + " ➲ " + changeParameterNotifyRequest.getNowCorePoolSize(),
// 最大线程数
changeParameterNotifyRequest.getBeforeMaximumPoolSize() + " ➲ " + changeParameterNotifyRequest.getNowMaximumPoolSize(),
// 核心线程超时
changeParameterNotifyRequest.getBeforeAllowsCoreThreadTimeOut() + " ➲ " + changeParameterNotifyRequest.getNowAllowsCoreThreadTimeOut(),
// 线程存活时间
changeParameterNotifyRequest.getBeforeKeepAliveTime() + " ➲ " + changeParameterNotifyRequest.getNowKeepAliveTime(),
// 阻塞队列
changeParameterNotifyRequest.getBlockingQueueName(),
// 阻塞队列容量
changeParameterNotifyRequest.getBeforeQueueCapacity() + " ➲ " + changeParameterNotifyRequest.getNowQueueCapacity(),
// 执行超时时间
changeParameterNotifyRequest.getBeforeExecuteTimeOut() + " ➲ " + changeParameterNotifyRequest.getNowExecuteTimeOut(),
// 拒绝策略
changeParameterNotifyRequest.getBeforeRejectedName(),
changeParameterNotifyRequest.getNowRejectedName(),
// 告警手机号
afterReceives,
// 当前时间
LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
execute(notifyConfig.getSecretKey(), text);
}

@ -37,22 +37,22 @@ public abstract class AbstractRobotSendMessageHandler implements SendMessageHand
/**
* Build message actual content.
*
* @return
* @return robot message actual content
*/
protected abstract RobotMessageActualContent buildMessageActualContent();
/**
* Execute.
*
* @param robotMessageExecuteDTO
* @param robotMessageExecuteDTO robot message execute dto
*/
protected abstract void execute(RobotMessageExecuteDTO robotMessageExecuteDTO);
/**
* Send alarm message.
*
* @param notifyConfig
* @param alarmNotifyRequest
* @param notifyConfig notify config
* @param alarmNotifyRequest alarm notify request
*/
public void sendAlarmMessage(NotifyConfigDTO notifyConfig, AlarmNotifyRequest alarmNotifyRequest) {
RobotMessageActualContent robotMessageActualContent = buildMessageActualContent();
@ -75,45 +75,25 @@ public abstract class AbstractRobotSendMessageHandler implements SendMessageHand
alarmContentTxt = StringUtil.replace(alarmContentTxt, "${timout-content}", replaceTxt);
String text = String.format(
alarmContentTxt,
// 环境
alarmNotifyRequest.getActive(),
// 报警类型
alarmNotifyRequest.getNotifyTypeEnum(),
// 线程池ID
alarmNotifyRequest.getThreadPoolId(),
// 应用名称
alarmNotifyRequest.getAppName(),
// 实例信息
alarmNotifyRequest.getIdentify(),
// 核心线程数
alarmNotifyRequest.getCorePoolSize(),
// 最大线程数
alarmNotifyRequest.getMaximumPoolSize(),
// 当前线程数
alarmNotifyRequest.getPoolSize(),
// 活跃线程数
alarmNotifyRequest.getActiveCount(),
// 最大任务数
alarmNotifyRequest.getLargestPoolSize(),
// 线程池任务总量
alarmNotifyRequest.getCompletedTaskCount(),
// 队列类型名称
alarmNotifyRequest.getQueueName(),
// 队列容量
alarmNotifyRequest.getCapacity(),
// 队列元素个数
alarmNotifyRequest.getQueueSize(),
// 队列剩余个数
alarmNotifyRequest.getRemainingCapacity(),
// 拒绝策略名称
alarmNotifyRequest.getRejectedExecutionHandlerName(),
// 拒绝策略次数
alarmNotifyRequest.getRejectCountNum(),
// 告警手机号
Joiner.on(robotMessageActualContent.getReceiveSeparator()).join(notifyConfig.getReceives().split(",")),
// 报警频率
notifyConfig.getInterval(),
// 当前时间
LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
execute(RobotMessageExecuteDTO.builder().text(text).notifyConfig(notifyConfig).build());
}
@ -121,8 +101,8 @@ public abstract class AbstractRobotSendMessageHandler implements SendMessageHand
/**
* Send change message.
*
* @param notifyConfig
* @param changeParameterNotifyRequest
* @param notifyConfig notify config
* @param changeParameterNotifyRequest change parameter notify request
*/
public void sendChangeMessage(NotifyConfigDTO notifyConfig, ChangeParameterNotifyRequest changeParameterNotifyRequest) {
RobotMessageActualContent robotMessageActualContent = buildMessageActualContent();
@ -130,34 +110,20 @@ public abstract class AbstractRobotSendMessageHandler implements SendMessageHand
String changeSeparator = robotMessageActualContent.getChangeSeparator();
String text = String.format(
robotMessageActualContent.getConfigMessageContent(),
// 环境
changeParameterNotifyRequest.getActive(),
// 线程池名称
threadPoolId,
// 应用名称
changeParameterNotifyRequest.getAppName(),
// 实例信息
changeParameterNotifyRequest.getIdentify(),
// 核心线程数
changeParameterNotifyRequest.getBeforeCorePoolSize() + changeSeparator + changeParameterNotifyRequest.getNowCorePoolSize(),
// 最大线程数
changeParameterNotifyRequest.getBeforeMaximumPoolSize() + changeSeparator + changeParameterNotifyRequest.getNowMaximumPoolSize(),
// 核心线程超时
changeParameterNotifyRequest.getBeforeAllowsCoreThreadTimeOut() + changeSeparator + changeParameterNotifyRequest.getNowAllowsCoreThreadTimeOut(),
// 线程存活时间
changeParameterNotifyRequest.getBeforeKeepAliveTime() + changeSeparator + changeParameterNotifyRequest.getNowKeepAliveTime(),
// 执行超时时间
changeParameterNotifyRequest.getBeforeExecuteTimeOut() + changeSeparator + changeParameterNotifyRequest.getNowExecuteTimeOut(),
// 阻塞队列
changeParameterNotifyRequest.getBlockingQueueName(),
// 阻塞队列容量
changeParameterNotifyRequest.getBeforeQueueCapacity() + changeSeparator + changeParameterNotifyRequest.getNowQueueCapacity(),
// 拒绝策略
changeParameterNotifyRequest.getBeforeRejectedName(),
changeParameterNotifyRequest.getNowRejectedName(),
// 告警手机号
Joiner.on(robotMessageActualContent.getReceiveSeparator()).join(notifyConfig.getReceives().split(",")),
// 当前时间
LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
execute(RobotMessageExecuteDTO.builder().text(text).notifyConfig(notifyConfig).build());
}

@ -40,14 +40,14 @@ public class DingAlarmConstants {
/**
* Trace info
*/
public static final String DING_ALARM_TIMOUT_TRACE_REPLACE_TXT = "<font color=#708090 size=2>链路信息:%s</font> \n\n ";
public static final String DING_ALARM_TIMEOUT_TRACE_REPLACE_TXT = "<font color=#708090 size=2>链路信息:%s</font> \n\n ";
/**
* Replace task timeout template
*/
public static final String DING_ALARM_TIMOUT_REPLACE_TXT =
public static final String DING_ALARM_TIMEOUT_REPLACE_TXT =
"<font color=#708090 size=2>任务执行时间:%d / ms </font> \n\n " +
"<font color=#708090 size=2>超时时间:%d / ms</font> \n\n " +
DING_ALARM_TIMOUT_TRACE_REPLACE_TXT +
DING_ALARM_TIMEOUT_TRACE_REPLACE_TXT +
" --- \n\n ";
}

@ -17,12 +17,6 @@
package cn.hippo4j.message.service;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantLock;
import cn.hippo4j.common.constant.Constants;
import cn.hippo4j.common.toolkit.IdUtil;
import cn.hippo4j.common.toolkit.StringUtil;
@ -30,6 +24,12 @@ import cn.hippo4j.message.dto.AlarmControlDTO;
import com.github.benmanes.caffeine.cache.Cache;
import com.github.benmanes.caffeine.cache.Caffeine;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantLock;
/**
* Alarm control assembly.
*/
@ -42,8 +42,8 @@ public class AlarmControlHandler {
/**
* Control message push alarm frequency.
*
* @param alarmControl
* @return
* @param alarmControl alarm control
* @return is it possible to send
*/
public boolean isSendAlarm(AlarmControlDTO alarmControl) {
String threadPoolKey = alarmControl.buildPk();
@ -72,9 +72,9 @@ public class AlarmControlHandler {
/**
* Init cache and lock.
*
* @param threadPoolId
* @param platform
* @param interval
* @param threadPoolId thread-pool id
* @param platform platform
* @param interval interval
*/
public void initCacheAndLock(String threadPoolId, String platform, Integer interval) {
String threadPoolKey = threadPoolId + Constants.GROUP_KEY_DELIMITER + platform;

@ -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;
@ -109,9 +109,9 @@ public class Hippo4jBaseSendMessageService implements Hippo4jSendMessageService,
/**
* Is send alarm.
*
* @param threadPoolId
* @param platform
* @param typeEnum
* @param threadPoolId thread-pool id
* @param platform platform
* @param typeEnum type enum
* @return
*/
private boolean isSendAlarm(String threadPoolId, String platform, NotifyTypeEnum typeEnum) {
@ -123,21 +123,21 @@ public class Hippo4jBaseSendMessageService implements Hippo4jSendMessageService,
return alarmControlHandler.isSendAlarm(alarmControl);
}
@Override
public void run(String... args) throws Exception {
Map<String, SendMessageHandler> sendMessageHandlerMap =
ApplicationContextHolder.getBeansOfType(SendMessageHandler.class);
sendMessageHandlerMap.values().forEach(each -> sendMessageHandlers.put(each.getType(), each));
Map<String, List<NotifyConfigDTO>> buildNotify = notifyConfigBuilder.buildNotify();
notifyConfigs.putAll(buildNotify);
}
/**
* Put platform.
*
* @param notifyConfigs
* @param notifyConfigs notify configs
*/
public synchronized void putPlatform(Map<String, List<NotifyConfigDTO>> notifyConfigs) {
this.notifyConfigs.putAll(notifyConfigs);
}
@Override
public void afterPropertiesSet() throws Exception {
Map<String, SendMessageHandler> sendMessageHandlerMap =
ApplicationContextHolder.getBeansOfType(SendMessageHandler.class);
sendMessageHandlerMap.values().forEach(each -> sendMessageHandlers.put(each.getType(), each));
Map<String, List<NotifyConfigDTO>> buildNotify = notifyConfigBuilder.buildNotify();
notifyConfigs.putAll(buildNotify);
}
}

@ -29,15 +29,15 @@ public interface Hippo4jSendMessageService {
/**
* Send dynamic thread pool alert notifications.
*
* @param typeEnum
* @param alarmNotifyRequest
* @param typeEnum type enum
* @param alarmNotifyRequest alarm notify request
*/
void sendAlarmMessage(NotifyTypeEnum typeEnum, AlarmNotifyRequest alarmNotifyRequest);
/**
* Send dynamic thread pool parameter change notification.
*
* @param changeParameterNotifyRequest
* @param changeParameterNotifyRequest change parameter notify request
*/
void sendChangeMessage(ChangeParameterNotifyRequest changeParameterNotifyRequest);
}

@ -26,25 +26,25 @@ import cn.hippo4j.message.request.base.NotifyRequest;
public interface SendMessageHandler<T extends NotifyRequest, R extends NotifyRequest> {
/**
* Get type.
* Get the message send type.
*
* @return
* @return message type
*/
String getType();
/**
* Send alarm message.
*
* @param notifyConfig
* @param alarmNotifyRequest
* @param notifyConfig notify config
* @param alarmNotifyRequest alarm notify request
*/
void sendAlarmMessage(NotifyConfigDTO notifyConfig, T alarmNotifyRequest);
/**
* Send change message.
*
* @param notifyConfig
* @param changeParameterNotifyRequest
* @param notifyConfig notify config
* @param changeParameterNotifyRequest change parameter notify request
*/
void sendChangeMessage(NotifyConfigDTO notifyConfig, R changeParameterNotifyRequest);
}

@ -14,8 +14,8 @@
"content": "** 超时时间:** %s",
"tag": "lark_md"
}
},
{
}
,{
"is_short": true,
"text": {
"content": "** 链路信息:** %s",

@ -1,5 +1,5 @@
{
,{
"is_short": true,
"text": {
"content": "** 链路信息:** %s",

@ -142,8 +142,8 @@
"content": "** 超时时间:** %s",
"tag": "lark_md"
}
},
{
}
,{
"is_short": true,
"text": {
"content": "** 链路信息:** %s",

@ -22,7 +22,7 @@ import cn.hippo4j.message.enums.NotifyTypeEnum;
import org.junit.Assert;
import org.junit.Test;
public class AlarmControlHandlerTest {
public final class AlarmControlHandlerTest {
@Test
public void assertIsNotSendAlarm() {

@ -13,6 +13,17 @@
<dependency>
<groupId>cn.hippo4j</groupId>
<artifactId>hippo4j-core</artifactId>
<version>${revision}</version>
</dependency>
<dependency>
<groupId>cn.hippo4j</groupId>
<artifactId>hippo4j-adapter-web</artifactId>
<version>${revision}</version>
</dependency>
<dependency>
<groupId>cn.hippo4j</groupId>
<artifactId>hippo4j-adapter-base</artifactId>
<version>${revision}</version>
</dependency>
</dependencies>
</project>

@ -0,0 +1,43 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package cn.hippo4j.monitor.base;
import cn.hippo4j.adapter.base.ThreadPoolAdapter;
import cn.hippo4j.adapter.base.ThreadPoolAdapterState;
import cn.hippo4j.common.config.ApplicationContextHolder;
import java.util.Map;
/**
* Abstract adapter thread-pool monitor.
*/
public abstract class AbstractAdapterThreadPoolMonitor implements AdapterThreadPoolMonitor {
/**
* Execute collection thread pool running data.
*
* @param threadPoolAdapterState thread-pool adapter state
*/
protected abstract void execute(ThreadPoolAdapterState threadPoolAdapterState);
@Override
public void collect() {
Map<String, ThreadPoolAdapter> threadPoolAdapterMap = ApplicationContextHolder.getBeansOfType(ThreadPoolAdapter.class);
threadPoolAdapterMap.forEach((beanName, bean) -> bean.getThreadPoolStates().forEach(each -> execute(each)));
}
}

@ -20,24 +20,24 @@ package cn.hippo4j.monitor.base;
import cn.hippo4j.common.model.ThreadPoolRunStateInfo;
import cn.hippo4j.core.executor.manage.GlobalThreadPoolManage;
import cn.hippo4j.core.executor.state.ThreadPoolRunStateHandler;
import lombok.RequiredArgsConstructor;
import javax.annotation.Resource;
import java.util.List;
/**
* Abstract dynamic thread-pool monitor.
*/
@RequiredArgsConstructor
public abstract class AbstractDynamicThreadPoolMonitor implements DynamicThreadPoolMonitor {
private final ThreadPoolRunStateHandler threadPoolRunStateHandler;
@Resource
private ThreadPoolRunStateHandler threadPoolRunStateHandler;
/**
* Execute collection thread pool running data.
*
* @param poolRunStateInfo
* @param dynamicThreadPoolRunStateInfo dynamic thread-pool run state info
*/
protected abstract void execute(ThreadPoolRunStateInfo poolRunStateInfo);
protected abstract void execute(ThreadPoolRunStateInfo dynamicThreadPoolRunStateInfo);
@Override
public void collect() {

@ -0,0 +1,45 @@
/*
* 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.monitor.base;
import cn.hippo4j.adapter.web.WebThreadPoolService;
import cn.hippo4j.common.model.ThreadPoolRunStateInfo;
import javax.annotation.Resource;
/**
* Abstract web thread-pool monitor.
*/
public abstract class AbstractWebThreadPoolMonitor implements WebThreadPoolMonitor {
@Resource
private WebThreadPoolService webThreadPoolService;
/**
* Execute collection thread pool running data.
*
* @param webThreadPoolRunStateInfo web thread-pool run state info
*/
protected abstract void execute(ThreadPoolRunStateInfo webThreadPoolRunStateInfo);
@Override
public void collect() {
ThreadPoolRunStateInfo webThreadPoolRunStateInfo = webThreadPoolService.getWebRunStateInfo();
execute(webThreadPoolRunStateInfo);
}
}

@ -15,21 +15,11 @@
* limitations under the License.
*/
package cn.hippo4j.springboot.starter.monitor.es;
import cn.hippo4j.core.executor.state.ThreadPoolRunStateHandler;
import cn.hippo4j.monitor.es.EsMonitorHandler;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
package cn.hippo4j.monitor.base;
/**
* Elastic-search monitor auto configuration.
* Adapter thread-pool monitor.
*/
@Configuration
public class EsMonitorAutoConfiguration {
public interface AdapterThreadPoolMonitor extends ThreadPoolMonitor {
@Bean
public EsMonitorHandler esMonitorHandler(ThreadPoolRunStateHandler threadPoolRunStateHandler) {
return new EsMonitorHandler(threadPoolRunStateHandler);
}
}

@ -15,20 +15,25 @@
* limitations under the License.
*/
package cn.hippo4j.springboot.starter.config;
import cn.hippo4j.springboot.starter.remote.HttpAgent;
import cn.hippo4j.springboot.starter.remote.ServerHttpAgent;
import org.springframework.context.annotation.Bean;
package cn.hippo4j.monitor.base;
/**
* Http client config.
* Monitor thread-pool type enum.
*/
public class HttpClientConfiguration {
public enum MonitorThreadPoolTypeEnum {
/**
* Dynamic thread-pool
*/
DYNAMIC,
/**
* Web thread-pool
*/
WEB,
@Bean
@SuppressWarnings("all")
public HttpAgent httpAgent(BootstrapProperties properties) {
return new ServerHttpAgent(properties);
}
/**
* Adapter thread-pool
*/
ADAPTER
}

@ -18,19 +18,19 @@
package cn.hippo4j.monitor.base;
/**
* Thread-pool monitor.
* Thread-pool runtime monitor.
*/
public interface ThreadPoolMonitor {
/**
* Get type.
* Get thread-pool monitoring type.
*
* @return
* @return monitoring type
*/
String getType();
/**
* Collect data.
* Collect thread-pool runtime data.
*/
void collect();
}

@ -15,7 +15,11 @@
* limitations under the License.
*/
package cn.hippo4j.auth.secuity;
package cn.hippo4j.monitor.base;
/**
* Web thread-pool monitor.
*/
public interface WebThreadPoolMonitor extends ThreadPoolMonitor {
public final class JwtTokenManagerTest {
}

@ -0,0 +1,40 @@
/*
* 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.monitor.elasticsearch;
import cn.hippo4j.common.model.ThreadPoolRunStateInfo;
import cn.hippo4j.monitor.base.AbstractDynamicThreadPoolMonitor;
import cn.hippo4j.monitor.base.MonitorTypeEnum;
import lombok.extern.slf4j.Slf4j;
/**
* Adapter thread-pool elastic-search monitor handler.
*/
@Slf4j
public class AdapterThreadPoolElasticSearchMonitorHandler extends AbstractDynamicThreadPoolMonitor {
@Override
protected void execute(ThreadPoolRunStateInfo poolRunStateInfo) {
// TODO
}
@Override
public String getType() {
return MonitorTypeEnum.ELASTICSEARCH.name().toLowerCase();
}
}

@ -15,26 +15,25 @@
* limitations under the License.
*/
package cn.hippo4j.monitor.es;
package cn.hippo4j.monitor.elasticsearch;
import cn.hippo4j.common.config.ApplicationContextHolder;
import cn.hippo4j.common.model.ThreadPoolRunStateInfo;
import cn.hippo4j.common.toolkit.BeanUtil;
import cn.hippo4j.common.toolkit.FileUtil;
import cn.hippo4j.common.toolkit.JSONUtil;
import cn.hippo4j.core.executor.state.ThreadPoolRunStateHandler;
import cn.hippo4j.monitor.es.model.EsThreadPoolRunStateInfo;
import cn.hippo4j.monitor.base.AbstractDynamicThreadPoolMonitor;
import cn.hippo4j.monitor.base.MonitorTypeEnum;
import cn.hippo4j.monitor.elasticsearch.model.ElasticSearchThreadPoolRunStateInfo;
import lombok.extern.slf4j.Slf4j;
import org.elasticsearch.action.admin.indices.alias.Alias;
import org.elasticsearch.action.admin.indices.create.CreateIndexRequest;
import org.elasticsearch.action.admin.indices.create.CreateIndexResponse;
import org.elasticsearch.client.indices.GetIndexRequest;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.client.indices.GetIndexRequest;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.xcontent.XContentType;
import org.springframework.core.env.Environment;
@ -47,20 +46,16 @@ import java.util.Objects;
import java.util.concurrent.atomic.AtomicBoolean;
/**
* Elastic-search monitor handler.
* Dynamic thread-pool elastic-search monitor handler.
*/
@Slf4j
public class EsMonitorHandler extends AbstractDynamicThreadPoolMonitor {
public EsMonitorHandler(ThreadPoolRunStateHandler threadPoolRunStateHandler) {
super(threadPoolRunStateHandler);
}
public class DynamicThreadPoolElasticSearchMonitorHandler extends AbstractDynamicThreadPoolMonitor {
private AtomicBoolean isIndexExist = null;
@Override
protected void execute(ThreadPoolRunStateInfo poolRunStateInfo) {
EsThreadPoolRunStateInfo esThreadPoolRunStateInfo = BeanUtil.convert(poolRunStateInfo, EsThreadPoolRunStateInfo.class);
ElasticSearchThreadPoolRunStateInfo esThreadPoolRunStateInfo = BeanUtil.convert(poolRunStateInfo, ElasticSearchThreadPoolRunStateInfo.class);
Environment environment = ApplicationContextHolder.getInstance().getEnvironment();
String indexName = environment.getProperty("es.thread-pool-state.index.name", "thread-pool-state");
String applicationName = environment.getProperty("spring.application.name", "application");
@ -75,8 +70,8 @@ public class EsMonitorHandler extends AbstractDynamicThreadPoolMonitor {
this.log2Es(esThreadPoolRunStateInfo, indexName);
}
public void log2Es(EsThreadPoolRunStateInfo esThreadPoolRunStateInfo, String indexName) {
RestHighLevelClient client = EsClientHolder.getClient();
public void log2Es(ElasticSearchThreadPoolRunStateInfo esThreadPoolRunStateInfo, String indexName) {
RestHighLevelClient client = ElasticSearchClientHolder.getClient();
try {
IndexRequest request = new IndexRequest(indexName, "_doc");
request.id(esThreadPoolRunStateInfo.getId());
@ -99,7 +94,7 @@ public class EsMonitorHandler extends AbstractDynamicThreadPoolMonitor {
boolean exists = false;
GetIndexRequest request = new GetIndexRequest(index);
try {
RestHighLevelClient client = EsClientHolder.getClient();
RestHighLevelClient client = ElasticSearchClientHolder.getClient();
exists = client.indices().exists(request, RequestOptions.DEFAULT);
} catch (IOException e) {
log.error("check es index fail");
@ -110,7 +105,7 @@ public class EsMonitorHandler extends AbstractDynamicThreadPoolMonitor {
}
public void createIndex(String index, String type, String mapping, Integer shards, Integer replicas, String alias) {
RestHighLevelClient client = EsClientHolder.getClient();
RestHighLevelClient client = ElasticSearchClientHolder.getClient();
boolean acknowledged = false;
CreateIndexRequest request = new CreateIndexRequest(index);
if (StringUtils.hasText(mapping)) {

@ -15,7 +15,7 @@
* limitations under the License.
*/
package cn.hippo4j.monitor.es;
package cn.hippo4j.monitor.elasticsearch;
import cn.hippo4j.common.config.ApplicationContextHolder;
import cn.hippo4j.common.toolkit.StringUtil;
@ -37,7 +37,7 @@ import java.util.List;
* Elastic-search client holder.
*/
@Slf4j
public class EsClientHolder {
public class ElasticSearchClientHolder {
private static String host;

@ -15,21 +15,26 @@
* limitations under the License.
*/
package cn.hippo4j.springboot.starter.monitor.local.log;
package cn.hippo4j.monitor.elasticsearch;
import cn.hippo4j.core.executor.state.ThreadPoolRunStateHandler;
import cn.hippo4j.monitor.local.log.LocalLogMonitorHandler;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import cn.hippo4j.common.model.ThreadPoolRunStateInfo;
import cn.hippo4j.monitor.base.AbstractDynamicThreadPoolMonitor;
import cn.hippo4j.monitor.base.MonitorTypeEnum;
import lombok.extern.slf4j.Slf4j;
/**
* Local log monitor configuration.
* Web thread-pool elastic-search monitor handler.
*/
@Configuration
public class LocalLogMonitorConfiguration {
@Slf4j
public class WebThreadPoolElasticSearchMonitorHandler extends AbstractDynamicThreadPoolMonitor {
@Bean
public LocalLogMonitorHandler localLogMonitorHandler(ThreadPoolRunStateHandler threadPoolRunStateHandler) {
return new LocalLogMonitorHandler(threadPoolRunStateHandler);
@Override
protected void execute(ThreadPoolRunStateInfo poolRunStateInfo) {
// TODO
}
@Override
public String getType() {
return MonitorTypeEnum.ELASTICSEARCH.name().toLowerCase();
}
}

@ -15,7 +15,7 @@
* limitations under the License.
*/
package cn.hippo4j.monitor.es.model;
package cn.hippo4j.monitor.elasticsearch.model;
import cn.hippo4j.common.model.ThreadPoolRunStateInfo;
import lombok.Getter;
@ -26,7 +26,7 @@ import lombok.Setter;
*/
@Getter
@Setter
public class EsThreadPoolRunStateInfo extends ThreadPoolRunStateInfo {
public class ElasticSearchThreadPoolRunStateInfo extends ThreadPoolRunStateInfo {
private String Id;

@ -15,21 +15,27 @@
* limitations under the License.
*/
package cn.hippo4j.springboot.starter.monitor.micrometer;
package cn.hippo4j.monitor.local.log;
import cn.hippo4j.core.executor.state.ThreadPoolRunStateHandler;
import cn.hippo4j.monitor.micrometer.MicrometerMonitorHandler;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import cn.hippo4j.adapter.base.ThreadPoolAdapterState;
import cn.hippo4j.common.toolkit.JSONUtil;
import cn.hippo4j.monitor.base.AbstractAdapterThreadPoolMonitor;
import cn.hippo4j.monitor.base.MonitorTypeEnum;
import lombok.extern.slf4j.Slf4j;
/**
* Micrometer monitor configuration.
* Adapter thread-pool local log monitor handler.
*/
@Configuration
public class MicrometerMonitorConfiguration {
@Slf4j
public class AdapterThreadPoolLocalLogMonitorHandler extends AbstractAdapterThreadPoolMonitor {
@Bean
public MicrometerMonitorHandler micrometerMonitorHandler(ThreadPoolRunStateHandler threadPoolRunStateHandler) {
return new MicrometerMonitorHandler(threadPoolRunStateHandler);
@Override
protected void execute(ThreadPoolAdapterState threadPoolAdapterState) {
log.info("{}", JSONUtil.toJSONString(threadPoolAdapterState));
}
@Override
public String getType() {
return MonitorTypeEnum.LOG.name().toLowerCase();
}
}

@ -19,20 +19,15 @@ package cn.hippo4j.monitor.local.log;
import cn.hippo4j.common.model.ThreadPoolRunStateInfo;
import cn.hippo4j.common.toolkit.JSONUtil;
import cn.hippo4j.core.executor.state.ThreadPoolRunStateHandler;
import cn.hippo4j.monitor.base.AbstractDynamicThreadPoolMonitor;
import cn.hippo4j.monitor.base.MonitorTypeEnum;
import lombok.extern.slf4j.Slf4j;
/**
* Local log monitor handler.
* Dynamic thread-pool local log monitor handler.
*/
@Slf4j
public class LocalLogMonitorHandler extends AbstractDynamicThreadPoolMonitor {
public LocalLogMonitorHandler(ThreadPoolRunStateHandler threadPoolRunStateHandler) {
super(threadPoolRunStateHandler);
}
public class DynamicThreadPoolLocalLogMonitorHandler extends AbstractDynamicThreadPoolMonitor {
@Override
protected void execute(ThreadPoolRunStateInfo poolRunStateInfo) {

@ -0,0 +1,41 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package cn.hippo4j.monitor.local.log;
import cn.hippo4j.common.model.ThreadPoolRunStateInfo;
import cn.hippo4j.common.toolkit.JSONUtil;
import cn.hippo4j.monitor.base.AbstractWebThreadPoolMonitor;
import cn.hippo4j.monitor.base.MonitorTypeEnum;
import lombok.extern.slf4j.Slf4j;
/**
* Web thread-pool local log monitor handler.
*/
@Slf4j
public class WebThreadPoolLocalLogMonitorHandler extends AbstractWebThreadPoolMonitor {
@Override
protected void execute(ThreadPoolRunStateInfo poolRunStateInfo) {
log.info("{}", JSONUtil.toJSONString(poolRunStateInfo));
}
@Override
public String getType() {
return MonitorTypeEnum.LOG.name().toLowerCase();
}
}

@ -0,0 +1,72 @@
/*
* 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.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
public String getType() {
return MonitorTypeEnum.MICROMETER.name().toLowerCase();
}
}

@ -21,7 +21,6 @@ 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.core.executor.state.ThreadPoolRunStateHandler;
import cn.hippo4j.monitor.base.AbstractDynamicThreadPoolMonitor;
import cn.hippo4j.monitor.base.MonitorTypeEnum;
import io.micrometer.core.instrument.Metrics;
@ -32,9 +31,9 @@ import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
* Micrometer monitor handler.
* Dynamic thread-pool micrometer monitor handler.
*/
public class MicrometerMonitorHandler extends AbstractDynamicThreadPoolMonitor {
public class DynamicThreadPoolMicrometerMonitorHandler extends AbstractDynamicThreadPoolMonitor {
private final static String METRIC_NAME_PREFIX = "dynamic.thread-pool";
@ -44,10 +43,6 @@ public class MicrometerMonitorHandler extends AbstractDynamicThreadPoolMonitor {
private final Map<String, ThreadPoolRunStateInfo> RUN_STATE_CACHE = new ConcurrentHashMap<>();
public MicrometerMonitorHandler(ThreadPoolRunStateHandler threadPoolRunStateHandler) {
super(threadPoolRunStateHandler);
}
@Override
protected void execute(ThreadPoolRunStateInfo poolRunStateInfo) {
ThreadPoolRunStateInfo stateInfo = RUN_STATE_CACHE.get(poolRunStateInfo.getTpId());

@ -0,0 +1,76 @@
/*
* 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.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
public String getType() {
return MonitorTypeEnum.MICROMETER.name().toLowerCase();
}
}

@ -4,7 +4,7 @@
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>cn.hippo4j</groupId>
<artifactId>hippo4j-all</artifactId>
<artifactId>hippo4j-server</artifactId>
<version>${revision}</version>
</parent>
<artifactId>hippo4j-auth</artifactId>

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

Loading…
Cancel
Save