主题
实习深挖 · 托底简历第三段「可观测性建设:基于 Spring AOP 实现统一日志埋点,覆盖 40+ 核心接口」。这一段是实习三段 bullet 里唯一没有平台团队托底的——完全是自有工作,三档动词里属于「我负责」,可以放开讲。
60 秒标准答案
实现是 @Aspect 切面加自定义注解:给需要观测的核心接口标 @InterfaceLog,切点按注解拦截,用 @Around 环绕通知,proceed() 前后计时,try-catch-finally 保证异常接口也输出状态。核心接口标了 40 多个——12 阶段发布流程的各阶段接口、任务创建发布修复的管理接口、数据源注册,RDS 读权限检查就是第 1 阶段的接口。
输出是统一的执行记录:接口标识、入参摘要、出参摘要、耗时、执行状态、异常摘要、traceId。三个细节:入参出参记摘要不全量,敏感字段脱敏——加密字段和密钥不落日志,和发布流程的加密步骤呼应;日志异步写,埋点不拖慢主链路;异常栈记关键帧。
价值链:结构化日志按接口聚合,得到调用次数、成功率、P95 耗时——就是调用统计看板的数据源;排查时按 traceId 串起一次发布流程跨多接口的调用链。选 AOP 不选拦截器,是因为 service 层的关键方法也能统一观测,注解声明式标注、业务代码零侵入。
设计判断(答题时先甩判断再讲实现)
- 埋哪些接口是显式声明的:按注解标注,不按包路径盲扫——「40+」是数注解数出来的精确口径,不是约数。
- 标准化是这条 bullet 的题眼:所有接口输出同一种执行记录格式,看板和排查才有结构化数据可消费——杂乱的自由文本日志撑不起「可观测性」三个字。
- 埋点不拖慢主链路:日志异步写;入参出参只记摘要并截断,大报文不进日志。
- 脱敏和发布流程呼应:任务配置里的加密字段、密钥(对应发布第 7 阶段)在日志里打码——埋点不能变成泄密源。
- 异常路径全覆盖:try-catch-finally 包住 proceed(),失败接口同样有状态记录——可观测性恰恰在故障时最有价值。
追问 Q&A
Q1:为什么用 AOP 不用拦截器 / 过滤器? 拦截器只能切 controller 层;切面可以连 service 层的关键方法(比如发布流程的核心编排方法)统一观测。另外注解是声明式的——哪些接口要观测一眼可见,业务代码零侵入。
Q2:切点表达式怎么写的? 按注解切:@annotation(interfaceLog)。不用 execution 按包扫,是因为「哪些接口进观测」要显式可控——新接口标了注解自动进入,取消标注自动退出。
Q3:traceId 从哪来、怎么串起一次流程? 入口接口生成(或从上游网关透传),放进 MDC,日志格式里统一输出——同一次发布流程跨多个接口的调用,用 traceId 一查全串起来。
Q4:异步写日志,进程挂了丢日志怎么办? 承认取舍:埋点是观测数据不是账务数据,丢个别条目可接受;异步队列设上限,满了走丢弃策略保护主链路——如果业务要求不丢,那就是另一个成本更高的方案(同步写或落盘队列),对日志场景不值得。
Q5:看板消费哪些指标? 按接口聚合出调用次数、成功率、P95/P99 耗时;再往上看单任务的接口调用序列——发布流程哪一步失败、哪一步慢,一眼定位。
Q6:40+ 这个数怎么来的? 显式标注 @InterfaceLog 的核心接口数:12 阶段发布流程的各阶段接口 + 任务创建/发布/修复的管理接口 + 数据源注册等。被追问就报构成,不报约数。
三档动词口径
这一段完全自有:切面、注解、日志格式、看板口径都是我做的——三档动词里属于「我负责」,可以放开讲。