简介:这是一份面向Java Web开发者的Tomcat 7.0.108服务器压缩包,适合用于运行JSP/Servlet应用、部署Web项目,也可作为学习Servlet容器工作原理的参考环境。压缩包共640个文件,大小约10.38MB,包含完整Tomcat目录结构:bin下的启动/停止脚本(bat/sh)、conf下的server.xml、web.xml等配置,lib下的运行库,webapps下的默认应用;文件类型以html、jsp、java、class为主,另有xml、properties等配置资源,可满足直接解压使用与二次开发需求。已有632人学习下载,适合正在搭建Java Web开发环境或需要快速部署测试项目的开发者。包内除开箱即用的运行环境外,还保留了大量示例页面与处理逻辑,有助于理解请求处理、部署流程和日志管理;开发者也可替换WAR包或调整配置文件,快速投入实际项目。
1. tomcat-7.0.108.zip 是什么:为什么还有人在找这个老版本
接手一套跑了七八年的老系统时,你会发现部署文档早就失传了,运维电脑上只留了一个tomcat-7.0.108.zip。这个压缩包是 Tomcat 7.0.x 系列的 Windows 发行版,解压即用,7.0.108 属于 7.0 分支的后期版本,修复了前面累积的多项安全问题,同时又保持了对 JDK 6/7/8 的兼容。对于还在维护旧业务、又没法立刻迁移到新容器的团队来说,这个版本就是过渡期最省心的选择。这篇文章会把解压、配置、部署、排错到备份迁移一条线讲完,照着做就能把服务正常跑起来。
2. 解压与目录结构:把 zip 包变成能跑的服务
拿到tomcat-7.0.108.zip之后,第一个动作不是双击解压,而是先确认机器上的 Java 环境。Tomcat 本身是用 Java 写的,启动脚本靠JAVA_HOME环境变量找 JVM。如果机器上装了多个 JDK,或者JAVA_HOME指到了一个不存在的路径,后面所有问题都会从这里开始。
# 先看 Java 是否可用,再决定要不要装 JDK java -version # Windows PowerShell 里解压 Expand-Archive -Path tomcat-7.0.108.zip -DestinationPath D:\apps # Linux/macOS 环境同样适用(zip 包跨平台) # 如果系统有 unzip 就用 unzip,没有就用 jar unzip tomcat-7.0.108.zip -d /opt/java -version的输出里要重点看两行:版本号和位数。Tomcat 7.0.x 要求 Java 6 以上,实际生产环境里 JDK 7 和 JDK 8 用得最多;位数方面建议 64 位 JVM,因为后面要给堆内存调参,32 位 JVM 的寻址上限大概只有 1.5GB 到 2GB,并发稍高就顶不住。如果java命令提示找不到,就得先装 JDK 并配置JAVA_HOME,Windows 下还要把%JAVA_HOME%\bin加进PATH。
解压完成之后,先别急着启动。花两分钟把目录结构过一遍,后面排查问题会快很多。bin目录放启动脚本,Windows 用startup.bat,Linux 用startup.sh;conf是全局配置目录,最重要的server.xml和tomcat-users.xml都在这里;webapps是应用发布目录,war 包丢进去 Tomcat 会自动展开并部署;logs存运行日志,temp和work是运行时生成的临时目录,work里存 JSP 编译后的 class 文件,很多奇怪的问题都和它有关。
2.1 先设 CATALINA_HOME,避免脚本到处找目录
CATALINA_HOME是 Tomcat 用来定位自身安装路径的环境变量。虽然startup.sh不设它也能跑,脚本会自动推断当前目录,但我建议还是显式配置,尤其是机器上可能装多个 Tomcat 实例的场景。
# 编辑 /etc/profile 或 ~/.bashrc,追加两行 export CATALINA_HOME=/opt/tomcat-7.0.108 export PATH=$CATALINA_HOME/bin:$PATH # 让配置立即生效 source ~/.bashrcWindows 下就在“系统属性 → 环境变量”里新建CATALINA_HOME,值指向解压目录。设置这个变量的意义在于,所有脚本和后续的部署工具都会读它,不设的话某些监控脚本或管理工具会找不到 Tomcat,表现为“服务起来了但管理端连不上”,本质是路径解析错了。
2.2 conf 与 webapps:先分清改什么、别动什么
新手最常见的误区是把conf里的配置当摆设,或者反过来——部署应用时顺手把conf/server.xml改得面目全非。我的建议是:默认配置能不动就不动,只在明确需要改端口、调并发、加虚拟目录时才碰它。conf下还有一个Catalina子目录,存放每个应用独立的 context 配置,优先级比server.xml里的全局配置高,这点后面部署 war 包时会用到。
webapps目录默认带几个示例应用:ROOT、docs、examples、manager、host-manager。生产环境里这些一个都不该留,尤其是examples和docs,纯属多余占位。把 ROOT 以外的目录清掉,再把 ROOT 里面默认的index.jsp换掉,避免被人看出服务器类型和版本。清空之前先停服务,因为 Tomcat 在运行状态下会不断写这些目录,强行删文件可能出现半删除状态。
3. server.xml 与启动参数:端口、内存、并发上线前必调
这一章是让 Tomcat 真正能抗住线上压力的关键。7.0.108 的默认配置是“能用但不好用”的水平:默认堆内存很小、连接器线程数偏保守、端口也是大家熟知的 8080。直接拿默认配置上线,一旦有活动或接口被频繁调用,服务就卡死给你看。下面按端口、内存、并发三个维度讲。
3.1 三个端口分别干什么,改哪个、怎么改
conf/server.xml里有三个端口:8005(shutdown)、8080(HTTP 连接器)、8009(AJP 连接器)。很多教程只讲改 8080,但另外两个端口同样值得关注。
<!-- 关闭指令端口,监听在本机即可,别暴露到外网 --> <Server port="8005" shutdown="SHUTDOWN"> <!-- HTTP 1.1 连接器,改成实际对外端口 --> <Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" /> <!-- AJP 连接器,如果不用 Apache 转发就注释掉 --> <!-- <Connector port="8009" protocol="AJP/1.3" redirectPort="8443" /> -->8005端口接收 shutdown 指令,默认只监听本机,问题不大。8080是主入口,改端口时注意别和机器上其他服务冲突,常见做法是换成 8081、8090 这类次常用端口。8009是 AJP 协议端口,只有在用 Apache HTTP Server 做前端转发时才需要,其他场景建议直接注释。redirectPort="8443"是 HTTPS 跳转端口,如果还没配 SSL,保持默认即可。
改完端口记得重启服务,然后确认监听状态:Linux 下用netstat -lnp | grep java,Windows 下用netstat -ano | findstr 端口号。看到端口进入 LISTEN 状态才算生效,否则就是配置没被正确加载。
3.2 JVM 内存参数:放在哪、怎么设才能不溢出
Tomcat 的 JVM 参数不要直接改catalina.sh,那个文件是发行包自带的,升级或者重新解压时会被覆盖。正确做法是在bin目录下新建setenv.sh(Linux)或setenv.bat(Windows),启动脚本会自动读取这个文件里的内容。
# bin/setenv.sh 文件内容 export CATALINA_OPTS="-Xms512m -Xmx1024m -XX:PermSize=128m -XX:MaxPermSize=256m" # Xms 初始堆内存,Xmx 最大堆内存 # PermSize/MaxPermSize 只在 JDK 7 及以下生效 # JDK 8 请换成 Metaspace 参数:-XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=256m堆内存设多大,取决于机器物理内存和应用类型。单机只跑一个 Tomcat 的话,-Xmx给物理内存的一半左右比较稳妥,比如 8G 机器给 4G。-Xms和-Xmx建议设成一样,避免运行期堆扩容带来的停顿。注意PermSize参数在 JDK 8 里已经被移除,如果机器装的是 JDK 8 还写这个参数,启动会直接报错。Tomcat 7.0.108 官方支持 JDK 8,用 Metaspace 替代 PermGen 即可。
3.3 连接器参数:线程数、acceptCount 与超时的关系
HTTP 连接器的默认配置对低并发没问题,但一旦接口被频繁调用,就会出现“端口活着但请求排队超时”的假死状态。核心参数有三个:maxThreads、acceptCount、connectionTimeout。
<Connector port="8080" protocol="HTTP/1.1" maxThreads="200" minSpareThreads="25" acceptCount="100" connectionTimeout="20000" redirectPort="8443" />| 参数 | 含义 | 建议值 |
|---|---|---|
| maxThreads | 处理请求的最大工作线程数 | 200~400,视 CPU 核数和业务耗时定 |
| minSpareThreads | 空闲时保留的最小线程数 | 20~50 |
| acceptCount | 线程池满时等待队列的长度 | 100~200 |
| connectionTimeout | 建立连接后的超时时间(毫秒) | 10000~20000 |
线程不是越多越好。每个线程都要占栈空间和内存,堆外内存会随线程数线性增长。如果接口本身耗时在几百毫秒,200 线程足够;如果接口涉及大量 IO 等待,可以适当调到 400,但超过这个数之后收益很小,反而增加 GC 压力。acceptCount设太大会让用户等很久才收到错误,设太小又容易在流量尖峰时直接拒绝连接,100 是大多数场景的平衡点。
4. 部署 war 包与虚拟目录:从 zip 包到能访问的业务接口
Tomcat 配好了,下一步就是把业务应用放进去。常见的做法有三种:把 war 包直接丢进webapps、把应用放在外部目录然后配置 context、以及通过 manager 管理界面远程部署。这三种方式的应用场景不一样,踩的坑也不一样。
4.1 直接把 war 丢进 webapps:简单但有两个隐藏行为
最常见的做法是把app.war复制到webapps目录,Tomcat 会自动展开成webapps/app目录,应用上下文路径默认就是 war 包文件名。
# 停服务后把 war 包复制进去 cp app.war $CATALINA_HOME/webapps/ # 启动后它会自动解压;如果已有同名 app 目录,会以目录为准这里有一个容易翻车的细节:如果webapps下已经存在同名的展开目录,Tomcat 会优先使用这个目录,war 包的新内容不会生效。所以每次更新应用的正确动作是:先停服务(或者等自动部署),删除旧的展开目录,再放新的 war 包,最后清理work目录。work目录里缓存了 JSP 编译产物和 session 序列化文件,不清理的话,旧页面可能被反复加载,表现为“代码改了但页面没变”。这个操作在多人共用测试环境时尤其常见,大家习惯性地只替换 war 包,结果看到的是旧页面,然后开始怀疑人生。
4.2 外部应用目录与 context 配置:把 war 包和 Tomcat 解耦
如果希望应用代码放在 Tomcat 安装目录之外(比如代码目录和运行时环境分开管理),可以用 context 配置指向外部目录。这里我一般用独立文件的方式,在conf/Catalina/localhost/下新建一个app.xml,文件名就是上下文路径。
<!-- conf/Catalina/localhost/app.xml --> <Context docBase="/data/myapp" reloadable="true"> <!-- docBase 指向外部应用根目录,目录里必须有 WEB-INF/web.xml --> </Context>注意docBase路径指向的目录里,WEB-INF/web.xml 不能少。外部目录的好处是:升级 Tomcat 版本时不用备份 webapps,代码目录独立存在;坏处是:目录权限和路径引用容易出问题。reloadable="true"表示 class 文件变化时自动热加载,开发环境建议开,生产环境建议关掉(设 false),因为热加载的机制是重建类加载器,在高并发下会引发短暂的全栈停顿。
4.3 manager 界面部署:先配用户,再谈远程发布
通过 manager 界面在线部署 war 包是很方便的,平时测试、临时发布一个包都用得上。但 manager 默认没有任何可用的账号,连上去会直接提示 403。要手动编辑conf/tomcat-users.xml,添加一个带manager-gui角色的用户。
<role rolename="manager-gui"/> <user username="admin" password="change-me" roles="manager-gui"/>加完重启 Tomcat,访问http://localhost:8080/manager/html,输入账号密码就能看到 webapps 里所有应用的状态,支持在线停止、启动、部署新包。要注意的是:manager 界面本身也是一个 web 应用,密码别用弱口令,manager-gui角色只允许本机 IP 访问的话,就在webapps/manager/META-INF/context.xml里加<Valve className="org.apache.catalina.valves.RemoteAddrValve" allow="127\.0\.0\.1"/>。
remote 部署的坑在于:上传的 war 包会先落到临时目录再移动到webapps,如果 webapps 目录权限不对,上传会成功,但部署会失败,日志里能看到 IOException。遇到这种现象先看 logs/catalina.out,别急着怀疑密码或角色配错。
5. 7.0.108 常见问题排查与避坑
这个版本我用下来的感受是:功能老但足够扎实,出问题多半出在环境和操作习惯上,而不是 Tomcat 本身。下面五条是从实际维护中沉淀下来的高频坑,每一条都按现象、原因、解决的顺序写清楚。
5.1 启动后立刻退出,端口明明没被占用却起不来
现象:执行 startup.sh 后,控制台没有任何报错,几秒后进程消失,访问端口无响应。
原因:多半是JAVA_HOME没设置,或者指向的 JDK 位数不对。Tomcat 的启动脚本在缺少环境变量时会静默退出,日志写得也含糊。还有一个隐蔽原因:conf/server.xml的端口号被改成了已被占用的端口,启动时 bind 失败但没在控制台输出,只写进了logs/catalina.out的第一行。
解决:先看logs/catalina.out最前面几行,明确是环境变量问题还是端口冲突。端口占用用netstat -lnp | grep 端口(Windows 用netstat -ano | findstr 端口)查,找到占用进程后换端口或者停掉对方。
5.2 部署后访问 404,应用目录明明存在
现象:war 包放进webapps后,访问http://ip:8080/app/返回 404,但webapps/app目录确实存在。
原因:要么是展开目录名和访问路径对不上,要么是应用本身的web.xml里<display-name>或 servlet-mapping 写错。还有一个容易忽略的点:把 war 包放在 ROOT 外部的目录后,用懒加载模式运行,第一次访问时才初始化,如果初始化抛异常,请求会落到 404 而不是 500。
解决:确认 war 包文件名与访问路径一致;然后看logs/localhost.日期.log,里面有应用部署时的完整上下文和异常堆栈。大多数时候是这个日志告诉了你真实原因,而不是浏览器页面。
5.3 页面停留在旧版本,改了代码也不生效
现象:用 IDE 或脚本替换了 war 包内容,重启 Tomcat,打开页面发现还是旧功能。
原因:webapps下同名展开目录残留,Tomcat 优先加载旧目录;或者work目录里的 JSP 编译缓存没清。这个问题在新手连续改包时会反复出现,过程非常消耗耐心。
解决:停服务,删除webapps/app整个目录,删除work/Catalina/localhost/app整个目录,放入新 war 包,再启动。只要顺序是“停→删→放→启”,基本不会出错。
5.4 请求参数中文乱码,GET 和 POST 表现还不一样
现象:表单提交的中文在服务端取出来全是乱码,GET 请求的 URL 参数也是乱码,POST 好一点。
原因:Tomcat 7 对 GET 请求的 URI 编码默认按 ISO-8859-1 解析,对 POST 请求的 body 编码则依赖request.setCharacterEncoding()是否被调用。7.0.108 的连接器已经支持通过URIEncoding属性设置统一编码。
解决:在连接器上加URIEncoding="UTF-8",并在应用的 web.xml 里配置字符编码过滤器。
<Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" URIEncoding="UTF-8" redirectPort="8443" />改完重启,原有多语言的字符串也要复核一遍,如果之前已经用错误编码把数据写进了数据库,改了连接器编码可能让旧数据变成乱码,这种情况需要在数据访问层做转码,不是 Tomcat 层能解决的。
5.5 内存溢出:java.lang.OutOfMemoryError: PermGen space
现象:系统跑几天后开始频繁卡顿,日志里持续出现PermGen space或Java heap space报错,重启后能好一阵,然后又复发。
原因:JDK 7 及以下版本的永久代(PermGen)空间默认偏小,频繁热部署或者加载大量第三方类时容易撑满。JDK 8 没有 PermGen 概念,报错会变成Metaspace,处理思路不同。
解决:JDK 7 环境,在setenv.sh里加大-XX:MaxPermSize;JDK 8 环境,换成加大-XX:MaxMetaspaceSize。同时检查是否有应用在运行期动态生成类,如果有,这类代码本身就是问题源头。
# JDK 7 调优示例(bin/setenv.sh) export CATALINA_OPTS="-Xms1024m -Xmx2048m -XX:PermSize=256m -XX:MaxPermSize=512m" # JDK 8 调优示例 export CATALINA_OPTS="-Xms1024m -Xmx2048m -XX:MetaspaceSize=256m -XX:MaxMetaspaceSize=512m"如果加了内存还持续溢出,回头检查 GC 日志里是哪个类加载器没有被回收,这类问题通常伴随应用的动态类生成,靠加参数只能拖延,根治要改代码。
6. 备份、恢复与升级替换:一条命令的迁移技巧
用 7.0.108 的团队迟早要面对两个场景:换机器、升版本。我的习惯是:把整个 Tomcat 目录打包,排除三个运行时目录,这样恢复时能保证配置一致。备份命令的核心是排除logs、temp、work,这三个目录内容不该进备份包。
tar -czf tomcat-backup.tgz \ --exclude=tomcat-7.0.108/logs \ --exclude=tomcat-7.0.108/temp \ --exclude=tomcat-7.0.108/work \ tomcat-7.0.108恢复时只要解压回原路径,配置和 webapps 里的应用都会回来。升级替换的推荐做法不是整个覆盖,而是停服务后,保留conf目录里的server.xml、tomcat-users.xml,保留webapps(去掉示例应用),然后把新版本解压出来,把这两块复制过去。从 7.0.x 升到 7.0.108,这个流程几乎不会有兼容问题;跨大版本升到 8.x/9.x 前,先核对server.xml里是否有过时属性,比如旧版的maxThreads默认值在新版里已经不同,照着老配置抄过去反而会出问题。
最后分享一个我踩过的真实教训:有一次迁移主机,图省事直接scp了整台服务器的 Tomcat,结果新机器上忘了同步JAVA_HOME,服务启动失败,排查半天才发现是环境变量问题。从那以后我迁移时都先写一个环境检查清单:JDK 版本、JAVA_HOME、CATALINA_HOME、端口占用、目录权限,逐项打勾再启动。老版本 Tomcat 本身不难伺候,难的是把这些基础项当成理所当然。希望这篇笔记帮到你,如果你也是刚拿到 7.0.108 这个包准备动手,照着这几章走一遍,会比你自己摸索快很多。
本文还有配套的精品资源,点击获取