三亩地 三亩地SAN MU DI · CODE DIARY
ARTICLE DETAIL

日记详情

真实记录编程学习的某一天,欢迎挑你感兴趣的翻一翻。

JeecgBoot与Vue3应用在TongWeb上的WAR包部署实战

JeecgBoot与Vue3应用在TongWeb上的WAR包部署实战

1. 项目背景与核心挑战

最近在帮一个客户做项目迁移,从原来的单体架构升级到前后端分离的微服务架构,后端选型了JeecgBoot,前端自然是Vue3。整个技术栈看起来挺现代,但部署环境却是个“老熟人”——东方通的TongWeb应用服务器。这个组合在实际落地时,踩了不少坑,也总结出了一套相对高效的部署方案。今天就来聊聊,如何把基于Spring Boot的JeecgBoot后端和Vue3前端,平滑、稳定地部署到TongWeb上,特别是如何处理那个让人头疼的WAR包问题。

JeecgBoot作为一个基于Spring Boot的低代码开发平台,其默认的打包和运行方式是内嵌的Tomcat,通过可执行的JAR包直接运行,这在其官方文档和大多数社区讨论中是主流。然而,很多传统企业或特定行业的信息化项目,出于合规、运维习惯或现有技术栈统一管理的考虑,会要求将应用部署到指定的商用中间件上,比如东方通的TongWeb、金蝶的Apusic、或者IBM的WebSphere等。这就带来了第一个核心矛盾:Spring Boot的“约定大于配置”与商用中间件严格部署规范之间的冲突。TongWeb作为一款符合Java EE规范的应用服务器,期望接收的是标准的WAR(Web Application Archive)包,而不是一个包含了整个Servlet容器的Fat Jar。

前端方面,Vue3项目通过构建工具(如Vite或Webpack)生成的是纯粹的静态资源(HTML、CSS、JS)。在开发环境,我们依赖npm run dev启动的Dev Server;在生产环境,则需要将这些静态文件放到一个Web服务器上。常见的做法是使用Nginx单独部署,或者将构建产物放入Spring Boot项目的src/main/resources/static目录下,随后端一起打包。当后端需要打WAR包部署到TongWeb时,前端的集成方式就需要仔细考量,以确保路由、接口代理、资源加载都能正常工作。

因此,这个“高效部署方案”的目标非常明确:将JeecgBoot后端改造为可部署于TongWeb的标准WAR应用,并优雅地集成Vue3前端静态资源,实现一键构建、统一部署,同时保证应用在TongWeb环境下的性能与稳定性。下面,我们就从环境准备开始,一步步拆解这个过程中的技术选型、配置改造和避坑指南。

2. 环境准备与项目结构剖析

在动手改造之前,我们必须先理清两个项目的基线状态和依赖关系。一个清晰的起点能避免后续很多混乱。

2.1 后端:JeecgBoot项目初始化与依赖审视

首先,确保你有一个可运行的JeecgBoot项目。你可以从官方Git仓库拉取最新的代码。重点检查pom.xml文件:

  1. 打包方式:默认应该是jar。这是我们第一个要改动的地方。

    <!-- 修改前 --> <packaging>jar</packaging> <!-- 修改后 --> <packaging>war</packaging>
  2. 内嵌Tomcat依赖作用域:Spring Boot项目内嵌了Tomcat,但当我们部署到外部的TongWeb(它本身就是一个Servlet容器)时,就需要避免内嵌容器与外部容器的冲突。我们需要将内嵌Tomcat的依赖标记为provided,意味着编译和测试时需要,但最终打包WAR时不会包含进去。

    <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-tomcat</artifactId> <scope>provided</scope> <!-- 关键修改 --> </dependency>

    有些JeecgBoot项目可能还引入了spring-boot-starter-web,它默认传递了Tomcat依赖。同样需要排除它或者确保其作用域正确。更稳妥的做法是,在spring-boot-starter-web依赖上也显式设置Tomcat为provided,但这通常通过上面的spring-boot-starter-tomcat设置即可生效,因为Maven依赖传递会尊重这个作用域。

  3. Servlet API依赖:确保项目包含了javax.servlet:javax.servlet-apijakarta.servlet:jakarta.servlet-api(取决于你使用的Java EE/Jakarta EE版本),并且作用域也是provided。TongWeb会提供这些API。

2.2 前端:Vue3项目构建产出分析

使用Vite或Vue CLI创建的Vue3项目,运行npm run build(或yarn buildpnpm build)后,默认会在项目根目录下生成一个dist文件夹。这个文件夹里通常包含:

  • index.html: 应用入口文件。
  • assets/: 存放编译后的JS、CSS文件以及图片等资源。
  • 可能还有其他如favicon.ico等文件。

我们的目标是将这个dist目录下的所有内容,作为静态资源,集成到后端的WAR包中。这样,当TongWeb启动应用后,用户访问应用根路径,就能直接访问到前端的index.html,前端再通过Ajax调用后端的REST API。

2.3 工具链统一:Maven与Node.js环境

整个部署流程会涉及Maven构建Java后端和Node构建前端。建议在CI/CD服务器或本地构建环境中统一管理:

  • JDK: 8或11(与JeecgBoot及TongWeb版本兼容,建议使用JeecgBoot官方推荐的版本)。
  • Maven: 3.6+。
  • Node.js: 16+ 或 18+(与Vue3构建工具兼容)。
  • npm/yarn/pnpm: 任选其一,确保锁文件(package-lock.json,yarn.lock,pnpm-lock.yaml)一致性,避免环境差异导致构建失败。

3. 后端改造:从Spring Boot Jar到TongWeb War

这是整个方案的核心技术环节。我们不能简单地把打包方式从jar改成war就了事,需要让Spring Boot应用学会在“别人的地盘”(TongWeb)上正确启动。

3.1 修改启动类:继承SpringBootServletInitializer

Spring Boot应用要部署为WAR包,其主启动类必须继承SpringBootServletInitializer并重写configure方法。这个类的作用是在WAR包被外部Servlet容器(如TongWeb)加载时,提供入口点来引导Spring Boot应用。

找到你的Application类(通常命名为JeecgApplicationApplication),进行如下改造:

import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.builder.SpringApplicationBuilder; import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; @SpringBootApplication public class JeecgApplication extends SpringBootServletInitializer { // 1. 继承 @Override // 2. 重写configure方法 protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) { // 指定配置源,即当前的启动类 return builder.sources(JeecgApplication.class); } public static void main(String[] args) { SpringApplication.run(JeecgApplication.class, args); } }

为什么必须这么做?当你在IDE中直接运行main方法,或者用java -jar命令启动JAR包时,Spring Boot的内嵌容器会直接启动。但当应用被打包成WAR并部署到TongWeb时,容器会按照Servlet规范,寻找并初始化ServletContainerInitializer的实现类。SpringBootServletInitializer就是Spring Boot提供的这个实现,它的configure方法会在容器启动时被调用,从而完成Spring应用上下文的构建。

3.2 处理静态资源路径与上下文根

在默认的Spring Boot Jar运行模式下,应用上下文根(Context Path)通常是/。但在TongWeb中部署WAR包,上下文根默认是WAR包的文件名(不含.war后缀),例如你的WAR包叫jeecg-app.war,那么访问地址可能就是http://server:port/jeecg-app/。这会对前端资源的加载和后端API的访问路径产生影响。

  1. 后端API路径:JeecgBoot中的Controller路径通常以/开头,如@RequestMapping(“/sys/user”)。在上下文根为/jeecg-app的情况下,完整的访问路径会变成/jeecg-app/sys/user。这本身不是问题,只要前端在请求API时带上这个上下文根即可。但为了灵活性,建议在application.ymlapplication.properties中配置server.servlet.context-path,使其与预期的部署路径一致,或者在代码中避免对根路径做硬编码假设。

  2. 前端静态资源集成:这是关键。我们需要将Vue3构建出的dist目录内容,复制到WAR包中WEB-INF目录之外的某个位置(例如根目录),并确保Spring Boot能将其作为静态资源提供服务。

3.3 使用Maven插件集成前端构建

为了实现“一键构建”,我们可以在后端项目的pom.xml中配置Maven插件,让Maven在打包过程中自动触发前端构建,并将产物复制到正确位置。

这里推荐使用frontend-maven-pluginmaven-resources-plugin组合。

<build> <plugins> <!-- 插件1:用于执行前端构建命令 (npm/yarn/pnpm) --> <plugin> <groupId>com.github.eirslett</groupId> <artifactId>frontend-maven-plugin</artifactId> <version>1.12.1</version> <configuration> <!-- 假设前端项目目录与后端平级,名为 `web-vue3` --> <workingDirectory>../web-vue3</workingDirectory> <installDirectory>target</installDirectory> </configuration> <executions> <execution> <id>install node and npm</id> <goals> <goal>install-node-and-npm</goal> </goals> <!-- 可配置特定Node版本 --> <configuration> <nodeVersion>v18.16.0</nodeVersion> </configuration> </execution> <execution> <id>npm install</id> <goals> <goal>npm</goal> </goals> <configuration> <arguments>install</arguments> </configuration> </execution> <execution> <id>npm run build</id> <goals> <goal>npm</goal> </goals> <configuration> <arguments>run build</arguments> </configuration> <phase>prepare-package</phase> <!-- 在打包阶段之前执行 --> </execution> </executions> </plugin> <!-- 插件2:将前端构建产物复制到WAR包的指定位置 --> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-resources-plugin</artifactId> <version>3.3.0</version> <executions> <execution> <id>copy-vue-dist</id> <phase>prepare-package</phase> <!-- 与前端构建同一阶段 --> <goals> <goal>copy-resources</goal> </goals> <configuration> <resources> <resource> <!-- 源目录:前端构建输出目录 --> <directory>../web-vue3/dist</directory> </resource> </resources> <!-- 目标目录:WAR包的根目录 --> <outputDirectory>${project.build.directory}/${project.build.finalName}</outputDirectory> <overwrite>true</overwrite> </configuration> </execution> </executions> </plugin> <!-- 插件3:Spring Boot Maven Plugin,用于打包 --> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <!-- 注意:当打包方式为war时,这个插件主要作用是提供Spring Boot的依赖管理支持, 实际的WAR包打包是由maven-war-plugin完成的。 --> <configuration> <!-- 如果你需要排除一些内嵌容器相关的依赖,可以在这里配置 --> <excludes> <exclude> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-tomcat</artifactId> </exclude> </excludes> </configuration> </plugin> </plugins> </build>

配置解析与避坑点

  • workingDirectory: 这个路径必须指向你前端项目的根目录。如果前端项目在后端项目内部(例如src/main/frontend),则路径需要相应调整。绝对路径和相对路径要写对,这是第一个容易出错的地方。
  • phase:prepare-package阶段会在Maven执行package目标(生成WAR/JAR)之前运行,确保前端先构建好,资源先复制好。
  • outputDirectory:${project.build.directory}通常是target${project.build.finalName}是你的项目名加版本号(如jeecg-app-1.0.0)。这个配置会把dist下的所有文件复制到WAR包解压后的根目录。这样,index.html就在WAR包的根路径下了。
  • 环境一致性frontend-maven-plugin会在构建时下载指定版本的Node和npm到target目录,这有助于保证不同构建环境的一致性。但如果你的服务器网络受限,也可以预先安装好Node,并在插件配置中跳过install-node-and-npm这个execution。

4. 前端适配:构建配置与API代理设置

前端项目也需要进行一些调整,以适配与后端WAR包一起部署的模式。

4.1 修改Vue Router的历史模式与Base URL

Vue Router有两种模式:hash模式和history模式。在history模式下,URL看起来更美观(没有#),但它需要服务器端的配合。当用户直接访问一个深层次的路由(如/user/profile)时,服务器需要能正确返回index.html,而不是404。

由于我们将前端静态文件放在了WAR包根目录,TongWeb(或任何Servlet容器)默认会对像/user/profile这样的路径去寻找对应的资源文件或Servlet,显然找不到。我们需要在前端和后端都做配置。

  1. 前端路由配置:在Vue Router的配置文件中,设置base选项和history模式。

    // router/index.js import { createRouter, createWebHistory } from 'vue-router' const router = createRouter({ // 假设你的应用部署在 /jeecg-app 下 history: createWebHistory(‘/jeecg-app/‘), // 关键:设置基础路径 routes: [...] })

    这个base值必须与后端应用在TongWeb中的上下文根(Context Path)一致。这样,Vue Router生成的所有路由链接都会自动带上这个前缀。

  2. 静态资源路径:在vite.config.jsvue.config.js中,配置base(Vite)或publicPath(Vue CLI),确保JS、CSS等静态资源能被正确加载。

    // vite.config.js export default defineConfig({ base: ‘/jeecg-app/‘, // 与路由base保持一致 // ...其他配置 })
    // vue.config.js module.exports = { publicPath: ‘/jeecg-app/‘, // ...其他配置 }

4.2 配置生产环境API请求基地址

在开发时,我们通常使用Vite或Webpack Dev Server的代理功能来解决跨域问题,API请求发向localhost:8080。但在生产环境,前端和后端在同一域名和端口下(都通过TongWeb访问),不存在跨域问题,API请求应该直接发向后端的相对路径。

我们需要根据环境变量来动态设置请求的基地址(Base URL)。可以使用Axios为例:

// src/utils/request.js import axios from ‘axios‘ // 判断是否是开发环境 const isDevelopment = process.env.NODE_ENV === ‘development‘ // 创建axios实例 const service = axios.create({ // 基础地址:开发环境使用代理前缀(需在vite.config.js中配置),生产环境使用空字符串(相对路径)或完整上下文路径 baseURL: isDevelopment ? ‘/api‘ : ‘‘, // 或者 ‘/jeecg-app‘ 如果后端Controller没有配置context-path timeout: 10000 }) // 请求拦截器、响应拦截器等... export default service

然后在你的Vite配置中设置开发环境代理:

// vite.config.js export default defineConfig({ // ...其他配置 server: { proxy: { ‘/api‘: { target: ‘http://localhost:8080‘, // 后端开发服务器地址 changeOrigin: true, rewrite: (path) => path.replace(/^\/api/, ‘/jeecg-app‘) // 重写路径,去掉/api前缀,加上上下文根 } } } })

这样,在开发时,请求/api/sys/user会被代理到http://localhost:8080/jeecg-app/sys/user;在生产环境,请求就直接是/jeecg-app/sys/user(因为前端和后台在同一个应用上下文内)。

5. TongWeb服务器配置与部署实战

一切准备就绪,接下来就是真刀真枪地部署到TongWeb了。

5.1 TongWeb版本选择与基础配置

首先确认你的TongWeb版本与JDK版本的兼容性。JeecgBoot 3.x 通常需要JDK 8或11,确保TongWeb支持对应的Java版本。登录TongWeb的管理控制台,通常地址是http://<server>:<port>/console

  1. 数据源配置:JeecgBoot需要连接数据库。在TongWeb控制台的“资源”->“JDBC”->“数据源”中,创建一个新的数据源。关键参数如下:

    • JNDI名称:例如java:comp/env/jdbc/jeecg-boot。这个名称需要与JeecgBoot配置文件中的jndi-name对应。
    • 数据库驱动:上传并选择对应的JDBC驱动JAR包(如MySQL的mysql-connector-java-8.0.xx.jar)。
    • 连接URL、用户名、密码:按实际数据库填写。
    • 连接池参数:根据应用负载设置初始连接数、最大连接数、最小连接数等。这里有个坑:TongWeb的数据源配置参数名可能与常见的Druid、HikariCP有些差异,需要仔细阅读文档。例如,测试连接是否成功的“验证查询”(Validation Query),MySQL通常是SELECT 1
  2. 应用部署

    • 在“应用”->“Web应用”中,点击“部署”。
    • 选择你打包好的WAR文件(jeecg-app.war)。
    • 上下文根:这是最重要的设置之一。你可以在这里指定应用的访问路径。如果留空,默认就是WAR文件名(不含后缀)。为了清晰,我建议在这里显式设置为/jeecg-app,与前端配置的base保持一致。
    • 虚拟主机:一般选择默认主机。
    • 点击“部署”后,TongWeb会将WAR包解压到其应用部署目录(如$TONGWEB_HOME/webapps/jeecg-app)。

5.2 解决JeecgBoot在TongWeb中的常见问题

部署后启动应用,很可能会遇到一些问题。以下是几个典型问题及解决方案:

问题一:应用启动失败,报错No Spring WebApplicationInitializer types detected on classpath

  • 原因:TongWeb没有正确识别到我们的SpringBootServletInitializer子类。这可能是因为WAR包结构有问题,或者TongWeb的类加载器配置。
  • 排查
    1. 检查WAR包内WEB-INF/classes目录下,你的启动类(如JeecgApplication.class)是否存在。
    2. 检查WEB-INF/lib目录下,是否包含了所有必要的依赖JAR包,特别是Spring相关的jar。确保没有因为<scope>provided</scope>导致核心Spring Boot依赖缺失。(注意:provided的依赖是期望容器提供的,但Spring Boot的核心JAR如spring-boot-*.jar不应该被标记为provided,只有spring-boot-starter-tomcat才需要。)
    3. 在TongWeb控制台查看应用日志,通常会有更详细的错误信息。

问题二:静态资源(前端页面)访问404

  • 原因:Spring Boot的静态资源处理默认会映射/**classpath:/static/,classpath:/public/,classpath:/resources/等目录。但我们通过Maven插件把前端dist放到了WAR包的根目录,这不在上述默认映射里。
  • 解决方案:我们需要自定义静态资源映射。在Spring Boot配置文件中(application.yml)添加:
    spring: web: resources: static-locations: classpath:/META-INF/resources/,classpath:/resources/,classpath:/static/,classpath:/public/,file:${webapp.root}/ mvc: static-path-pattern: /**
    同时,在Java代码中,通过@Configuration配置一个WebMvcConfigurer,将根路径/映射到我们放置前端资源的物理目录。但更简单的方法是依赖TongWeb的默认静态文件服务:因为我们将dist下的文件直接放在了WAR包根目录,TongWeb会像对待普通HTML文件一样直接提供它们。只要确保没有其他Servlet(比如Spring MVC的DispatcherServlet)拦截了所有请求(/*)即可。Spring Boot默认的DispatcherServlet映射是/,这意味着它不会拦截像.html,.js,.css这样的静态资源请求(具体规则由spring.mvc.static-path-patternspring.web.resources.static-locations决定)。我们的配置确保了静态资源请求能被正确响应。

问题三:数据库连接失败,JNDI查找不到数据源

  • 原因:JeecgBoot配置文件中指定的JNDI名称与TongWeb中配置的不一致,或者应用没有权限访问JNDI资源。
  • 解决方案:在application.yml中配置JNDI数据源:
    spring: datasource: jndi-name: java:comp/env/jdbc/jeecg-boot
    同时,必须在WAR包的WEB-INF/web.xml(或通过Java Config)中声明对这个资源引用的依赖。对于Spring Boot,可以通过在启动类或配置类上添加@EnableJpaRepositories等注解,但更关键的是要确保应用有WEB-INF/web.xml文件。如果没有,可以创建一个简单的web.xml
    <?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" version="3.1"> <resource-ref> <description>DB Connection</description> <res-ref-name>jdbc/jeecg-boot</res-ref-name> <res-type>javax.sql.DataSource</res-type> <res-auth>Container</res-auth> </resource-ref> </web-app>
    这个web.xml告诉TongWeb容器,这个应用需要引用一个名为jdbc/jeecg-bootDataSource资源。res-ref-namespring.datasource.jndi-namejava:comp/env/后面的部分对应。

问题四:应用启动慢,或首次访问超时

  • 原因:TongWeb在部署WAR包时,会进行解压、类加载、Spring上下文初始化等操作。JeecgBoot项目通常较大,依赖多,初始化耗时较长。
  • 优化建议
    1. 预热:在TongWeb中配置应用为“启动时加载”,并在非业务高峰期进行部署或重启。
    2. 调整JVM参数:在TongWeb的启动脚本(如startserver.sh)中,为JVM分配足够的内存(-Xms,-Xmx)并选择合适的垃圾回收器。
    3. 精简依赖:检查pom.xml,移除不必要的依赖。使用mvn dependency:analyze命令分析未使用的依赖。
    4. 使用TongWeb的部署优化:有些应用服务器支持“分解式部署”(Exploded Deployment),即直接部署解压后的目录,而不是WAR包,可以避免每次解压。但管理上可能不如WAR包方便。

6. 持续集成与部署优化

对于企业级项目,手动打包、上传、部署显然不够高效。我们可以将上述流程脚本化、自动化。

6.1 基于Shell脚本的一键部署

编写一个部署脚本deploy.sh,可以放在项目根目录或CI/CD服务器上:

#!/bin/bash # 定义变量 APP_NAME="jeecg-app" WAR_FILE="target/${APP_NAME}.war" TONGWEB_HOME="/opt/tongweb" TONGWEB_DEPLOY_DIR="${TONGWEB_HOME}/webapps" BACKUP_DIR="/opt/backup/$(date +%Y%m%d_%H%M%S)" echo “开始部署 ${APP_NAME}...“ # 1. 备份当前运行的应用(如果存在) if [ -d "${TONGWEB_DEPLOY_DIR}/${APP_NAME}" ]; then echo “备份旧版本...“ mkdir -p ${BACKUP_DIR} cp -r ${TONGWEB_DEPLOY_DIR}/${APP_NAME} ${BACKUP_DIR}/ cp ${TONGWEB_DEPLOY_DIR}/${APP_NAME}.war ${BACKUP_DIR}/ 2>/dev/null || true fi # 2. 停止应用(通过TongWeb管理命令或API,这里以直接删除文件触发热部署为例,生产环境建议使用管理控制台操作) echo “停止应用...“ # 注意:直接删除文件可能不优雅,生产环境建议使用TongWeb的停止命令或REST API rm -f ${TONGWEB_DEPLOY_DIR}/${APP_NAME}.war rm -rf ${TONGWEB_DEPLOY_DIR}/${APP_NAME} # 3. 复制新的WAR包 echo “复制新WAR包...“ if [ ! -f "${WAR_FILE}" ]; then echo “错误:WAR文件 ${WAR_FILE} 不存在!请先执行Maven打包。“ exit 1 fi cp ${WAR_FILE} ${TONGWEB_DEPLOY_DIR}/ # 4. 等待TongWeb自动解压和部署(监控日志) echo “等待应用启动...“ sleep 30 # 等待时间取决于应用大小,可调整 # 5. 简单健康检查 HEALTH_URL="http://localhost:8080/${APP_NAME}/sys/common/version" # JeecgBoot的一个健康检查或版本接口 echo “执行健康检查: ${HEALTH_URL}“ max_attempts=10 attempt=1 while [ ${attempt} -le ${max_attempts} ]; do if curl -f -s ${HEALTH_URL} > /dev/null; then echo “应用启动成功!“ exit 0 else echo “尝试 ${attempt}/${max_attempts}: 应用尚未就绪,等待5秒...“ sleep 5 ((attempt++)) fi done echo “错误:应用在指定时间内未启动成功。“ exit 1

注意:这个脚本是一个简单示例,直接操作文件系统。在生产环境中,更安全的方式是通过TongWeb的管理控制台REST API(如果提供)来执行部署、启动、停止操作,或者使用Ansible、SaltStack等配置管理工具。

6.2 与Jenkins/GitLab CI集成

在CI/CD流水线中,可以定义如下阶段:

  1. 拉取代码:从Git仓库拉取前后端代码。
  2. 构建前端:进入前端目录,执行npm installnpm run build
  3. 构建后端:进入后端目录,执行mvn clean package -DskipTests。此时,frontend-maven-pluginmaven-resources-plugin会自动执行,完成前端构建和资源复制,最终生成WAR包。
  4. 制品归档:将生成的jeecg-app.war保存为制品(Artifact)。
  5. 部署:将制品传输到目标服务器,并执行上述的部署脚本,或调用TongWeb的部署接口。

通过自动化流水线,可以实现代码提交后自动测试、构建、部署到测试环境,大大提升交付效率。

7. 监控、日志与性能调优

应用部署上线后,稳定运行离不开监控和调优。

7.1 日志配置与收集

JeecgBoot默认使用Logback,日志配置在logback-spring.xml中。在TongWeb环境中,需要注意日志文件的路径权限。

  1. 日志路径:避免将日志直接写在$TONGWEB_HOME目录下,以免在TongWeb升级或清理时被误删。建议配置一个独立的日志目录,如/var/log/jeecg-app/,并确保TongWeb的运行用户对该目录有写权限。

    <!-- 在logback-spring.xml中 --> <property name="LOG_PATH" value="/var/log/jeecg-app"/> <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> <file>${LOG_PATH}/app.log</file> <!-- ...滚动策略等 --> </appender>
  2. 日志级别:生产环境通常将级别设为INFOWARN。对于性能排查,可以临时开启DEBUG级别,但要注意日志量。

  3. TongWeb访问日志:TongWeb自身也有访问日志,可以在其管理控制台的“虚拟主机”->“HTTP”->“访问日志”中配置,用于分析请求流量和响应时间。

7.2 性能监控与JVM调优

  1. TongWeb控制台监控:TongWeb管理控制台提供了对JVM内存、线程池、数据库连接池、请求统计等的监控面板。定期查看这些指标,可以及时发现内存泄漏、连接池耗尽等问题。
  2. JVM参数调优:根据服务器硬件和应用实际使用情况调整JVM堆内存大小。例如,在$TONGWEB_HOME/bin/startserver.sh(Linux)中:
    JAVA_OPTS="$JAVA_OPTS -Xms4096m -Xmx4096m -XX:+UseG1GC -XX:+PrintGCDetails -XX:+PrintGCDateStamps -Xloggc:/opt/tongweb/logs/gc.log"
    • -Xms-Xmx设置堆内存初始大小和最大值,建议设为相同值以避免运行时调整带来的性能开销。
    • -XX:+UseG1GC使用G1垃圾收集器,适用于多核大内存服务器,能提供相对均衡的吞吐量和停顿时间。
    • -Xloggc将GC日志输出到文件,便于后续分析。
  3. 数据库连接池监控:在TongWeb控制台监控配置的数据源,关注活跃连接数、等待连接数等指标。如果等待连接数持续很高,可能需要增大连接池最大连接数,或者优化应用中数据库操作的性能。

7.3 常见故障排查思路

当应用出现访问慢、报错时,可以按以下步骤排查:

  1. 检查TongWeb应用日志:首先查看TongWeb控制台中该应用的“日志查看器”,或者直接查看$TONGWEB_HOME/logs目录下对应应用和日期的日志文件。错误堆栈信息是定位问题的第一手资料。
  2. 检查应用自身日志:查看我们配置的独立日志文件(如/var/log/jeecg-app/app.log),看是否有业务逻辑错误或异常。
  3. 检查资源使用:通过TongWeb控制台或服务器命令(如top,free)查看CPU、内存、磁盘I/O使用情况。如果内存使用率持续很高,结合GC日志分析是否存在内存泄漏。
  4. 检查网络与数据库:使用pingtelnetnc命令检查应用服务器与数据库服务器之间的网络连通性。在数据库端检查慢查询日志。
  5. 简化问题:如果问题复杂,尝试剥离前端,直接通过工具(如Postman)调用后端API,看是否是后端问题。或者,暂时将前端静态资源部署到独立的Nginx上,看是否是TongWeb静态资源服务的问题。

将JeecgBoot和Vue3应用部署到TongWeb,是一个将现代开发框架与传统企业级中间件相结合的过程。核心在于理解Spring Boot WAR包部署的机制,以及如何将前端静态资源无缝集成。方案的重点不仅仅是让应用“跑起来”,更要确保其在生产环境下的性能、稳定性和可维护性。通过本文的步骤,从项目改造、构建集成、服务器配置到自动化部署和监控,形成了一套完整的闭环。在实际操作中,可能还会遇到特定版本兼容性、依赖冲突等细节问题,这就需要我们根据具体的错误信息,结合Spring Boot、TongWeb的官方文档和社区资源,具体问题具体分析了。记住,耐心查看日志,永远是解决问题的第一步。

← 返回列表