1.3 用SpringBoot搭建可追踪实验场


1.3 用 Spring Boot 搭建可追踪实验场

本节摘要:十分钟左右搭起一个能跑的 Spring Boot 工程,并配上让请求旅程"现形"的三件观察工具:请求日志、调用栈断点、执行耗时埋点。后续各章的实验都在这个工程里做,不必再分心环境问题。

动手:最小工程

新建 Maven 工程,父依赖交给 Spring Boot:

<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>3.2.0</version> </parent> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> </dependencies>

启动类与探针接口:

@SpringBootApplication public class TraceApplication { public static void main(String[] args) { SpringApplication.run(TraceApplication.class, args); } } @RestController class PingController { @GetMapping("/ping") public String ping() { return "pong"; } }

浏览器访问本地端口的 ping 路径返回 pong,实验场就绪。这里值得留意的是 @SpringBootApplication 干了什么:它组合了自动配置、组件扫描两个开关,把第 3 章要讲的容器装配工作自动完成了一大半。眼下只需知道:启动日志的最后一行出现在控制台时,请求旅程的所有关卡都已建好,静候第一个请求。

三件观察工具

其一:请求进出日志。 给容器配一个最简的访问日志,让每个请求的到达与离开有据可查:

server: tomcat: accesslog: enabled: true pattern: '%t %a "%r" %s %D ms' spring: application: name: trace-lab

其二:调用栈断点。ping 方法上打断点发起请求,IDE 会冻结那根容器线程并展示完整调用栈。从栈底往上读:线程入口 → 连接器处理 → 分发 → 你的方法。这张栈就是 1.1 节九站旅程的实物证据。

其三:最简耗时过滤器。 自己写一个过滤器,在旅程最外层计时报时:

@Component public class TimingFilter extends OncePerRequestFilter { private static final Logger log = LoggerFactory.getLogger(TimingFilter.class); @Override protected void doFilterInternal(HttpServletRequest req, HttpServletResponse resp, FilterChain chain) throws ServletException, IOException { long start = System.nanoTime(); try { chain.doFilter(req, resp); } finally { log.info("{} 耗时 {} 微秒", req.getRequestURI(), (System.nanoTime() - start) / 1000); } } }

把耗时打点放在过滤器这一层,量到的是"控制器之前的一切 + 控制器本身",与控制器内部日志的耗时相减,就能估算出旅程前半段(分发、映射、拦截)的开销。

图 1-4 实验场结构与观察点位置

图 1-4 实验场结构与观察点位置

💡 一个工程用到底:后续章节往这个工程里逐章加依赖(数据访问、安全、消息),每加一章就重放同一条请求,观察旅程多出的新关卡。这比每章新建工程更能看清"模块如何改变旅程"。

排错实录:第一次启动失败的四种常见形态

实验场虽小,第一次跑失败却是常态。下面四个真实高频故障,逐一给出定位路径。

第一种:端口被占用,启动日志出现绑定异常后进程退出。定位:看异常信息里的端口号,换一个端口或停掉占用进程即可。第二种:包位置放错,启动成功但访问 ping 返回 404。背景:组件扫描以启动类所在包为根,控制器放在兄弟包之外就扫不到。操作:把控制器移进启动类的子包,或用注解显式扩大扫描范围。结果:404 消失。第三种:依赖下载中断导致构建失败,表现为仓库路径下的临时文件残留。操作:删掉本地仓库中对应目录后重新构建。第四种:Java 版本不符,启动即报版本错误。Boot 3.x 要求 Java 17 以上,用老版本运行时最先暴露的就是它。

把四种故障记录下来很有价值:它们分别对应旅程的四个不同层——网络层(端口)、装配层(扫描)、构建层(依赖)、运行环境(版本)。此后任何一次启动失败,先判断它发生在哪一层,再动手排查,这个习惯比记住具体命令更重要。

最后补一条工作习惯:实验场工程建好后提交到版本库时,把访问日志目录排除在外,避免日志文件污染仓库历史;计时过滤器建议保留,它是后续每一章观察耗时的公共基础设施。环境搭建是全书投入产出比最高的一小时——此后任何机制存疑,都能在这个工程里两分钟内得到实证。

本节要点回顾

  • starter parent 统管版本:工程里不再手写依赖版本号
  • 启动完成即关卡就绪:启动日志走完,所有站点已装配完毕
  • 三个观察点覆盖旅程三段:连接器、过滤器、分发到控制器
  • 计时用纳秒并放在 finally:异常路径的耗时也要量到

作者与出处
原作者: 灏天文库
来源:灏天文库
整理: 灏天文库整理
由灏天文库平台收录,内容或由平台用户上传,仅供学习交流
发布者: 作者: 灏天文库 转发
评论区 (0)
U