线程池是一种基于池化思想管理线程的工具,使用线程池可以减少创建销毁线程的开销,避免线程过多导致系统资源耗尽。在高并发以及大批量的任务处理场景,线程池的使用是必不可少的。
如果有在项目中实际使用线程池,相信你可能会遇到以下痛点:
-
线程池随便定义,线程资源过多,造成服务器高负载。
-
线程池参数不易评估,随着业务的并发提升,业务面临出现故障的风险。
-
线程池任务执行时间超过平均执行周期,开发人员无法感知。
-
线程池任务堆积,触发拒绝策略,影响既有业务正常运行。
-
当业务出现超时、熔断等问题时,因为没有监控,无法确定是不是线程池引起。
-
原生线程池不支持运行时变量的传递,比如 MDC 上下文遇到线程池就 GG。
-
无法执行优雅关闭,当项目关闭时,大量正在运行的线程池任务被丢弃。
-
线程池运行中,任务执行停止,怀疑发生死锁或执行耗时操作,但是无从下手。
Hippo4j是一个基于JDK原生线程池扩展的线程池框架,它为业务系统提供了强大的线程池管理能力,旨在提高线上运行的稳定性和可靠性。
以下是对Hippo4j的详细介绍:
一、基本概述
- 定义:Hippo4j是一个动态可观测的线程池框架,通过对JDK线程池进行增强,以及扩展三方框架底层线程池等功能,为业务系统提供线上运行保障。
- 开源时间:Hippo4j项目自2021年6月份开源,一直保持快速迭代,共经历多次版本发布。
- 使用公司:已知有23家公司登记使用Hippo4j。
- 社区贡献:截止目前,共计83位开源社区小伙伴参与贡献,这也是Hippo4j能保持快速迭代的原因。
二、主要功能
全局管控:管理应用线程池实例,提供统一的线程池管理界面。
动态变更:应用运行时动态变更线程池参数,包括但不限于核心线程数、最大线程数、阻塞队列容量、拒绝策略等。
通知报警:内置四种报警通知策略,包括线程池活跃度、容量水位、拒绝策略以及任务执行时间超长等,确保系统稳定运行。
数据采集:采集线程池运行时数据,支持多种采集方式,如日志打印、内置采集、Prometheus、ElasticSearch、InfluxDB等。
运行监控:实时查看线程池运行时数据,支持自定义时间内线程池运行数据图表展示,帮助开发者快速定位问题。
功能扩展:支持线程池任务传递上下文;项目关闭时,支持等待线程池在指定时间内完成任务。
多种模式:内置两种使用模式:依赖配置中心和无中间件依赖,满足不同场景下的使用需求。
容器管理:支持Tomcat、Jetty、Undertow等容器线程池运行时查看和线程数变更。
框架适配:适配Dubbo、Hystrix、RabbitMQ、RocketMQ等消费线程池,提供运行时数据查看和线程数变更功能。
三、技术特点
- 基于Spring框架开发:Hippo4j基于Spring框架开发,能够很好地与Spring Boot等主流框架集成。
- 动态化插件:内置多种线程池插件,支持用户自定义插件以及运行时扩展,满足不同的业务需求。
- 变更审核:提供多种用户角色,普通用户变更线程池参数需要Admin用户审核方可生效,确保变更的安全性。
- 长轮询机制:Hippo4j客户端与服务通信采用长轮询机制,确保数据的实时性和准确性。
四、应用场景
Hippo4j适用于流量较大或者任务型的系统,通过合理的线程池管理,确保系统在高并发下的稳定性和性能。同时,Hippo4j也适用于需要实时监控和报警的业务场景,帮助开发者快速定位和解决问题。
五、集成步骤
Hippo4j与Spring Boot的集成相对简单,主要通过引入Hippo4j的Starter Jar包来实现。以下是一个详细的集成步骤,包括必要的依赖添加、配置设置和代码示例:
1. 添加依赖
首先,你需要在Spring Boot项目的pom.xml
文件中添加Hippo4j的客户端依赖。确保你使用的是最新版本的依赖,以获取最新的功能和修复。
<dependency>
<groupId>cn.hippo4j</groupId>
<artifactId>hippo4j-spring-boot-starter</artifactId>
<version>最新版本号</version> <!-- 请替换为实际可用的最新版本号 -->
</dependency>
2. 配置文件
接下来,在Spring Boot的配置文件(application.properties
或application.yml
)中配置Hippo4j Server的地址和其他相关参数。这些参数包括服务器地址、用户名、密码、租户名称和项目名称等。
示例(application.yml)
spring:
application:
name: your-spring-boot-application
dynamic:
thread-pool:
server-addr: 192.168.x.x:6691 # Hippo4j Server的地址和端口
username: admin
password: 123456
namespace: your-namespace # 租户名称
item-id: ${spring.application.name} # 项目名称,建议与Spring Boot应用名称一致
3. 启动类注解
在你的Spring Boot启动类上添加@EnableDynamicThreadPool
注解,以启用动态线程池功能。
import cn.hippo4j.core.starter.annotation.EnableDynamicThreadPool;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
@EnableDynamicThreadPool
public class YourApplication {
public static void main(String[] args) {
SpringApplication.run(YourApplication.class, args);
}
}
4. 配置线程池
在Spring Boot项目中,你可以通过配置类来定义线程池。使用Hippo4j提供的ThreadPoolBuilder
来构建线程池,并将其注册为Spring容器中的Bean。
import cn.hippo4j.core.thread.ThreadPoolBuilder;
import cn.hippo4j.core.toolkit.concurrent.ThreadPoolExecutor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class ThreadPoolConfig {
@Bean
@DynamicThreadPool
public ThreadPoolExecutor testThreadPool() {
return ThreadPoolBuilder.builder()
.corePoolSize(10)
.maximumPoolSize(20)
.keepAliveTime(60)
.timeUnit(TimeUnit.SECONDS)
.workQueue(BlockingQueueTypeEnum.LINKED_BLOCKING_QUEUE)
.threadFactory("custom-thread-factory")
.rejected(new ThreadPoolExecutor.CallerRunsPolicy())
.threadPoolId("test-thread-pool")
.dynamicPool()
.build();
}
}
配置完成后,就可以在Hippo4j控制台中监控并管理该线程池了。