1.2 Tomcat的定位:与Nginx、Apache、Jetty的分工


文档摘要

1.2 Tomcat 的定位:与 Nginx、Apache、Jetty 的分工 本节摘要:Tomcat 的准确定位是"Servlet 容器兼静态 Web 服务器",不是全能应用服务器。本节用一个常见误解切入,通过与 Nginx、Apache HTTP Server、Jetty 的逐项对比划清能力边界,再给出"Nginx 在前、Tomcat 在后"的典型生产拓扑与配置实证,最后按场景给出选型建议。学完你能回答"这个请求该由谁处理"。 承接 1.1 的旅程图:请求已经能走完 Tomcat 内部的管道,但真实生产中请求往往先经过别的服务器。本节解决"Tomcat 在整个 Web 服务生态里站在哪一层"——想清楚这一点,第 3 章的端口与协议配置才有方向。

1.2 Tomcat 的定位:与 Nginx、Apache、Jetty 的分工

本节摘要:Tomcat 的准确定位是"Servlet 容器兼静态 Web 服务器",不是全能应用服务器。本节用一个常见误解切入,通过与 Nginx、Apache HTTP Server、Jetty 的逐项对比划清能力边界,再给出"Nginx 在前、Tomcat 在后"的典型生产拓扑与配置实证,最后按场景给出选型建议。学完你能回答"这个请求该由谁处理"。

承接 1.1 的旅程图:请求已经能走完 Tomcat 内部的管道,但真实生产中请求往往先经过别的服务器。本节解决"Tomcat 在整个 Web 服务生态里站在哪一层"——想清楚这一点,第 3 章的端口与协议配置才有方向。

从一个常见的误解说起

"Tomcat 是应用服务器吗?"——面试里十有八九会碰到,而答错的人往往不是没用过 Tomcat,而是没分清三样东西:Web 服务器、Servlet 容器、应用服务器。

Web 服务器(Nginx、Apache HTTP Server 的本职)擅长把静态文件高速发给浏览器,处理并发连接,做反向代理与负载均衡,但它不认识 Servlet。Servlet 容器(Tomcat 的本职)提供 Servlet 规范的运行环境:管理 Servlet 生命周期、编译 JSP、提供会话与安全机制。应用服务器(WildFly、WebLogic、WebSphere 这类)则在容器之上再叠加事务、消息、EJB 等完整 Jakarta EE 能力。Tomcat 只实现了 Web 规范那一小块——Servlet、JSP、EL、WebSocket——所以它轻、快、稳定,也所以在纯 Web 场景下几乎是默认选择。

这个定位直接决定了一个事实:Tomcat 可以当静态 Web 服务器用,但没人这么用。发静态文件它比不过 Nginx,跑分布式事务它又不够格。它的价值在中间那层:让 Java 写的动态应用有一个符合规范的家。

四个选手放在一张桌上比

对比维度 Tomcat Nginx Apache HTTP Server Jetty
本职角色 Servlet 容器 反向代理与静态服务 静态服务与模块化代理 Servlet 容器
Servlet 与 JSP 原生支持 不支持 需插件且已边缘化 原生支持
静态文件吞吐 中等 极强 中等
内存与启动 中等 极轻 中等 极轻
嵌入式使用 可内嵌 少见 少见 最常见
典型场景 Java Web 应用部署 前置代理与静态分流 传统站点与 CGI 时代存量 异步与云原生场景

两个容易忽略的点。其一,Tomcat 与 Jetty 是同类,选择更多看团队习惯:Tomcat 生态文档更全、默认配置更稳,Jetty 架构更灵活、嵌进自定义产品更顺手。其二,Nginx 与 Tomcat 不是竞争关系而是上下游——前者站在公网边上挡流量、发静态,后者在局域网里跑业务。

生产拓扑:为什么要一前一后

直接把 Tomcat 暴露在公网行不行?技术上可以,工程上不明智,理由有三。第一,静态资源分流:图片、脚本、样式表交给 Nginx 直接返回,Tomcat 的宝贵线程只服务动态请求。第二,安全缓冲:TLS 终止、请求大小限制、恶意连接拦截都在 Nginx 完成,Tomcat 只听内网。第三,运维弹性:Nginx 上做负载均衡,后端 Tomcat 可以随时扩容、重启、灰度。

下面是一套最小可用的配合配置。先是 Nginx 侧的反向代理,动态请求转给 Tomcat,静态文件自己消化。

server { listen 80; server_name shop.example.com; # 静态资源:Nginx 自己处理,不进 Tomcat location /assets/ { root /data/web; expires 7d; } # 其余全部转给后端 Tomcat location / { proxy_pass http://127.0.0.1:8080; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } }

再看 Tomcat 侧的配合动作。既然流量都来自本机的 Nginx,连接器就没必要对外多开口,而且要正确识别代理传来的真实客户端地址。

<!-- server.xml 中让 Engine 感知前置代理 --> <Host name="localhost" appBase="webapps"> <!-- RemoteIpValve 把代理头里的真实地址还原为请求来源 --> <Valve className="org.apache.catalina.valves.RemoteIpValve" internalProxies="127\.0\.0\.1" remoteIpHeader="X-Forwarded-For" protocolHeader="X-Forwarded-Proto"/> </Host>

这套组合拳的验证方式很直接:从外网访问站点,静态资源命中 Nginx 缓存,动态请求在 Tomcat 访问日志里看到的来源 IP 是真实客户端而非 127.0.0.1——后者正是 RemoteIpValve 在起作用。如果忘了配这个阀门,你会得到一整页"来源全是本机"的访问日志,排障时两眼一抹黑。

⚠️ 常见坑:internalProxies 的值是正则。抄配置时如果 Nginx 不在 127.0.0.1 而在别的内网段,这个阀门会静默失效——不报错,只是不还原地址。验证方法就看访问日志第一列。

按场景选型,不按信仰

  • 内部管理系统、传统企业应用:单台 Tomcat 直接跑,简单够用,没必要多养一层 Nginx。
  • 面向公网的 Web 服务:Nginx 在前做 TLS 终止与静态分流,Tomcat 只监听内网,这是最主流的搭配。
  • 高并发长连接或推送场景:评估 Jetty 或直接用 Netty 类方案;若留恋 Servlet 生态,Tomcat 的 NIO2 与 WebSocket 支持也能撑住大多数场景。
  • 需要完整 Jakarta EE(事务、消息、EJB):Tomcat 不够,去看 WildFly 或商业容器。
  • 微服务与内嵌场景:Spring Boot 默认内嵌 Tomcat,第 6 章会专门讲这条路线。

带走三句话

  • Tomcat 是 Servlet 容器,静态能力是附赠品,事务能力是别人的地盘。
  • Nginx 与 Tomcat 是上下游,配合的核心是"静态分流 + 地址还原",后者靠 RemoteIpValve。
  • 选型看场景:公网服务前后分层,内部系统单机直跑,重量级规范需求换平台。

位置讲清楚了,时间坐标还没交代。下一节把版本史摊开——特别是 javax 与 jakarta 这道分水岭,它直接决定你的依赖能不能跑。


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