线程池配置化

解决问题:1.服务中有众多的线程池,如何进行管理?

                   2.如何动态的生成线程池减少代码量的维护

                  3.线程池如何进行动态设置并生效

目前上开源框架dynamic-tp 可以通过配置化中心来解决刷新线程池的问题,但依旧还有改善的空间,

1.如何获取系统中有哪些线程池的配置

2.如何快速批量更新配置

3.如果做到不同服务器,不同配置

4.不用注册中心依旧能进行项目定制化开发

重点使用:spring bean的生命周期执行方法来实现beandefinition加载,从而实现动态加载目的

目录

一、github项目

二、核心代码


一、github项目

GitHub - haohaounique/xpool

1.到自己的数据库中执行脚本

2.配置属性文件中mysql连接

3.修改数据库配置测试

二、核心代码

package com.xpool.config;

import com.alibaba.fastjson2.JSON;
import com.xpool.bean.ConfigThread;
import com.xpool.enums.RejectedExecutionHandlerEnum;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.GenericBeanDefinition;
import org.springframework.context.EnvironmentAware;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.core.env.Environment;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import java.sql.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * description: 通过加载数据库配置到达动态控制线程池参数的目的
 */
@Slf4j
public class DBThreadPoolInit implements ImportBeanDefinitionRegistrar, EnvironmentAware {


    private Environment environment;

    @Override
    public void setEnvironment(Environment environment) {
        this.environment = environment;
    }

    @Override
    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
        log.info("registerBeanDefinitions start .....");
        List<ConfigThread> threads = loadDataFromDB(environment);
        log.info("registerBeanDefinitions init config:{}", JSON.toJSONString(threads));
        registerBean(registry, threads);
        log.info("registerBeanDefinitions end .....");
    }

    private static void registerBean(BeanDefinitionRegistry registry, List<ConfigThread> threads) {
        Map<String, Object> propertyValues = new HashMap<>();
        for (ConfigThread thread : threads) {
            propertyValues.put("corePoolSize", thread.getCorePoolSize());
            propertyValues.put("maxPoolSize", thread.getMaxPoolSize());
            propertyValues.put("keepAliveSeconds", thread.getKeepAliveSeconds());
            propertyValues.put("queueCapacity", thread.getQueueCapacity());
            propertyValues.put("allowCoreThreadTimeOut", false);
            propertyValues.put("rejectedExecutionHandler", RejectedExecutionHandlerEnum.getHandlerByName(thread.getRejectedExecutionHandler()));
            propertyValues.put("threadGroup", new ThreadGroup(thread.getThreadGroupName()));
            propertyValues.put("beanName", thread.getBeanName());
            GenericBeanDefinition beanDefinition = new GenericBeanDefinition();
            beanDefinition.setBeanClass(ThreadPoolTaskExecutor.class);
            for (Map.Entry<String, Object> entry : propertyValues.entrySet()) {
                beanDefinition.getPropertyValues().addPropertyValue(entry.getKey(), entry.getValue());
            }
            registry.registerBeanDefinition(thread.getBeanName(), beanDefinition);
            propertyValues.clear(); //用完一次清理一次
        }
    }

    public List<ConfigThread> loadDataFromDB(Environment environment) {
        List<ConfigThread> list = new ArrayList<>();
        try {
            //加载mysql驱动
            Class.forName(environment.getProperty("spring.datasource.driver-class-name"));
            //获取数据库连接
            Connection conn = DriverManager.getConnection(environment.getProperty("spring.datasource.url"), environment.getProperty("spring.datasource.username"), environment.getProperty("spring.datasource.password"));
            //编写sql语句
            String sql = "select id,bean_name,core_pool_size,max_pool_size,keep_alive_seconds,queue_capacity,rejected_execution_handler,thread_group_name,v_json from config_thread ";
            //创建Statement
            Statement statement = conn.createStatement();
            //执行sql语句
            ResultSet r = statement.executeQuery(sql);
            while (r.next()) {
                ConfigThread thread = new ConfigThread();
                thread.setId(r.getInt("id"));
                thread.setBeanName(r.getString("bean_name"));
                thread.setCorePoolSize(r.getInt("core_pool_size"));
                thread.setMaxPoolSize(r.getInt("max_pool_size"));
                thread.setKeepAliveSeconds(r.getInt("keep_alive_seconds"));
                thread.setQueueCapacity(r.getInt("queue_capacity"));
                thread.setRejectedExecutionHandler(r.getString("rejected_execution_handler"));
                thread.setThreadGroupName(r.getString("thread_group_name"));
                thread.setVJson(r.getString("v_json"));
                list.add(thread);
            }
            if (r != null) {
                r.close();
            }
            if (statement != null) {
                statement.close();
            }
            if (conn != null) {
                conn.close();
            }
        } catch (ClassNotFoundException e) {
            throw new RuntimeException(e);
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
        return list;
    }


}

配置效果

当修改配置调用刷新方法,再次请求,通过jdk\bin下的VisualVm工具查看

刷新方法:http://localhost:8080/updateTask

测试方法:http://localhost:8080/getTask

猜你喜欢

转载自blog.csdn.net/haohaounique/article/details/131838980