目录

大橙子

VX:ZzzChChen
Phone:13403656751
Email:zxydczzs@gmail.com

X

Hippo4j动态线程池监控接入

简单了解

线程池痛点

原文摘录

线程池是一张基于池化思想管理线程的工具,使用线程池可以减少创建销毁线程的开销,避免线程过多导致系统资源耗尽。在高并发以及大批量的任务处理场景,线程池的使用是必不可少的。

如果有在项目中实际使用线程池,相信你可能会遇到一下痛点

  • 线程池随便定义,线程资源过多,造成服务器高负载;
  • 线程池参数不易评估,随着业务的并发提升,业务面临出现故障的风险;
  • 线程池任务执行时间超过平均时间,开发人员无法感知;
  • 线程池任务堆积,触发拒绝策略,影响既有业务正常运行;
  • 当业务出现超时、熔断等问题时,因为没有监控,无法确定是不是线程池引起;
  • 原生线程池不支持运行时变量的传递,比如MDC上下文遇到线程池就GC。
  • 无法执行优雅关闭,当项目关闭时,大量正在运行的线程池任务被丢弃;
  • 线程池运行中,任务执行停止,怀疑发生死锁或执行耗时操作,但是无从下手;

如果同学们有以上的问题或者疑问,接着往下看。

什么是Hippo4j

原文摘录

Hippo4j通过对 JDK 线程池增强,以及扩展三方框架底层线程池等功能,为业务系统提高线上运行保障能力。

提供一下功能支持

  • 全局管控 - 管理应用线程池实例;
  • 动态变更 - 应用运行时动态变成线程池参数,包括不限于:核心、最大线程数、阻塞队列容量、拒绝策略等。
  • 通知报警 - 内置四种报警通知策略,线程池活跃度、容量水位、拒绝策略以及任务执行时间超长;
  • 运行监控 - 实时查看线程池运行时数据,最近半小时线程池运行数据图表展示;
  • 功能扩展 - 支持线程池任务传递上下文,项目关闭时,支持等待线程池在指定时间内完成任务;
  • 多种模式 - 内置两种使用模式:依赖配置中心 和 无中间件依赖。
  • 容器管理 - Tomcat、Jetty、Undertow容器线程池运行时查看和线程数变更;
  • 框架适配 - Dubbo、Hystrix、RabbitMQ、RocketMQ等消费线程池运行时数据查看和线程数变更。

正文

采用源码编译以及无中间件依赖方式

一、拉取源码以及前期准备

源码地址
  1. github:https://github.com/opengoofy/hippo4j;
  2. gitee:https://gitee.com/opengoofy/hippo4j;
目录结构

directory.png

数据库录入(MySQL)
  1. 在 "/hippo4j-develop/hippo4j-server/hippo4j-bootstrap/conf" 目录下找到“hippo4j_manager.sql”并导入,导入后如图
    sqlconfig.png

二、服务端启动

配置更改
  1. 在" /hippo4j-develop/hippo4j-server/hippo4j-bootstrap/src/main/resources "下找到 “application.properties”文件,更改数据库用户名以及密码

    spring.datasource.username=root
    spring.datasource.password=root
    
  2. 找到启动类后启动,位置:“/hippo4j-develop/hippo4j-server/hippo4j-bootstrap/src/main/java/cn/hippo4j/server/ServerApplication.java”

  3. 启动成功后网页打开"http://localhost:6691/index.html",默认用户名、密码 admin 123456,启动后如图

    index.png

三、客户端启动

示例项目启动
  1. 启动“/hippo4j-develop/hippo4j-example/hippo4j-spring-boot-starter-example/src/main/java/cn/hippo4j/example/server/ServerExampleApplication.java”应用类;

  2. 默认项目已经帮你创建好了示例项目的租户、项目、线程池;

    1. Hippo4j 按照租户、项目、线程池的维度划分。举个例子,小编在一家公司的公共组件团队,团队中负责消息、短链接网关等项目。公共组件是租户,消息或短链接就是项目。
  3. 动态更新线程池参数:

    1. 动态线程池 — 线程池实例 — 选择对应的租户、项目以及线程池实例
      Snipaste20230413145645.png
    2. 编辑此线程池实例,可以修改各种参数,项目控制台输出更新日志及代表成功
      Snipaste20230413150916.png
实际项目使用(SpringBoot)
  1. pom文件引入对应依赖

            <dependency>
                <groupId>cn.hippo4j</groupId>
                <artifactId>hippo4j-spring-boot-starter</artifactId>
                <version>1.4.3-upgrade</version>
            </dependency>
    
  2. 启动类加注解

    @SpringBootApplication
    @EnableDynamicThreadPool
    public class DemoApplication {
        public static void main(String[] args) {
            SpringApplication.run(DemoApplication.class, args);
        }
    }
    
  3. 线程池改造

    package com.demo.config;
    
    import cn.hippo4j.core.executor.DynamicThreadPool;
    import cn.hippo4j.core.executor.support.ThreadPoolBuilder;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    
    import java.util.concurrent.ThreadPoolExecutor;
    
    @Configuration
    public class ThreadPoolConfig {
    
        @Bean
        @DynamicThreadPool
        public ThreadPoolExecutor messageConsumeDynamicExecutor() {
            String threadPoolId = "message-consume-demo";
            return ThreadPoolBuilder.builder()
                    .threadFactory(threadPoolId)
                    .threadPoolId(threadPoolId)
                    .dynamicPool()
                    .build();
        }
    
    }
    
  4. 配置文件(yaml)

    spring:
      profiles:
        active: dev
      application:
        # 服务端创建的项目 id 需要与 application.name 保持一致
        name: study-service
      dynamic:
        thread-pool:
          # 服务端地址
          server-addr: http://localhost:6691
          # 用户名
          username: admin
          # 密码
          password: 123456
          # 租户 id, 对应 tenant 表
          namespace: demo
          # 项目 id, 对应 item 表
          item-id: study-service
    
  5. 服务端配置租户、项目以及线程池管理

    1. 租户可以使用已存在的,建议新建一个租户;
      Snipaste20230413152851.png
    2. 创建项目,选择租户,项目一栏需填写客户端的application.name
      Snipaste20230413153048.png
    3. 动态线程池中创建线程池管理,选择租户、项目,线程池一栏填入客户端创建的线程池threadpoolId
      Snipaste20230413153249.png
  6. 客户端项目启动

    1. 创建完成,启动客户端项目,启动日志输出
      Snipaste20230413153750.png

    2. 启动成功,查看服务端日志输出

      2023-04-13 15:39:11.192  INFO 20992 --- [er.long.polling] c.h.config.service.LongPollingService    : Dynamic Thread Pool Long pulling client count: 2
      

      这里的count代表客户端实例为两个,一个是示例项目,一个是实际项目

  7. 查看服务端网页,动态线程池 — 线程池实例,选择租户、项目、线程池后查询

    Snipaste20230413154253.png

  8. 至此已经监控到客户端的线程池实例,可在此页面动态更改线程池参数,线程池管理和线程池实例的区别

    1. 在线程池管理中修改线程池参数,客户端并不能实时感知并变更参数,需要重启客户端。而线程池实例中去对具体的实例修改参数时,客户端无需重启,可以试试感知到参数变化。如果二者针对同一线程池的参数配置不同,则在重启客户端时,客户端会去拉取线程池管理中的参数配置;
    2. 二者对应的定位:线程池管理中的配置是常态化配置,而线程池实例中的配置变成更像是一种临时修改,比如突发的流量激增等场景,并不具备普适性。
异常告警(企业微信)
  1. 先找个企微群,企业微信创建机器人,机器人创建教程(https://open.work.weixin.qq.com/help2/pc/14931?person_id=1&from=homesearch);
  2. 机器人加入至群聊后,取机器人Webhook地址中的key值,图中红圈圈起来的马赛克部分,以及机器人的名字,创建机器人的时候会输入;
    Snipaste20230413160152.png
  3. 服务端异常告警通知配置
    Snipaste20230413155513.png
  4. 测试编辑线程池实例参数通知
    Snipaste20230413155654.png
  5. 测试动态线程池异常通知
    Snipaste20230413155747.png
  6. 其余平台通知请自行尝试,按照官网文档说明;

标题:Hippo4j动态线程池监控接入
作者:zzzzchen
地址:https://www.dczzs.com/articles/2023/04/12/1681288036887.html