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:

  1. 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

  2. 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.

  3. 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!