Tomcat 7.0.108 部署与调优:从解压到线上稳定运行
简介这是一份面向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_HOMEWindows 下还要把%JAVA_HOME%\bin加进PATH。解压完成之后先别急着启动。花两分钟把目录结构过一遍后面排查问题会快很多。bin目录放启动脚本Windows 用startup.batLinux 用startup.shconf是全局配置目录最重要的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里有三个端口8005shutdown、8080HTTP 连接器、8009AJP 连接器。很多教程只讲改 8080但另外两个端口同样值得关注。!-- 关闭指令端口监听在本机即可别暴露到外网 -- Server port8005 shutdownSHUTDOWN !-- HTTP 1.1 连接器改成实际对外端口 -- Connector port8080 protocolHTTP/1.1 connectionTimeout20000 redirectPort8443 / !-- AJP 连接器如果不用 Apache 转发就注释掉 -- !-- Connector port8009 protocolAJP/1.3 redirectPort8443 / --8005端口接收 shutdown 指令默认只监听本机问题不大。8080是主入口改端口时注意别和机器上其他服务冲突常见做法是换成 8081、8090 这类次常用端口。8009是 AJP 协议端口只有在用 Apache HTTP Server 做前端转发时才需要其他场景建议直接注释。redirectPort8443是 HTTPS 跳转端口如果还没配 SSL保持默认即可。改完端口记得重启服务然后确认监听状态Linux 下用netstat -lnp | grep javaWindows 下用netstat -ano | findstr 端口号。看到端口进入 LISTEN 状态才算生效否则就是配置没被正确加载。3.2 JVM 内存参数放在哪、怎么设才能不溢出Tomcat 的 JVM 参数不要直接改catalina.sh那个文件是发行包自带的升级或者重新解压时会被覆盖。正确做法是在bin目录下新建setenv.shLinux或setenv.batWindows启动脚本会自动读取这个文件里的内容。# bin/setenv.sh 文件内容 export CATALINA_OPTS-Xms512m -Xmx1024m -XX:PermSize128m -XX:MaxPermSize256m # Xms 初始堆内存Xmx 最大堆内存 # PermSize/MaxPermSize 只在 JDK 7 及以下生效 # JDK 8 请换成 Metaspace 参数-XX:MetaspaceSize128m -XX:MaxMetaspaceSize256m堆内存设多大取决于机器物理内存和应用类型。单机只跑一个 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 port8080 protocolHTTP/1.1 maxThreads200 minSpareThreads25 acceptCount100 connectionTimeout20000 redirectPort8443 /参数含义建议值maxThreads处理请求的最大工作线程数200~400视 CPU 核数和业务耗时定minSpareThreads空闲时保留的最小线程数20~50acceptCount线程池满时等待队列的长度100~200connectionTimeout建立连接后的超时时间毫秒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 reloadabletrue !-- docBase 指向外部应用根目录目录里必须有 WEB-INF/web.xml -- /Context注意docBase路径指向的目录里WEB-INF/web.xml 不能少。外部目录的好处是升级 Tomcat 版本时不用备份 webapps代码目录独立存在坏处是目录权限和路径引用容易出问题。reloadabletrue表示 class 文件变化时自动热加载开发环境建议开生产环境建议关掉设 false因为热加载的机制是重建类加载器在高并发下会引发短暂的全栈停顿。4.3 manager 界面部署先配用户再谈远程发布通过 manager 界面在线部署 war 包是很方便的平时测试、临时发布一个包都用得上。但 manager 默认没有任何可用的账号连上去会直接提示 403。要手动编辑conf/tomcat-users.xml添加一个带manager-gui角色的用户。role rolenamemanager-gui/ user usernameadmin passwordchange-me rolesmanager-gui/加完重启 Tomcat访问http://localhost:8080/manager/html输入账号密码就能看到 webapps 里所有应用的状态支持在线停止、启动、部署新包。要注意的是manager 界面本身也是一个 web 应用密码别用弱口令manager-gui角色只允许本机 IP 访问的话就在webapps/manager/META-INF/context.xml里加Valve classNameorg.apache.catalina.valves.RemoteAddrValve allow127\.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属性设置统一编码。解决在连接器上加URIEncodingUTF-8并在应用的 web.xml 里配置字符编码过滤器。Connector port8080 protocolHTTP/1.1 connectionTimeout20000 URIEncodingUTF-8 redirectPort8443 /改完重启原有多语言的字符串也要复核一遍如果之前已经用错误编码把数据写进了数据库改了连接器编码可能让旧数据变成乱码这种情况需要在数据访问层做转码不是 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:MaxPermSizeJDK 8 环境换成加大-XX:MaxMetaspaceSize。同时检查是否有应用在运行期动态生成类如果有这类代码本身就是问题源头。# JDK 7 调优示例bin/setenv.sh export CATALINA_OPTS-Xms1024m -Xmx2048m -XX:PermSize256m -XX:MaxPermSize512m # JDK 8 调优示例 export CATALINA_OPTS-Xms1024m -Xmx2048m -XX:MetaspaceSize256m -XX:MaxMetaspaceSize512m如果加了内存还持续溢出回头检查 GC 日志里是哪个类加载器没有被回收这类问题通常伴随应用的动态类生成靠加参数只能拖延根治要改代码。6. 备份、恢复与升级替换一条命令的迁移技巧用 7.0.108 的团队迟早要面对两个场景换机器、升版本。我的习惯是把整个 Tomcat 目录打包排除三个运行时目录这样恢复时能保证配置一致。备份命令的核心是排除logs、temp、work这三个目录内容不该进备份包。tar -czf tomcat-backup.tgz \ --excludetomcat-7.0.108/logs \ --excludetomcat-7.0.108/temp \ --excludetomcat-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 这个包准备动手照着这几章走一遍会比你自己摸索快很多。本文还有配套的精品资源点击获取