导语:
JDK21 的虚拟线程与 ZGC 为低延迟服务带来新选择。本文给出组合打法:线程模型、GC、IO 与容量策略,并附灰度与回滚清单。
1. 线程模型
- 虚拟线程适用:大量阻塞 IO、短任务;避免在虚拟线程中持有锁。
- 搭配 Loom 友好的连接池/驱动;禁用线程池滥用。
- 观测:线程数量、阻塞点、调度延迟;异常时回退到平台线程。
2. GC 策略
- 首选 ZGC(JDK17+),参数示例:
-XX:+UseZGC -XX:+ZGenerational -XX:ConcGCThreads=4 -XX:ZCollectionInterval=1。 - 监控:GC 暂停/并发时间、晋升失败、堆占用;超阈值告警。
- 基线:压测对比 ZGC vs G1 的 P99 延迟与 CPU 占用,记录选型。
3. IO 与协议
- Netty:EPOLL/KQueue,
write_buffer_water_mark控制背压;对大文件用FileRegion/sendfile。 - HTTP/2:合理流量控制与头压缩白名单;大响应分块/流式。
- 序列化:优先 JSON/Proto 的零拷贝解码;减少对象分配。
4. 队列与背压
- 线程池分级(计算/IO/阻塞);队列长度基于压测设置。
- 背压:对下游依赖设置舱壁与超时;重试带抖动,禁止级联重试。
- 返回排队信息,避免盲重试。
5. 缓存与数据路径
- 热点缓存:本地/分布式缓存 + 版本号,防止穿透/击穿;写路径落盘幂等。
- 读写隔离:写走主库,读走只读副本或搜索,失败回退主库要有限流。
- CDC:Binlog/CDC 更新缓存与搜索索引,监控复制延迟。
6. 容量与压测
- 容量模型:QPS、P99、CPU/内存、外部依赖时延;写入 Runbook。
- 压测:核心路由 P99 + GC + 线程池/队列/连接池水位;形成基线。
- 预算:高成本接口设配额;成本看板可视。
7. 安全与韧性
- 超时/重试/断路器:每个依赖单独配置;熔断自动降级到缓存/静态响应。
- 启动探针:类加载/预热/健康检查;失败即回滚。
- 证据包:参数、压测、容量、限流/熔断配置、回滚记录。
8. 灰度与回滚
- 流量:1%→10%→50%→全量,覆盖高峰时段。
- 观察:P99、错误率、GC、线程池/队列水位、依赖超时。
- 回滚:镜像+配置双通道;回滚后 30 分钟验证指标。
9. 快速核查
- 虚拟线程适用性评估与开关就绪;ZGC 参数与监控上线。
- 线程池/队列/限流/断路器配置明确,压测基线完成。
- 灰度/回滚脚本可用,证据包已沉淀。
结语:
用“虚拟线程 + ZGC + 零拷贝 IO + 背压/限流 + 观测”形成固定打法,低延迟 Java 服务才能在高峰下保持稳定。
10. 操作示例
- 虚拟线程灰度:为阻塞型接口开启虚拟线程,观察线程数、调度延迟与 P99;异常可快速关闭开关。
- GC 对比:压测同一场景下 ZGC vs G1,记录暂停、CPU、P99,选型与参数写入 Runbook。
- 回滚验证:预置
rollback.sh version,回滚后 30 分钟内自动收集 P99/GC/线程池/队列水位快照。