文章目录
- [Hippo4j 线程池监控接入方法](#Hippo4j 线程池监控接入方法)
-
- 为什么只能看到样例线程池
- 当前环境
- [Auth 模块试点接入](#Auth 模块试点接入)
-
- [1. 父 POM 管理版本](#1. 父 POM 管理版本)
- [2. 业务模块引入依赖](#2. 业务模块引入依赖)
- [3. 启动类开启 Hippo4j](#3. 启动类开启 Hippo4j)
- [4. 改造线程池 Bean](#4. 改造线程池 Bean)
- [5. Boot 3 兼容处理](#5. Boot 3 兼容处理)
- [6. Nacos 配置](#6. Nacos 配置)
- [7. Hippo4j Server 数据库配置](#7. Hippo4j Server 数据库配置)
- [Java 17 启动参数](#Java 17 启动参数)
- 验收方法
-
- [1. 编译](#1. 编译)
- [2. 启动日志](#2. 启动日志)
- [3. 数据库落库](#3. 数据库落库)
- [4. Dashboard API](#4. Dashboard API)
- 常见问题
-
- [`/monitor` 返回 200,但 Dashboard 没实例](#
/monitor返回 200,但 Dashboard 没实例) - [Java 17 报 unable to make field workQueue accessible](#Java 17 报 unable to make field workQueue accessible)
- 控制台只能看到配置,看不到曲线
- [普通 `ThreadPoolTaskExecutor` 能不能直接监控](#普通
ThreadPoolTaskExecutor能不能直接监控)
- [`/monitor` 返回 200,但 Dashboard 没实例](#
- 后续模块接入清单
Hippo4j 线程池监控接入方法
为什么只能看到样例线程池
http://192.168.93.128:6691/index.html#/dashboard 只能看到样例线程池时,通常不是 Dashboard 坏了,而是业务微服务还没有完成 Hippo4j 客户端接入。
业务里的普通 ThreadPoolTaskExecutor 不会自动出现在 Hippo4j 控制台。要被监控,需要满足:
- 微服务引入
hippo4j-spring-boot-starter。 - 启动类开启
@EnableDynamicThreadPool。 - 配置
spring.dynamic.thread-pool.server-addr、namespace、item-id。 - Hippo4j Server 数据库里存在对应租户、项目、线程池配置。
- 线程池注册进 Hippo4j 的
GlobalThreadPoolManage。 - 客户端长轮询启动成功,服务端能收到
/configs/listener和/monitor。
当前环境
text
Hippo4j Dashboard: http://192.168.93.128:6691/index.html
账号: admin
密码: 123456
Hippo4j 数据库: hippo4j_manager
MySQL 用户: hippo4j
MySQL 密码: hippo4j_pwd
Nacos: http://192.168.93.128:8848/nacos
Nacos namespace: xiaohashu
Nacos group: DEFAULT_GROUP
Auth 模块试点接入
1. 父 POM 管理版本
父 POM 统一管理 Hippo4j 版本:
xml
<hippo4j.version>1.5.0</hippo4j.version>
xml
<dependency>
<groupId>cn.hippo4j</groupId>
<artifactId>hippo4j-spring-boot-starter</artifactId>
<version>${hippo4j.version}</version>
</dependency>
2. 业务模块引入依赖
xiaohashu-auth/pom.xml:
xml
<dependency>
<groupId>cn.hippo4j</groupId>
<artifactId>hippo4j-spring-boot-starter</artifactId>
</dependency>
3. 启动类开启 Hippo4j
XiaohashuAuthApplication:
java
@SpringBootApplication
@EnableFeignClients(basePackages = "com.quanxiaoha.xiaohashu")
@EnableDynamicThreadPool
@Import(DynamicThreadPoolAutoConfiguration.class)
public class XiaohashuAuthApplication {
public static void main(String[] args) {
SpringApplication.run(XiaohashuAuthApplication.class, args);
}
}
说明:当前项目是 Spring Boot 3.0.2,Hippo4j 1.5.0 的 starter 自动装配不完全适配 Boot 3,所以这里显式 @Import(DynamicThreadPoolAutoConfiguration.class)。
4. 改造线程池 Bean
ThreadPoolConfig:
java
@Configuration
public class ThreadPoolConfig {
@Bean(name = "taskExecutor")
public ThreadPoolExecutor taskExecutor() {
return ThreadPoolBuilder.builder()
.threadPoolId(threadPoolId())
.threadFactory("AuthExecutor")
.dynamicPool()
.build();
}
@Bean
public DynamicThreadPoolWrapper authTaskExecutorDynamicWrapper(ThreadPoolExecutor taskExecutor) {
return new DynamicThreadPoolWrapper(threadPoolId(), taskExecutor);
}
private String threadPoolId() {
return "auth-task-executor";
}
}
业务类注入类型同步改成:
java
@Resource(name = "taskExecutor")
private ThreadPoolExecutor threadPoolExecutor;
提交任务可以继续用:
java
threadPoolExecutor.execute(() -> {
// business logic
});
或:
java
threadPoolExecutor.submit(() -> {
// business logic
});
5. Boot 3 兼容处理
Hippo4j 1.5.0 的 ApplicationContentPostProcessor 在当前 Boot 3/OpenFeign 场景下会触发空指针,但它又负责通知 ClientWorker 启动长轮询。
处理方式:
java
@Configuration
public class Hippo4jCompatibilityConfig {
private final ClientWorker clientWorker;
public Hippo4jCompatibilityConfig(ClientWorker clientWorker) {
this.clientWorker = clientWorker;
}
@Bean
public static BeanDefinitionRegistryPostProcessor hippo4jBoot3CompatibilityPostProcessor() {
return new BeanDefinitionRegistryPostProcessor() {
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
String beanName = "applicationContentPostProcessor";
if (registry.containsBeanDefinition(beanName)) {
registry.removeBeanDefinition(beanName);
}
}
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
}
};
}
@EventListener(ApplicationReadyEvent.class)
public void notifyHippo4jApplicationReady() {
clientWorker.notifyApplicationComplete();
}
}
关键点:不能只删除 applicationContentPostProcessor,否则客户端不会请求 /configs/listener,服务端缓存没有实例信息,/monitor 虽然返回 200,但 his_run_data 不会落库。
6. Nacos 配置
本地 xiaohashu-auth/src/main/resources/config/application-dev.yml 和 Nacos 的 xiaohashu-auth-dev.yaml 都要包含:
yaml
spring:
dynamic:
thread-pool:
server-addr: 192.168.93.128:6691
username: admin
password: 123456
namespace: xiaohashu
item-id: ${spring.application.name}
推送到 Nacos:
powershell
curl.exe -s -X POST "http://192.168.93.128:8848/nacos/v1/cs/configs?dataId=xiaohashu-auth-dev.yaml&group=DEFAULT_GROUP&tenant=xiaohashu&type=yaml" --data-urlencode "content@xiaohashu-auth/src/main/resources/config/application-dev.yml"
7. Hippo4j Server 数据库配置
需要有:
text
tenant_id: xiaohashu
item_id: xiaohashu-auth
tp_id: auth-task-executor
core_size: 10
max_size: 50
queue_type: 9
capacity: 200
keep_alive_time: 30
校验 SQL:
bash
ssh ubuntu@192.168.93.128 "mysql -uhippo4j -phippo4j_pwd -Dhippo4j_manager -e \"SELECT tenant_id,item_id,tp_id,core_size,max_size,capacity FROM config WHERE tenant_id='xiaohashu' AND item_id='xiaohashu-auth';\""
Java 17 启动参数
Hippo4j 1.5.0 会反射替换 ThreadPoolExecutor.workQueue。Java 17 下必须加:
text
--add-opens=java.base/java.util.concurrent=ALL-UNNAMED
IDEA Run Configuration 的 VM options 加这一行。
命令行 smoke run 示例:
powershell
mvn -pl xiaohashu-auth spring-boot:run `
-Dspring-boot.run.profiles=dev `
-Dspring-boot.run.arguments=--server.port=18080 `
-Dspring-boot.run.jvmArguments=--add-opens=java.base/java.util.concurrent=ALL-UNNAMED
验收方法
1. 编译
powershell
mvn -pl xiaohashu-auth -am compile -DskipTests
2. 启动日志
必须看到类似日志:
text
Dynamic ThreadPool :: (v1.5.0)
Client identify: 10.150.214.41:18080_xxx
Add listener status: ok, thread pool id: auth-task-executor
Dynamic thread pool: [1]. The dynamic thread pool starts data collection and reporting.
3. 数据库落库
bash
ssh ubuntu@192.168.93.128 "mysql -uhippo4j -phippo4j_pwd -Dhippo4j_manager -e \"SELECT tenant_id,item_id,tp_id,instance_id,current_load,pool_size,queue_capacity,gmt_create FROM his_run_data WHERE tenant_id='xiaohashu' AND item_id='xiaohashu-auth' ORDER BY gmt_create DESC LIMIT 5;\""
能看到 xiaohashu-auth / auth-task-executor 每 5 秒一条数据,表示监控链路已经打通。
4. Dashboard API
powershell
$body = '{"userName":"admin","password":"123456"}'
$token = ((curl.exe -s -H "Content-Type: application/json" --data-binary $body http://192.168.93.128:6691/hippo4j/v1/cs/auth/users/apply/token) | ConvertFrom-Json).data.accessToken
curl.exe -s "http://192.168.93.128:6691/hippo4j/v1/cs/dashboard?accessToken=$token"
curl.exe -s "http://192.168.93.128:6691/hippo4j/v1/cs/dashboard/pie/chart?accessToken=$token"
验收结果应包含:
json
"threadPoolInstanceCount": 1
饼图里应包含:
json
{"name":"xiaohashu-auth","value":1}
常见问题
/monitor 返回 200,但 Dashboard 没实例
检查客户端是否请求了 /configs/listener。如果没有,服务端内存缓存没有实例,HisRunDataServiceImpl.save() 会过滤掉运行数据。
当前 Boot 3 兼容方案必须同时做到:
- 移除会 NPE 的
applicationContentPostProcessor。 - 在
ApplicationReadyEvent里调用clientWorker.notifyApplicationComplete()。
Java 17 报 unable to make field workQueue accessible
缺少:
text
--add-opens=java.base/java.util.concurrent=ALL-UNNAMED
控制台只能看到配置,看不到曲线
只创建 config 表记录只能让线程池配置出现;要看到实例和曲线,微服务必须启动并持续上报,his_run_data 表必须有数据。
普通 ThreadPoolTaskExecutor 能不能直接监控
当前项目推荐统一改成 ThreadPoolExecutor + ThreadPoolBuilder + DynamicThreadPoolWrapper。这样能明确 threadPoolId,也能走 Hippo4j 的动态配置、长轮询和监控上报链路。
后续模块接入清单
按 auth 的方式逐个接入:
text
xiaohashu-comment/xiaohashu-comment-biz
xiaohashu-count/xiaohashu-count-biz
xiaohashu-note/xiaohashu-note-biz
xiaohashu-user/xiaohashu-user-biz
xiaohashu-user-relation/xiaohashu-user-relation-biz
每个模块都要同步:
- POM 依赖。
- 启动类注解。
- 线程池 Bean。
- 业务注入类型。
- Nacos 配置。
- Hippo4j tenant/item/config。
- Java 17
--add-opens启动参数。 his_run_data和 Dashboard API 验收。