简介:apache-tomcat-7.0.100-windows-x64.zip 是面向 Java Web 开发与运维人员的 64 位 Windows 版 Tomcat 服务器安装包,用于部署和运行 Servlet、JSP 应用,适合需要搭建本地测试环境或学习 Java EE 6 规范的初中级开发者。压缩包共 648 个文件,约 10.43MB,以 html 文档、class 字节码、java 源码、jsp 页面、gif 图标、jar 依赖库及 xml 配置为主,另含少量 bat 启动脚本、properties 配置、sh 脚本与 exe 可执行文件,覆盖 bin、conf、lib、logs、temp、webapps、work 等标准目录结构。已有 1379 人学习下载。资源完整保留 Tomcat 7.0.100 的默认配置与示例应用,读者可据此快速完成环境变量设置、端口与连接器调整、应用部署及日志排查,理解 Servlet 3.0、JSP 2.2 与 EL 2.2 的异步处理、过滤器链增强等特性,是学习 Java Web 容器原理与运维配置的实用参考。
1. 从一台老工控机说起:为什么还有人需要 Tomcat 7.0.100
上周帮一个做设备管理系统的朋友排查问题,他那台跑在车间的 Windows 工控机上,一个 Java Web 应用突然起不来了。远程连过去一看,日志里报的是Unsupported major.minor version,再一问,机器上装的是 JDK 7,而应用打包时用的编译目标也是 1.7。他试过换 Tomcat 9,结果启动直接抛NoClassDefFoundError,因为 Tomcat 9 要求 JDK 8 起步。折腾一圈,最后还是回到 Tomcat 7.0.100 这个版本才把服务拉起来。
这就是apache-tomcat-7.0.100-windows-x64.zip存在的意义。它是 Apache Tomcat 7.x 分支的最后一个发布版本,Windows 64 位免安装压缩包,解压即可用,不需要跑安装程序,也不写注册表。适合谁?三类人:一是维护老系统的运维,生产环境锁死在 JDK 7 或更早版本;二是做嵌入式设备或工控上位机的开发者,客户现场机器配置低、系统老;三是教学或实验环境,需要复现某个特定版本的行为。如果你手上全是 JDK 8+ 的新项目,这个包对你没用,直接上 Tomcat 9 或 10 更省心。
Tomcat 7.0.100 这个版本号本身值得说一句。7.0.x 系列从 2010 年一直维护到 2021 年,0.100 是这条线的终点,意味着它之后不会再有安全补丁和 bug 修复。选它,本质上是拿“不再更新”换“与老 JDK 和老应用的兼容性”。这个取舍在封闭的内网环境里是划算的,但放到公网暴露的服务上就要格外谨慎。下面我从解压目录结构讲起,把配置、部署、调优和几个血泪坑一次说清楚。
2. 解压后的目录结构与 JDK 版本匹配:先搞懂每个文件夹干什么
拿到 zip 包,第一件事不是急着双击 startup.bat,而是先看清楚解压出来的是什么。很多人翻车就翻在“以为解压完就能跑”,结果 JAVA_HOME 没配对,或者把应用扔错了目录。
2.1 七个核心目录的职责划分
解压apache-tomcat-7.0.100-windows-x64.zip后,根目录下会出现这些文件夹,每个都有明确分工:
| 目录 | 作用 | 能不能动 |
|---|---|---|
| bin | 启动/停止脚本、bootstrap.jar、tomcat-juli.jar | 脚本可改,jar 别动 |
| conf | server.xml、web.xml、context.xml、tomcat-users.xml 等配置 | 核心配置区,改前备份 |
| lib | Tomcat 自身运行依赖的 jar | 一般不动,除非加 JDBC 驱动 |
| logs | 日志输出,catalina.out 在 Windows 下是 catalina.YYYY-MM-DD.log | 可清理 |
| temp | 临时文件,Tomcat 运行时用 | 可清理 |
| webapps | 默认应用部署目录,ROOT、docs、examples、manager、host-manager | 部署主战场 |
| work | JSP 编译后的 .java 和 .class 缓存 | 出问题可整个删掉重建 |
bin目录里 Windows 用户主要用两个脚本:startup.bat和shutdown.bat。它们本质上是设置好环境变量后调用catalina.bat。catalina.bat才是真正干活的,支持run(前台运行)、start(后台启动)、stop等参数。调试阶段我建议直接用catalina.bat run,日志直接打在控制台,不用去 logs 目录翻。
conf/server.xml是整个 Tomcat 的心脏,端口、连接器、虚拟主机、Context 都在这里定义。conf/tomcat-users.xml管的是 manager 和 host-manager 这两个 Web 管理界面的登录账号,默认是注释掉的,不配就进不去。conf/web.xml是全局的 Servlet 和 MIME 映射,一般不动,但改默认欢迎页、改 session 超时时间会用到。
2.2 JDK 版本匹配是第一条红线
Tomcat 7.0.100 官方要求 JDK 1.6 及以上。但“能跑”和“跑得好”是两回事。实际经验是:
- JDK 1.6:能启动,但 7.0.100 里部分代码用了 1.7 的语法糖,个别场景会出问题,不推荐。
- JDK 1.7:最匹配的组合,7.0.100 就是为这个版本线收尾的。
- JDK 1.8:能跑,但要注意
tools.jar在 JDK 8 里还在,到 JDK 9 就没了,而 Tomcat 7 的 JSP 编译依赖它。 - JDK 9 及以上:基本别想,模块化系统会让 Tomcat 7 的类加载机制直接崩掉。
验证 JDK 是否配对,解压后先在命令行敲:
# 查看当前 JAVA_HOME 指向哪个 JDK echo %JAVA_HOME% # 查看 java 版本,确认是 1.7.x java -version如果JAVA_HOME没设置,或者指向了 JDK 9+,startup.bat会一闪而过,窗口都留不住。这是新手最常见的第一个坑。正确做法是在系统环境变量里新建JAVA_HOME,值指向 JDK 安装根目录,比如C:\Java\jdk1.7.0_80,注意结尾不要带分号,也不要用引号包起来。然后把%JAVA_HOME%\bin加到Path里。
提示:Windows 下如果路径里有空格,比如
C:\Program Files\Java\...,某些老脚本会解析出错。JDK 尽量装在无空格路径下,能省掉一类玄学问题。
2.3 启动脚本背后的环境变量逻辑
startup.bat本身很短,它调用catalina.bat start。真正决定 Tomcat 行为的是catalina.bat里读取的几个环境变量:
CATALINA_HOME:Tomcat 安装根目录,脚本会自动推断,一般不用手动设。CATALINA_BASE:运行实例的根目录,默认等于CATALINA_HOME。想在一台机器上跑多个实例时,才需要单独设这个,让多个实例共享同一份程序文件、各自独立的 conf 和 webapps。JAVA_OPTS:JVM 启动参数,内存、编码、GC 都从这里传。CATALINA_OPTS:只传给 Tomcat 启动进程的参数,stop时不传。
我一般会在bin下新建一个setenv.bat,把自定义参数写进去,而不是直接改catalina.bat。这样升级或替换 Tomcat 时,自己的配置不会丢。setenv.bat会被catalina.bat自动调用,内容大概长这样:
# setenv.bat - 自定义 JVM 参数,避免污染 catalina.bat set JAVA_OPTS=-Xms512m -Xmx1024m -XX:PermSize=128m -XX:MaxPermSize=256m set JAVA_OPTS=%JAVA_OPTS% -Dfile.encoding=UTF-8 set CATALINA_OPTS=-Djava.awt.headless=true这里-XX:PermSize和-XX:MaxPermSize是 JDK 7 及以前的永久代参数,JDK 8 换成了 Metaspace,参数名变成-XX:MetaspaceSize。用错版本会看到Unrecognized VM option的报错。-Dfile.encoding=UTF-8是防中文乱码的,Windows 默认 GBK,不设这个,日志和页面里的中文经常变成问号。
3. server.xml 关键配置与 Web 应用部署:端口、连接器和 Context
配置改对了,Tomcat 才听话。server.xml里能改的东西很多,但日常真正需要动的就那么几处。改之前先复制一份server.xml.bak,这是后悔药。
3.1 端口冲突与 Connector 参数
默认配置下,Tomcat 监听三个端口:8080(HTTP)、8005(SHUTDOWN)、8009(AJP)。8080 被占用是最常见的启动失败原因,报错是Address already in use: JVM_Bind。查占用:
# 查 8080 端口被哪个进程占用 netstat -ano | findstr :8080 # 根据 PID 查进程名 tasklist | findstr <PID>找到后要么停掉那个进程,要么改 Tomcat 端口。改端口在server.xml的 Connector 节点:
<!-- HTTP 连接器,port 改成 8081 避开冲突 --> <Connector port="8081" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" URIEncoding="UTF-8" maxThreads="300" minSpareThreads="25" acceptCount="200" />几个参数的实际含义:connectionTimeout是连接超时毫秒数,20000 即 20 秒;URIEncoding="UTF-8"决定 GET 请求 URL 里中文参数的解码方式,不设的话中文查询参数会乱码;maxThreads是最大工作线程数,默认 200,并发高的内部系统可以调到 300 到 500;acceptCount是等待队列长度,线程满了之后还能排多少人,默认 100,调大能扛住突发流量但会拉长响应时间。
AJP 连接器(8009 端口)是给 Apache HTTP Server 做反向代理用的。如果前面没有 Apache,这个连接器可以整个注释掉,少一个端口暴露面。SHUTDOWN 端口(8005)是shutdown.bat发关闭指令用的,如果改了端口,shutdown.bat也要同步改,否则关不掉。
3.2 部署一个 WAR 包的完整流程
Tomcat 部署应用有几种方式,最省事的是把 WAR 包丢进webapps。假设你有一个device-mgr.war:
# 停掉 Tomcat,避免热部署时的类加载冲突 cd C:\tomcat7\bin shutdown.bat # 把 war 包复制到 webapps copy C:\build\device-mgr.war C:\tomcat7\webapps\ # 重新启动 startup.bat启动后 Tomcat 会自动解压 WAR 到同名目录webapps\device-mgr\,访问路径就是http://localhost:8081/device-mgr/。这里有个细节:如果webapps下已经存在同名的旧目录,Tomcat 启动时会比较 WAR 和目录的时间戳,决定是否重新解压。有时候改了 WAR 但目录没更新,就是因为时间戳判断出了问题。稳妥做法是停服后先删掉旧目录再放新 WAR。
另一种方式是在conf/server.xml里配 Context,把应用指向webapps之外的路径:
<!-- 部署到外部目录,path 是访问路径,docBase 是实际物理路径 --> <Context path="/device" docBase="D:\apps\device-mgr" reloadable="false" />reloadable="false"是生产环境必须的。设成true时 Tomcat 会监控WEB-INF/classes和WEB-INF/lib下的类文件变化并自动重载,开发时方便,但生产环境会带来严重的性能开销和内存泄漏风险。我见过一个项目因为忘了关 reloadable,跑了一周后 PermGen 爆掉,日志里全是OutOfMemoryError: PermGen space。
3.3 虚拟主机与多应用隔离
一台 Tomcat 跑多个应用,除了用不同的 Context path,还可以用虚拟主机按域名隔离。在server.xml的 Engine 节点下加 Host:
<Host name="app1.internal" appBase="webapps-app1" unpackWARs="true" autoDeploy="false"> <Context path="" docBase="device-mgr" reloadable="false" /> </Host>appBase指定这个虚拟主机的应用目录,autoDeploy="false"关掉自动部署,避免 Tomcat 扫描目录带来的启动延迟。path=""表示根路径,访问http://app1.internal:8081/就直接进 device-mgr。多应用隔离时要注意,不同应用如果依赖同一个库的不同版本,类加载器会打架,这种时候要么统一版本,要么拆成多个 Tomcat 实例。
注意:
server.xml改完必须重启才生效,Tomcat 7 不支持这个文件的动态重载。改之前备份,改之后先用catalina.bat run前台启动看有没有解析错误,确认无误再转后台。
4. 内存、编码与日志:三个最容易翻车的配置点
配置能启动只是第一步,跑起来之后内存、编码、日志这三块出问题的概率最高。这一章按“现象 → 原因 → 解决”的方式,把几个典型坑拆开讲。
4.1 内存参数与 PermGen 溢出
现象:应用跑一段时间后页面卡死,日志里出现java.lang.OutOfMemoryError: PermGen space,重启后恢复,过一阵又复发。
原因:JDK 7 及以前,类的元数据、常量池、静态变量都存在永久代(PermGen)里,默认上限才 64MB 到 82MB。应用一多、JSP 一多、或者有 reloadable 导致的类反复加载,永久代很快被撑满。
解决:在setenv.bat里显式设置永久代大小,并加上-XX:+CMSClassUnloadingEnabled让 GC 能回收类元数据:
set JAVA_OPTS=-Xms1024m -Xmx1024m -XX:PermSize=256m -XX:MaxPermSize=512m set JAVA_OPTS=%JAVA_OPTS% -XX:+CMSClassUnloadingEnabled -XX:+UseConcMarkSweepGC-Xms和-Xmx设成一样大,避免堆动态伸缩带来的抖动。PermSize是初始值,MaxPermSize是上限,设成 256m/512m 对大多数中小应用够用。注意这两个参数在 JDK 8 上会报警告,JDK 8 要换成-XX:MetaspaceSize和-XX:MaxMetaspaceSize。
4.2 中文乱码的三层来源
现象:页面显示的中文变成乱码,或者表单提交的中文存进数据库变成问号。
原因:乱码可能来自三个地方,要逐层排查。第一层是 JVM 默认编码,Windows 下是 GBK;第二层是 Connector 的URIEncoding,影响 GET 参数;第三层是应用自己的 request/response 编码设置,影响 POST 和输出。
解决:三层一起治。JVM 层加-Dfile.encoding=UTF-8;Connector 层加URIEncoding="UTF-8";应用层在web.xml里配 CharacterEncodingFilter,或者每个 Servlet 里手动request.setCharacterEncoding("UTF-8")。JSP 页面头部加<%@ page contentType="text/html;charset=UTF-8" %>。三层都对齐 UTF-8,乱码基本绝迹。
4.3 日志切割与 catalina.out 膨胀
现象:磁盘被日志写满,logs目录下单个文件几个 GB。
原因:Windows 下 Tomcat 默认用java.util.logging,catalina.YYYY-MM-DD.log按天切,但localhost.YYYY-MM-DD.log和catalina.out(如果配了)可能不切。加上应用自己往控制台打大量日志,文件涨得飞快。
解决:在conf/logging.properties里调整日志级别,把org.apache.catalina从FINE调到INFO或WARNING,减少无用输出。同时用 Windows 的任务计划程序定期清理超过 30 天的日志,或者引入 log4j 做滚动切割。生产环境我一般把logging.properties里的 ConsoleHandler 级别设成WARNING,只留必要信息。
5. 避坑与排查:五个真实踩过的坑
这一章全是血泪经验,每条都按“现象 → 原因 → 解决”写,照着排查能省不少时间。
坑一:startup.bat 一闪而过,窗口留不住。现象是双击startup.bat,黑窗口闪一下就没了,Tomcat 没起来。原因通常是JAVA_HOME没设或设错,脚本找不到 java.exe 直接退出。解决:在命令行里手动执行catalina.bat run,错误信息会留在窗口里;确认JAVA_HOME指向正确的 JDK 根目录,且%JAVA_HOME%\bin\java.exe真实存在。
坑二:8080 端口被占用,启动报 Address already in use。现象是日志里java.net.BindException: Address already in use: JVM_Bind。原因是别的程序占了 8080,常见的是另一个 Tomcat、某些开发工具的内置服务器、或者迅雷之类的下载软件。解决:netstat -ano | findstr :8080找到 PID,tasklist确认进程,能停就停,不能停就改 Tomcat 端口。
坑三:部署后访问 404,但应用明明在 webapps 里。现象是webapps下有应用目录,访问却报 404。原因可能是 Context path 和目录名不一致,或者server.xml里配了autoDeploy="false"导致新应用没被加载。解决:检查访问 URL 的路径部分是否和目录名或 Context 的 path 一致;确认Host节点的autoDeploy和deployOnStartup设置;重启 Tomcat 让配置生效。
坑四:JDK 8 下启动报 Unrecognized VM option 'MaxPermSize'。现象是启动时 JVM 直接拒绝,报无法识别的参数。原因是setenv.bat里还留着 JDK 7 的永久代参数,JDK 8 已经移除。解决:把-XX:PermSize和-XX:MaxPermSize换成-XX:MetaspaceSize和-XX:MaxMetaspaceSize,或者干脆删掉让 JVM 用默认值。
坑五:manager 界面 403,配了用户也进不去。现象是访问/manager/html提示 403 Access Denied。原因是tomcat-users.xml里没配角色,或者配了角色但没配manager-gui这个特定角色名。解决:在tomcat-users.xml里加<user username="admin" password="xxx" roles="manager-gui,admin-gui"/>,注意 Tomcat 7 的角色名是manager-gui而不是老版本的manager。改完重启。
提示:
tomcat-users.xml里的密码尽量别用弱口令,manager 应用能部署和卸载 WAR,等于半个服务器控制权。内网环境也别大意。
6. 用 JVM 参数和访问日志把问题钉死在现场
前面讲的都是“出问题了怎么救”,这一章讲“怎么让问题在发生时就留下证据”。老系统排查最怕的是“现象无法复现”,等你去现场的时候它又好了。我的习惯是提前把两样东西配好:JVM 的 GC 日志和 Tomcat 的访问日志。
GC 日志能告诉你内存到底怎么用的。在setenv.bat里加:
set JAVA_OPTS=%JAVA_OPTS% -XX:+PrintGCDetails -XX:+PrintGCDateStamps set JAVA_OPTS=%JAVA_OPTS% -Xloggc:C:\tomcat7\logs\gc.logPrintGCDetails输出每次 GC 的详细情况,PrintGCDateStamps带上时间戳,Xloggc指定日志文件。跑一段时间后看gc.log,如果 Full GC 频繁且每次回收后老年代占用还是很高,说明有内存泄漏,要配合 jmap 做堆转储分析。JDK 7 自带jmap和jhat,jmap -dump:format=b,file=heap.bin <pid>导出堆,再用 MAT 之类的工具打开。
访问日志则记录每个请求的来龙去脉。在server.xml的 Host 节点里加 AccessLogValve:
<Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs" prefix="access." suffix=".log" pattern="%h %l %u %t "%r" %s %b %D" resolveHosts="false" />pattern里的%h是客户端 IP,%r是请求行,%s是状态码,%b是响应字节数,%D是处理耗时微秒。resolveHosts="false"关掉反向 DNS 解析,否则每个请求都要查一次 DNS,性能会明显下降。有了这个日志,哪个接口慢、哪个 IP 在刷、哪个请求返回 500,一目了然。
还有一个技巧是给 Tomcat 加 JMX 监控。在setenv.bat里加:
set CATALINA_OPTS=%CATALINA_OPTS% -Dcom.sun.management.jmxremote set CATALINA_OPTS=%CATALINA_OPTS% -Dcom.sun.management.jmxremote.port=9999 set CATALINA_OPTS=%CATALINA_OPTS% -Dcom.sun.management.jmxremote.ssl=false set CATALINA_OPTS=%CATALINA_OPTS% -Dcom.sun.management.jmxremote.authenticate=false然后用 jconsole 连上去,能实时看线程数、堆使用、类加载数量。注意authenticate=false和ssl=false只适合内网隔离环境,公网机器千万别这么配。我一般只在排查阶段临时开,问题定位完就关掉。
从那以后我每次拿到一个老版本的 Tomcat 包,第一件事不是急着部署应用,而是先把setenv.bat、GC 日志、访问日志这三样配好,再跑一个空应用观察半小时。确认基线正常了,才往上放业务。这个习惯帮我省掉了无数次“到底是应用问题还是容器问题”的扯皮。希望帮到你。
本文还有配套的精品资源,点击获取