The background,
Although after careful evaluation, is still not able to guarantee a calculated the appropriate parameters, when we adjust parameters of the thread pool, needs to be deployed to work for the application, so if we can modify the parameters of the thread pool costs down, so at least can happen failure can quickly adjust to shorten the time of fault recovery? Based on this consideration, whether we can migrate the thread pool parameters from the code or configuration file to the distributed configuration center such as ZooKeeper, Appllo and NACOS, so that the thread pool parameters can be dynamically configured and take effect immediately.
The comparison of parameter modification processes before and after dynamic thread pool parameters is as follows:
Second, the overall design
The core design of dynamic thread pools includes the following three aspects:
-
Simplify thread pool configuration: There are eight thread pool construction parameters, but the core three are corePoolSize, maximumPoolSize, and workQueue, which most determine the task allocation and thread allocation strategy of the thread pool. Considering that in practical application, there are mainly two scenarios for obtaining concurrency :(1) parallel execution of sub-tasks to improve response speed. In this case, a synchronous queue should be used, and no task should be cached, but should be executed immediately. (2) Perform a large number of tasks in parallel to improve throughput. In this case, bounded queues should be used. Queues should be used to buffer large numbers of tasks, and queue capacity must be declared to prevent unrestricted accumulation of tasks. So the thread pool only needs to provide the configuration of these three key parameters
-
Parameters can be dynamically modified: in order to solve the problem of parameter mismatch and high cost of modifying parameters. On the basis of the high scalability of Java thread pool, encapsulate the thread pool, allowing the thread pool to listen for messages outside the synchronization, and modify the configuration according to the message. The thread pool configuration is placed on the platform side, allowing developers to easily view and modify the thread pool configuration.
-
Add thread pool monitoring: Lack of observation of something’s state makes it impossible to improve. Add the ability to monitor the life cycle of thread pool tasks to help developers understand thread pool status.
Iii. Module classification
Dynamic thread pool is mainly divided into the following modules:
4. Functional architecture
Dynamic thread pools provide the following functions:
1. Dynamically adjust thread pool parameters
Dynamic adjustment of thread pool parameters and interface operation are supported. Including modifying thread pool core size, maximum core size, queue length, queue type, etc. After parameters are modified, they take effect immediately
Principle: The thread pool parameters are changed through the visual management platform of the thread pool and pushed to the NACOS configuration center. The dynamic-Thread-pool-Autoconfigure module will monitor the NACOS, sense the change of thread pool parameters in real time, and then set the response parameters to take effect in real time. ThreadPoolExecutor provides setCorePoolSize (), setMaximumPoolSzie (), setRejectedExecutionHandle () method, is to carry on the dynamic parameters of the thread pool configuration. However, blocking queues themselves do not provide methods to modify the queue size, so we need to inherit AbstractQueue and add a setCapacity() method.
2. Real-time monitoring
You can view the running status of the thread pool in real time, including the number of active threads, queue size, and completed threads.
3. Load alarms are generated
In addition to parameter dynamics, in order to make good use of thread pools, we need to be aware of the health of the thread pool. For example, what is the current load of the thread pool? Are the resources allocated adequate? What was the performance of the mission? Based on the thinking of these problems, the dynamic thread pool provides multiple dimensions of monitoring and warning ability, including: thread pool activity, Reject abnormality, thread pool internal statistics, and so on, which can help users analyze the usage of the thread pool from multiple dimensions, and can immediately inform to the user in the event of a problem, to avoid failure or accelerated failure recovery.
The core issue of thread pool load is whether there are enough resources allocated based on the current thread pool parameters. We can approach this question from both antecedent and middle perspectives. Beforehand, thread pool, defines the concept of “active” to let the user able to perceive the thread pool before occurrence Reject abnormal load problem, the thread pool activity calculation formula is: thread pool activity = activeCount/maximumPoolSize. This formula represents a higher thread load as the number of active threads approaches maximumPoolSize. There is a Reject exception, and there is a waiting task in the queue (custom threshold is supported). When the preceding two situations occur, an alarm will be triggered, and the alarm information will be pushed to the person in charge of the service through the mailbox, Tongs, and wechat of the enterprise. You can also view historical alarm records on the management platform.
V. Access mode
1. Maven reference method
<! Add dependencies to pom.xml -->
<dependency>
<groupId>com.cyy.threadpool</groupId>
<artifactId>cxm-dynamic-thread-pool-starter</artifactId>
<version>1.0 the SNAPSHOT</version>
</dependency>
Copy the code
2. Configuration files
## application.yml
nacos:
config:
bootstrap:
enable: true
log:
enable: true
type: yaml
server-addr: mse-6fa4aba2-nacos-ans.mse.aliyuncs.com:8848
namespace: bc619399-bc3f-4af1-8b11-bbb5d964e528
context-path: nacos
data-id: fcs-web
auto-refresh: true
group: DEFAULT_GROUP
Add a configuration to the original configuration of nacOS
ext-config:
- auto-refresh: true
config-long-poll-timeout: 46000
config-retry-time: 30000
data-id: fcs-web-dynamic-thread-pool The data-id of the current applied thread pool corresponds to the following thread pool configuration
enable-remote-sync-config: true
group: dynamic_thread_pool ## is fixed
max-retry: 10
type: yaml
# dynamic-thread-pool.yml To dynamically refresh the thread pool configuration, changes to the thread pool configuration take effect in real time
dynamic:
threadpools:
nacosDataId: fcs-web-dynamic-thread-pool
nacosGroup: dynamic_thread_pool
nacosWaitRefreshConfigSeconds: 1
db:
type: mysql
alarm:
enabled: true
alarmTimeInterval: 2
apiAlarmUrl: https://treecem.com/api/test
wxRobotApiUrl: https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=192547a4-8d93-4b55-a885
dingDing:
accessToken: widaiwe9123h129
secret: 2381je912hj39123ij
email:
host: smtp.exmail.qq.com
username: [email protected]
password: 9123nbidaawiudi
port: 587
properties:
toUsers:
- [email protected]
- [email protected]
executors:
- threadPoolName: dynamic-thread-pool
owner: admin
alarmEnable: true
corePoolSize: 5
maximumPoolSize: 10
queueCapacity: 10
keepAliveTime: 0
queueType: DynamicLinkedBlockingQueue
rejectedExecutionType: AbortPolicy
activeRateCapacityThreshold: 80
queueCapacityThreshold: 10
fair: true
Copy the code
3. Parameter Description
Parameter names | Must be | The default value | instructions |
---|---|---|---|
dynamic.threadpools.nacosDataId | no | There is no | Nacos configures the dataId for the center, which must be configured if dynamic adjustment of thread pool parameters is to be implemented |
dynamic.threadpools.nacosGroup | no | dynamic_thread_pool | Nacos The nacosGroup of the configuration center, which is always dynamic_thread_pool, cannot be modified. This parameter must be configured to dynamically adjust thread pool parameters |
dynamic.threadpools.db.type | no | empty | The persistence type currently supports mysql mongodb |
dynamic.threadpools.alarm.enabled | no | false | Whether to enable warning push |
dynamic.threadpools.alarm.alarmTimeInterval | no | 1 minute | Warning push interval, unit: minute |
dynamic.threadpools.alarm.apiAlarmUrl | no | empty | The URL of the alert push is POST and JSON request |
dynamic.threadpools.alarm.wxRobotApiUrl | no | empty | Enterprise wechat robot push address |
dynamic.threadpools.alarm.dingDing.accessToken | no | empty | Nailing token |
dynamic.threadpools.alarm.dingDing.secret | no | empty | Nailing secret |
dynamic.threadpools.alarm.email.host | no | empty | host |
dynamic.threadpools.alarm.email.username | no | empty | E-mail account |
dynamic.threadpools.alarm.email.password | no | empty | Your password |
dynamic.threadpools.alarm.email.port | no | empty | port |
dynamic.threadpools.alarm.email.properties | no | empty | Additional parameters |
dynamic.threadpools.alarm.email.toUsers | no | empty | Recipient email address list |
dynamic.threadpools.executors.threadPoolName | is | Dynamic-Thread-Pool | Thread pool name |
dynamic.threadpools.executors.ower | no | empty | Thread pool principal |
dynamic.threadpools.executors.alarmEnable | no | false | Whether to enable alarm |
dynamic.threadpools.executors.corePoolSize | is | 1 | Resident thread size |
dynamic.threadpools.executors.maximumPoolSize | is | Number of CPU core | Maximum number of threads. Default is CPU cores |
dynamic.threadpools.executors.queueCapacity | is | 1000 | Task queue size |
dynamic.threadpools.executors.keepAliveTime | is | 0 | When the space time reaches the keepAliveTime value, the extra threads are destroyed until only corePoolSize remains |
dynamic.threadpools.executors.queueType | no | DynamicLinkedBlockingQueue | Task queue type, DynamicLinkedBlockingQueue (dynamically resize), LinkedBlockingQueue, SynchronousQueue will, ArrayBlockingQueue, DelayQueue, LinkedTransferQue Ue, LinkedBlockingDeque, PriorityBlockingQueue |
dynamic.threadpools.executors.rejectedExecutionType | no | DISCARD_POLICY | Reject policy, CallerRunsPolicy, AbortPolicy, DiscardPolicy, DiscardOldestPolicy |
dynamic.threadpools.executors.activeRateCapacityThreshold | no | – 1 | Activity alarm threshold, default -1, indicates no alarm |
dynamic.threadpools.executors.queueCapacityThreshold | no | – 1 | Queue accumulation warning threshold, default -1, indicates no warning |
dynamic.threadpools.executors.fair | no | false | Fair policy. The configuration takes effect when queueType is SynchronousQueue |
4. Alarm information
Return information
[warning] application: shop - service (IP) : 127.0.0.1 [thread pool name] : dynamic - thread - pool] [warning: the activeCount/maximumPoolSize value of (100), a touch of threshold (80). [Thread pool parameter]: ThreadPoolName: dynamic-thread-pool corePoolSize: 5 maximumPoolSize: 10 queueCapacity: 10 keepAliveTime: 0 unit: MILLISECONDS rejectedExecutionType: AbortPolicy queueType: DynamicLinkedBlockingQueue fair: false queueCapacityThreshold: 10 activeRateCapacityThreshold: 80 queueSize: 10 activeCount: 10 activeRate: 100 completeTaskCount: 0 largestPoolSize: 10 rejectCount: 0 [Service owner]:admin [Alarm interval]:2 minutesCopy the code
Parameters that
parameter | instructions |
---|---|
threadPoolName | Thread pool name |
corePoolSize | Resident threads |
maximumPoolSize | Maximum number of threads |
queueCapacity | Maximum size of a task queue |
keepAliveTime | Thread lifetime |
unit | Unit of time |
rejectedExecutionType | Task rejection strategy |
queueType | Queue type |
fair | Fair strategy |
queueCapacityThreshold | Queue task accumulation threshold |
activeRateCapacityThreshold | Activity alarm threshold |
queueSize | The queue length |
activeCount | Active threads |
activeRate | active |
completeTaskCount | Number of completed tasks |
largestPoolSize | Maximum number of tasks in a queue history |
rejectCount | Task rejection number |
5, use
public class DynamicThreadPoolDemo{
@Autowired
private DynamicThreadPoolManager dynamicThreadPoolManager;
/ * * * *@author admin
* @date2021/04/10 answering *@paramThreadPoolName Specifies the name of the thread pool configured in the configuration center */
public void submitTask(String threadPoolName){
dynamicThreadPoolManager.getThreadPoolExecutor(threadPoolName).execute(() -> {
// TODO handles tasks
}, "I'm a hell of a mission.");
}
/** * Get thread pool running information in real time *@author admin
* @date2021/04/10 answering *@paramThreadPoolName Specifies the name of the thread pool configured in the configuration center */
public ThreadPoolIndicatorInfo getThreadPoolIndicatorInfo(String threadPoolName){
returndynamicThreadPoolManager.getThreadPoolIndicatorInfo(threadPoolName); }}// Customize the alarm processing class
@ThreadPoolAlarmListener
public class MyThreadPoolAlarmNotify implements ThreadPoolAlarmNotify{
@Override
public void alarmNotify(AlarmMessage alarmMessage){
// TODO handles alarm information by itself
log.info("message:", alarmMessage.getMessage()); }}// A custom thread pool runs a listener class that receives messages every 5 seconds by default
@ThreadPoolIndicatorListener
public class MyThreadPoolIndicatorNotify implements ThreadPoolIndicatorNotify {
@Override
public void indicatorNotify(List<ThreadPoolIndicatorInfo> indicatorInfoList) {
// TODO processes indicator informationSystem.out.println(JSON.toJSONString(indicatorInfoList)); }}Copy the code
Source code portal
Six, description,
This project refers to the United States of a thread pool article to achieve, the source code is pulled out from the company’s early version, can be used normally, but there are still imperfect place!