http服务器和servelet容器有什么不同

HTTP 服务器 和 Servlet 容器 到底有啥区别?为什么 Tomcat 既是 HTTP 服务器又是 Servlet 容器?

你现在困惑的点,本质就是:它们管的层级不一样、职责完全分开

一、先给你一句终极结论

  • HTTP 服务器:只懂 HTTP 协议、网络、静态文件,不懂 Java、Servlet、Controller
  • Servlet 容器:只懂 Servlet 规范、运行 Java Web 应用、管理 Servlet/Filter/Session,不懂底层网络 HTTP 解析

Tomcat = HTTP 服务器 + Servlet 容器它把两件事都干了,所以你会混淆。

二、HTTP 服务器是干嘛的?(举例:Nginx、Apache httpd、Tomcat 的 Connector 部分)

职责(只做底层)

  1. 监听端口(80、443、8080)
  2. 处理 TCP 连接
  3. 解析 HTTP 请求报文(头、方法、URL、body)
  4. 返回 HTTP 响应
  5. 能返回静态资源:html、css、js、jpg
  6. 不懂任何 Java 代码,完全不执行 Servlet

你可以理解:

HTTP 服务器 = 收发快递的驿站只负责拆包、打包、传输,不关心里面是什么业务。

三、Servlet 容器是干嘛的?(举例:Tomcat 的 Container 部分、Jetty、Undertow)

职责(只做 Java Web 上层)

  1. 实现 Servlet 规范
  2. 加载、管理、运行 Servlet
  3. 管理 Filter、Listener、Session
  4. 给 Servlet 提供 Request/Response 对象
  5. 调度请求到对应的 Servlet
  6. 不关心底层网络怎么读 HTTP,只拿解析好的对象用

你可以理解:

Servlet 容器 = 业务办公室只管处理业务逻辑,不管快递怎么送过来。

四、一张表秒懂区别

维度 HTTP 服务器 Servlet 容器
核心功能 处理网络、HTTP 协议、静态文件 运行 Java Web 应用、管理 Servlet
懂不懂 Java/Servlet 完全不懂 必须懂 Servlet 规范
主要做什么 接收请求、解析 HTTP、返回响应 执行 Servlet、Filter、Session、业务代码
典型软件 Nginx、Apache httpd Tomcat、Jetty、Undertow
对应 Tomcat 哪部分 Connector(连接器) Container(容器)

五、用生活例子彻底讲透(你一下就通)

场景:用户点一个接口 /user/list

  1. 浏览器发 HTTP 请求

  2. HTTP 服务器(Tomcat Connector)

    • 接到网络数据
    • 解析出:URL=/user/list,方法 GET
    • 封装成 Request 对象
    • 自己不处理,交给 Servlet 容器
  3. Servlet 容器(Tomcat Container)

    • 拿到 Request
    • 找到 DispatcherServlet
    • 交给 Spring MVC
    • 执行你的 @Controller
    • 把结果写到 Response
  4. HTTP 服务器

    • 拿到 Response
    • 组装成 HTTP 报文
    • 发回浏览器

六、为什么要分开?(架构意义)

  1. 职责单一

    • HTTP 服务器:专注高性能网络 IO、并发、静态资源
    • Servlet 容器:专注业务运行、Java 规范
  2. 真实部署结构(你以后必会遇到)

浏览器 → Nginx(HTTP服务器) → Tomcat(Servlet容器)
  • Nginx 做反向代理、负载均衡、静态资源、HTTPS
  • Tomcat 只跑 Java 业务

这就是:HTTP 服务器 和 Servlet 容器分工配合

七、回到你最关心的:SpringBoot 内置 Tomcat

  • Tomcat 里的 Connector = HTTP 服务器
  • Tomcat 里的 Container = Servlet 容器
  • SpringBoot 应用 = 跑在 Servlet 容器里的 Web 应用
  • 请求流程:
    浏览器
      ↓
    Connector(HTTP服务器:解析HTTP)
      ↓
    Container(Servlet容器:执行Servlet/Controller)
      ↓
    返回响应
    

八、极简总结(背这几句就行)

  1. HTTP 服务器:管网络、HTTP 解析、静态文件,不懂 Java
  2. Servlet 容器:管运行 Java Web 应用、Servlet、Session,依赖 HTTP 服务器提供请求
  3. Tomcat 同时包含两者,所以既是 HTTP 服务器,又是 Servlet 容器
  4. 真实线上:Nginx (HTTP) + Tomcat (Servlet 容器) 配合使用

那其他语言呢

不光 Java,所有语言的 Web 服务,架构思路完全一样,只是名字不同。

你刚才理解的这套:HTTP服务器 <-> 应用容器 <-> 业务代码是通用架构,不是 Java 独有

先把通用模型抽出来(所有语言都遵守)

不管什么语言,Web 请求一定分两层:

  1. HTTP 服务器(通用层)

    • 处理 TCP、HTTP 协议、解析请求、发响应
    • 负责网络、并发、长连接、静态文件
    • 不执行业务代码
  2. 应用运行层(语言专属层)

    • 执行业务逻辑
    • 管理路由、控制器、中间件、连接池等
    • 不懂底层 HTTP 解析

Java 只是把这两层打包在了 Tomcat 里,别的语言是分开或换名字。

我直接给你对标:其他语言对应什么?

1. Java 你已经懂了

  • HTTP 服务器:Tomcat Connector / Nginx
  • 应用容器(Servlet 容器):Tomcat Container
  • 业务:Servlet / SpringMVC / Controller

2. Go 语言

  • HTTP 服务器:Go 内置 net/http自己实现 HTTP 解析、TCP 监听
  • 应用框架:Gin、Echo、Beego负责路由、中间件、参数解析
  • 结构:
    浏览器 → Go内置HTTP服务器 → Gin路由 → Handler函数
    

Go 把 HTTP 服务器直接嵌到语言里了,不需要外置 Tomcat。

3. Python

  • HTTP 服务器:gunicorn、uWSGI、uvicorn
  • 应用容器 / 规范:WSGI / ASGI
  • 业务框架:Django、Flask、FastAPI结构:
浏览器 → gunicorn(HTTP服务器) → WSGI → Flask/Django

对应 Java:

  • gunicorn ≈ Tomcat Connector
  • WSGI ≈ Servlet 规范
  • Flask ≈ SpringMVC

4. PHP

  • HTTP 服务器:Nginx、Apache
  • 应用运行器:php-fpm
  • 业务:PHP 代码结构:
浏览器 → Nginx → php-fpm → PHP脚本
  • Nginx 做 HTTP 解析
  • php-fpm 负责运行 PHP、管理进程 / 线程

5. Node.js

  • HTTP 服务器:Node 内置 http 模块
  • 框架:Express、Koa、NestJS结构:
浏览器 → Node内置HTTP → Express路由 → 接口

和 Go 很像:自带 HTTP 服务器,不需要外置容器

核心规律(非常重要)

所有语言 Web 架构,本质只有两种模式:

模式 1:自带 HTTP 服务器(Go、Node、SpringBoot 内嵌)

  • HTTP 服务器直接嵌在进程里
  • 一个进程跑完全部
  • 代表:
    • SpringBoot 内嵌 Tomcat
    • Go net/http
    • Node http

就是你现在项目的样子:一个 Java 进程全包。

模式 2:HTTP 服务器与应用分离(传统 PHP、Python、Java 外置 Tomcat)

浏览器 → Nginx/Apache → 应用容器 → 代码
  • Nginx 只管 HTTP
  • 后面容器只管业务

回到你最疑惑的点:为什么 Java 要搞 Servlet 容器?

因为历史 + 规范

  • Java 很早就定了 Servlet 规范
  • 把「业务运行」和「HTTP 网络」强行拆成两层
  • Tomcat 把两层都实现了,所以它既是 HTTP 服务器,又是 Servlet 容器

其他语言没有统一规范,就自己随便组合:

  • Go:自带 HTTP + 框架
  • Python:HTTP 服务器 (gunicorn) + WSGI 规范 + 框架
  • PHP:Nginx + php-fpm

思想完全一样,只是名字不同。

用最简单的话总结(你记这个就够)

  1. HTTP 服务器:所有语言都有,负责 TCP、HTTP、网络,通用
  2. 应用容器 / 运行器:语言专属,负责跑业务代码
  3. Tomcat 特殊在:它同时包含 HTTP 服务器 + Servlet 容器
  4. 其他语言只是拆成不同组件,架构逻辑一模一样

Java 外置 Tomcat,项目跑起来的时候有几个进程

Java 外置 Tomcat 和 SpringBoot 内嵌,进程数量完全不一样,这是面试和部署最容易搞混的点。

一句话结论

  • 外置 Tomcat(传统方式,把 war 丢进 webapps)1 个 Tomcat 进程,里面可以跑多个 Java 项目
  • SpringBoot 内嵌 Tomcat(jar 方式)1 个项目 = 1 个独立 Java 进程

一、外置 Tomcat 启动时:几个进程?

你平时这种玩法:

  1. 下载 apache-tomcat-xxx.zip
  2. startup.bat/startup.sh 启动 Tomcat
  3. 把你的项目打成 war 包 丢进 webapps

启动后:

  • 操作系统里 只有 1 个 Java 进程:tomcat 自己
  • 你的项目 不是独立进程,是跑在 Tomcat 内部的
操作系统
└── 1 个 Java 进程(Tomcat)
    ├── 你的项目A(war1)
    ├── 项目B(war2)
    └── 项目C(war3)

所以:项目跑起来,仍然只有 1 个进程(Tomcat 进程)。

二、那它和内嵌 Tomcat 区别到底在哪?(重点)

1. 内嵌(SpringBoot jar)

  • java -jar app.jar
  • → 启动 1 个 JVM 进程
  • → 里面自己 new 了一个 Tomcat
  • 一个项目 = 一个进程

2. 外置(传统 war 部署)

  • 先启动 tomcat/bin/startup.sh
  • → 启动 1 个 JVM 进程
  • 然后你丢 N 个 war 进去
  • N 个项目 共用 同一个 Tomcat 进程

最核心区别:

  • 内嵌:项目自带 Tomcat,独立进程,隔离性好
  • 外置:多个项目共用一个 Tomcat 进程,不隔离

三、外置 Tomcat 内部结构(一眼看懂)

Tomcat JVM 进程
├── Server / Service
├── Connector(监听8080)
├── Engine
│   ├── Host
│   │   ├── Context1  → 项目A war
│   │   ├── Context2  → 项目B war
│   │   └── Context3  → 项目C war
  • 每个 war = 一个 Context
  • 所有 Context 共用同一个 JVM、同一个堆内存、同一个 Tomcat 线程池

四、请求怎么处理?(和你之前知识串起来)

  1. 浏览器请求进来
  2. Tomcat Connector(HTTP 服务器)接收
  3. 根据 URL 找到对应 Context(你的项目)
  4. 进入该项目的 DispatcherServlet
  5. 执行 Controller
  6. 返回响应

全程都在 同一个 Tomcat 进程 里。

五、你最容易懵的 3 个问题,直接答死

1. 外置 Tomcat 跑 3 个项目,有几个进程?

1 个进程(Tomcat)

2. 一个项目挂了,会影响其他项目吗?

会!因为共用一个 JVM:

  • 某个项目 OOM
  • 直接把整个 Tomcat 搞崩
  • 所有项目一起挂👉 这就是为什么现在都用 SpringBoot 独立部署。

3. 外置 Tomcat 里,项目是进程吗?

不是。项目只是 Tomcat 里的 一组 Class + 一组 Bean + 一个 Context,不是进程。

六、极简总结(背这个)

  • 外置 Tomcat:1 个进程,多项目共享
  • 内嵌 Tomcat:1 个项目 = 1 个独立进程
  • 线程模型、HTTP 服务器、Servlet 容器原理完全一样,只是进程模型不同
Logo

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

更多推荐