当前位置:首页 > 科技  > 软件

Spring Boot + Nacos 实现了一个动态化线程池,非常实用!

来源: 责编: 时间:2024-02-04 08:59:05 319观看
导读在后台开发中,会经常用到线程池技术,对于线程池核心参数的配置很大程度上依靠经验。然而,由于系统运行过程中存在的不确定性,我们很难一劳永逸地规划一个合理的线程池参数。在对线程池配置参数进行调整时,一般需要对服务进

在后台开发中,会经常用到线程池技术,对于线程池核心参数的配置很大程度上依靠经验。然而,由于系统运行过程中存在的不确定性,我们很难一劳永逸地规划一个合理的线程池参数。在对线程池配置参数进行调整时,一般需要对服务进行重启,这样修改的成本就会偏高。一种解决办法就是,将线程池的配置放到平台侧,运行开发同学根据系统运行情况对核心参数进行动态配置。IhX28资讯网——每日最新资讯28at.com

本文以Nacos作为服务配置中心,以修改线程池核心线程数、最大线程数为例,实现一个简单的动态化线程池。IhX28资讯网——每日最新资讯28at.com

代码实现

1.依赖

<dependency>    <groupId>com.alibaba.cloud</groupId>    <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>    <version>2021.1</version></dependency><dependency>    <groupId>com.alibaba.cloud</groupId>    <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>    <version>2021.1</version></dependency><dependency>    <groupId>org.springframework.boot</groupId>    <artifactId>spring-boot-starter-web</artifactId></dependency><dependency>    <groupId>org.springframework.boot</groupId>    <artifactId>spring-boot-starter</artifactId></dependency>

2.配置yml文件

bootstrap.yml:IhX28资讯网——每日最新资讯28at.com

server:  port: 8010  # 应用名称(nacos会将该名称当做服务名称)spring:  application:    name: order-service  cloud:    nacos:      discovery:        namespace: public        server-addr: 192.168.174.129:8848      config:        server-addr: 192.168.174.129:8848        file-extension: yml

application.yml:IhX28资讯网——每日最新资讯28at.com

spring:  profiles:    active: dev

为什么要配置两个yml文件?IhX28资讯网——每日最新资讯28at.com

springboot中配置文件的加载是存在优先级顺序的,bootstrap优先级高于application。IhX28资讯网——每日最新资讯28at.com

nacos在项目初始化时,要保证先从配置中心进行配置拉取,拉取配置之后才能保证项目的正常启动。IhX28资讯网——每日最新资讯28at.com

3.nacos配置

登录到nacos管理页面,新建配置,如下图所示:IhX28资讯网——每日最新资讯28at.com

图片图片IhX28资讯网——每日最新资讯28at.com

注意Data ID的命名格式为,${spring.application.name}-${spring.profile.active}.${spring.cloud.nacos.config.file-extension} ,在本文中,Data ID的名字就是order-service-dev.yml。IhX28资讯网——每日最新资讯28at.com

图片图片IhX28资讯网——每日最新资讯28at.com

这里我们只配置了两个参数,核心线程数量和最大线程数。IhX28资讯网——每日最新资讯28at.com

4.线程池配置和nacos配置变更监听

@RefreshScope@Configurationpublic class DynamicThreadPool implements InitializingBean {    @Value("${core.size}")    private String coreSize;     @Value("${max.size}")    private String maxSize;     private static ThreadPoolExecutor threadPoolExecutor;     @Autowired    private NacosConfigManager nacosConfigManager;     @Autowired    private NacosConfigProperties nacosConfigProperties;     @Override    public void afterPropertiesSet() throws Exception {        //按照nacos配置初始化线程池        threadPoolExecutor = new ThreadPoolExecutor(Integer.parseInt(coreSize), Integer.parseInt(maxSize), 10L, TimeUnit.SECONDS,                new LinkedBlockingQueue<>(10),                new ThreadFactoryBuilder().setNameFormat("c_t_%d").build(),                new RejectedExecutionHandler() {                    @Override                    public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {                        System.out.println("rejected!");                    }                });         //nacos配置变更监听        nacosConfigManager.getConfigService().addListener("order-service-dev.yml", nacosConfigProperties.getGroup(),                new Listener() {                    @Override                    public Executor getExecutor() {                        return null;                    }                     @Override                    public void receiveConfigInfo(String configInfo) {                        //配置变更,修改线程池配置                        System.out.println(configInfo);                        changeThreadPoolConfig(Integer.parseInt(coreSize), Integer.parseInt(maxSize));                    }                });    }     /**     * 打印当前线程池的状态     */    public String printThreadPoolStatus() {        return String.format("core_size:%s,thread_current_size:%s;" +                        "thread_max_size:%s;queue_current_size:%s,total_task_count:%s", threadPoolExecutor.getCorePoolSize(),                threadPoolExecutor.getActiveCount(), threadPoolExecutor.getMaximumPoolSize(), threadPoolExecutor.getQueue().size(),                threadPoolExecutor.getTaskCount());    }     /**     * 给线程池增加任务     *     * @param count     */    public void dynamicThreadPoolAddTask(int count) {        for (int i = 0; i < count; i++) {            int finalI = i;            threadPoolExecutor.execute(new Runnable() {                @Override                public void run() {                    try {                        System.out.println(finalI);                        Thread.sleep(10000);                    } catch (InterruptedException e) {                        e.printStackTrace();                    }                }            });        }    }     /**     * 修改线程池核心参数     *     * @param coreSize     * @param maxSize     */    private void changeThreadPoolConfig(int coreSize, int maxSize) {        threadPoolExecutor.setCorePoolSize(coreSize);        threadPoolExecutor.setMaximumPoolSize(maxSize);    }}

这个代码就是实现动态线程池和核心了,需要说明的是:IhX28资讯网——每日最新资讯28at.com

  • @RefreshScope:这个注解用来支持nacos的动态刷新功能;
  • @Value("${max.size}"),@Value("${core.size}"):这两个注解用来读取我们上一步在nacos配置的具体信息;同时,nacos配置变更时,能够实时读取到变更后的内容
  • nacosConfigManager.getConfigService().addListener:配置监听,nacos配置变更时实时修改线程池的配置。

5.controller

为了观察线程池动态变更的效果,增加Controller类。IhX28资讯网——每日最新资讯28at.com

@RestController@RequestMapping("/threadpool")public class ThreadPoolController {     @Autowired    private DynamicThreadPool dynamicThreadPool;     /**     * 打印当前线程池的状态     */    @GetMapping("/print")    public String printThreadPoolStatus() {        return dynamicThreadPool.printThreadPoolStatus();    }     /**     * 给线程池增加任务     *     * @param count     */    @GetMapping("/add")    public String dynamicThreadPoolAddTask(int count) {        dynamicThreadPool.dynamicThreadPoolAddTask(count);        return String.valueOf(count);    }}

6.测试

启动项目,访问http://localhost:8010/threadpool/print打印当前线程池的配置。IhX28资讯网——每日最新资讯28at.com

图片图片IhX28资讯网——每日最新资讯28at.com

可以看到,这个就是我们之前在nacos配置的线程数。IhX28资讯网——每日最新资讯28at.com

访问http://localhost:8010/threadpool/add?count=20增加20个任务,重新打印线程池配置IhX28资讯网——每日最新资讯28at.com

图片图片IhX28资讯网——每日最新资讯28at.com

可以看到已经有线程在排队了。IhX28资讯网——每日最新资讯28at.com

为了能够看到效果,我们多访问几次/add接口,增加任务数,在控制台出现拒绝信息时调整nacos配置。IhX28资讯网——每日最新资讯28at.com

图片图片IhX28资讯网——每日最新资讯28at.com

此时,执行/add命令时,所有的线程都会提示rejected。IhX28资讯网——每日最新资讯28at.com

调整nacos配置,将核心线程数调整为50,最大线程数调整为100.IhX28资讯网——每日最新资讯28at.com

图片图片IhX28资讯网——每日最新资讯28at.com

重新多次访问/add接口增加任务,发现没有拒绝信息了。这时,打印具体的线程状态,发现线程池参数修改成功。IhX28资讯网——每日最新资讯28at.com

图片IhX28资讯网——每日最新资讯28at.com

总结

这里,只是简单实现了一个可以调整核心线程数和最大线程数的动态线程池。具体的线程池实现原理可以参考美团的这篇文章:https://tech.meituan.com/2020/04/02/java-pooling-pratice-in-meituan.html,结合监控告警等实现一个完善的动态线程池产品。IhX28资讯网——每日最新资讯28at.com

优秀的轮子还有好多,比如Hippo4J ,使用起来和dynamic-tp差不多。Hippo4J 有无依赖中间件实现动静线程池,也有默认实现Nacos和Apollo的版本,而dynamic-tp 默认实现依赖Nacos或Apollo。IhX28资讯网——每日最新资讯28at.com

本文链接:http://www.28at.com/showinfo-26-72425-0.htmlSpring Boot + Nacos 实现了一个动态化线程池,非常实用!

声明:本网页内容旨在传播知识,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。邮件:2376512515@qq.com

上一篇: 微信发布公告:打击网络赌博类违法行为,涉赌账号将被限制支付能力、封号

下一篇: 没研究过SynchronousQueue源码,就别写精通线程池

标签:
  • 热门焦点
  • 一加Ace2 Pro官宣:普及16G内存 引领24G

    一加官方今天继续为本月发布的新机一加Ace2 Pro带来预热,公布了内存方面的信息。“淘汰 8GB ,12GB 起步,16GB 普及,24GB 引领,还有呢?#一加Ace2Pro#,2023 年 8 月,敬请期待。”同时
  • 7月安卓手机性能榜:红魔8S Pro再夺榜首

    7月份的手机市场风平浪静,除了红魔和努比亚带来了两款搭载骁龙8Gen2领先版处理器的新机之外,别的也想不到有什么新品了,这也正常,通常6月7月都是手机厂商修整的时间,进入8月份之
  • 得物效率前端微应用推进过程与思考

    一、背景效率工程随着业务的发展,组织规模的扩大,越来越多的企业开始意识到协作效率对于企业团队的重要性,甚至是决定其在某个行业竞争中突围的关键,是企业长久生存的根本。得物
  • JVM优化:实战OutOfMemoryError异常

    一、Java堆溢出堆内存中主要存放对象、数组等,只要不断地创建这些对象,并且保证 GC Roots 到对象之间有可达路径来避免垃 圾收集回收机制清除这些对象,当这些对象所占空间超过
  • 自律,给不了Keep自由!

    来源 | 互联网品牌官作者 | 李大为编排 | 又耳 审核 | 谷晓辉自律能不能给用户自由暂时不好说,但大概率不能给Keep自由。近日,全球最大的在线健身平台Keep正式登陆港交所,努力
  • 腾讯VS网易,最卷游戏暑期档,谁能笑到最后?

    作者:无锈钵来源:财经无忌7月16日晚,上海1862时尚艺术中心。伴随着幻象的精准命中,硕大的荧幕之上,比分被定格在了14:12,被寄予厚望的EDG战队以绝对的优势战胜了BLG战队,拿下了总决
  • 机构称Q2全球智能手机出货量同比下滑11% 苹果份额依旧第2

    7月20日消息,据外媒报道,研究机构的报告显示,由于需求下滑,今年二季度全球智能手机的出货量,同比下滑了11%,三星、苹果等主要厂商的销量,较去年同期均有下
  • SN570 NVMe SSD固态硬盘 价格与性能兼具

    SN570 NVMe SSD固态硬盘是西部数据发布的最新一代WD Blue系列的固态硬盘,不仅闪存技术更为精进,性能也得到了进一步的跃升。WD Blue SN570 NVMe SSD的包装外
  • 北京:科技教育体验基地开始登记

      北京“科技馆之城”科技教育体验基地登记和认证工作日前启动。首批北京科技教育体验基地拟于2023年全国科普日期间挂牌,后续还将开展常态化登记。  北京科技教育体验基
Top