积木报表集群部署:Nginx负载均衡配置教程
1. 集群部署痛点与解决方案
你是否正面临单节点部署的性能瓶颈?当报表并发量突破500+、用户数超过1000人时,传统单机架构常出现报表生成缓慢、设计器卡顿甚至服务宕机。本文将通过Nginx负载均衡+Redis会话共享方案,实现积木报表的高可用集群部署,彻底解决高并发场景下的稳定性问题。
读完本文你将掌握:
- 多实例部署架构设计与环境准备
- Redis分布式会话配置实践
- Nginx负载均衡策略与健康检查配置
- 静态资源共享与文件存储优化
- 集群部署后的性能测试与监控方案
2. 集群架构设计
2.1 整体架构图
2.2 服务器配置建议
| 组件 | 推荐配置 | 最低配置 | 作用说明 |
|---|---|---|---|
| Nginx服务器 | 4核8G/SSD 100G | 2核4G/SSD 50G | 流量入口、负载分发、静态资源 |
| 应用服务器 | 8核16G/每实例 | 4核8G/每实例 | 报表引擎、数据处理 |
| Redis集群 | 4G内存/3主3从 | 2G内存/1主1从 | 会话共享、缓存、分布式锁 |
| MySQL数据库 | 8核16G/SSD 500G | 4核8G/SSD 200G | 报表元数据、业务数据 |
| MinIO存储 | 4核8G/SSD 1T | 2核4G/HDD 500G | 报表模板、上传文件存储 |
3. 环境准备
3.1 基础软件安装
# 安装JDK 17 (已验证兼容版本)
sudo apt update && sudo apt install openjdk-17-jdk -y
# 安装Redis (用于会话共享)
sudo apt install redis-server -y
sudo systemctl enable redis-server && sudo systemctl start redis-server
# 安装MySQL (主从配置参考官方文档)
sudo apt install mysql-server -y
# 安装MinIO (用于共享存储)
wget https://dl.min.io/server/minio/release/linux-amd64/minio
chmod +x minio
sudo mv minio /usr/local/bin/
3.2 源码获取与编译
# 克隆代码仓库
git clone https://gitcode.com/jeecgboot/jimureport.git
cd jimureport/jimureport-example
# 修改配置文件 (数据库连接等)
vi src/main/resources/application-prod.yml
# 编译打包
mvn clean package -Dmaven.test.skip=true -Pprod
4. 核心配置实现
4.1 Redis会话共享配置
修改application-prod.yml添加Redis会话支持:
spring:
# 会话存储配置
session:
store-type: redis
redis:
flush-mode: on_save
namespace: jmreport:session
# Redis连接配置
redis:
host: 192.168.1.200 # Redis集群地址
port: 6379
password: your_redis_password
database: 0
lettuce:
pool:
max-active: 8
max-idle: 8
min-idle: 2
验证Redis配置类:
// JimuReport已内置Redis配置类
@Configuration
@ConditionalOnMissingBean(RedisTemplate.class)
public class RedisConfig {
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
RedisTemplate<String, Object> template = new RedisTemplate<>();
template.setConnectionFactory(factory);
// JSON序列化配置
Jackson2JsonRedisSerializer<Object> serializer = new Jackson2JsonRedisSerializer<>(Object.class);
ObjectMapper mapper = new ObjectMapper();
mapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
mapper.activateDefaultTyping(LaissezFaireSubTypeValidator.instance,
ObjectMapper.DefaultTyping.NON_FINAL);
serializer.setObjectMapper(mapper);
template.setValueSerializer(serializer);
template.setKeySerializer(new StringRedisSerializer());
template.afterPropertiesSet();
return template;
}
}
4.2 文件存储配置
修改application-prod.yml配置MinIO共享存储:
jeecg:
uploadType: minio # 替换local为minio
minio:
minio_url: http://192.168.1.201:9000 # MinIO服务地址
minio_name: minio_access_key
minio_pass: minio_secret_key
bucketName: jimureport # 提前创建的桶名称
5. 多实例部署
5.1 准备启动脚本
创建start-instance.sh:
#!/bin/bash
# 实例启动脚本
PORT=$1
nohup java -jar jimureport-example-2.1.3.jar \
--server.port=$PORT \
--spring.profiles.active=prod \
--spring.datasource.url=jdbc:mysql://192.168.1.202:3306/jimureport \
--spring.redis.host=192.168.1.200 \
--jeecg.jmreport.apiBasePath=http://192.168.1.100:$PORT \
> logs/instance-$PORT.log 2>&1 &
echo "Instance started on port $PORT"
5.2 启动多个实例
# 创建日志目录
mkdir -p logs
# 启动3个实例 (8085/8086/8087)
chmod +x start-instance.sh
./start-instance.sh 8085
./start-instance.sh 8086
./start-instance.sh 8087
# 检查启动状态
netstat -tlnp | grep java
6. Nginx负载均衡配置
6.1 安装与基础配置
# 安装Nginx
sudo apt install nginx -y
sudo systemctl enable nginx && sudo systemctl start nginx
6.2 负载均衡核心配置
创建/etc/nginx/conf.d/jimureport.conf:
upstream jimureport_cluster {
server 192.168.1.100:8085 weight=1 max_fails=3 fail_timeout=30s;
server 192.168.1.100:8086 weight=1 max_fails=3 fail_timeout=30s;
server 192.168.1.100:8087 weight=1 max_fails=3 fail_timeout=30s;
# 健康检查配置
keepalive 32;
}
server {
listen 80;
server_name report.yourdomain.com; # 替换为实际域名
# 静态资源缓存配置
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2)$ {
proxy_pass http://jimureport_cluster;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
expires 30d; # 静态资源缓存30天
add_header Cache-Control "public, max-age=2592000";
}
# WebSocket支持 (报表设计器实时协作)
location /ws {
proxy_pass http://jimureport_cluster;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
}
# 主请求代理
location / {
proxy_pass http://jimureport_cluster;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# 会话保持配置 (基于IP哈希)
proxy_set_header Cookie $http_cookie;
ip_hash; # 可选,确保同一IP请求到同一实例
}
# 健康检查端点
location /actuator/health {
proxy_pass http://jimureport_cluster/actuator/health;
access_log off;
allow 127.0.0.1;
deny all;
}
}
6.3 负载均衡策略说明
| 策略类型 | 配置语法 | 适用场景 | 优缺点分析 |
|---|---|---|---|
| 轮询 | 默认配置 | 服务器配置均衡场景 | 简单公平,但可能导致会话问题 |
| 权重 | server ... weight=5 | 服务器性能不均场景 | 可按性能分配流量,需手动调整权重 |
| IP哈希 | ip_hash; | 会话状态敏感场景 | 保证会话一致性,但可能负载不均 |
| 最少连接 | least_conn; | 请求处理时间差异大的场景 | 动态分配到负载较轻节点 |
| URL哈希 | hash $request_uri; | 静态资源缓存优化 | 同一URL定向到同一节点,提高缓存命中率 |
6.4 健康检查配置
添加到http块:
http {
# ... 其他配置 ...
# 健康检查配置
upstream jimureport_cluster {
server 192.168.1.100:8085 max_fails=3 fail_timeout=30s;
server 192.168.1.100:8086 max_fails=3 fail_timeout=30s;
server 192.168.1.100:8087 max_fails=3 fail_timeout=30s;
# 主动健康检查 (需要nginx-upstream-check-module)
check interval=3000 rise=2 fall=3 timeout=1000 type=http;
check_http_send "HEAD /actuator/health HTTP/1.0\r\n\r\n";
check_http_expect_alive http_2xx http_3xx;
}
}
7. 集群验证与测试
7.1 基础功能验证
# 检查Nginx配置
nginx -t
# 重载Nginx配置
sudo systemctl reload nginx
# 验证负载均衡
for i in {1..10}; do curl -I http://localhost/actuator/health; done
7.2 压力测试
使用JMeter创建测试计划:
- 线程组:100用户,循环10次
- HTTP请求:访问报表列表页和设计器
- 断言:响应包含"操作成功"
- 监听器:查看结果树、聚合报告、响应时间图表
预期性能指标:
- 平均响应时间 < 500ms
- 95%响应时间 < 1000ms
- 错误率 < 0.1%
- 吞吐量 > 100 QPS
8. 高可用增强配置
8.1 Redis主从复制配置
# Redis主从配置 (在从节点执行)
redis-cli SLAVEOF 192.168.1.200 6379
redis-cli CONFIG SET requirepass "your_redis_password"
redis-cli CONFIG SET masterauth "your_redis_password"
8.2 数据库主从配置
-- MySQL主库配置 (my.cnf)
server-id=1
log_bin=mysql-bin
binlog_do_db=jimureport
-- 从库配置
server-id=2
relay_log=mysql-relay-bin
replicate_do_db=jimureport
-- 主从同步命令
CHANGE MASTER TO
MASTER_HOST='192.168.1.202',
MASTER_USER='repl_user',
MASTER_PASSWORD='repl_password',
MASTER_LOG_FILE='mysql-bin.000001',
MASTER_LOG_POS=154;
START SLAVE;
9. 常见问题解决方案
9.1 会话共享问题
症状:用户频繁登出或操作错乱
排查步骤:
# 检查Redis连接
redis-cli -h 192.168.1.200 PING
# 查看会话存储
redis-cli KEYS "jmreport:session:*"
# 检查应用Redis配置
grep -A 10 "spring.redis" application-prod.yml
解决方案:确保所有实例连接同一Redis,配置spring.session.store-type=redis
9.2 文件上传不一致
症状:A实例上传文件在B实例无法访问
解决方案:
- 确认
jeecg.uploadType=minio - 检查MinIO桶权限
- 验证所有实例MinIO配置一致
9.3 Nginx 502错误
排查命令:
# 查看Nginx错误日志
tail -f /var/log/nginx/error.log
# 检查后端实例状态
curl http://192.168.1.100:8085/actuator/health
常见原因:
- 后端实例未启动或端口错误
- 防火墙阻止Nginx访问后端端口
- 实例启动失败(查看应用日志)
10. 监控与运维
10.1 应用监控配置
添加Spring Boot Actuator依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
配置监控端点:
management:
endpoints:
web:
exposure:
include: health,info,metrics,prometheus
endpoint:
health:
show-details: always
probes:
enabled: true
10.2 监控面板搭建
Grafana监控面板配置:
- 添加Prometheus数据源
- 导入JVM监控模板 (ID: 4701)
- 创建自定义报表指标面板:
- 报表生成响应时间:
http_server_requests_seconds_sum{uri=~"/jmreport/api/.*"} - 设计器打开次数:
http_server_requests_count{uri="/jmreport/design"} - 活跃会话数:
redis_key_count{key_pattern="jmreport:session:*"}
- 报表生成响应时间:
11. 性能优化建议
11.1 JVM参数调优
# 启动参数优化
java -jar ... \
-Xms4G -Xmx8G \ # 堆内存设置
-XX:+UseG1GC \ # G1垃圾收集器
-XX:MaxGCPauseMillis=200 \ # 最大停顿时间
-XX:ParallelGCThreads=4 \ # 并行GC线程数
-XX:ConcGCThreads=2 \ # 并发GC线程数
-XX:+HeapDumpOnOutOfMemoryError # OOM时生成堆转储
11.2 Redis性能优化
# 修改Redis配置 (redis.conf)
maxmemory 4G
maxmemory-policy allkeys-lru
appendonly yes
save 60 1000
12. 总结与展望
通过本文配置,积木报表已具备企业级高可用集群能力,可支撑300+并发用户的日常报表设计与查看需求。建议后续从以下方面持续优化:
- 自动化部署:集成Jenkins实现CI/CD流水线
- 弹性伸缩:基于K8s实现实例自动扩缩容
- 全链路追踪:集成SkyWalking分析性能瓶颈
- 多区域部署:通过CDN实现静态资源加速
点赞收藏本文,关注作者获取更多积木报表高级配置技巧!下期预告:《积木报表数据缓存优化实战》
附录:配置文件模板
完整的application-prod.yml和Nginx配置文件可从以下地址获取:
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考



