This commit is contained in:
yanhom 2022-01-19 02:12:53 +08:00
parent 1272786483
commit c46e6e7da2
93 changed files with 1343 additions and 529 deletions

201
LICENSE Normal file
View File

@ -0,0 +1,201 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed 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.

334
README.md Normal file
View File

@ -0,0 +1,334 @@
## 基于配置中心的轻量级动态线程池 - DynamicTp
```yml
| __ \ (_) |__ __|
| | | |_ _ _ __ __ _ _ __ ___ _ ___| |_ __
| | | | | | | '_ \ / _` | '_ ` _ \| |/ __| | '_ \
| |__| | |_| | | | | (_| | | | | | | | (__| | |_) |
|_____/ \__, |_| |_|\__,_|_| |_| |_|_|\___|_| .__/
__/ | | |
|___/ |_|
:: Dynamic Thread Pool ::
```
***
### 背景
**使用ThreadPoolExecutor过程中你是否有以下痛点呢?**
> 1.代码中创建了一个ThreadPoolExecutor,但是不知道那几个核心参数设置多少比较合适
>
> 2.凭经验设置参数值,上线后发现需要调整,改代码重启服务,非常麻烦
>
> 3.线程池相对开发人员来说是个黑盒,运行情况不能感知到,直到出现问题
如果你有以上痛点,动态可监控线程池(DynamicTp)或许能帮助到你。
如果看过ThreadPoolExecutor的源码,大概可以知道其实它有提供一些set方法,可以在运行时动态去修改相应的值,这些方法有:
```java
public void setCorePoolSize(int corePoolSize);
public void setMaximumPoolSize(int maximumPoolSize);
public void setKeepAliveTime(long time, TimeUnit unit);
public void setThreadFactory(ThreadFactory threadFactory);
public void setRejectedExecutionHandler(RejectedExecutionHandler handler);
```
现在大多数的互联网项目其实都会微服务化部署,有一套自己的服务治理体系,微服务组件中的分布式配置中心扮演的就是动态修改配置,
实时生效的角色。那么我们是否可以结合配置中心来做运行时线程池参数的动态调整呢?答案是肯定的,而且配置中心相对都是高可用的,
使用它也不用过于担心配置推送出现问题这类事儿,而且也能减少研发动态线程池组件的难度和工作量。
**综上,我们总结出以下的背景**
+ 广泛性:在Java开发中,想要提高系统性能,线程池已经是一个90%以上的人都会选择使用的基础工具
+ 不确定性:项目中可能会创建很多线程池,既有IO密集型的,也有CPU密集型的,但线程池的参数并不好确定;需要有套机制在运行过程中动态去调整参数
+ 无感知性,线程池运行过程中的各项指标一般感知不到;需要有套监控报警机制在事前、事中就能让开发人员感知到线程池的运行状况,及时处理
+ 高可用性,配置变更需要及时推送到客户端;需要有高可用的配置管理推送服务,配置中心是现在大多数互联网系统都会使用的组件,与之结合可以大幅度减少开发量及接入难度
***
### 简介
我们基于配置中心对线程池ThreadPoolExecutor做一些扩展,实现对运行中线程池参数的动态修改,实时生效;
以及实时监控线程池的运行状态,触发设置的报警策略时报警,报警信息会推送办公平台(钉钉、企微等)。
报警维度包括(队列容量、线程池活性、拒绝触发等);同时也会定时采集线程池指标数据供监控平台可视化使用。
使我们能时刻感知到线程池的负载,根据情况及时调整,避免出现问题影响线上业务。
```bash
| __ \ (_) |__ __|
| | | |_ _ _ __ __ _ _ __ ___ _ ___| |_ __
| | | | | | | '_ \ / _` | '_ ` _ | |/ __| | '_ \
| |__| | |_| | | | | (_| | | | | | | | (__| | |_) |
|_____/ __, |_| |_|__,_|_| |_| |_|_|___|_| .__/
__/ | | |
|___/ |_|
:: Dynamic Thread Pool ::
```
**特性**
+ 参考[美团线程池实践](https://tech.meituan.com/2020/04/02/java-pooling-pratice-in-meituan.html),对线程池参数动态化管理,增加监控、报警功能
+ 基于Spring框架,现只支持SpringBoot项目使用,轻量级,引入starter即可食用
+ 基于配置中心实现线程池参数动态调整,实时生效;集成主流配置中心,默认支持Nacos、Apollo,
同时也提供SPI接口可自定义扩展实现
+ 内置通知报警功能,提供多种报警维度(配置变更通知、活性报警、容量阈值报警、拒绝策略触发报警),
默认支持企业微信、钉钉报警,同时提供SPI接口可自定义扩展实现
+ 内置线程池指标采集功能,支持通过MicroMeter、JsonLog日志输出、Endpoint三种方式,可通过SPI接口自定义扩展实现
***
### 架构设计
**主要分四大模块**
+ 配置变更监听模块:
1.监听特定配置中心的指定配置文件(默认实现Nacos、Apollo),可通过内部提供的SPI接口扩展其他实现
2.解析配置文件内容,内置实现yml、properties配置文件的解析,可通过内部提供的SPI接口扩展其他实现
3.通知线程池管理模块实现刷新
+ 线程池管理模块:
1.服务启动时从配置中心拉取配置信息,生成线程池实例注册到内部线程池注册中心中
2.监听模块监听到配置变更时,将变更信息传递给管理模块,实现线程池参数的刷新
3.代码中通过getExecutor()方法根据线程池名称来获取线程池对象实例
+ 监控模块:
实现监控指标采集以及输出,默认提供以下三种方式,也可通过内部提供的SPI接口扩展其他实现
1.默认实现Json log输出到磁盘
2.MicroMeter采集,引入MicroMeter相关依赖
3.暴雷Endpoint端点,可通过http方式访问
+ 通知告警模块:
对接办公平台,实现通告告警功能,默认实现钉钉、企微,可通过内部提供的SPI接口扩展其他实现,通知告警类型如下
1.线程池参数变更通知
2.阻塞队列容量达到设置阈值告警
3.线程池活性达到设置阈值告警
4.触发拒绝策略告警
![](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/91ea4c3e1166426e8dca9903dacfd9eb~tplv-k3u1fbpfcp-zoom-1.image)
***
### 使用
+ maven依赖
```xml
<dependency>
<groupId>io.github.lyh200</groupId>
<artifactId>dynamic-tp-spring-cloud-starter</artifactId>
<version>1.0.2-RELEASE</version>
</dependency>
```
+ 线程池配置
```yaml
spring:
dynamic:
tp:
enabled: true
enabledBanner: true # 是否开启banner打印,默认true
enabledCollect: false # 是否开启监控指标采集,默认false
collectorType: logging # 监控数据采集器类型(JsonLog | MicroMeter),默认logging
logPath: /home/logs # 监控日志数据路径,默认${user.home}/logs
monitorInterval: 5 # 监控时间间隔(报警判断、指标采集),默认5s
nacos: # nacos配置,不配置有默认值(规则name-dev.yml这样)
dataId: dynamic-tp-demo-dev.yml
group: DEFAULT_GROUP
apollo: # apollo配置,不配置默认拿apollo配置第一个namespace
namespace: dynamic-tp-demo-dev.yml
configType: yml # 配置文件类型
platforms: # 通知报警平台配置
- platform: wechat
urlKey: 3a7500-1287-4bd-a798-c5c3d8b69c # 替换
receivers: test1,test2 # 接受人企微名称
- platform: ding
urlKey: f80dad441fcd655438f4a08dcd6a # 替换
secret: SECb5441fa6f375d5b9d21 # 替换,非sign模式可以没有此值
receivers: 15810119805 # 钉钉账号手机号
executors: # 动态线程池配置
- threadPoolName: dynamic-tp-test-1
corePoolSize: 6
maximumPoolSize: 8
queueCapacity: 200
queueType: VariableLinkedBlockingQueue # 任务队列,查看源码QueueTypeEnum枚举类
rejectedHandlerType: CallerRunsPolicy # 拒绝策略,查看RejectedTypeEnum枚举类
keepAliveTime: 50
allowCoreThreadTimeOut: false
threadNamePrefix: test # 线程名前缀
notifyItems: # 报警项,不配置自动会配置(变更通知、容量报警、活性报警、拒绝报警)
- type: capacity # 报警项类型,查看源码 NotifyTypeEnum枚举类
enabled: true
threshold: 80 # 报警阈值
platforms: [ding,wechat] # 可选配置,不配置默认拿上层platforms配置的所以平台
interval: 120 # 报警间隔(单位:s)
- type: change
enabled: true
- type: liveness
enabled: true
threshold: 80
- type: reject
enabled: true
threshold: 1
```
+ 代码方式生成,服务启动会自动注册
```java
@Configuration
public class DtpConfig {
@Bean
public DtpExecutor demo1Executor() {
return DtpCreator.createDynamicFast("demo1-executor");
}
@Bean
public ThreadPoolExecutor demo2Executor() {
return ThreadPoolBuilder.newBuilder()
.threadPoolName("demo2-executor")
.corePoolSize(8)
.maximumPoolSize(16)
.keepAliveTime(50)
.allowCoreThreadTimeOut(true)
.workQueue(QueueTypeEnum.SYNCHRONOUS_QUEUE.getName(), null, false)
.rejectedExecutionHandler(RejectedTypeEnum.CALLER_RUNS_POLICY.getName())
.buildDynamic();
}
}
```
+ 代码调用,根据线程池名称获取
```java
public static void main(String[] args) {
DtpExecutor dtpExecutor = DtpRegistry.getExecutor("dynamic-tp-test-1");
dtpExecutor.execute(() -> System.out.println("test"));
}
```
***
### 注意事项
+ 配置文件配置的参数会覆盖通过代码生成方式配置的参数
+ 阻塞队列只有VariableLinkedBlockingQueue类型可以修改capacity,该类型功能和LinkedBlockingQueue相似,
只是capacity不是final类型,可以修改, VariableLinkedBlockingQueue参考RabbitMq的实现
+ 启动看到如下日志输出证明接入成功
```bash
| __ \ (_) |__ __|
| | | |_ _ _ __ __ _ _ __ ___ _ ___| |_ __
| | | | | | | '_ \ / _` | '_ ` _ | |/ __| | '_ \
| |__| | |_| | | | | (_| | | | | | | | (__| | |_) |
|_____/ __, |_| |_|__,_|_| |_| |_|_|___|_| .__/
__/ | | |
|___/ |_|
:: Dynamic Thread Pool ::
DynamicTp register, executor: DtpMainPropWrapper(dtpName=dynamic-tp-test-1, corePoolSize=6, maxPoolSize=8, keepAliveTime=50, queueType=VariableLinkedBlockingQueue, queueCapacity=200, rejectType=RejectedCountableCallerRunsPolicy, allowCoreThreadTimeOut=false)
```
+ 配置变更会推送通知消息,且会高亮变更的字段
```bash
DynamicTp [dynamic-tp-test-1] refresh end, changed keys: [corePoolSize, queueCapacity], corePoolSize: [6 => 4], maxPoolSize: [8 => 8], queueType: [VariableLinkedBlockingQueue => VariableLinkedBlockingQueue], queueCapacity: [200 => 2000], keepAliveTime: [50s => 50s], rejectedType: [CallerRunsPolicy => CallerRunsPolicy], allowsCoreThreadTimeOut: [false => false]
```
***
### 通知报警
+ 触发报警阈值会推送相应报警消息(活性、容量、拒绝),且会高亮显示相应字段
![](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/bb4b2d4390b14965b7470b708674ccbe~tplv-k3u1fbpfcp-zoom-1.image)
+ 配置变更会推送通知消息,且会高亮变更的字段
![](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/9fb3e28c1a4e4d46a3ecbf3427181576~tplv-k3u1fbpfcp-zoom-1.image)
***
### 监控日志
通过collectType属性配置监控指标采集类型,默认 logging
+ MicroMeter:通过引入相关MicroMeter依赖采集到相应的平台
(如Prometheus,InfluxDb...)
+ Logging:定时采集指标数据以Json日志格式输出磁盘,地址${logPath}/dy
namictp/${appName}.monitor.log
```bash
2022-01-11 00:25:20.599 INFO [dtp-monitor-thread-1:d.m.log] {"activeCount":0,"queueSize":0,"largestPoolSize":0,"poolSize":0,"rejectHandlerName":"RejectedCountableCallerRunsPolicy","queueCapacity":1024,"fair":false,"rejectCount":0,"waitTaskCount":0,"taskCount":0,"queueRemainingCapacity":1024,"corePoolSize":6,"queueType":"VariableLinkedBlockingQueue","completedTaskCount":0,"dtpName":"remoting-call","maximumPoolSize":8}
2022-01-11 00:25:25.603 INFO [dtp-monitor-thread-1:d.m.log] {"activeCount":0,"queueSize":0,"largestPoolSize":0,"poolSize":0,"rejectHandlerName":"RejectedCountableCallerRunsPolicy","queueCapacity":1024,"fair":false,"rejectCount":0,"waitTaskCount":0,"taskCount":0,"queueRemainingCapacity":1024,"corePoolSize":6,"queueType":"VariableLinkedBlockingQueue","completedTaskCount":0,"dtpName":"remoting-call","maximumPoolSize":8}
2022-01-11 00:25:30.609 INFO [dtp-monitor-thread-1:d.m.log] {"activeCount":0,"queueSize":0,"largestPoolSize":0,"poolSize":0,"rejectHandlerName":"RejectedCountableCallerRunsPolicy","queueCapacity":1024,"fair":false,"rejectCount":0,"waitTaskCount":0,"taskCount":0,"queueRemainingCapacity":1024,"corePoolSize":6,"queueType":"VariableLinkedBlockingQueue","completedTaskCount":0,"dtpName":"remoting-call","maximumPoolSize":8}
2022-01-11 00:25:35.613 INFO [dtp-monitor-thread-1:d.m.log] {"activeCount":0,"queueSize":0,"largestPoolSize":0,"poolSize":0,"rejectHandlerName":"RejectedCountableCallerRunsPolicy","queueCapacity":1024,"fair":false,"rejectCount":0,"waitTaskCount":0,"taskCount":0,"queueRemainingCapacity":1024,"corePoolSize":6,"queueType":"VariableLinkedBlockingQueue","completedTaskCount":0,"dtpName":"remoting-call","maximumPoolSize":8}
2022-01-11 00:25:40.616 INFO [dtp-monitor-thread-1:d.m.log] {"activeCount":0,"queueSize":0,"largestPoolSize":0,"poolSize":0,"rejectHandlerName":"RejectedCountableCallerRunsPolicy","queueCapacity":1024,"fair":false,"rejectCount":0,"waitTaskCount":0,"taskCount":0,"queueRemainingCapacity":1024,"corePoolSize":6,"queueType":"VariableLinkedBlockingQueue","completedTaskCount":0,"dtpName":"remoting-call","maximumPoolSize":8}
```
+ 暴露EndPoint端点(dynamic-tp),可以通过http方式请求
```json
[
{
"dtp_name": "remoting-call",
"core_pool_size": 6,
"maximum_pool_size": 12,
"queue_type": "SynchronousQueue",
"queue_capacity": 0,
"queue_size": 0,
"fair": false,
"queue_remaining_capacity": 0,
"active_count": 0,
"task_count": 21760,
"completed_task_count": 21760,
"largest_pool_size": 12,
"pool_size": 6,
"wait_task_count": 0,
"reject_count": 124662,
"reject_handler_name": "CallerRunsPolicy"
},
{
"max_memory": "228 MB",
"total_memory": "147 MB",
"free_memory": "44.07 MB",
"usable_memory": "125.07 MB"
}
]
```
***
### 联系我
对项目有什么想法或者建议,可以加我微信交流,或者创建[issues](https://github.com/lyh200/dynamic-tp-spring-cloud-starter/issues),一起完善项目
![](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/52693295459f45b88acb3846a8a6d618~tplv-k3u1fbpfcp-zoom-1.image)

View File

@ -1,4 +1,4 @@
package io.lyh.dynamic.tp.common;
package com.dtp.common;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;

View File

@ -1,6 +1,6 @@
package io.lyh.dynamic.tp.common;
package com.dtp.common;
import io.lyh.dynamic.tp.common.config.DtpProperties;
import com.dtp.common.config.DtpProperties;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.boot.ansi.AnsiColor;

View File

@ -24,7 +24,7 @@
* https://creativecommons.org/licenses/publicdomain
*/
package io.lyh.dynamic.tp.common;
package com.dtp.common;
import java.util.AbstractQueue;
import java.util.Collection;

View File

@ -1,7 +1,7 @@
package io.lyh.dynamic.tp.common.config;
package com.dtp.common.config;
import io.lyh.dynamic.tp.common.constant.DynamicTpConst;
import io.lyh.dynamic.tp.common.dto.NotifyPlatform;
import com.dtp.common.constant.DynamicTpConst;
import com.dtp.common.dto.NotifyPlatform;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.context.properties.ConfigurationProperties;
@ -81,7 +81,7 @@ public class DtpProperties {
private String dataId;
private String group = "DEFAULT_GROUP";;
private String group = "DEFAULT_GROUP";
private String namespace = "public";
}

View File

@ -1,10 +1,10 @@
package io.lyh.dynamic.tp.common.config;
package com.dtp.common.config;
import io.lyh.dynamic.tp.common.constant.DynamicTpConst;
import io.lyh.dynamic.tp.common.dto.NotifyItem;
import io.lyh.dynamic.tp.common.em.NotifyTypeEnum;
import io.lyh.dynamic.tp.common.em.QueueTypeEnum;
import io.lyh.dynamic.tp.common.em.RejectedTypeEnum;
import com.dtp.common.em.NotifyTypeEnum;
import com.dtp.common.em.QueueTypeEnum;
import com.dtp.common.constant.DynamicTpConst;
import com.dtp.common.dto.NotifyItem;
import com.dtp.common.em.RejectedTypeEnum;
import lombok.Data;
import java.util.List;

View File

@ -1,4 +1,4 @@
package io.lyh.dynamic.tp.common.constant;
package com.dtp.common.constant;
/**
* DingNotifyConst related

View File

@ -1,4 +1,4 @@
package io.lyh.dynamic.tp.common.constant;
package com.dtp.common.constant;
import com.google.common.collect.Lists;
@ -18,6 +18,8 @@ public class DynamicTpConst {
public static final String MAIN_PROPERTIES_PREFIX = "spring.dynamic.tp";
public static final String DTP_ENABLED_PROP = MAIN_PROPERTIES_PREFIX + ".enabled";
public static final int AVAILABLE_PROCESSORS = Runtime.getRuntime().availableProcessors();
public static final String PROPERTIES_CHANGE_SHOW_STYLE = "%s => %s";

View File

@ -1,4 +1,4 @@
package io.lyh.dynamic.tp.common.constant;
package com.dtp.common.constant;
/**
* Wechat alarm constant

View File

@ -1,4 +1,4 @@
package io.lyh.dynamic.tp.common.dto;
package com.dtp.common.dto;
import lombok.Data;

View File

@ -1,4 +1,4 @@
package io.lyh.dynamic.tp.common.dto;
package com.dtp.common.dto;
import lombok.AllArgsConstructor;
import lombok.Data;

View File

@ -1,4 +1,4 @@
package io.lyh.dynamic.tp.common.dto;
package com.dtp.common.dto;
import lombok.Data;

View File

@ -1,4 +1,4 @@
package io.lyh.dynamic.tp.common.dto;
package com.dtp.common.dto;
import lombok.Data;

View File

@ -1,4 +1,4 @@
package io.lyh.dynamic.tp.common.dto;
package com.dtp.common.dto;
import lombok.Data;

View File

@ -1,10 +1,10 @@
package io.lyh.dynamic.tp.common.dto;
package com.dtp.common.dto;
import com.google.common.collect.Lists;
import io.lyh.dynamic.tp.common.em.NotifyPlatformEnum;
import io.lyh.dynamic.tp.common.em.NotifyTypeEnum;
import com.dtp.common.em.NotifyPlatformEnum;
import com.dtp.common.em.NotifyTypeEnum;
import lombok.Data;
import java.util.ArrayList;
import java.util.List;
/**
@ -66,7 +66,7 @@ public class NotifyItem {
rejectNotify.setThreshold(1);
rejectNotify.setInterval(300);
DEFAULT_NOTIFY_ITEMS = Lists.newArrayList();
DEFAULT_NOTIFY_ITEMS = new ArrayList<>(4);
DEFAULT_NOTIFY_ITEMS.add(livenessNotify);
DEFAULT_NOTIFY_ITEMS.add(changeNotify);
DEFAULT_NOTIFY_ITEMS.add(capacityNotify);

View File

@ -1,4 +1,4 @@
package io.lyh.dynamic.tp.common.dto;
package com.dtp.common.dto;
import lombok.Data;

View File

@ -1,4 +1,4 @@
package io.lyh.dynamic.tp.common.dto;
package com.dtp.common.dto;
import lombok.Data;

View File

@ -1,4 +1,4 @@
package io.lyh.dynamic.tp.common.em;
package com.dtp.common.em;
import lombok.Getter;

View File

@ -1,4 +1,4 @@
package io.lyh.dynamic.tp.common.em;
package com.dtp.common.em;
import lombok.Getter;

View File

@ -1,4 +1,4 @@
package io.lyh.dynamic.tp.common.em;
package com.dtp.common.em;
/**
* Notify platform type.

View File

@ -1,4 +1,4 @@
package io.lyh.dynamic.tp.common.em;
package com.dtp.common.em;
import lombok.Getter;

View File

@ -1,7 +1,7 @@
package io.lyh.dynamic.tp.common.em;
package com.dtp.common.em;
import io.lyh.dynamic.tp.common.VariableLinkedBlockingQueue;
import io.lyh.dynamic.tp.common.ex.DtpException;
import com.dtp.common.VariableLinkedBlockingQueue;
import com.dtp.common.ex.DtpException;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;

View File

@ -1,4 +1,4 @@
package io.lyh.dynamic.tp.common.em;
package com.dtp.common.em;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
@ -14,7 +14,7 @@ import lombok.extern.slf4j.Slf4j;
public enum RejectedTypeEnum {
/**
* RejectedExecutionHandler type while trigger reject policy.
* RejectedExecutionHandler type while triggering reject policy.
*/
ABORT_POLICY("AbortPolicy"),
@ -26,13 +26,15 @@ public enum RejectedTypeEnum {
private final String name;
private static final String REJECTED_PREFIX = "RejectedCountable";
RejectedTypeEnum(String name) {
this.name = name;
}
public static String formatRejectName(String name) {
if (name.startsWith("RejectedCountable")) {
return name.replace("RejectedCountable", "");
if (name.startsWith(REJECTED_PREFIX)) {
return name.replace(REJECTED_PREFIX, "");
}
return name;
}

View File

@ -1,4 +1,4 @@
package io.lyh.dynamic.tp.common.ex;
package com.dtp.common.ex;
/**
* DtpException related

View File

@ -1,4 +1,4 @@
package io.lyh.dynamic.tp.common.util;
package com.dtp.common.util;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.binary.Base64;

View File

@ -1,4 +1,4 @@
package io.lyh.dynamic.tp.common.util;
package com.dtp.common.util;
import org.slf4j.Logger;

View File

@ -1,7 +1,7 @@
package io.lyh.dynamic.tp.common.util;
package com.dtp.common.util;
import io.lyh.dynamic.tp.common.config.DtpProperties;
import io.lyh.dynamic.tp.common.em.ConfigFileTypeEnum;
import com.dtp.common.config.DtpProperties;
import com.dtp.common.em.ConfigFileTypeEnum;
import org.apache.commons.lang3.StringUtils;
import org.springframework.core.env.Environment;

View File

@ -20,6 +20,32 @@
<artifactId>dynamic-tp-common</artifactId>
<version>1.0.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-core</artifactId>
<version>1.8.1</version>
<scope>compile</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>com.github.dadiyang</groupId>
<artifactId>equator</artifactId>
<version>1.0.4</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>transmittable-thread-local</artifactId>
<version>2.12.1</version>
</dependency>
</dependencies>
</project>

View File

@ -1,8 +1,8 @@
package io.lyh.dynamic.tp.core;
package com.dtp.core;
import io.lyh.dynamic.tp.common.em.NotifyTypeEnum;
import io.lyh.dynamic.tp.common.dto.NotifyItem;
import io.lyh.dynamic.tp.core.reject.RejectedCountableCallerRunsPolicy;
import com.dtp.common.dto.NotifyItem;
import com.dtp.common.em.NotifyTypeEnum;
import com.dtp.core.reject.RejectedCountableCallerRunsPolicy;
import java.util.List;
import java.util.concurrent.*;
@ -50,11 +50,6 @@ public class DtpExecutor extends ThreadPoolExecutor {
super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, threadFactory, handler);
}
@Override
public void execute(Runnable command) {
super.execute(command);
}
public void setThreadPoolName(String threadPoolName) {
this.threadPoolName = threadPoolName;
}

View File

@ -1,27 +1,27 @@
package io.lyh.dynamic.tp.core;
package com.dtp.core;
import cn.hutool.core.collection.CollUtil;
import com.dtp.core.helper.BuildHelper;
import com.dtp.core.helper.NotifyHelper;
import com.dtp.core.notify.AlarmLimiter;
import com.github.dadiyang.equator.Equator;
import com.github.dadiyang.equator.FieldInfo;
import com.github.dadiyang.equator.GetterBaseEquator;
import com.google.common.collect.Lists;
import io.lyh.dynamic.tp.common.dto.DtpMainProp;
import io.lyh.dynamic.tp.common.VariableLinkedBlockingQueue;
import io.lyh.dynamic.tp.common.constant.DynamicTpConst;
import io.lyh.dynamic.tp.common.em.NotifyTypeEnum;
import io.lyh.dynamic.tp.common.em.QueueTypeEnum;
import io.lyh.dynamic.tp.common.ex.DtpException;
import io.lyh.dynamic.tp.core.notify.AlarmLimiter;
import io.lyh.dynamic.tp.core.helper.NotifyHelper;
import io.lyh.dynamic.tp.common.config.DtpProperties;
import io.lyh.dynamic.tp.common.config.ThreadPoolProperties;
import io.lyh.dynamic.tp.core.context.DtpContext;
import io.lyh.dynamic.tp.core.context.DtpContextHolder;
import io.lyh.dynamic.tp.core.handler.NotifierHandler;
import io.lyh.dynamic.tp.common.em.RejectedTypeEnum;
import io.lyh.dynamic.tp.core.helper.BuildHelper;
import io.lyh.dynamic.tp.core.support.DtpCreator;
import io.lyh.dynamic.tp.core.thread.ThreadPoolBuilder;
import com.dtp.common.dto.DtpMainProp;
import com.dtp.common.VariableLinkedBlockingQueue;
import com.dtp.common.constant.DynamicTpConst;
import com.dtp.common.em.NotifyTypeEnum;
import com.dtp.common.em.QueueTypeEnum;
import com.dtp.common.ex.DtpException;
import com.dtp.common.config.DtpProperties;
import com.dtp.common.config.ThreadPoolProperties;
import com.dtp.core.context.DtpContext;
import com.dtp.core.context.DtpContextHolder;
import com.dtp.core.handler.NotifierHandler;
import com.dtp.common.em.RejectedTypeEnum;
import com.dtp.core.support.DtpCreator;
import com.dtp.core.thread.ThreadPoolBuilder;
import lombok.extern.slf4j.Slf4j;
import lombok.val;
import org.apache.commons.lang3.StringUtils;

View File

@ -1,9 +1,9 @@
package io.lyh.dynamic.tp.core.context;
package com.dtp.core.context;
import cn.hutool.core.collection.CollUtil;
import io.lyh.dynamic.tp.common.dto.NotifyItem;
import io.lyh.dynamic.tp.common.dto.NotifyPlatform;
import io.lyh.dynamic.tp.core.DtpExecutor;
import com.dtp.common.dto.NotifyItem;
import com.dtp.common.dto.NotifyPlatform;
import com.dtp.core.DtpExecutor;
import lombok.Builder;
import lombok.Data;
import lombok.val;

View File

@ -1,4 +1,4 @@
package io.lyh.dynamic.tp.core.context;
package com.dtp.core.context;
import com.alibaba.ttl.TransmittableThreadLocal;
@ -10,7 +10,7 @@ import com.alibaba.ttl.TransmittableThreadLocal;
*/
public class DtpContextHolder {
private static final TransmittableThreadLocal<DtpContext> CONTEXT = new TransmittableThreadLocal();
private static final TransmittableThreadLocal<DtpContext> CONTEXT = new TransmittableThreadLocal<>();
private DtpContextHolder() {}

View File

@ -1,10 +1,10 @@
package io.lyh.dynamic.tp.core.handler;
package com.dtp.core.handler;
import com.dtp.core.DtpExecutor;
import com.google.common.collect.Lists;
import io.lyh.dynamic.tp.core.DtpExecutor;
import io.lyh.dynamic.tp.core.monitor.collector.LogCollector;
import io.lyh.dynamic.tp.core.monitor.collector.MetricsCollector;
import io.lyh.dynamic.tp.core.monitor.collector.MicroMeterCollector;
import com.dtp.core.monitor.collector.LogCollector;
import com.dtp.core.monitor.collector.MetricsCollector;
import com.dtp.core.monitor.collector.MicroMeterCollector;
import lombok.extern.slf4j.Slf4j;
import java.util.List;

View File

@ -1,10 +1,10 @@
package io.lyh.dynamic.tp.core.handler;
package com.dtp.core.handler;
import com.google.common.collect.Lists;
import io.lyh.dynamic.tp.common.em.ConfigFileTypeEnum;
import io.lyh.dynamic.tp.core.parser.ConfigParser;
import io.lyh.dynamic.tp.core.parser.PropertiesConfigParser;
import io.lyh.dynamic.tp.core.parser.YamlConfigParser;
import com.dtp.common.em.ConfigFileTypeEnum;
import com.dtp.core.parser.ConfigParser;
import com.dtp.core.parser.PropertiesConfigParser;
import com.dtp.core.parser.YamlConfigParser;
import java.io.IOException;
import java.util.Collections;

View File

@ -1,12 +1,12 @@
package io.lyh.dynamic.tp.core.handler;
package com.dtp.core.handler;
import io.lyh.dynamic.tp.common.dto.DtpMainProp;
import io.lyh.dynamic.tp.common.dto.NotifyItem;
import io.lyh.dynamic.tp.common.em.NotifyTypeEnum;
import io.lyh.dynamic.tp.core.context.DtpContextHolder;
import io.lyh.dynamic.tp.core.notify.Notifier;
import io.lyh.dynamic.tp.core.notify.ding.DtpDingNotifier;
import io.lyh.dynamic.tp.core.notify.wechat.DtpWechatNotifier;
import com.dtp.common.dto.DtpMainProp;
import com.dtp.common.dto.NotifyItem;
import com.dtp.common.em.NotifyTypeEnum;
import com.dtp.core.context.DtpContextHolder;
import com.dtp.core.notify.Notifier;
import com.dtp.core.notify.ding.DtpDingNotifier;
import com.dtp.core.notify.wechat.DtpWechatNotifier;
import lombok.extern.slf4j.Slf4j;
import java.util.HashMap;

View File

@ -1,12 +1,12 @@
package io.lyh.dynamic.tp.core.helper;
package com.dtp.core.helper;
import io.lyh.dynamic.tp.common.dto.DtpMainProp;
import io.lyh.dynamic.tp.common.ex.DtpException;
import io.lyh.dynamic.tp.core.DtpExecutor;
import io.lyh.dynamic.tp.core.reject.RejectedCountableAbortPolicy;
import io.lyh.dynamic.tp.core.reject.RejectedCountableCallerRunsPolicy;
import io.lyh.dynamic.tp.core.reject.RejectedCountableDiscardOldestPolicy;
import io.lyh.dynamic.tp.core.reject.RejectedCountableDiscardPolicy;
import com.dtp.common.dto.DtpMainProp;
import com.dtp.common.ex.DtpException;
import com.dtp.core.DtpExecutor;
import com.dtp.core.reject.RejectedCountableAbortPolicy;
import com.dtp.core.reject.RejectedCountableCallerRunsPolicy;
import com.dtp.core.reject.RejectedCountableDiscardOldestPolicy;
import com.dtp.core.reject.RejectedCountableDiscardPolicy;
import lombok.extern.slf4j.Slf4j;
import java.util.Objects;
@ -14,7 +14,7 @@ import java.util.ServiceLoader;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.TimeUnit;
import static io.lyh.dynamic.tp.common.em.RejectedTypeEnum.*;
import static com.dtp.common.em.RejectedTypeEnum.*;
/**
* BuildHelper related

View File

@ -1,9 +1,9 @@
package io.lyh.dynamic.tp.core.helper;
package com.dtp.core.helper;
import io.lyh.dynamic.tp.common.dto.ThreadPoolMetrics;
import io.lyh.dynamic.tp.core.DtpExecutor;
import com.dtp.common.dto.ThreadPoolMetrics;
import com.dtp.core.DtpExecutor;
import static io.lyh.dynamic.tp.common.em.RejectedTypeEnum.formatRejectName;
import static com.dtp.common.em.RejectedTypeEnum.formatRejectName;
/**
* MetricsHelper related

View File

@ -1,10 +1,10 @@
package io.lyh.dynamic.tp.core.helper;
package com.dtp.core.helper;
import cn.hutool.core.collection.CollUtil;
import io.lyh.dynamic.tp.common.dto.NotifyItem;
import io.lyh.dynamic.tp.common.dto.NotifyPlatform;
import io.lyh.dynamic.tp.common.em.NotifyTypeEnum;
import io.lyh.dynamic.tp.core.DtpExecutor;
import com.dtp.common.dto.NotifyItem;
import com.dtp.common.dto.NotifyPlatform;
import com.dtp.common.em.NotifyTypeEnum;
import com.dtp.core.DtpExecutor;
import lombok.extern.slf4j.Slf4j;
import java.util.List;

View File

@ -1,13 +1,13 @@
package io.lyh.dynamic.tp.core.monitor;
package com.dtp.core.monitor;
import com.dtp.core.DtpExecutor;
import com.dtp.core.DtpRegistry;
import com.dtp.core.handler.CollectorHandler;
import com.dtp.core.notify.AlarmManager;
import com.dtp.core.thread.NamedThreadFactory;
import com.google.common.collect.Lists;
import io.lyh.dynamic.tp.common.config.DtpProperties;
import io.lyh.dynamic.tp.common.em.NotifyTypeEnum;
import io.lyh.dynamic.tp.core.DtpExecutor;
import io.lyh.dynamic.tp.core.DtpRegistry;
import io.lyh.dynamic.tp.core.handler.CollectorHandler;
import io.lyh.dynamic.tp.core.notify.AlarmManager;
import io.lyh.dynamic.tp.core.thread.NamedThreadFactory;
import com.dtp.common.config.DtpProperties;
import com.dtp.common.em.NotifyTypeEnum;
import lombok.extern.slf4j.Slf4j;
import lombok.val;
import org.springframework.boot.ApplicationArguments;

View File

@ -1,4 +1,4 @@
package io.lyh.dynamic.tp.core.monitor.collector;
package com.dtp.core.monitor.collector;
/**
* AbstractCollector related

View File

@ -1,10 +1,10 @@
package io.lyh.dynamic.tp.core.monitor.collector;
package com.dtp.core.monitor.collector;
import cn.hutool.json.JSONUtil;
import io.lyh.dynamic.tp.common.em.CollectorTypeEnum;
import io.lyh.dynamic.tp.common.util.LogUtil;
import io.lyh.dynamic.tp.core.DtpExecutor;
import io.lyh.dynamic.tp.core.helper.MetricsHelper;
import com.dtp.common.em.CollectorTypeEnum;
import com.dtp.common.util.LogUtil;
import com.dtp.core.DtpExecutor;
import com.dtp.core.helper.MetricsHelper;
/**
* LogCollector related

View File

@ -1,6 +1,6 @@
package io.lyh.dynamic.tp.core.monitor.collector;
package com.dtp.core.monitor.collector;
import io.lyh.dynamic.tp.core.DtpExecutor;
import com.dtp.core.DtpExecutor;
/**
* MetricsCollector related
@ -18,14 +18,14 @@ public interface MetricsCollector {
/**
* Collector type.
* @return
* @return collector type
*/
String type();
/**
* Judge collector type.
* @param type
* @return
* @param type collector type
* @return true if the collector supports this type, else false
*/
boolean support(String type);
}

View File

@ -0,0 +1,51 @@
package com.dtp.core.monitor.collector;
import com.dtp.common.dto.ThreadPoolMetrics;
import com.dtp.common.em.CollectorTypeEnum;
import com.dtp.core.DtpExecutor;
import com.dtp.core.helper.MetricsHelper;
import io.micrometer.core.instrument.Metrics;
import io.micrometer.core.instrument.Tag;
import lombok.extern.slf4j.Slf4j;
import java.util.Collections;
/**
* MicroMeterCollector related
*
* @author: yanhom
* @since 1.0.0
*/
@Slf4j
public class MicroMeterCollector extends AbstractCollector {
@Override
public void collect(DtpExecutor executor) {
gauge(MetricsHelper.getMetrics(executor));
}
@Override
public String type() {
return CollectorTypeEnum.MICROMETER.name();
}
public void gauge(ThreadPoolMetrics metrics) {
Iterable<Tag> tags = Collections.singletonList(Tag.of("thread.pool.name", metrics.getDtpName()));
Metrics.gauge("thread.pool.core.size", tags, metrics, ThreadPoolMetrics::getCorePoolSize);
Metrics.gauge("thread.pool.maximum.size", tags, metrics, ThreadPoolMetrics::getMaximumPoolSize);
Metrics.gauge("thread.pool.current.size", tags, metrics, ThreadPoolMetrics::getPoolSize);
Metrics.gauge("thread.pool.largest.size", tags, metrics, ThreadPoolMetrics::getLargestPoolSize);
Metrics.gauge("thread.pool.active.count", tags, metrics, ThreadPoolMetrics::getActiveCount);
Metrics.gauge("thread.pool.task.count", tags, metrics, ThreadPoolMetrics::getTaskCount);
Metrics.gauge("thread.pool.completed.task.count", tags, metrics, ThreadPoolMetrics::getCompletedTaskCount);
Metrics.gauge("thread.pool.wait.task.count", tags, metrics, ThreadPoolMetrics::getWaitTaskCount);
Metrics.gauge("thread.pool.queue.size", tags, metrics, ThreadPoolMetrics::getQueueSize);
Metrics.gauge("thread.pool.queue.capacity", tags, metrics, ThreadPoolMetrics::getQueueCapacity);
Metrics.gauge("thread.pool.queue.remaining.capacity", tags, metrics, ThreadPoolMetrics::getQueueRemainingCapacity);
Metrics.gauge("thread.pool.reject.count", tags, metrics, ThreadPoolMetrics::getRejectCount);
}
}

View File

@ -1,13 +1,13 @@
package io.lyh.dynamic.tp.core.monitor.endpoint;
package com.dtp.core.monitor.endpoint;
import cn.hutool.core.io.FileUtil;
import cn.hutool.system.RuntimeInfo;
import com.dtp.core.DtpExecutor;
import com.dtp.core.DtpRegistry;
import com.dtp.core.helper.MetricsHelper;
import com.google.common.collect.Lists;
import io.lyh.dynamic.tp.common.dto.JvmMetrics;
import io.lyh.dynamic.tp.common.dto.Metrics;
import io.lyh.dynamic.tp.core.DtpExecutor;
import io.lyh.dynamic.tp.core.DtpRegistry;
import io.lyh.dynamic.tp.core.helper.MetricsHelper;
import com.dtp.common.dto.JvmMetrics;
import com.dtp.common.dto.Metrics;
import org.springframework.boot.actuate.endpoint.annotation.Endpoint;
import org.springframework.boot.actuate.endpoint.annotation.ReadOperation;

View File

@ -1,22 +1,22 @@
package io.lyh.dynamic.tp.core.notify;
package com.dtp.core.notify;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.dtp.core.DtpExecutor;
import com.dtp.core.DtpRegistry;
import com.dtp.core.context.DtpContext;
import com.dtp.core.context.DtpContextHolder;
import com.google.common.base.Joiner;
import io.lyh.dynamic.tp.common.ApplicationContextHolder;
import io.lyh.dynamic.tp.common.dto.DtpMainProp;
import io.lyh.dynamic.tp.common.dto.Instance;
import io.lyh.dynamic.tp.common.constant.DynamicTpConst;
import io.lyh.dynamic.tp.common.dto.NotifyItem;
import io.lyh.dynamic.tp.common.dto.NotifyPlatform;
import io.lyh.dynamic.tp.common.em.NotifyTypeEnum;
import io.lyh.dynamic.tp.common.em.RejectedTypeEnum;
import io.lyh.dynamic.tp.core.context.DtpContext;
import io.lyh.dynamic.tp.core.context.DtpContextHolder;
import io.lyh.dynamic.tp.core.DtpExecutor;
import io.lyh.dynamic.tp.core.DtpRegistry;
import com.dtp.common.ApplicationContextHolder;
import com.dtp.common.dto.DtpMainProp;
import com.dtp.common.dto.Instance;
import com.dtp.common.constant.DynamicTpConst;
import com.dtp.common.dto.NotifyItem;
import com.dtp.common.dto.NotifyPlatform;
import com.dtp.common.em.NotifyTypeEnum;
import com.dtp.common.em.RejectedTypeEnum;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

View File

@ -1,9 +1,9 @@
package io.lyh.dynamic.tp.core.notify;
package com.dtp.core.notify;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import io.lyh.dynamic.tp.common.dto.NotifyItem;
import io.lyh.dynamic.tp.core.DtpExecutor;
import com.dtp.common.dto.NotifyItem;
import com.dtp.core.DtpExecutor;
import org.apache.commons.lang3.StringUtils;
import java.util.Map;

View File

@ -1,19 +1,19 @@
package io.lyh.dynamic.tp.core.notify;
package com.dtp.core.notify;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.NumberUtil;
import io.lyh.dynamic.tp.common.ApplicationContextHolder;
import io.lyh.dynamic.tp.common.config.DtpProperties;
import io.lyh.dynamic.tp.common.dto.NotifyItem;
import io.lyh.dynamic.tp.common.em.NotifyTypeEnum;
import io.lyh.dynamic.tp.common.em.QueueTypeEnum;
import io.lyh.dynamic.tp.common.em.RejectedTypeEnum;
import io.lyh.dynamic.tp.core.context.DtpContext;
import io.lyh.dynamic.tp.core.context.DtpContextHolder;
import io.lyh.dynamic.tp.core.DtpExecutor;
import io.lyh.dynamic.tp.core.handler.NotifierHandler;
import io.lyh.dynamic.tp.core.helper.NotifyHelper;
import io.lyh.dynamic.tp.core.thread.ThreadPoolBuilder;
import com.dtp.common.ApplicationContextHolder;
import com.dtp.common.config.DtpProperties;
import com.dtp.common.dto.NotifyItem;
import com.dtp.common.em.NotifyTypeEnum;
import com.dtp.common.em.QueueTypeEnum;
import com.dtp.common.em.RejectedTypeEnum;
import com.dtp.core.context.DtpContext;
import com.dtp.core.context.DtpContextHolder;
import com.dtp.core.DtpExecutor;
import com.dtp.core.handler.NotifierHandler;
import com.dtp.core.helper.NotifyHelper;
import com.dtp.core.thread.ThreadPoolBuilder;
import lombok.extern.slf4j.Slf4j;
import java.util.List;

View File

@ -1,7 +1,7 @@
package io.lyh.dynamic.tp.core.notify;
package com.dtp.core.notify;
import io.lyh.dynamic.tp.common.dto.DtpMainProp;
import io.lyh.dynamic.tp.common.em.NotifyTypeEnum;
import com.dtp.common.dto.DtpMainProp;
import com.dtp.common.em.NotifyTypeEnum;
import java.util.List;

View File

@ -1,14 +1,14 @@
package io.lyh.dynamic.tp.core.notify.ding;
package com.dtp.core.notify.ding;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import cn.hutool.json.JSONUtil;
import io.lyh.dynamic.tp.common.constant.DingNotifyConst;
import io.lyh.dynamic.tp.core.notify.AbstractNotifier;
import io.lyh.dynamic.tp.common.dto.MarkdownReq;
import io.lyh.dynamic.tp.common.dto.NotifyPlatform;
import io.lyh.dynamic.tp.common.util.DingSignUtil;
import com.dtp.common.constant.DingNotifyConst;
import com.dtp.core.notify.AbstractNotifier;
import com.dtp.common.dto.MarkdownReq;
import com.dtp.common.dto.NotifyPlatform;
import com.dtp.common.util.DingSignUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

View File

@ -1,14 +1,13 @@
package io.lyh.dynamic.tp.core.notify.ding;
package com.dtp.core.notify.ding;
import cn.hutool.core.util.StrUtil;
import io.lyh.dynamic.tp.common.constant.DingNotifyConst;
import io.lyh.dynamic.tp.common.dto.DtpMainProp;
import io.lyh.dynamic.tp.common.constant.DynamicTpConst;
import io.lyh.dynamic.tp.common.em.NotifyPlatformEnum;
import io.lyh.dynamic.tp.common.em.NotifyTypeEnum;
import io.lyh.dynamic.tp.common.dto.NotifyPlatform;
import io.lyh.dynamic.tp.core.context.DtpContext;
import io.lyh.dynamic.tp.core.context.DtpContextHolder;
import com.dtp.common.constant.DingNotifyConst;
import com.dtp.common.dto.DtpMainProp;
import com.dtp.common.em.NotifyPlatformEnum;
import com.dtp.common.em.NotifyTypeEnum;
import com.dtp.common.dto.NotifyPlatform;
import com.dtp.core.context.DtpContext;
import com.dtp.core.context.DtpContextHolder;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.tuple.ImmutablePair;
@ -16,9 +15,6 @@ import org.apache.commons.lang3.tuple.Pair;
import java.util.List;
import static io.lyh.dynamic.tp.common.constant.DingNotifyConst.CONTENT_COLOR;
import static io.lyh.dynamic.tp.common.constant.DingNotifyConst.WARNING_COLOR;
/**
* DtpDingNotifier related
*

View File

@ -1,12 +1,12 @@
package io.lyh.dynamic.tp.core.notify.wechat;
package com.dtp.core.notify.wechat;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import cn.hutool.json.JSONUtil;
import io.lyh.dynamic.tp.common.constant.WechatNotifyConst;
import io.lyh.dynamic.tp.common.dto.MarkdownReq;
import io.lyh.dynamic.tp.common.dto.NotifyPlatform;
import io.lyh.dynamic.tp.core.notify.AbstractNotifier;
import com.dtp.common.constant.WechatNotifyConst;
import com.dtp.common.dto.MarkdownReq;
import com.dtp.common.dto.NotifyPlatform;
import com.dtp.core.notify.AbstractNotifier;
import lombok.extern.slf4j.Slf4j;
import java.util.Objects;

View File

@ -1,12 +1,12 @@
package io.lyh.dynamic.tp.core.notify.wechat;
package com.dtp.core.notify.wechat;
import io.lyh.dynamic.tp.common.constant.WechatNotifyConst;
import io.lyh.dynamic.tp.common.dto.DtpMainProp;
import io.lyh.dynamic.tp.common.dto.NotifyPlatform;
import io.lyh.dynamic.tp.common.em.NotifyPlatformEnum;
import io.lyh.dynamic.tp.common.em.NotifyTypeEnum;
import io.lyh.dynamic.tp.core.context.DtpContext;
import io.lyh.dynamic.tp.core.context.DtpContextHolder;
import com.dtp.common.constant.WechatNotifyConst;
import com.dtp.common.dto.DtpMainProp;
import com.dtp.common.dto.NotifyPlatform;
import com.dtp.common.em.NotifyPlatformEnum;
import com.dtp.common.em.NotifyTypeEnum;
import com.dtp.core.context.DtpContext;
import com.dtp.core.context.DtpContextHolder;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.tuple.ImmutablePair;

View File

@ -1,6 +1,6 @@
package io.lyh.dynamic.tp.core.parser;
package com.dtp.core.parser;
import io.lyh.dynamic.tp.common.em.ConfigFileTypeEnum;
import com.dtp.common.em.ConfigFileTypeEnum;
/**
* AbstractConfigParser related

View File

@ -1,6 +1,6 @@
package io.lyh.dynamic.tp.core.parser;
package com.dtp.core.parser;
import io.lyh.dynamic.tp.common.em.ConfigFileTypeEnum;
import com.dtp.common.em.ConfigFileTypeEnum;
import java.io.IOException;
import java.util.List;
@ -16,22 +16,22 @@ public interface ConfigParser {
/**
* Judge type.
* @param type
* @return
* @param type config file type
* @return true if the parse supports this type, else false
*/
boolean supports(ConfigFileTypeEnum type);
/**
* Type: yaml, properties...
* @return
* @return the parse supports types.
*/
List<ConfigFileTypeEnum> type();
/**
* Parse content.
* @param content
* @return
* @throws IOException
* @param content content
* @return k-v properties
* @throws IOException if occurs error while parsing
*/
Map<Object, Object> doParse(String content) throws IOException;
}

View File

@ -1,7 +1,7 @@
package io.lyh.dynamic.tp.core.parser;
package com.dtp.core.parser;
import com.google.common.collect.Lists;
import io.lyh.dynamic.tp.common.em.ConfigFileTypeEnum;
import com.dtp.common.em.ConfigFileTypeEnum;
import java.io.IOException;
import java.io.StringReader;

View File

@ -1,8 +1,8 @@
package io.lyh.dynamic.tp.core.parser;
package com.dtp.core.parser;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import io.lyh.dynamic.tp.common.em.ConfigFileTypeEnum;
import com.dtp.common.em.ConfigFileTypeEnum;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.config.YamlPropertiesFactoryBean;
import org.springframework.core.io.ByteArrayResource;

View File

@ -1,10 +1,10 @@
package io.lyh.dynamic.tp.core.refresh;
package com.dtp.core.refresh;
import io.lyh.dynamic.tp.common.config.DtpProperties;
import io.lyh.dynamic.tp.common.constant.DynamicTpConst;
import io.lyh.dynamic.tp.common.em.ConfigFileTypeEnum;
import io.lyh.dynamic.tp.core.DtpRegistry;
import io.lyh.dynamic.tp.core.handler.ConfigHandler;
import com.dtp.common.config.DtpProperties;
import com.dtp.common.constant.DynamicTpConst;
import com.dtp.common.em.ConfigFileTypeEnum;
import com.dtp.core.DtpRegistry;
import com.dtp.core.handler.ConfigHandler;
import lombok.extern.slf4j.Slf4j;
import lombok.val;
import org.apache.commons.lang3.StringUtils;

View File

@ -1,6 +1,6 @@
package io.lyh.dynamic.tp.core.refresh;
package com.dtp.core.refresh;
import io.lyh.dynamic.tp.common.em.ConfigFileTypeEnum;
import com.dtp.common.em.ConfigFileTypeEnum;
/**
* Refresher related

View File

@ -1,8 +1,8 @@
package io.lyh.dynamic.tp.core.reject;
package com.dtp.core.reject;
import io.lyh.dynamic.tp.common.em.NotifyTypeEnum;
import io.lyh.dynamic.tp.core.notify.AlarmManager;
import io.lyh.dynamic.tp.core.DtpExecutor;
import com.dtp.common.em.NotifyTypeEnum;
import com.dtp.core.DtpExecutor;
import com.dtp.core.notify.AlarmManager;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ThreadPoolExecutor;
@ -17,7 +17,7 @@ public interface RejectedCountable extends RejectedExecutionHandler {
/**
* Do sth before reject.
* @param executor
* @param executor ThreadPoolExecutor instance
*/
default void beforeReject(ThreadPoolExecutor executor) {
if (executor instanceof DtpExecutor) {

View File

@ -1,4 +1,4 @@
package io.lyh.dynamic.tp.core.reject;
package com.dtp.core.reject;
import java.util.concurrent.ThreadPoolExecutor;

View File

@ -1,4 +1,4 @@
package io.lyh.dynamic.tp.core.reject;
package com.dtp.core.reject;
import java.util.concurrent.ThreadPoolExecutor;

View File

@ -1,4 +1,4 @@
package io.lyh.dynamic.tp.core.reject;
package com.dtp.core.reject;
import java.util.concurrent.ThreadPoolExecutor;

View File

@ -1,4 +1,4 @@
package io.lyh.dynamic.tp.core.reject;
package com.dtp.core.reject;
import java.util.concurrent.ThreadPoolExecutor;

View File

@ -1,7 +1,7 @@
package io.lyh.dynamic.tp.core.support;
package com.dtp.core.support;
import io.lyh.dynamic.tp.core.DtpExecutor;
import io.lyh.dynamic.tp.core.thread.ThreadPoolBuilder;
import com.dtp.core.DtpExecutor;
import com.dtp.core.thread.ThreadPoolBuilder;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.ThreadPoolExecutor;

View File

@ -1,7 +1,7 @@
package io.lyh.dynamic.tp.core.support;
package com.dtp.core.support;
import io.lyh.dynamic.tp.core.DtpExecutor;
import io.lyh.dynamic.tp.core.DtpRegistry;
import com.dtp.core.DtpExecutor;
import com.dtp.core.DtpRegistry;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;

View File

@ -1,4 +1,4 @@
package io.lyh.dynamic.tp.core.thread;
package com.dtp.core.thread;
import lombok.extern.slf4j.Slf4j;

View File

@ -1,16 +1,16 @@
package io.lyh.dynamic.tp.core.thread;
package com.dtp.core.thread;
import cn.hutool.core.collection.CollUtil;
import com.alibaba.ttl.threadpool.TtlExecutors;
import io.lyh.dynamic.tp.common.VariableLinkedBlockingQueue;
import io.lyh.dynamic.tp.common.constant.DynamicTpConst;
import io.lyh.dynamic.tp.common.em.NotifyTypeEnum;
import io.lyh.dynamic.tp.common.em.QueueTypeEnum;
import io.lyh.dynamic.tp.common.dto.NotifyItem;
import io.lyh.dynamic.tp.core.DtpExecutor;
import io.lyh.dynamic.tp.core.helper.BuildHelper;
import io.lyh.dynamic.tp.core.reject.RejectedCountableCallerRunsPolicy;
import io.lyh.dynamic.tp.common.em.RejectedTypeEnum;
import com.dtp.common.VariableLinkedBlockingQueue;
import com.dtp.common.constant.DynamicTpConst;
import com.dtp.common.em.NotifyTypeEnum;
import com.dtp.common.em.QueueTypeEnum;
import com.dtp.common.dto.NotifyItem;
import com.dtp.core.DtpExecutor;
import com.dtp.core.helper.BuildHelper;
import com.dtp.core.reject.RejectedCountableCallerRunsPolicy;
import com.dtp.common.em.RejectedTypeEnum;
import org.apache.commons.lang3.StringUtils;
import org.springframework.util.Assert;
@ -126,7 +126,7 @@ public class ThreadPoolBuilder {
* @param queueName queue name
* @param capacity queue capacity
* @param fair for SynchronousQueue
* @return
* @return ThreadPoolBuilder instance
*/
public ThreadPoolBuilder workQueue(String queueName, Integer capacity, Boolean fair) {
if (StringUtils.isNotBlank(queueName)) {
@ -169,7 +169,7 @@ public class ThreadPoolBuilder {
/**
* Build according to dynamic field.
* @return
* @return ThreadPoolExecutor instance
*/
public ThreadPoolExecutor build() {
if (dynamic) {
@ -181,7 +181,7 @@ public class ThreadPoolBuilder {
/**
* Build dynamic ThreadPoolExecutor.
* @return
* @return DtpExecutor instance
*/
public DtpExecutor buildDynamic() {
return buildDtpExecutor(this);
@ -189,7 +189,7 @@ public class ThreadPoolBuilder {
/**
* Build common ThreadPoolExecutor.
* @return
* @return ThreadPoolExecutor instance
*/
public ThreadPoolExecutor buildCommon() {
return buildCommonExecutor(this);
@ -198,7 +198,7 @@ public class ThreadPoolBuilder {
/**
* Build and wrapper with ttl
* @see com.alibaba.ttl.TransmittableThreadLocal
* @return
* @return ExecutorService instance
*/
public ExecutorService buildWithTtl() {
return TtlExecutors.getTtlExecutorService(buildCommonExecutor(this));

View File

@ -1,51 +0,0 @@
package io.lyh.dynamic.tp.core.monitor.collector;
import io.lyh.dynamic.tp.common.dto.ThreadPoolMetrics;
import io.lyh.dynamic.tp.common.em.CollectorTypeEnum;
import io.lyh.dynamic.tp.core.DtpExecutor;
import io.lyh.dynamic.tp.core.helper.MetricsHelper;
import io.micrometer.core.instrument.Metrics;
import io.micrometer.core.instrument.Tag;
import lombok.extern.slf4j.Slf4j;
import java.util.Collections;
/**
* MicroMeterCollector related
*
* @author: yanhom
* @since 1.0.0
*/
@Slf4j
public class MicroMeterCollector extends AbstractCollector {
@Override
public void collect(DtpExecutor executor) {
gauge(MetricsHelper.getMetrics(executor));
}
@Override
public String type() {
return CollectorTypeEnum.MICROMETER.name();
}
public void gauge(ThreadPoolMetrics metrics) {
Iterable<Tag> TAG = Collections.singletonList(Tag.of("thread.pool.name", metrics.getDtpName()));
Metrics.gauge("thread.pool.core.size", TAG, metrics, ThreadPoolMetrics::getCorePoolSize);
Metrics.gauge("thread.pool.maximum.size", TAG, metrics, ThreadPoolMetrics::getMaximumPoolSize);
Metrics.gauge("thread.pool.current.size", TAG, metrics, ThreadPoolMetrics::getPoolSize);
Metrics.gauge("thread.pool.largest.size", TAG, metrics, ThreadPoolMetrics::getLargestPoolSize);
Metrics.gauge("thread.pool.active.count", TAG, metrics, ThreadPoolMetrics::getActiveCount);
Metrics.gauge("thread.pool.task.count", TAG, metrics, ThreadPoolMetrics::getTaskCount);
Metrics.gauge("thread.pool.completed.task.count", TAG, metrics, ThreadPoolMetrics::getCompletedTaskCount);
Metrics.gauge("thread.pool.wait.task.count", TAG, metrics, ThreadPoolMetrics::getWaitTaskCount);
Metrics.gauge("thread.pool.queue.size", TAG, metrics, ThreadPoolMetrics::getQueueSize);
Metrics.gauge("thread.pool.queue.capacity", TAG, metrics, ThreadPoolMetrics::getQueueCapacity);
Metrics.gauge("thread.pool.queue.remaining.capacity", TAG, metrics, ThreadPoolMetrics::getQueueRemainingCapacity);
Metrics.gauge("thread.pool.reject.count", TAG, metrics, ThreadPoolMetrics::getRejectCount);
}
}

View File

@ -13,4 +13,39 @@
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bootstrap</artifactId>
</dependency>
<dependency>
<groupId>io.github.lyh200</groupId>
<artifactId>dynamic-tp-spring-cloud-starter-nacos</artifactId>
<version>1.0.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- <dependency>-->
<!-- <groupId>com.ctrip.framework.apollo</groupId>-->
<!-- <artifactId>apollo-client</artifactId>-->
<!-- <version>1.9.1</version>-->
<!-- </dependency>-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,20 @@
package com.dtp.example;
import com.dtp.core.DtpExecutor;
import com.dtp.core.support.DtpCreator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* DtpConfig related
*
* @author yanhom
*/
@Configuration
public class DtpConfig {
@Bean
public DtpExecutor dtpExecutor() {
return DtpCreator.createDynamicFast("dynamic-tp-test");
}
}

View File

@ -1,4 +1,4 @@
package io.lyh.dynamic.tp.example;
package com.dtp.example;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

View File

@ -0,0 +1,28 @@
package com.dtp.example;
import com.dtp.core.DtpExecutor;
import com.dtp.core.DtpRegistry;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* IndexController related
*
* @author yanhom
* @date 2021-08-13 下午11:49
*/
@RestController
@RequestMapping("/dtp")
public class IndexController {
private static final Logger logger = LogManager.getLogger();
@GetMapping("/test")
public void test() {
DtpExecutor dtpExecutor = DtpRegistry.getExecutor("dynamic-tp-test");
dtpExecutor.execute(() -> System.out.println("test"));
}
}

View File

@ -0,0 +1,24 @@
server:
port: 8099
spring:
application:
name: dynamic-tp-example
profiles:
active: dev
cloud:
nacos:
discovery:
server-addr: localhost:8848
config:
server-addr: ${spring.cloud.nacos.discovery.server-addr}
file-extension: yml
#apollo:
# bootstrap:
# enabled: true
# namespaces: application
# meta: http://localhost:8080
# config-service: http://localhost:8080
#app:
# id: dynamic-tp-example

View File

@ -20,5 +20,26 @@
<artifactId>dynamic-tp-common</artifactId>
<version>1.0.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>${logback.version}</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
<version>${logback.version}</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-context</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
</project>

View File

@ -1,9 +1,9 @@
package io.lyh.dynamic.tp.logging;
package com.dtp.logging;
import ch.qos.logback.classic.LoggerContext;
import ch.qos.logback.classic.util.ContextInitializer;
import io.lyh.dynamic.tp.common.ApplicationContextHolder;
import io.lyh.dynamic.tp.common.config.DtpProperties;
import com.dtp.common.ApplicationContextHolder;
import com.dtp.common.config.DtpProperties;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.impl.StaticLoggerBinder;
@ -37,7 +37,7 @@ public class DtpLogging {
}
String appName = ApplicationContextHolder.getEnvironment().getProperty("spring.application.name");
appName = StringUtils.isNoneBlank(appName) ? appName : "application";
appName = StringUtils.isNotBlank(appName) ? appName : "application";
System.setProperty(APP_NAME, appName);
}

View File

@ -1,5 +1,6 @@
package io.lyh.dynamic.tp.logging;
package com.dtp.logging;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.context.event.ApplicationStartedEvent;
import org.springframework.cloud.bootstrap.BootstrapImportSelectorConfiguration;
@ -17,6 +18,7 @@ import java.util.Set;
* @author: yanhom
* @since 1.0.0
**/
@Slf4j
public class DtpLoggingListener implements GenericApplicationListener {
@Override
@ -30,14 +32,20 @@ public class DtpLoggingListener implements GenericApplicationListener {
@Override
public void onApplicationEvent(ApplicationEvent applicationEvent) {
Class<?> type = applicationEvent.getSource().getClass();
if (SpringApplication.class.isAssignableFrom(type)) {
SpringApplication application = (SpringApplication) applicationEvent.getSource();
Set<Object> sources = application.getAllSources();
if (sources.size() == 1 && sources.contains(BootstrapImportSelectorConfiguration.class)) {
return;
try {
Class.forName("org.springframework.cloud.bootstrap.BootstrapImportSelectorConfiguration");
Class<?> type = applicationEvent.getSource().getClass();
if (SpringApplication.class.isAssignableFrom(type)) {
SpringApplication application = (SpringApplication) applicationEvent.getSource();
Set<Object> sources = application.getAllSources();
if (sources.size() == 1 && sources.contains(BootstrapImportSelectorConfiguration.class)) {
return;
}
}
} catch (ClassNotFoundException e) {
log.warn("DynamicTp logging init, not spring cloud application.");
}
DtpLogging.getInstance().loadConfiguration();
}

84
pom.xml
View File

@ -15,10 +15,13 @@
<properties>
<java.version>1.8</java.version>
<spring-boot.version>2.5.8</spring-boot.version>
<spring-cloud.version>2020.0.5</spring-cloud.version>
<spring-cloud-alibaba.version>2021.1</spring-cloud-alibaba.version>
<hutool.version>5.5.1</hutool.version>
<lombok.version>1.18.22</lombok.version>
<apollo.version>1.9.1</apollo.version>
<logback.version>1.2.10</logback.version>
<guava.version>31.0.1-jre</guava.version>
</properties>
<modules>
@ -30,6 +33,11 @@
</modules>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
@ -41,10 +49,9 @@
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
<scope>compile</scope>
<optional>true</optional>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>${guava.version}</version>
</dependency>
<dependency>
@ -58,59 +65,6 @@
<artifactId>hutool-all</artifactId>
<version>${hutool.version}</version>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
<scope>compile</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.ctrip.framework.apollo</groupId>
<artifactId>apollo-client</artifactId>
<version>${apollo.version}</version>
<scope>compile</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.github.dadiyang</groupId>
<artifactId>equator</artifactId>
<version>1.0.4</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>transmittable-thread-local</artifactId>
<version>2.12.1</version>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>31.0.1-jre</version>
</dependency>
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-core</artifactId>
<version>1.8.1</version>
<scope>compile</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
<dependencyManagement>
@ -123,6 +77,14 @@
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
@ -130,6 +92,14 @@
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
<version>${spring-boot.version}</version>
<scope>compile</scope>
<optional>true</optional>
</dependency>
</dependencies>
</dependencyManagement>

View File

@ -2,37 +2,24 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>io.github.lyh200</groupId>
<artifactId>dynamic-tp-all</artifactId>
<version>1.0.0-SNAPSHOT</version>
</parent>
<artifactId>dynamic-tp-spring-boot-starter</artifactId>
<packaging>jar</packaging>
<artifactId>dynamic-tp-starter</artifactId>
<packaging>pom</packaging>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>io.github.lyh200</groupId>
<artifactId>dynamic-tp-common</artifactId>
<version>1.0.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>io.github.lyh200</groupId>
<artifactId>dynamic-tp-core</artifactId>
<version>1.0.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>io.github.lyh200</groupId>
<artifactId>dynamic-tp-logging</artifactId>
<version>1.0.0-SNAPSHOT</version>
</dependency>
</dependencies>
<modules>
<module>starter-common</module>
<module>starter-apollo</module>
<module>starter-nacos</module>
</modules>
</project>

View File

@ -1,113 +0,0 @@
package io.lyh.dynamic.tp.starter;
import com.alibaba.cloud.nacos.NacosConfigProperties;
import io.lyh.dynamic.tp.common.ApplicationContextHolder;
import io.lyh.dynamic.tp.common.DtpBannerPrinter;
import io.lyh.dynamic.tp.common.config.DtpProperties;
import io.lyh.dynamic.tp.common.constant.DynamicTpConst;
import io.lyh.dynamic.tp.core.DtpRegistry;
import io.lyh.dynamic.tp.core.monitor.DtpMonitor;
import io.lyh.dynamic.tp.core.monitor.endpoint.DtpEndpoint;
import io.lyh.dynamic.tp.core.refresh.apollo.ApolloRefresher;
import io.lyh.dynamic.tp.core.refresh.nacos.CloudNacosRefresher;
import io.lyh.dynamic.tp.core.refresh.nacos.NacosRefresher;
import io.lyh.dynamic.tp.core.support.DtpPostProcessor;
import org.springframework.boot.actuate.autoconfigure.endpoint.condition.ConditionalOnAvailableEndpoint;
import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.annotation.Resource;
import static com.ctrip.framework.apollo.spring.config.PropertySourcesConstants.APOLLO_BOOTSTRAP_ENABLED;
/**
* DtpAutoConfiguration related
*
* @author: yanhom
* @since 1.0.0
**/
@Configuration
@ImportAutoConfiguration({DtpProperties.class})
@ConditionalOnProperty(prefix = DynamicTpConst.MAIN_PROPERTIES_PREFIX,
value = "enabled", matchIfMissing = true, havingValue = "true")
public class DtpAutoConfiguration {
@Resource
private DtpProperties properties;
@Bean
public ApplicationContextHolder dtpApplicationContextHolder() {
return new ApplicationContextHolder();
}
@Bean
@ConditionalOnMissingBean
public DtpBannerPrinter dtpBannerPrinter() {
return new DtpBannerPrinter(properties);
}
@Bean
@ConditionalOnMissingBean
public DtpPostProcessor dtpPostProcessor() {
return new DtpPostProcessor();
}
@Bean
@ConditionalOnMissingBean
public DtpRegistry dtpRegistry() {
return new DtpRegistry();
}
@Bean
@ConditionalOnMissingBean
public DtpMonitor DtpMonitor() {
return new DtpMonitor();
}
@Bean
@ConditionalOnMissingBean
@ConditionalOnAvailableEndpoint
public DtpEndpoint dtpEndpoint() {
return new DtpEndpoint();
}
@Configuration
@ConditionalOnClass(NacosConfigProperties.class)
protected static class SpringCloudNacosConfiguration {
@Bean
@ConditionalOnMissingBean()
public CloudNacosRefresher cloudNacosRefresher() {
return new CloudNacosRefresher();
}
}
@Configuration
@ConditionalOnClass(value = com.alibaba.nacos.api.config.ConfigService.class)
@ConditionalOnMissingClass(value = {"com.alibaba.cloud.nacos.NacosConfigProperties"})
protected static class NacosConfiguration {
@Bean
@ConditionalOnMissingBean()
public NacosRefresher nacosRefresher() {
return new NacosRefresher();
}
}
@Configuration
@ConditionalOnProperty(value = APOLLO_BOOTSTRAP_ENABLED, havingValue = "true")
@ConditionalOnClass(com.ctrip.framework.apollo.ConfigService.class)
protected static class ApolloConfiguration {
@Bean
@ConditionalOnMissingBean
public ApolloRefresher apolloRefresher() {
return new ApolloRefresher();
}
}
}

View File

@ -0,0 +1,41 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>io.github.lyh200</groupId>
<artifactId>dynamic-tp-starter</artifactId>
<version>1.0.0-SNAPSHOT</version>
</parent>
<artifactId>dynamic-tp-spring-boot-starter-apollo</artifactId>
<packaging>jar</packaging>
<dependencies>
<dependency>
<groupId>io.github.lyh200</groupId>
<artifactId>dynamic-tp-common</artifactId>
<version>1.0.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>io.github.lyh200</groupId>
<artifactId>dynamic-tp-core</artifactId>
<version>1.0.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>io.github.lyh200</groupId>
<artifactId>dynamic-tp-spring-boot-starter-common</artifactId>
<version>1.0.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.ctrip.framework.apollo</groupId>
<artifactId>apollo-client</artifactId>
<version>${apollo.version}</version>
<scope>compile</scope>
<optional>true</optional>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,33 @@
package com.dtp.starter.apollo.autoconfigure;
import com.dtp.common.constant.DynamicTpConst;
import com.dtp.starter.apollo.refresh.ApolloRefresher;
import com.dtp.starter.common.config.BaseBeanConfiguration;
import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import static com.ctrip.framework.apollo.spring.config.PropertySourcesConstants.APOLLO_BOOTSTRAP_ENABLED;
/**
* DtpAutoConfiguration related
*
* @author: yanhom
* @since 1.0.0
**/
@Configuration
@ConditionalOnClass(com.ctrip.framework.apollo.ConfigService.class)
@ConditionalOnProperty(value = {APOLLO_BOOTSTRAP_ENABLED, DynamicTpConst.DTP_ENABLED_PROP},
havingValue = "true", matchIfMissing = true)
@ImportAutoConfiguration({BaseBeanConfiguration.class})
public class DtpAutoConfiguration {
@Bean
@ConditionalOnMissingBean
public ApolloRefresher apolloRefresher() {
return new ApolloRefresher();
}
}

View File

@ -1,4 +1,4 @@
package io.lyh.dynamic.tp.core.refresh.apollo;
package com.dtp.starter.apollo.refresh;
import com.ctrip.framework.apollo.Config;
import com.ctrip.framework.apollo.ConfigChangeListener;
@ -6,9 +6,9 @@ import com.ctrip.framework.apollo.ConfigFile;
import com.ctrip.framework.apollo.ConfigService;
import com.ctrip.framework.apollo.core.enums.ConfigFileFormat;
import com.ctrip.framework.apollo.model.ConfigChangeEvent;
import io.lyh.dynamic.tp.common.config.DtpProperties;
import io.lyh.dynamic.tp.common.em.ConfigFileTypeEnum;
import io.lyh.dynamic.tp.core.refresh.AbstractRefresher;
import com.dtp.common.config.DtpProperties;
import com.dtp.common.em.ConfigFileTypeEnum;
import com.dtp.core.refresh.AbstractRefresher;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.InitializingBean;

View File

@ -0,0 +1,2 @@
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.dtp.starter.apollo.autoconfigure.DtpAutoConfiguration

View File

@ -0,0 +1,39 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>io.github.lyh200</groupId>
<artifactId>dynamic-tp-starter</artifactId>
<version>1.0.0-SNAPSHOT</version>
</parent>
<artifactId>dynamic-tp-spring-boot-starter-common</artifactId>
<packaging>jar</packaging>
<dependencies>
<dependency>
<groupId>io.github.lyh200</groupId>
<artifactId>dynamic-tp-common</artifactId>
<version>1.0.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>io.github.lyh200</groupId>
<artifactId>dynamic-tp-core</artifactId>
<version>1.0.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>io.github.lyh200</groupId>
<artifactId>dynamic-tp-logging</artifactId>
<version>1.0.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,70 @@
package com.dtp.starter.common.config;
import com.dtp.common.ApplicationContextHolder;
import com.dtp.common.DtpBannerPrinter;
import com.dtp.common.config.DtpProperties;
import com.dtp.common.constant.DynamicTpConst;
import com.dtp.core.DtpRegistry;
import com.dtp.core.monitor.DtpMonitor;
import com.dtp.core.monitor.endpoint.DtpEndpoint;
import com.dtp.core.support.DtpPostProcessor;
import org.springframework.boot.actuate.autoconfigure.endpoint.condition.ConditionalOnAvailableEndpoint;
import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.annotation.Resource;
/**
* BaseBeanConfiguration related
*
* @author: yanhom
* @since 1.0.0
**/
@Configuration
@ImportAutoConfiguration({DtpProperties.class})
@ConditionalOnProperty(prefix = DynamicTpConst.MAIN_PROPERTIES_PREFIX,
value = "enabled", matchIfMissing = true, havingValue = "true")
public class BaseBeanConfiguration {
@Resource
private DtpProperties properties;
@Bean
public ApplicationContextHolder dtpApplicationContextHolder() {
return new ApplicationContextHolder();
}
@Bean
@ConditionalOnMissingBean
public DtpBannerPrinter dtpBannerPrinter() {
return new DtpBannerPrinter(properties);
}
@Bean
@ConditionalOnMissingBean
public DtpPostProcessor dtpPostProcessor() {
return new DtpPostProcessor();
}
@Bean
@ConditionalOnMissingBean
public DtpRegistry dtpRegistry() {
return new DtpRegistry();
}
@Bean
@ConditionalOnMissingBean
public DtpMonitor dtpMonitor() {
return new DtpMonitor();
}
@Bean
@ConditionalOnMissingBean
@ConditionalOnAvailableEndpoint
public DtpEndpoint dtpEndpoint() {
return new DtpEndpoint();
}
}

View File

@ -1,4 +1,4 @@
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
io.lyh.dynamic.tp.starter.DtpAutoConfiguration
com.dtp.starter.common.config.BaseBeanConfiguration
org.springframework.context.ApplicationListener=\
io.lyh.dynamic.tp.logging.DtpLoggingListener
com.dtp.logging.DtpLoggingListener

View File

@ -0,0 +1,42 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>io.github.lyh200</groupId>
<artifactId>dynamic-tp-starter</artifactId>
<version>1.0.0-SNAPSHOT</version>
</parent>
<artifactId>dynamic-tp-spring-cloud-starter-nacos</artifactId>
<packaging>jar</packaging>
<dependencies>
<dependency>
<groupId>io.github.lyh200</groupId>
<artifactId>dynamic-tp-common</artifactId>
<version>1.0.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>io.github.lyh200</groupId>
<artifactId>dynamic-tp-core</artifactId>
<version>1.0.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>io.github.lyh200</groupId>
<artifactId>dynamic-tp-spring-boot-starter-common</artifactId>
<version>1.0.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
<scope>compile</scope>
<optional>true</optional>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,50 @@
package com.dtp.starter.nacos.autoconfigure;
import com.alibaba.cloud.nacos.NacosConfigProperties;
import com.dtp.common.constant.DynamicTpConst;
import com.dtp.starter.common.config.BaseBeanConfiguration;
import com.dtp.starter.nacos.refresh.CloudNacosRefresher;
import com.dtp.starter.nacos.refresh.NacosRefresher;
import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* DtpAutoConfiguration related
*
* @author: yanhom
* @since 1.0.0
**/
@Configuration
@ImportAutoConfiguration({BaseBeanConfiguration.class})
@ConditionalOnProperty(value = DynamicTpConst.DTP_ENABLED_PROP,
matchIfMissing = true, havingValue = "true")
public class DtpAutoConfiguration {
@Configuration
@ConditionalOnClass(NacosConfigProperties.class)
protected static class SpringCloudNacosConfiguration {
@Bean
@ConditionalOnMissingBean()
public CloudNacosRefresher cloudNacosRefresher() {
return new CloudNacosRefresher();
}
}
@Configuration
@ConditionalOnClass(value = com.alibaba.nacos.api.config.ConfigService.class)
@ConditionalOnMissingClass(value = {"com.alibaba.cloud.nacos.NacosConfigProperties"})
protected static class NacosConfiguration {
@Bean
@ConditionalOnMissingBean()
public NacosRefresher nacosRefresher() {
return new NacosRefresher();
}
}
}

View File

@ -1,14 +1,14 @@
package io.lyh.dynamic.tp.core.refresh.nacos;
package com.dtp.starter.nacos.refresh;
import com.alibaba.cloud.nacos.NacosConfigManager;
import com.alibaba.cloud.nacos.NacosConfigProperties;
import com.alibaba.nacos.api.config.listener.Listener;
import com.alibaba.nacos.api.exception.NacosException;
import io.lyh.dynamic.tp.common.config.DtpProperties;
import io.lyh.dynamic.tp.common.em.ConfigFileTypeEnum;
import io.lyh.dynamic.tp.common.util.NacosUtil;
import io.lyh.dynamic.tp.core.refresh.AbstractRefresher;
import io.lyh.dynamic.tp.core.support.DtpCreator;
import com.dtp.common.config.DtpProperties;
import com.dtp.common.em.ConfigFileTypeEnum;
import com.dtp.common.util.NacosUtil;
import com.dtp.core.refresh.AbstractRefresher;
import com.dtp.core.support.DtpCreator;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.core.env.Environment;

View File

@ -1,14 +1,14 @@
package io.lyh.dynamic.tp.core.refresh.nacos;
package com.dtp.starter.nacos.refresh;
import com.alibaba.nacos.api.annotation.NacosInjected;
import com.alibaba.nacos.api.config.ConfigService;
import com.alibaba.nacos.api.config.listener.Listener;
import com.alibaba.nacos.api.exception.NacosException;
import io.lyh.dynamic.tp.common.config.DtpProperties;
import io.lyh.dynamic.tp.common.em.ConfigFileTypeEnum;
import io.lyh.dynamic.tp.common.util.NacosUtil;
import io.lyh.dynamic.tp.core.refresh.AbstractRefresher;
import io.lyh.dynamic.tp.core.support.DtpCreator;
import com.dtp.common.config.DtpProperties;
import com.dtp.common.em.ConfigFileTypeEnum;
import com.dtp.common.util.NacosUtil;
import com.dtp.core.refresh.AbstractRefresher;
import com.dtp.core.support.DtpCreator;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.core.env.Environment;

View File

@ -0,0 +1,2 @@
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.dtp.starter.nacos.autoconfigure.DtpAutoConfiguration