JeecgBoot项目在TongWeb容器中的部署问题分析与解决方案
前言
在企业级应用部署过程中,国产化信创环境下的中间件适配是一个重要课题。JeecgBoot作为一款优秀的企业级低代码开发平台,在东方通TongWeb应用服务器上的部署经常会遇到各种兼容性问题。本文将深入分析JeecgBoot在TongWeb容器中的常见部署问题,并提供详细的解决方案。
部署环境准备
环境要求
| 组件 | 版本要求 | 说明 |
|---|---|---|
| TongWeb | 7.0+ | 东方通应用服务器 |
| JDK | 1.8/11/17 | 根据JeecgBoot版本选择 |
| JeecgBoot | 3.5.0+ | 推荐使用最新稳定版 |
| 数据库 | MySQL 5.7+/Oracle 11g+ | 支持多种数据库 |
项目结构分析
JeecgBoot采用标准的Spring Boot架构,主要包含以下模块:
常见部署问题及解决方案
问题一:类加载冲突
症状表现
- ClassNotFoundException 或 NoClassDefFoundError
- NoSuchMethodError
- 启动时出现类加载器相关的异常
根本原因
TongWeb使用了自己的类加载机制,与Spring Boot内嵌的Tomcat存在差异。
解决方案
1. 排除内嵌容器依赖
在pom.xml中排除Spring Boot内嵌的Tomcat:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
2. 修改打包方式
修改为war包打包方式:
<packaging>war</packaging>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<scope>provided</scope>
</dependency>
3. 创建Servlet初始化类
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
public class ServletInitializer extends SpringBootServletInitializer {
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(JeecgSystemApplication.class);
}
}
问题二:配置文件加载异常
症状表现
- 配置文件无法正确读取
- 环境变量不生效
- 数据库连接失败
解决方案
1. 统一配置文件路径
在TongWeb的启动脚本中指定配置文件路径:
export JAVA_OPTS="$JAVA_OPTS -Dspring.config.location=file:/path/to/jeecg-boot/config/"
2. 使用绝对路径配置
在application.properties中使用绝对路径:
# 数据库配置
spring.datasource.url=jdbc:mysql://localhost:3306/jeecg-boot?useUnicode=true&characterEncoding=utf8
spring.datasource.username=root
spring.datasource.password=123456
# 文件上传路径(使用绝对路径)
jeecg.uploadpath=/data/jeecg-boot/upload
问题三:静态资源访问问题
症状表现
- 前端页面无法加载静态资源
- CSS/JS文件404错误
- 图片无法显示
解决方案
1. 配置静态资源映射
在Spring Boot配置中添加:
# 静态资源路径配置
spring.web.resources.static-locations=classpath:/static/,file:/data/jeecg-boot/upload/
spring.mvc.static-path-pattern=/**
# 文件上传大小限制
spring.servlet.multipart.max-file-size=100MB
spring.servlet.multipart.max-request-size=100MB
2. TongWeb虚拟目录配置
在TongWeb管理控制台中配置虚拟目录:
<Context path="/jeecg-boot" docBase="/path/to/jeecg-boot-war"
reloadable="true" crossContext="true">
<Resources className="org.apache.catalina.webresources.StandardRoot">
<PreResources className="org.apache.catalina.webresources.DirResourceSet"
base="/data/jeecg-boot/upload" webAppMount="/upload"/>
</Resources>
</Context>
问题四:数据库连接池配置
症状表现
- 数据库连接超时
- 连接池资源耗尽
- 性能低下
解决方案
Druid连接池优化配置:
# Druid连接池配置
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.druid.initial-size=5
spring.datasource.druid.min-idle=5
spring.datasource.druid.max-active=20
spring.datasource.druid.max-wait=60000
spring.datasource.druid.time-between-eviction-runs-millis=60000
spring.datasource.druid.min-evictable-idle-time-millis=300000
spring.datasource.druid.validation-query=SELECT 1 FROM DUAL
spring.datasource.druid.test-while-idle=true
spring.datasource.druid.test-on-borrow=false
spring.datasource.druid.test-on-return=false
spring.datasource.druid.pool-prepared-statements=true
spring.datasource.druid.max-pool-prepared-statement-per-connection-size=20
问题五:日志配置冲突
症状表现
- 日志文件无法生成
- 日志输出混乱
- 日志级别不生效
解决方案
1. 排除冲突的日志依赖
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
2. 使用Log4j2日志框架
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>
3. 配置log4j2.xml
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
</Console>
<RollingFile name="File" fileName="/logs/jeecg-boot/app.log"
filePattern="/logs/jeecg-boot/app-%d{yyyy-MM-dd}-%i.log">
<PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
<Policies>
<TimeBasedTriggeringPolicy/>
<SizeBasedTriggeringPolicy size="100MB"/>
</Policies>
<DefaultRolloverStrategy max="10"/>
</RollingFile>
</Appenders>
<Loggers>
<Root level="info">
<AppenderRef ref="Console"/>
<AppenderRef ref="File"/>
</Root>
</Loggers>
</Configuration>
部署流程详解
步骤一:项目编译打包
# 切换到项目根目录
cd /path/to/JeecgBoot
# 清理并打包项目
mvn clean package -DskipTests
# 生成的war包位置
ls jeecg-boot/jeecg-module-system/jeecg-system-start/target/*.war
步骤二:TongWeb部署配置
1. 部署描述符配置
创建 jeecg-boot.xml 部署描述文件:
<?xml version="1.0" encoding="UTF-8"?>
<Context docBase="/path/to/jeecg-boot.war"
path="/jeecg-boot"
reloadable="false"
crossContext="true">
<!-- 环境变量配置 -->
<Environment name="spring.profiles.active" value="prod" type="java.lang.String"/>
<Environment name="spring.config.location"
value="file:/etc/jeecg-boot/application-prod.properties"
type="java.lang.String"/>
<!-- 资源文件配置 -->
<Resources className="org.apache.catalina.webresources.StandardRoot">
<PreResources className="org.apache.catalina.webresources.DirResourceSet"
base="/data/jeecg-boot/upload"
webAppMount="/upload"/>
</Resources>
<!-- JNDI数据源配置 -->
<Resource name="jdbc/jeecgDS"
auth="Container"
type="javax.sql.DataSource"
factory="org.apache.tomcat.jdbc.pool.DataSourceFactory"
driverClassName="com.mysql.cj.jdbc.Driver"
url="jdbc:mysql://localhost:3306/jeecg_boot"
username="jeecg_user"
password="password123"
maxTotal="20"
maxIdle="10"
maxWaitMillis="10000"/>
</Context>
2. TongWeb服务器优化
修改TongWeb的server.xml配置:
<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443"
maxThreads="200"
minSpareThreads="10"
acceptCount="100"
enableLookups="false"
URIEncoding="UTF-8"/>
<Context path="" docBase="jeecg-boot" debug="0" reloadable="false"/>
步骤三:启动脚本优化
创建启动脚本 start_jeecg.sh:
#!/bin/bash
# 设置JAVA环境
export JAVA_HOME=/usr/java/jdk1.8.0_291
export PATH=$JAVA_HOME/bin:$PATH
# 设置应用参数
export APP_HOME=/opt/jeecg-boot
export LOG_DIR=/var/log/jeecg-boot
# JVM参数优化
export JAVA_OPTS="-server -Xms2g -Xmx2g -XX:MetaspaceSize=256m -XX:MaxMetaspaceSize=512m"
export JAVA_OPTS="$JAVA_OPTS -XX:+UseG1GC -XX:MaxGCPauseMillis=200"
export JAVA_OPTS="$JAVA_OPTS -XX:+DisableExplicitGC -XX:+HeapDumpOnOutOfMemoryError"
export JAVA_OPTS="$JAVA_OPTS -Dspring.profiles.active=prod"
export JAVA_OPTS="$JAVA_OPTS -Dspring.config.location=file:/etc/jeecg-boot/application-prod.properties"
export JAVA_OPTS="$JAVA_OPTS -Dlogging.config=file:/etc/jeecg-boot/log4j2.xml"
# 启动TongWeb
cd /opt/tongweb/bin
./startserver.sh
性能优化建议
1. JVM参数优化
# 生产环境JVM参数推荐
-Xms4g -Xmx4g
-XX:MetaspaceSize=512m -XX:MaxMetaspaceSize=1g
-XX:+UseG1GC
-XX:MaxGCPauseMillis=200
-XX:ParallelGCThreads=4
-XX:ConcGCThreads=2
-XX:+HeapDumpOnOutOfMemoryError
-XX:HeapDumpPath=/tmp/heapdump.hprof
2. 数据库连接池监控
配置Druid监控界面:
@Configuration
public class DruidConfig {
@Bean
public ServletRegistrationBean<StatViewServlet> statViewServlet() {
ServletRegistrationBean<StatViewServlet> bean =
new ServletRegistrationBean<>(new StatViewServlet(), "/druid/*");
Map<String, String> initParams = new HashMap<>();
initParams.put("loginUsername", "admin");
initParams.put("loginPassword", "admin123");
initParams.put("allow", "");
bean.setInitParameters(initParams);
return bean;
}
@Bean
public FilterRegistrationBean<WebStatFilter> webStatFilter() {
FilterRegistrationBean<WebStatFilter> bean =
new FilterRegistrationBean<>(new WebStatFilter());
bean.addUrlPatterns("/*");
bean.addInitParameter("exclusions", "*.js,*.gif,*.jpg,*.css,/druid/*");
return bean;
}
}
3. 缓存配置优化
# Redis缓存配置
spring.redis.host=localhost
spring.redis.port=6379
spring.redis.password=
spring.redis.database=0
spring.redis.timeout=3000
spring.redis.lettuce.pool.max-active=8
spring.redis.lettuce.pool.max-wait=-1
spring.redis.lettuce.pool.max-idle=8
spring.redis.lettuce.pool.min-idle=0
# 本地缓存配置
spring.cache.type=redis
spring.cache.redis.time-to-live=3600000
spring.cache.redis.cache-null-values=true
故障排查指南
常见错误代码及解决方法
| 错误代码 | 问题描述 | 解决方案 |
|---|---|---|
| ClassNotFoundException | 类找不到异常 | 检查依赖冲突,排除重复jar包 |
| NoSuchMethodError | 方法不存在错误 | 统一依赖版本,清理缓存 |
| Connection refused | 数据库连接拒绝 | 检查数据库服务状态和网络连接 |
| 404 Not Found | 资源找不到 | 检查静态资源路径配置 |
| 500 Internal Error | 服务器内部错误 | 查看详细日志定位问题 |
日志分析技巧
# 实时查看应用日志
tail -f /var/log/jeecg-boot/app.log
# 搜索特定错误
grep -i "error\|exception" /var/log/jeecg-boot/app.log
# 查看GC日志
jstat -gc <pid> 1000
# 生成线程转储
jstack <pid> > thread_dump.txt
总结
JeecgBoot在TongWeb容器中的部署虽然会遇到一些兼容性问题,但通过合理的配置和优化,完全可以实现稳定高效的运行。关键点在于:
- 依赖管理:正确处理Spring Boot内嵌容器与TongWeb的冲突
- 配置优化:根据生产环境需求调整各项参数
- 资源管理:确保静态资源和文件上传路径正确配置
- 监控维护:建立完善的监控和日志分析体系
通过本文提供的解决方案,您可以顺利完成JeecgBoot在TongWeb环境下的部署,并确保系统的稳定性和性能。在实际部署过程中,建议根据具体的业务需求和硬件环境进行适当的调整和优化。
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考



