hippo4j
快速开始 | Hippo4j (官方文档!!)
动态线程池框架 hippo4j 源码解析 - 风小雅 - 博客园 (这篇文章剖析了部分源码,很好!!!)
hippo4j也分为客户端和服务端,类似于注册中心。
客户端注册自己的信息和线程给服务端,服务端监控线程。
客户端通过心跳上报自己的状态线程池参数状态。
服务端改了参数后,客户端通过长轮询能获取到修改的参数信息, 客户端再调线程池api去更改。
步骤
- 线程池注册(通过bean生命周期后置处理器实现)。
- 服务端监控线程池状态,客户端 (定时调用ThreadPoolExecutor的api) 上报线程池状态(心跳机制?)。
- 用户 在服务端修改参数配置。
- 客户端 长轮询 获取修改的参数信息
- 客户端 调用ThreadPoolExecutor线程池的api修改参数(setCorePoolSize)。
- 客户端下线,停机,线程池bean销毁(通过bean生命周期销毁方法,等待线程池任务执行完毕)。
线程池注册,线程池如何注册的,如何注册到server?
因为线程池都是bean嘛,框架实现了 beanPostProcessor, 重写了 postProcessAfterInitialization方法。
在线程池bean初始化完成之后,将线程池信息注册到Server端 或者 本地容器中。
一句话,通过Spring生命周期的bean后置处理器,将bean的信息注册到了server中。
运行监控 - 实时查看线程池运行时数据,自定义时间内线程池运行数据图表展示。
如何监控,其实就是客户端 定时调用 getCoreSize和getMaximumSize和getActiveSize等api获取核心线程、最大线程、活跃线程、队列中的任务数量 , 获取信息。
然后定时上报给hippo4j服务端,。
不用框架,如何动态设置线程池参数? 或者说框架是如何改变线程池的参数的?
我猜线程池框架也是通过监控,然后调这些api实现的动态调参:
那运行时,是如何获取到线程池对象 并设置动态参数的呢? 通过反射
ThreadPoolExecutor类部分api:
核心线程
- setCorePoolSize
- getCorePoolSize
最大线程
- setMaximumPoolSize
- getMaximumPoolSize
阻塞队列
- getQueue
存活的线程
- getActiveCount
获取线程堆栈信息
- ThreadPoolExecuto.workers
我在控制台(hippo4j)服务端设置的参数,客户端如何获取到线程池参数信息的?
推拉模型。hippo4j采用的 拉模式,且是长轮询。
为什么不采用推模式呢:我猜推模式的缺点是,如果客户端太多,推的效率就比较低了。
框架不但能监控自定义线程池,还能监控第三方组件的线程池(如rocketMQ),框架是如何获取到第三方组件的线程池的?
Hippo4j需要做的就是在项目启动的过程中,挨个适配捕获不同组件依赖的线程池(通过反射获取) 。然后将他们注册到服务端进行管理起来。
kill -15 停机时等线程池在指定时间内执行完任务
优雅停机后,通过bean生命周期销毁方法,等待线程池任务执行完毕后,销毁线程池Bean
- 实现DisposableBean接口,重写了destroy方法。
- 在destroy方法中,等待线程池的任务执行完毕再关闭线程池。
shardingsphere
改写引擎 :: ShardingSphere(shardingsphere官方文档)
它如何实现分表的?
- 它是一个增强版的JDBC框架,JDBC就是java连接数据库的中间层嘛。
- 它的作用就是,拦截SQL,解析SQL,并改写SQL(分表的情况下 它会根据改写SQL,根据分片规则去查对应的表)。
- 工程师面向逻辑库与逻辑表书写的 SQL,并不能够直接在真实的数据库中执行,SQL 改写用于将逻辑 SQL 改写为在真实数据库中可以正确执行的 SQL。
如何自定义的复合分片算法?
- 在yaml中配置
- 实现shaardingxxx的复合分片算法类,重写doSharding方法,返回 真实表名。