Wow4j Wow4j
首页
个人使用说明书
后端开发
前端开发
测试开发
运维开发
大数据开发
产品&UI交互
团队管理
软技能
他山之石
开源产品
敬请期待
GitHub (opens new window)
首页
个人使用说明书
后端开发
前端开发
测试开发
运维开发
大数据开发
产品&UI交互
团队管理
软技能
他山之石
开源产品
敬请期待
GitHub (opens new window)
  • 概要
  • 面试八股文

  • 服务端小技巧合集

    • byte buddy 实现链路上所有方法耗时打印
    • 业务线程池不丢 traceId 的方法
    • 让你的java业务代码并发的调用,并正确的处理返回结果
    • 服务端常见线上问题整理与解决措施
    • 服务端日志打印最佳实践
    • 轻松正确理解并上手RESTful
    • 服务端业务线程池优雅使用
    • 服务端如何正确优雅使用流控平台
    • 服务端如何正确的使用分布式锁防止缓存击穿
    • 服务端接口设计最佳实践
  • Java基础

  • MySQL 相关

  • Redis 最佳实践指南

  • 文本搜索Elasticsearch

  • Kafka 最佳实践指南

  • 网络相关

  • 架构相关

  • 监控告警

  • 防爬风控

  • 稳定性 checklist

  • 效能工具

  • 后端开发
  • 服务端小技巧合集
timchen525
2022-11-16

服务端业务线程池优雅使用


/**
 * 线程池配置
 *
 * @author chenjintian
 * @date 2019/9/27
 */
@Configuration
@EnableAsync
@Slf4j
public class ThreadPoolConfig {

    private static final String TRACE_ID = "traceId";
    private CommonThreadPoolProperties commonThreadPoolProperties;
    private RedisOperatorThreadPoolProperties redisOperatorThreadPoolProperties;

    @Autowired
    public ThreadPoolConfig(CommonThreadPoolProperties commonThreadPoolProperties, RedisOperatorThreadPoolProperties redisOperatorThreadPoolProperties) {
        this.commonThreadPoolProperties = commonThreadPoolProperties;
        this.redisOperatorThreadPoolProperties = redisOperatorThreadPoolProperties;
    }

    /**
     * 公共线程池
     *
     * <p> 如果觉得不是很重要的服务可以统一用一个线程池
     */
    @Bean(value = "commonThreadPoolTaskExecutor")
    public ThreadPoolTaskExecutor commonThreadPoolTaskExecutor() {
        return getThreadPoolTaskExecutor(commonThreadPoolProperties);
    }

    /**
     * redis 操作线程池
     */
    @Bean(value = "redisOperatorThreadPoolTaskExecutor")
    public ThreadPoolTaskExecutor redisOperatorThreadPoolTaskExecutor() {
        // todo 监听线程池使用的情况

        return getThreadPoolTaskExecutor(redisOperatorThreadPoolProperties);
    }

    /**
     * 根据线程池的属性值获取对应线程的设置
     *
     * @param baseThreadPoolProperties 线程池配置信息
     * @return 线程池
     */
    private ThreadPoolTaskExecutor getThreadPoolTaskExecutor(BaseThreadPoolProperties baseThreadPoolProperties) {
        ThreadPoolTaskExecutor threadPoolTaskExecutor = new ThreadPoolTaskExecutor();
        if (StringUtils.isNotBlank(baseThreadPoolProperties.getThreadGroupName())) {
            threadPoolTaskExecutor.setThreadGroupName(baseThreadPoolProperties.getThreadGroupName());
        }
        if (StringUtils.isNotBlank(baseThreadPoolProperties.getThreadNamePrefix())) {
            threadPoolTaskExecutor.setThreadNamePrefix(baseThreadPoolProperties.getThreadNamePrefix());
        }
        if (null != baseThreadPoolProperties.getCorePoolSize() && baseThreadPoolProperties.getCorePoolSize() > 0) {
            threadPoolTaskExecutor.setCorePoolSize(baseThreadPoolProperties.getCorePoolSize());
        }
        if (null != baseThreadPoolProperties.getQueueCapacity() && baseThreadPoolProperties.getQueueCapacity() > 0) {
            threadPoolTaskExecutor.setQueueCapacity(baseThreadPoolProperties.getQueueCapacity());
        }
        if (null != baseThreadPoolProperties.getMaxPoolSize() && baseThreadPoolProperties.getMaxPoolSize() > 0) {
            threadPoolTaskExecutor.setMaxPoolSize(baseThreadPoolProperties.getMaxPoolSize());
        }
        if (null != baseThreadPoolProperties.getKeepAliveSeconds() && baseThreadPoolProperties.getKeepAliveSeconds() > 0) {
            threadPoolTaskExecutor.setKeepAliveSeconds(baseThreadPoolProperties.getKeepAliveSeconds());
        }
        // 设置拒绝策略
        if (StringUtils.isNotBlank(baseThreadPoolProperties.getRejectedPolicy())) {
            ThreadPoolRejectedPolicyEnum threadPoolRejectedPolicyEnum = ThreadPoolRejectedPolicyEnum.toEnum(baseThreadPoolProperties.getRejectedPolicy());
            if (null != threadPoolRejectedPolicyEnum) {
                threadPoolTaskExecutor.setRejectedExecutionHandler(threadPoolRejectedPolicyEnum.getRejectedExecutionHandler());
            } else {
                log.warn("Not exist rejectedPolicy:{}, return threadPoolRejectedPolicyEnum null.", baseThreadPoolProperties.getRejectedPolicy());
            }
        }
        // 设置MdcRunnable
        threadPoolTaskExecutor.setTaskDecorator(new MdcTaskDecorator());
        return threadPoolTaskExecutor;
    }

    /**
     * 主线程traceId传入到子线程(注意:线程池池化)
     */
    private static class MdcTaskDecorator implements TaskDecorator {

        @Override
        public Runnable decorate(Runnable runnable) {
            String traceId = MDC.get(TRACE_ID);
            return () -> {
                try {
                    MDC.put(TRACE_ID, traceId);
                    runnable.run();
                } finally {
                    MDC.remove(TRACE_ID);
                }
            };
        }
    }
}
上次更新: 2023/03/22, 15:21:20
轻松正确理解并上手RESTful
服务端如何正确优雅使用流控平台

← 轻松正确理解并上手RESTful 服务端如何正确优雅使用流控平台→

Theme by Vdoing | Copyright © 2022-2023 timchen525 | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式
×