🍏自定义线程池
# 线程池隔离
Gobrs-Async 提供线程池配置隔离机制。 不同的规则可以使用不同的线程池,防止某一条任务规则出现性能瓶颈后影响其他流程规则的执行。
如果规则不做线程池配置。 那么默认会使用统一的线程池配置。 如果也没有做统一的线程池配置。则SDK会默认使用 Executors.newCachedThreadPool()
# 自定义固定线程池(API方式)
Gobrs-Async 默认使用的是 Executors.newCachedThreadPool()
的线程池, 如果你想自定义线程池。满足自己的线程池需求。
只需要 继承GobrsThreadPoolConfiguration
重写doInitialize
方法,如下:
@Configuration
public class ThreadPoolConfig extends GobrsThreadPoolConfiguration {
@Override
protected void doInitialize(GobrsAsyncThreadPoolFactory factory) {
/**
* 自定义线程池
*/
ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(300, 500, 30, TimeUnit.SECONDS,
new LinkedBlockingQueue());
// ExecutorService executorService = Executors.newCachedThreadPool();
factory.setDefaultThreadPoolExecutor(threadPoolExecutor);
// factory.setThreadPoolExecutor("ruleName",threadPoolExecutor); // 设置规则隔离的线程池 ruleName 为 yml中配置的规则名称
}
}
# 配置方式
# 默认线程池配置
gobrs:
async:
config:
## 如果规则没有制定 线程池 则使用 统一的线程池配置 如果通过 API 的方式动态更新了线程池 则使用动态更新 替换配置文件线程池配置 参见: ThreadPoolConfig
thread-pool:
core-pool-size: 1000
max-pool-size: 2000
# 自定义规则配置
如果开发者针对流程规则做了单独的线程池配置。 那么会优先使用规则自定义的配置。也就是如下:caseOne
流程 会使用 线程池配置为corePoolSize: 10 maxPoolSize: 20
gobrs:
async:
config:
## 如果规则没有制定 线程池 则使用 统一的线程池配置 如果通过 API 的方式动态更新了线程池 则使用动态更新 替换配置文件线程池配置 参见: ThreadPoolConfig
thread-pool:
core-pool-size: 1000
max-pool-size: 2000
rules:
- name: "caseOne"
content: "caseOneTaskA->caseOneTaskB,caseOneTaskC,caseOneTaskD"
threadPool:
corePoolSize: 10
maxPoolSize: 20
# 官方场景二 https://async.sizegang.cn/pages/2f844b/#%E5%9C%BA%E6%99%AF%E4%BA%8C
- name: "caseTwo"
content: "caseTwoTaskA->caseTwoTaskB->caseTwoTaskC,caseTwoTaskD"
threadPool:
corePoolSize: 30
maxPoolSize: 40
# 热更新线程池
开发者可能有这种苦恼,线程池在运行时是在项目初始化的时候从application.yml
中 加载的, 一旦程序运行起来之后,就无法修改使用的线程池了。
如果自己公司有分布式配置中心,可以实时更新程序内存的应用的话,那么gobrs也为你提供了入口。
在我们公司是有自己的热更新组件的,所有可以如下使用:
# 配置中心配置
{
corePoolSize: 210,
maxPoolSize: 600,
keepAliveTime: 30,
capacity: 10000,
threadNamePrefix: "m-detail"
rejectedExecutionHandler: "CallerRunsPolicy"
}
@Slf4j
@Configuration
public class ThreadPoolConfig {
@Autowired
private GobrsAsyncThreadPoolFactory factory;
@Resource
private DUCCConfigService duccConfigService;
@PostConstruct
public void gobrsThreadPoolExecutor() {
// 从配置中心拿到 线程池配置规则 DuccConstant.GOBRS_ASYNC_THREAD_POOL 为线程池配置在配置中心的key
String config = duccConfigService.getString(DuccConstant.GOBRS_ASYNC_THREAD_POOL);
ThreadPool threadPool = JSONObject.parseObject(config, ThreadPool.class);
// 通过gobrs-async 提供的构造器进行构造线程池
ThreadPoolExecutor executor = ThreadPoolBuilder.buildByThreadPool(threadPool);
factory.setDefaultThreadPoolExecutor(executor); // 设置默认线程池
// factory.setThreadPoolExecutor("ruleName",threadPoolExecutor); // 设置规则隔离线程池
listenerDucc();
}
// 监听配置中心 线程池改动
private void listenerDucc() {
duccConfigService.addListener(new DuccListener(DuccConstant.GOBRS_ASYNC_THREAD_POOL, property -> {
log.warn("监听到DUCC配置GobrsAsync 线程池配置变更,property:{}", JSON.toJSONString(property.getValue()));
ThreadPool threadPool = JSONObject.parseObject(property.getValue().toString(), ThreadPool.class);
ThreadPoolExecutor executor = ThreadPoolBuilder.buildByThreadPool(threadPool);
factory.setThreadPoolExecutor(executor);
// 线程池更新成功
log.warn("GobrsAsync thread pool update success");
}));
}
}
# 配置优先级
实时更新配置 > API配置 > (yml、yaml、properties) 配置
- name: 技术小屋
desc: 大道至简,知易行难
avatar: https://cdn.jsdelivr.net/gh/xugaoyi/image_store/blog/20200122153807.jpg # 可选
link: https://docs.sizegang.cn/ # 可选
bgColor: '#CBEAFA' # 可选,默认var(--bodyBg)。颜色值有#号时请添加单引号
textColor: '#6854A1' # 可选,默认var(--textColor)
- name: 架构师必经之路
desc: '精品学习资源'
avatar: https://cdn.jsdelivr.net/gh/xaoxuu/assets@master/avatar/avatar.png
link: https://learn.sizegang.cn
bgColor: '#718971'
textColor: '#fff'
- name: 平凡的你我
desc: 快乐购物,享受生活
avatar: https://reinness.com/avatar.png
link: https://m.jd.com
bgColor: '#FCDBA0'
textColor: '#A05F2C'
Last Updated: 1/6/2023, 9:59:30 AM