SpringBoot 服务迁移至东方通 TongWeb 的实践指南
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 \ -DgroupId=com.tongweb \ -DartifactId=tongweb-embed-servlet \ -Dversion=7.0.E.5 \ -Dpackaging=jar-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> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <!-- 排除内嵌的 Tomcat --> <exclusions> <exclusion> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-tomcat</artifactId> </exclusion> </exclusions> </dependency>其次,添加 TongWeb 的 SpringBoot Starter 依赖。这个 Starter 包会提供 TongWeb 容器的自动配置和集成。
<dependency> <groupId>com.tongweb.springboot</groupId> <artifactId>tongweb-spring-boot-starter</artifactId> <version>2.x-7.0.E.5</version> <!-- 版本号务必与你安装的一致 --> </dependency>最后,修改打包方式为 war。因为我们要部署到独立的 TongWeb 服务器。
<packaging>war</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/myapp(TongWeb 的默认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 官方文档,那才是最权威的参考资料。
