1. 为什么要把 SpringBoot 从 Tomcat 搬到 TongWeb如果你和我一样是个在 Java 服务端摸爬滚打了好几年的老开发肯定对 SpringBoot 内嵌的 Tomcat 再熟悉不过了。它简单、轻量开箱即用简直是快速开发和原型验证的神器。但是当项目真正要上生产尤其是面对一些对稳定性、安全性、性能监控有更高要求或者需要满足特定国产化替代需求的场景时光靠一个内嵌的 Tomcat 可能就有点“力不从心”了。这时候专业的应用服务器Application Server的价值就体现出来了。东方通的 TongWeb 就是这样一款产品。你可以把它理解为一个功能更全面的“大管家”。它不仅仅是一个 Servlet 容器像 Tomcat 那样它还提供了完整的 Java EE现在叫 Jakarta EE企业级特性支持比如更精细化的连接池管理、分布式事务JTA、消息服务JMS、更强大的集群和会话保持能力以及一套完整的管理控制台。对于企业级应用来说这些特性意味着更好的可靠性、可管理性和可观测性。我最近就主导了一个老项目的迁移从 SpringBoot 内嵌 Tomcat 整体迁到了 TongWeb 上。驱动原因很明确客户环境要求使用国产化中间件并且需要对应用进行更深入的性能监控和统一管理。整个过程踩过一些坑也积累了不少实战经验。这篇文章我就想把这些从零开始的迁移步骤、关键配置调整、以及那些让人头疼的常见问题用最直白的话分享给你。无论你是为了满足信创要求还是单纯想提升服务的健壮性这篇指南都能帮你少走弯路。简单来说这次迁移的核心就是让我们的 SpringBoot 应用“忘记”内嵌的 Tomcat学会在 TongWeb 这个更强大的“舞台”上运行。下面我们就一步步来看具体怎么做。2. 迁移前你需要准备好这些“粮草”老话说兵马未动粮草先行。迁移工作开始前把环境和资料准备妥当能避免很多临阵磨枪的尴尬。2.1 获取 TongWeb 官方资源这是第一步也是最关键的一步。TongWeb 的依赖包不像 SpringBoot 或者 Tomcat 那样可以直接从 Maven 中央仓库拉取。你需要联系东方通官方或其授权代理商申请试用或者购买从而获取到必要的软件包和文档。通常你会拿到一个压缩包里面至少包含以下几样东西TongWeb 应用服务器安装包用于在服务器上部署 TongWeb 运行环境。TongWeb Embed 依赖包这是一组 JAR 文件是我们 SpringBoot 项目能够集成 TongWeb 容器的核心。原始文章里提到的tongweb-embed-*.jar和tongweb-spring-boot-starter-*.jar都在这里面。用户手册官方文档遇到复杂问题时它是终极参考。License 文件一个.lic格式的许可证文件。没有它TongWeb 要么无法启动要么会在运行一段时间后停止服务。这个文件需要放在特定的路径下后面会详细说。我建议你在本地先建立一个专门的文件夹比如tongweb-libs把这些获取到的 JAR 包都放进去方便后续操作。2.2 梳理你的 SpringBoot 应用在动手改代码之前先给自己做个“体检”。打开你的项目重点检查以下几点SpringBoot 版本确认你的项目用的是 SpringBoot 2.x 的哪个具体版本如 2.3.12.RELEASE, 2.5.14等。TongWeb 的 Starter 包通常对主版本有明确支持。我这次迁移的项目用的是 SpringBoot 2.5.x一切顺利。内嵌容器相关配置在application.yml或application.properties里有没有关于 Tomcat 的特殊配置比如server.tomcat.*下面的连接器参数、线程池设置、URI 编码等。这些配置在迁移后大部分会失效需要转化为 TongWeb 的配置方式或者酌情删除。打包方式你的项目最终是打成一个可执行的jar包Fat Jar还是一个传统的war包这是迁移策略的分水岭。迁移到 TongWeb我们通常需要将应用打包成war包然后部署到 TongWeb 的 webapps 目录下。这意味着你需要调整 Maven 或 Gradle 的打包插件配置。花半小时把这些情况理清楚心里有个底后续操作就会有条不紊。3. 核心改造让项目“认识” TongWeb环境备好项目摸清现在进入实战环节。我们要对 SpringBoot 项目动几个“小手术”让它能适配 TongWeb。3.1 处理依赖把 TongWeb 的 JAR 装进本地仓库由于官方仓库没有我们必须手动将拿到的 TongWeb Embed JAR 包安装到本地的 Maven 仓库。这样项目才能通过 Maven 坐标正常引用它们。打开终端进入你存放那些 JAR 包的目录然后逐一执行mvn install:install-file命令。这个过程有点枯燥但必须做。我来解释一下原始文章里那条命令每个参数的意思你理解了就能举一反三mvn install:install-file -Dfile/你的路径/tongweb-embed-servlet-7.0.E.5.jar \ -DgroupIdcom.tongweb \ -DartifactIdtongweb-embed-servlet \ -Dversion7.0.E.5 \ -Dpackagingjar-Dfile指定 JAR 包在你电脑上的绝对路径。-DgroupId,-DartifactId,-Dversion这三个参数合起来定义了将来你在pom.xml里引用这个依赖的坐标。这里非常重要必须和官方提供的包名、版本号完全一致否则后面项目编译会找不到。-Dpackaging就是 jar。你需要对照你拿到手的 JAR 包文件列表把以下几个核心包都安装一遍版本号请以你实际获取的为准tongweb-embed-7.0.E.5.jar(核心嵌入包)tongweb-embed-servlet-7.0.E.5.jar(Servlet API 实现)tongweb-spring-boot-starter-2.x-7.0.E.5.jar(SpringBoot 集成启动器最关键)以及其他相关的tongweb-javax-*.jar(Java EE API 包)全部安装成功后你可以在本地 Maven 仓库通常是~/.m2/repository/com/tongweb目录下看到这些依赖。3.2 修改项目配置移除 Tomcat引入 TongWeb依赖准备好了现在来修改项目的pom.xml文件。首先排除 SpringBoot 内嵌的 Tomcat 依赖。因为我们要使用外部的 TongWeb 容器所以必须把默认打包进来的 Tomcat 移出去。找到spring-boot-starter-web依赖添加排除项dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-web/artifactId !-- 排除内嵌的 Tomcat -- exclusions exclusion groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-tomcat/artifactId /exclusion /exclusions /dependency其次添加 TongWeb 的 SpringBoot Starter 依赖。这个 Starter 包会提供 TongWeb 容器的自动配置和集成。dependency groupIdcom.tongweb.springboot/groupId artifactIdtongweb-spring-boot-starter/artifactId version2.x-7.0.E.5/version !-- 版本号务必与你安装的一致 -- /dependency最后修改打包方式为 war。因为我们要部署到独立的 TongWeb 服务器。packagingwar/packaging同时如果你之前是通过继承spring-boot-starter-parent来管理项目的SpringBoot 的 Maven 插件默认会打可执行 jar。现在需要确保它支持打 war 包通常插件配置不需要额外修改它会根据packaging标签自动适应。3.3 调整应用启动类这是一个非常关键但容易被忽略的步骤。为了让我们的 SpringBoot 应用在作为 WAR 包部署到外部容器TongWeb时能正常启动我们需要修改主应用类。通常SpringBoot 应用的入口类是这样的SpringBootApplication public class MyApplication { public static void main(String[] args) { SpringApplication.run(MyApplication.class, args); } }我们需要让它继承SpringBootServletInitializer并重写configure方法SpringBootApplication public class MyApplication extends SpringBootServletInitializer { // 重点继承这个类 Override // 重点重写这个方法 protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) { // 指向原本的启动类 return builder.sources(MyApplication.class); } public static void main(String[] args) { SpringApplication.run(MyApplication.class, args); } }这个改动的作用是当 WAR 包被 TongWeb 加载时TongWeb 会调用configure方法从而引导 SpringBoot 应用启动。而原有的main方法仍然保留这保证了你在开发时依然可以用java -jar的方式直接运行当然前提是你不排除 Tomcat 依赖或者用于单元测试非常灵活。3.4 处理配置文件现在打开你的application.yml或application.properties。之前所有以server.tomcat开头的配置都可以注释掉或者删除了因为它们不再生效。TongWeb 作为独立的应用服务器其核心配置如端口、线程池、连接器等是在 TongWeb 自身的配置文件中管理的位于TONGWEB_HOME/conf/server.xml等位置。我们的 SpringBoot 应用配置主要关注应用本身的属性比如数据源、Redis、业务开关等。但是有一个地方需要注意上下文路径Context Path。在 SpringBoot 内嵌 Tomcat 时我们通常用server.servlet.context-path来设置。当部署到 TongWeb 时这个配置可能会与 TongWeb 中部署应用时设置的上下文路径冲突。更常见的做法是在 TongWeb 的管理控制台部署应用时直接指定上下文路径。为了保险起见我建议在迁移阶段先注释掉 SpringBoot 中的server.servlet.context-path配置让应用默认在根路径/启动避免不必要的干扰。等应用在 TongWeb 上跑通后再通过 TongWeb 的配置来管理访问路径。4. 打包、部署与启动验证代码和配置都改好了接下来就是见证结果的时刻。4.1 打包生成 WAR 文件在项目根目录下运行熟悉的打包命令mvn clean package如果一切顺利你会在target目录下看到生成的你的项目名-版本.war文件。这个 WAR 包就是我们要部署到 TongWeb 的最终产物。4.2 部署到 TongWeb 服务器首先你需要在你测试或生产的服务器上安装并启动 TongWeb 应用服务器。安装过程通常就是解压、配置环境变量如TONGWEB_HOME、然后运行启动脚本如startserver.sh或startserver.bat。TongWeb 启动后可以通过http://服务器IP:9060访问其管理控制台默认端口是9060具体看你的配置。登录控制台后部署 WAR 包一般有两种方式通过管理控制台部署这是最直观的方式。在控制台找到“应用部署”或类似的模块上传你的 WAR 文件并指定一个上下文路径比如/myapp然后点击部署。TongWeb 会自动将 WAR 包解压到其webapps目录下。手动拷贝直接将 WAR 文件复制到TONGWEB_HOME/webapps目录下。TongWeb 的热部署功能会检测到新的 WAR 文件并自动进行解压和加载。这种方式更“极客”适合自动化脚本操作。关于 License记得把申请到的.lic许可证文件放到 TongWeb 指定的目录下通常是TONGWEB_HOME/conf/license。如果放置不正确启动应用时可能会报“找不到 License file”的错误。4.3 启动与问题排查部署完成后访问你设置的应用地址例如http://服务器IP:8080/myappTongWeb 的默认HTTP端口通常是8080。如果页面正常打开功能测试无误那么恭喜你迁移成功了90%但事情往往没那么一帆风顺。下面是我在迁移过程中遇到的几个典型问题及解决办法问题一ClassNotFoundException或NoClassDefFoundError这通常意味着依赖没有处理好。请回头仔细检查是否将所有必需的 TongWeb Embed JAR 包都正确安装到了本地 Maven 仓库项目pom.xml中tongweb-spring-boot-starter的groupId、artifactId、version是否与安装时指定的完全一致执行mvn dependency:tree命令查看依赖树中是否成功引入了 TongWeb 相关的包并且没有版本冲突。问题二应用启动失败日志中提示与 Servlet API 相关的错误这可能是因为项目中其他依赖引入了与 TongWeb 提供的 Servlet API 冲突的版本。可以尝试在pom.xml中对可能引起冲突的依赖如某些老的javax.servlet:servlet-api进行排除。问题三静态资源访问不到或页面乱码这可能是上下文路径或字符编码问题。确保你访问的 URL 路径正确。同时检查 TongWeb 服务器本身的server.xml配置中HTTP 连接器的URIEncoding是否设置为UTF-8以确保字符编码正确。问题四数据库连接池等资源初始化失败如果你的应用使用了 HikariCP、Druid 等连接池并且配置写在application.yml里通常不会受影响。但要确保 TongWeb 服务器运行的 JDK 版本与你开发环境一致。同时检查 TongWeb 的lib目录下是否有与你应用冲突的旧版本数据库驱动 JAR 包如果有可以考虑移除或升级。5. 迁移后的优化与思考应用成功跑起来只是第一步。迁移到 TongWeb 这样的专业应用服务器后我们还可以做一些优化更好地利用它的特性。5.1 利用 TongWeb 控制台进行监控TongWeb 的管理控制台提供了比 Spring Boot Actuator 更直观、更贴近中间件层面的监控信息。你可以在这里看到应用运行状态每个部署的应用是运行、停止还是挂起。会话Session管理查看活跃会话数、会话详情这对于排查用户登录状态相关的问题非常有用。JDBC 连接池监控如果你使用了 TongWeb 自带的数据源可以在这里监控连接的使用情况避免连接泄漏。JVM 监控内存使用情况、GC 次数和时间等方便进行性能调优。花点时间熟悉这个控制台它能在出问题时帮你快速定位是应用代码问题还是中间件资源瓶颈。5.2 性能调优参数配置TongWeb 的性能配置主要在conf/server.xml和conf/web.xml等配置文件中。对于从 Tomcat 迁移过来的应用有几个参数可以关注连接器Connector配置在server.xml里可以调整 HTTP/1.1 连接器的maxThreads最大处理线程数、acceptCount等待队列长度、connectionTimeout连接超时等这些参数直接影响服务的并发处理能力。你可以根据压测结果进行调整。JVM 参数通过修改 TongWeb 的启动脚本如startserver.sh中的JAVA_OPTS可以设置堆内存大小-Xms,-Xmx、垃圾回收器类型等。这对于提升大型应用的性能至关重要。5.3 关于“Fat Jar”与“WAR”的再思考这次迁移强制我们使用了 WAR 包部署。这带来一个好处应用包WAR和服务器运行时TongWeb是分离的。这意味着升级独立你可以单独升级 TongWeb 版本以获得新特性和安全补丁而不必重新打包应用。资源复用多个应用可以部署在同一个 TongWeb 实例上共享 JVM 和部分库节省资源。专业化管理由专业的应用服务器来管理线程池、连接池等资源通常比内嵌容器更稳定、功能更全。当然这也增加了运维的复杂度需要维护 TongWeb 服务器本身。这就需要根据团队的运维能力和项目的实际需求来做权衡了。整个迁移过程从最初的调研、踩坑到最终平稳上线给我的感觉是只要把依赖、配置、打包方式这几个关键点理顺了SpringBoot 应用迁移到 TongWeb 的技术难度并不高。真正的挑战可能在于对 TongWeb 这个新中间件本身的学习和熟悉以及后续的运维监控体系的建立。希望我的这些实践经验能为你接下来的迁移之旅铺平道路。如果在实际操作中遇到文中没覆盖的问题多查查 TongWeb 官方文档那才是最权威的参考资料。