场景问题思考

数据库类场景

一、理赔业务8张表强关联JOIN无法删减业务,除索引外还有哪些优化方案?

(业务层+技术层两层)

如果业务上确实没办法精简关联表数量,先做业务层面梳理,再用多层技术方案兜底:

  1. 业务前置优化

和产品、业务方确认:8张表里有没有可以提前冗余的静态基础数据,比如基础配置、用户基础信息这类很少变更的数据,提前冗余到宽表里面,减少实时JOIN的表数量;也可以拆分查询场景,把一次性多维度大查询,拆成分步小查询,前端做数据聚合,降低单条SQL压力。

  1. 技术落地优化

① SQL层面:建立联合覆盖索引,避免回表;拆解大JOIN为小关联子查询,先过滤小结果集再做关联;禁止select *,只查询业务必需字段减少IO。

② 存储层面:把高频多表查询结果预热 到Redis做缓存;如果查询量级很大,同步把数据同步到ES,用搜索引擎做复杂多条件关联查询,MySQL只承载基础事务写入。

③ 架构层面:定时任务离线预计算报表类查询结果,线上直接读取预计算数据,避免实时计算压力。

二、只能用UUID做主键,怎么解决分页慢+索引页分裂问题

UUID无序带来两大问题:深分页遍历慢、主键索引频繁页分裂,分两步解决:

  1. 主键改造:放弃无序UUID v4,改用有序UUID v7或者雪花算法ID,保证插入有序,从根源解决InnoDB主键页分裂、磁盘碎片问题,插入性能恢复到接近自增主键水平。

  2. 分页优化:规避大offset深分页,采用主键游标分页,比如 where id > 上一页最大id limit 20 ;同时给分页查询条件建立覆盖索引,减少回表开销;超大分页场景限制前端最大分页页数,或者引导用户用筛选条件缩小范围。

三、冷热数据共存(多年历史保单+在保热保单),海量数据怎么优化

结合业务做冷热分层,兼顾查询性能和存储成本:

  1. 业务分层归档:定义归档规则,比如保单完结超过3年判定为冷数据,定时迁移到归档分表或者OceanBase冷分区,热数据保留在主表,缩小主表体量,日常查询绝大多数只会命中热数据。

  2. 存储区分:热数据留在高性能MySQL/OceanBase,冷数据可以低成本存储至对象存储+ES检索,只有用户主动查询历史保单时才检索冷数据。

  3. 缓存区分:热保单信息常驻Redis缓存,冷保单不做缓存,减少缓存内存占用。

Java并发&虚拟线程场景

一、异步核保任务必须使用synchronized加锁,会钉住虚拟线程,业务不能改锁类型,怎么折中解决?

核心矛盾是 synchronized是操作系统阻塞锁,虚拟线程阻塞时会一直占用载体线程,失去轻量调度优势 ,无法替换锁的前提下,我有两套折中落地方案:

  1. 任务拆分隔离:把需要加锁的同步代码块最小化,只把竞争修改共享数据的代码放在锁内,锁外耗时逻辑全部拆分到虚拟线程异步执行,缩短锁持有时间,减少载体线程长时间占用。

  2. 载体线程资源扩容:给执行这类带synchronized的虚拟线程,单独配置专属载体线程池,和普通无阻塞虚拟线程池物理隔离,避免同步阻塞耗尽公共载体线程,影响整体异步任务调度。

  3. 兜底监控:接入线程监控,识别长时间被synchronized阻塞的虚拟线程,告警业务死锁、长时间阻塞问题,线上及时干预。

二、自研隔离线程池,怎么给多业务(核保/扣费/通知)做资源隔离,防止雪崩

参考之前导出引擎自定义线程池隔离的经验,做业务线程池物理隔离:

  1. 按业务维度拆分独立线程池:核保、资金扣费、消息通知、报表导出分别配置专属线程池,设置独立核心线程数、拒绝策略,一个业务线程池打满阻塞,不会占用其他业务线程资源。

  2. 配置差异化拒绝策略:资金扣费这类核心业务使用CallerRuns策略,保障业务不丢失;导出、通知非核心业务使用丢弃+告警策略,高峰期主动限流保护核心链路。

  3. 统一监控:所有线程池暴露监控指标,线程活跃数、队列堆积、拒绝次数,出现队列堆积提前告警扩容或者限流。

Redis分布式锁&缓存一致性场景

一、理缓存更新失败,如何用RocketMQ做最终一致性兜底,还要保证消息不丢不重复

沿用「先写库更新缓存+MQ兜底」的思路,适配高可靠要求:

  1. 正常流程:业务更新保单数据库之后,直接同步更新Redis缓存,保证绝大多数场景实时一致性。

  2. 失败兜底:如果缓存更新抛出异常,本地发送可靠事务消息到RocketMQ,消息携带保单ID、更新字段,消费端重试执行缓存更新操作。

  3. 可靠性保障:

消息不丢失:生产者使用事务消息保证本地库更新成功才投递消息;Broker开启同步刷盘;消费者手动ACK,处理失败重试。

消息不重复:消费端基于保单唯一ID做Redis幂等标记,或者数据库唯一索引防重复更新。

二、分布式锁出现锁过期、业务还未执行完,Redisson看门狗失效怎么办?怎么兜底防数据错乱

正常情况下Redisson看门狗会每隔1/3过期时间自动续期,看门狗失效属于异常场景,双层兜底:

  1. 事前规避:拉长锁过期时间,根据业务压测得出最大执行耗时,锁过期时间设置为最大耗时的2~3倍,减少过期概率。

  2. 异常兜底:看门狗失效锁提前释放后,业务执行更新前做数据版本号校验(乐观锁),比如update set status=新状态 where id=保单id and version=当前版本号,版本不匹配直接放弃更新,防止并发覆盖脏数据;同时记录异常日志告警,人工复盘看门狗失效原因。

RocketMQ分布式事务场景

一、跨服务流程:核保→扣费→生成保单,TCC/事务消息/SAGA怎么选型?

结合业务容错性选型:

  1. RocketMQ事务消息:适合最终一致性要求、回滚成本低的场景,比如核保成功之后扣费失败,回滚核保状态,适配绝大多数普通理赔流程,开发成本低。

  2. TCC:适合资金强一致性场景,比如扣费环节,需要Try锁定资金、Confirm实际扣款、Cancel释放资金,金融资金链路优先TCC,一致性最强,开发成本最高。

  3. SAGA:适合长链路复杂理赔流程,拆分本地子事务,失败逆向补偿,适配流程节点多、跨多系统的理赔场景。

架构优化类场景

一、接手老旧系统,大量慢查询、老旧接口,如何制定优化方案,推动业务方配合改造

分为落地执行+跨部门推动两步:

  1. 技术落地步骤:

① 监控摸底:接入慢查询日志、接口RT监控,统计慢SQL访问频次、影响用户范围,划分优先级,优先优化高频影响核心接口慢查询。

② 小步迭代:先做无业务侵入优化,比如索引优化、SQL改写、缓存预热,快速降低线上故障;高频且改造难度大的慢查询,设计分阶段重构方案。

  1. 业务推动方式:

给业务方提供数据支撑,展示慢查询带来的用户投诉、高峰期超时率、服务器资源损耗,同时提供兼容改造方案,保证改造期间业务无停机、无功能变更,打消业务方改动风险顾虑;小范围灰度验证效果之后,再全量推广优化。

总结

没有完整落地过的场景,可以基于掌握的通用技术原理,结合技术+业务双向思路推导方案。如果是并发数据安全问题,我会用分布式锁、乐观锁、事务消息保障一致性;如果是流量打垮数据库,用缓存、限流、读写分离做分层防护;同时一定会联动业务侧精简无效逻辑,从源头降低技术压力,上线前做压测验证稳定性。