是的,你的直觉非常准!

在现代的 Spring Boot 微服务架构中,每一个微服务实例都拥有一个完全独立的、内嵌的 Tomcat(或者其他 Web 服务器)。

为了让你彻底摆脱“一锅粥”的状态,我们把新老架构做个对比,你就秒懂了。


1. 过去 vs 现在:从“合租房”到“独栋单身公寓”

过去(传统单体架构):大合租房

以前部署 Java Web 应用,我们需要在服务器上单独下载、安装一个笨重的 Tomcat 软件。然后把“用户模块.war”、“订单模块.war”、“商品模块.war”全部丢进这同一个 Tomcat 的 webapps 目录里。

  • 弊端: 这几个模块共享同一个 Tomcat 的线程池和内存。如果“订单模块”写了个死循环把 Tomcat 搞崩溃了,或者把线程池占满了,“用户模块”和“商品模块”也会跟着一起死。
现在(现代微服务架构):独栋公寓

现代微服务采用的是 内嵌 Tomcat (Embedded Tomcat) 的模式。Tomcat 不再是一个独立的外部软件,而是变成了几个 jar 包依赖,直接被打包进了你微服务的 JAR 包内部

当你启动微服务时:

  1. 用户服务 (User Service): 启动一个独立的 JVM 进程,在自己内部默默初始化了一个 Tomcat,监听 8081 端口。
  2. 订单服务 (Order Service): 启动另一个完全独立的 JVM 进程,在自己内部也初始化了一个 Tomcat,监听 8082 端口。

这两个 Tomcat 在内存上、线程池上、端口上完全隔离,互不干扰。


2. 这样做有什么惊人的好处?

既然每个微服务都自带一个 Tomcat,内存开销不是变大了吗?为什么大家还要这么做?核心原因有三个:

  • 核心优势一:彻底的故障隔离
    如果“订单服务”因为大促被秒杀流量冲垮了,它的 Tomcat 线程池爆满、甚至 OOM(内存溢出)死掉了,“用户服务”的 Tomcat 依然活得好好的,用户依然可以正常登录、浏览个人中心。
  • 核心优势二:精准的独立伸缩 (Scaling)
    双十一到了,订单量暴增。网关(Gateway)发现订单服务快扛不住了,于是运维人员(或者自动化脚本)可以瞬间把“订单服务”在不同机器上克隆出 10 个实例(也就是启动了 10 个独立的 Tomcat 进程)。而访问量不大的“用户服务”依然保持 2 个实例。这种精准的资源分配在过去是做不到的。
  • 核心优势三:量身定制的服务器配置
    在上一问中我们提到 Tomcat 有工作线程池。在微服务架构下:
  • “商品详情服务”主要是查缓存,速度极快,我们可以把它的 Tomcat 最大线程数调小一点。
  • “报表导出服务”非常消耗时间,我们可以把它的 Tomcat 超时时间(Timeout)调大一点。
    每个服务都能根据自己的性格,定制自己的 Tomcat。

3. 高级避坑指南:微服务里一定都是 Tomcat 吗?

虽然绝大多数 Spring Boot 微服务默认内嵌的都是 Tomcat,但有一个特例你需要注意:网关(如 Spring Cloud Gateway)。

我们在上一问的流程里提到,网关是所有请求的“总调度中心”,它需要迎接海量的并发连接。Tomcat 的“一请求一线程”模型在网关这里会显得有些吃力。

因此,Spring Cloud Gateway 底层默认内嵌的是 Netty,而不是 Tomcat。Netty 采用了异步非阻塞的网络模型,用极少的线程就能扛住海量的并发请求。

一句话总结:
无论是 Tomcat 还是 Netty,现代微服务的核心思想就是:一个微服务,一个独立的 JVM 进程,一个专属的内嵌 Web 服务器。

搞懂了每个微服务都是独立 Tomcat 之后,你回想一下上一问的请求全流程:当网关(Gateway)把请求转发给某个具体的微服务时,是不是就是通过网络,精准地投递到了该服务专属的那个 Tomcat 端口上?在这个“独立服务器”的理解基础上,你对刚才聊到的 Filter(过滤器)和 Interceptor(拦截器)的执行边界,有没有产生什么新的疑问?

Logo

openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构

更多推荐