明朗北街七万号·数研工坊|扎根雄安新区中关村科技园,专注受限环境下软件搭建与数据平台落地
一、问题#
假设我们有 20 多个服务的微服务集群,但甲方要降本增效,服务器资源直接砍半。
我们怎么办?
当然,如果从架构设计当初就考虑好了,支持服务按模块方式聚合,当然就不是问题了。但我们大多时候考虑的都是如何支持更大体量的业务、更高的并发、扩容分布式多实例——很少考虑资源缩小的问题。
二、可选方案#
面对资源砍半的约束,我列举了以下几种可行的方向:
| # | 方案 | 说明 | 改造成本 |
|---|---|---|---|
| 1 | JVM 调优 | 对每个服务监控分析,调节 JVM 参数 | 低 |
| 2 | Tomcat 合并部署 | 改造为 war 包,多个服务部署到同一 Tomcat | 中 |
| 3 | 代码融合 | 直接做代码整合,缩减服务数量 | 高 |
| 4 | Spring Modulith | Spring Boot 官方模块化方案 | 中高 |
| 5 | Koupleless / SOFAArk | 动态加载的热部署模式,快速聚合 | 中 |
方案 4 算是比较均衡的,但需要较强的架构思维和业务梳理能力。方案 5 适合快速验证。方案 1 和 3 不做展开。
我对方案 2 进行改造和验证——将多个 Spring Boot 服务改造为 war 包,统一部署到一个 Tomcat 中。
三、实验过程#
测试环境#
- 拉取开源项目 SpringBlade 的代码
- 启动 6 个核心服务:blade-develop、blade-admin、blade-auth、blade-report、blade-resource、blade-system
- JVM 参数统一设置为 -Xmx 768m
- 对比两轮:独立 jar 启动 vs 合并 war 部署到 Tomcat 11
独立 JAR 模式#
六个服务分别以 java -jar 启动,在 Nacos 中注册为独立实例。
Tomcat 合并模式#
简单改造启动类后,将六个服务的 war 包放入 Tomcat 11 的 webapps 目录,通过健康接口确认全部正常启动。
资源占用对比#
| 模式 | PID | RES | MEM% |
|---|---|---|---|
| Tomcat 合并 | 147478 | 3.4g | 11.2% |
| blade-develop | 160608 | 987.2m | 3.1% |
| blade-admin | 160049 | 1.4g | 4.6% |
| blade-auth | 160417 | 989.5m | 3.1% |
| blade-report | 160178 | 1.1g | 3.7% |
| blade-resource | 160739 | 986.5m | 3.1% |
| blade-system | 160262 | 1.0g | 3.2% |
| JAR 合计 | 6 个进程 | ~6.4g | ~20.8% |
四、结果分析#
预期与现实的差距#
说实话,在做这个实验之前,我的预期是 Tomcat 部署多个服务会比独立 JAR 有明显的资源节省。但实际数据告诉我——差距不是想象中那种数量级的差异。
6 个独立 JAR 总占用约 6.4g,合并到 Tomcat 后约 3.4g。省了将近一半,但如果仔细看数据会发现,Tomcat 自身就占用了不小的固定开销。在 Tomcat 中跑 6 个服务和跑 1 个服务对比,边际资源增长是有限的——这才是节流的本质:共享了基础运行时的成本。
那合并部署的意义在哪?#
内存不是唯一的维度。换个角度看收益:
| 维度 | 独立 JAR 部署 | Tomcat 合并部署 | 变化 |
|---|---|---|---|
| 进程数 | 6 | 1 + Tomcat 管理进程 | -83% |
| 端口占用 | 6 | 1 | -83% |
| 内存总占用 | ~6.4g | ~3.4g | -47% |
| 启动时间 | 6 x 各自启动 | 1 次 Tomcat 启动 | 大幅缩短 |
| 运维管理 | 6 个进程分别管理 | 1 个容器统一管理 | 显著简化 |
真正的收益不在内存绝对值,而在管理成本和进程数量的降低。尤其是在资源受限的内网环境,少一个进程就意味着少一分运维负担。
什么场景适合这个方案#
- 服务器资源紧张,短期内无法扩容
- 服务数量多但单个服务负载不高
- 运维人力有限,需要降低管理复杂度
- 改造预算有限,不能做代码层面的重构
什么场景不适合#
- 单个服务负载本身就很高(需要独立扩缩容)
- 服务间隔离要求严格(故障隔离、安全域)
- 已经上了 K8s 容器编排(没必要倒退回 Tomcat)
五、总结#
这次实验给我最大的启发是:架构决策不是在完美方案之间做选择,而是在当前约束下找最优解。
Tomcat 合并部署不是一个漂亮的方案,但在服务器资源砍半、又不能重构代码的约束下,它是能最快落地、风险最低的选择。省下的是实实在在的管理成本和进程开销。
后面我还会继续测试方案 4(Spring Modulith)和方案 5(Koupleless),看看在资源受限场景下,还有哪些被低估的妥协式方案。欢迎持续关注。
本文首发于掘金 | 作者:七万号 扎根雄安新区中关村科技园,专注受限环境下软件搭建与数据平台落地