Spring Boot 集群集成 Nginx:负载均衡 + 静态资源分离实战指南
- 第一章:架构概述与设计理念
-
- 1.1 为什么需要集群化?
- 1.2 整体架构设计
- 第二章:Spring Boot 应用集群化准备
-
- 2.1 应用无状态化改造
- 2.2 应用配置标准化
- 第三章:Nginx 负载均衡配置详解
-
- 3.1 Nginx 安装与基础配置
- 3.2 高级负载均衡策略
- 第四章:静态资源分离实战
-
- 4.1 静态资源配置优化
- 4.2 CDN 集成配置
- 第五章:高可用与故障转移
-
- 5.1 Nginx 高可用架构
- 5.2 故障转移策略
- 第六章:安全配置与优化
-
- 6.1 安全加固配置
- 6.2 SSL/TLS 配置
- 第七章:监控与日志管理
-
- 7.1 全方位监控配置
- 7.2 集中日志管理
- 第八章:性能调优实战
-
- 8.1 Nginx 性能优化
- 8.2 Spring Boot 集群优化
- 第九章:部署与自动化
-
- 9.1 Docker Compose 集群部署
- 9.2 CI/CD 流水线配置
- 第十章:故障排查与维护
-
- 10.1 常见问题解决方案
- 10.2 自动化维护脚本
- 总结
第一章:架构概述与设计理念
1.1 为什么需要集群化?
在现代互联网应用中,单点故障和性能瓶颈是主要风险。Spring Boot 应用集群化带来以下核心价值:
高可用性
- 消除单点故障,确保服务连续性
- 某个节点故障时自动切换到健康节点
- 实现 99.9% 以上的服务可用性
弹性扩展 - 根据流量动态调整节点数量
- 轻松应对业务高峰和促销活动
- 线性提升系统处理能力
性能优化 - 分布式处理请求,降低单个节点压力
- 就近部署,减少网络延迟
- 专业化节点处理特定类型请求
1.2 整体架构设计
下图展示了完整的 Spring Boot 集群架构:
应用集群
外部服务
Spring Boot 应用 1
Spring Boot 应用 2
Spring Boot 应用 3
数据库集群
Redis 缓存集群
静态资源服务器
客户端
DNS 负载均衡
Nginx 负载均衡器
第二章:Spring Boot 应用集群化准备
2.1 应用无状态化改造
问题分析:有状态应用的挑战
1// 有状态示例 - 会话存储在应用内存中 2@Controller 3public class UserController { 4 // 问题:会话数据存储在单个实例内存中 5 private Map<String, UserSession> userSessions = new ConcurrentHashMap<>(); 6 7 @PostMapping("/login") 8 public String login(User user, HttpServletRequest request) { 9 // 会话存储在当前实例内存 10 UserSession session = new UserSession(user); 11 userSessions.put(session.getId(), session); 12 request.getSession().setAttribute("sessionId", session.getId()); 13 return "dashboard"; 14 } 15} 16
解决方案:外部化会话管理
1// 无状态改造 - 使用 Redis 存储会话 2@Configuration 3@EnableRedisHttpSession(maxInactiveIntervalInSeconds = 1800) 4public class HttpSessionConfig { 5 6 @Bean 7 public LettuceConnectionFactory connectionFactory() { 8 return new LettuceConnectionFactory(); 9 } 10} 11 12// 应用代码无需修改,Spring Session 自动处理 13@RestController 14public class StatelessController { 15 16 @GetMapping("/user/profile") 17 public UserProfile getProfile(HttpSession session) { 18 // 会话数据存储在 Redis 中,任何实例都可访问 19 String userId = (String) session.getAttribute("userId"); 20 return userService.getProfile(userId); 21 } 22} 23
2.2 应用配置标准化
集群化应用配置
1# application-cluster.yml 2server: 3 port: 8080 4 servlet: 5 session: 6 timeout: 30m 7 8spring: 9 application: 10 name: ecommerce-cluster 11 redis: 12 host: redis-cluster.redis.svc.cluster.local 13 port: 6379 14 password: ${REDIS_PASSWORD} 15 datasource: 16 url: jdbc:mysql://mysql-cluster.mysql.svc.cluster.local:3306/ecommerce 17 username: ${DB_USERNAME} 18 password: ${DB_PASSWORD} 19 hikari: 20 maximum-pool-size: 20 21 minimum-idle: 5 22 23management: 24 endpoints: 25 web: 26 exposure: 27 include: health,info,metrics 28 endpoint: 29 health: 30 show-details: always 31 probes: 32 enabled: true 33 34# 自定义配置 35cluster: 36 instance-id: ${INSTANCE_ID:unknown} 37 load-balancer: 38 health-check-path: /actuator/health 39
第三章:Nginx 负载均衡配置详解
3.1 Nginx 安装与基础配置
Ubuntu/CentOS 安装
1# Ubuntu 2sudo apt update 3sudo apt install nginx 4 5# CentOS 6sudo yum install epel-release 7sudo yum install nginx 8 9# 启动服务 10sudo systemctl start nginx 11sudo systemctl enable nginx 12 13# 验证安装 14nginx -v 15
基础负载均衡配置
1# /etc/nginx/nginx.conf 2http { 3 # 定义上游服务器组 4 upstream springboot_cluster { 5 # 负载均衡算法 6 least_conn; # 最少连接数算法 7 8 # 服务器列表 9 server 192.168.1.101:8080 weight=3 max_fails=2 fail_timeout=30s; 10 server 192.168.1.102:8080 weight=2 max_fails=2 fail_timeout=30s; 11 server 192.168.1.103:8080 weight=2 max_fails=2 fail_timeout=30s; 12 server 192.168.1.104:8080 weight=1 max_fails=2 fail_timeout=30s; 13 14 # 会话保持(可选) 15 # sticky cookie srv_id expires=1h domain=.example.com path=/; 16 } 17 18 server { 19 listen 80; 20 server_name api.example.com; 21 22 location / { 23 proxy_pass http://springboot_cluster; 24 25 # 代理头设置 26 proxy_set_header Host $host; 27 proxy_set_header X-Real-IP $remote_addr; 28 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 29 proxy_set_header X-Forwarded-Proto $scheme; 30 31 # 超时设置 32 proxy_connect_timeout 30s; 33 proxy_send_timeout 30s; 34 proxy_read_timeout 30s; 35 } 36 } 37} 38
3.2 高级负载均衡策略
多种负载均衡算法配置
1upstream springboot_cluster { 2 # 1. 轮询(默认) 3 # 默认算法,无需指定 4 5 # 2. 加权轮询 6 # server 192.168.1.101:8080 weight=5; 7 # server 192.168.1.102:8080 weight=3; 8 # server 192.168.1.103:8080 weight=1; 9 10 # 3. IP哈希(会话保持) 11 ip_hash; 12 13 # 4. 最少连接数 14 # least_conn; 15 16 # 5. 响应时间优先(需要nginx-plus) 17 # fair; 18 19 server 192.168.1.101:8080; 20 server 192.168.1.102:8080; 21 server 192.168.1.103:8080; 22 23 # 备份服务器 24 server 192.168.1.100:8080 backup; 25} 26
健康检查配置
1upstream springboot_cluster { 2 server 192.168.1.101:8080; 3 server 192.168.1.102:8080; 4 server 192.168.1.103:8080; 5 6 # 健康检查配置 7 check interval=3000 rise=2 fall=3 timeout=1000 type=http; 8 check_http_send "HEAD /actuator/health HTTP/1.0\r\n\r\n"; 9 check_http_expect_alive http_2xx http_3xx; 10} 11 12server { 13 location /nginx_status { 14 check_status; 15 access_log off; 16 allow 192.168.1.0/24; 17 deny all; 18 } 19} 20
第四章:静态资源分离实战
4.1 静态资源配置优化
Nginx 静态资源服务配置
1# 静态资源服务器配置 2server { 3 listen 80; 4 server_name static.example.com; 5 6 # Gzip 压缩 7 gzip on; 8 gzip_vary on; 9 gzip_min_length 1024; 10 gzip_types text/plain text/css application/json application/javascript text/xml application/xml image/svg+xml; 11 12 # 静态资源路径 13 root /var/www/static; 14 15 location / { 16 # 缓存控制 17 expires 1y; 18 add_header Cache-Control "public, immutable"; 19 add_header Access-Control-Allow-Origin "*"; 20 } 21 22 # CSS/JS 文件 23 location ~* \.(css|js)$ { 24 expires 1y; 25 add_header Cache-Control "public, immutable"; 26 } 27 28 # 图片文件 29 location ~* \.(jpg|jpeg|png|gif|ico|svg)$ { 30 expires 1y; 31 add_header Cache-Control "public, immutable"; 32 } 33 34 # 字体文件 35 location ~* \.(woff|woff2|ttf|eot)$ { 36 expires 1y; 37 add_header Cache-Control "public, immutable"; 38 add_header Access-Control-Allow-Origin "*"; 39 } 40} 41
Spring Boot 静态资源优化
1@Configuration 2public class WebConfig implements WebMvcConfigurer { 3 4 @Value("${static.resource.url:https://static.example.com}") 5 private String staticResourceUrl; 6 7 @Override 8 public void addResourceHandlers(ResourceHandlerRegistry registry) { 9 // 禁用内置静态资源服务(生产环境) 10 // 或者重定向到CDN/静态资源服务器 11 registry.addResourceHandler("/static/**") 12 .addResourceLocations(staticResourceUrl + "/static/"); 13 14 registry.addResourceHandler("/webjars/**") 15 .addResourceLocations(staticResourceUrl + "/webjars/"); 16 } 17 18 @Bean 19 public FilterRegistrationBean<StaticResourceFilter> staticResourceFilter() { 20 FilterRegistrationBean<StaticResourceFilter> registrationBean = new FilterRegistrationBean<>(); 21 registrationBean.setFilter(new StaticResourceFilter()); 22 registrationBean.addUrlPatterns("*.css", "*.js", "*.png", "*.jpg", "*.gif"); 23 return registrationBean; 24 } 25} 26
4.2 CDN 集成配置
Nginx CDN 回源配置
1# CDN 回源服务器配置 2server { 3 listen 80; 4 server_name origin-static.example.com; 5 6 # CDN 特定头处理 7 set $cdn_origin ""; 8 if ($http_x_cdn_origin) { 9 set $cdn_origin $http_x_cdn_origin; 10 } 11 12 location /static/ { 13 root /var/www; 14 15 # 缓存控制(CDN 遵循) 16 expires 1y; 17 add_header Cache-Control "public, immutable"; 18 add_header X-Origin "nginx-static-server"; 19 20 # 防盗链 21 valid_referers none blocked server_names *.example.com; 22 if ($invalid_referer) { 23 return 403; 24 } 25 } 26 27 # 动态内容不缓存 28 location ~* \.(do|action|api)$ { 29 proxy_pass http://springboot_cluster; 30 proxy_set_header X-CDN-Origin $cdn_origin; 31 } 32} 33
第五章:高可用与故障转移
5.1 Nginx 高可用架构
主从备份配置
1# 主负载均衡器配置 2upstream springboot_cluster { 3 zone backend 64k; 4 state /var/lib/nginx/state/backend.conf; 5 6 server 192.168.1.101:8080 resolve; 7 server 192.168.1.102:8080 resolve; 8 server 192.168.1.103:8080 resolve; 9} 10 11# 健康检查增强 12server { 13 location /health { 14 access_log off; 15 return 200 "healthy\n"; 16 add_header Content-Type text/plain; 17 } 18 19 location /nginx-health { 20 check_status; 21 access_log off; 22 } 23} 24
Keepalived 高可用配置
1# /etc/keepalived/keepalived.conf 2# 主节点配置 3vrrp_instance VI_1 { 4 state MASTER 5 interface eth0 6 virtual_router_id 51 7 priority 100 8 advert_int 1 9 10 authentication { 11 auth_type PASS 12 auth_pass 1111 13 } 14 15 virtual_ipaddress { 16 192.168.1.200/24 dev eth0 17 } 18 19 track_script { 20 chk_nginx 21 } 22} 23 24vrrp_script chk_nginx { 25 script "/usr/bin/killall -0 nginx" 26 interval 2 27 weight -50 28} 29
5.2 故障转移策略
Spring Boot 健康检查端点
1@Component 2public class ClusterHealthIndicator implements HealthIndicator { 3 4 @Value("${cluster.instance-id:unknown}") 5 private String instanceId; 6 7 @Autowired 8 private DataSource dataSource; 9 10 @Autowired 11 private RedisTemplate<String, String> redisTemplate; 12 13 @Override 14 public Health health() { 15 try { 16 // 检查数据库连接 17 if (!dataSource.getConnection().isValid(5)) { 18 return Health.down() 19 .withDetail("database", "unavailable") 20 .withDetail("instance", instanceId) 21 .build(); 22 } 23 24 // 检查Redis连接 25 redisTemplate.getConnectionFactory().getConnection().ping(); 26 27 // 检查磁盘空间 28 File root = new File("/"); 29 long freeSpace = root.getFreeSpace(); 30 long totalSpace = root.getTotalSpace(); 31 double freePercent = (double) freeSpace / totalSpace * 100; 32 33 if (freePercent < 10) { 34 return Health.down() 35 .withDetail("disk", "low space: " + freePercent + "% free") 36 .build(); 37 } 38 39 return Health.up() 40 .withDetail("instance", instanceId) 41 .withDetail("disk", String.format("%.2f%% free", freePercent)) 42 .build(); 43 44 } catch (Exception e) { 45 return Health.down(e) 46 .withDetail("instance", instanceId) 47 .build(); 48 } 49 } 50} 51
第六章:安全配置与优化
6.1 安全加固配置
Nginx 安全配置
1server { 2 listen 80; 3 server_name api.example.com; 4 5 # 安全头设置 6 add_header X-Frame-Options "SAMEORIGIN" always; 7 add_header X-XSS-Protection "1; mode=block" always; 8 add_header X-Content-Type-Options "nosniff" always; 9 add_header Referrer-Policy "no-referrer-when-downgrade" always; 10 add_header Content-Security-Policy "default-src 'self' http: https: data: blob: 'unsafe-inline'" always; 11 12 # 隐藏Nginx版本号 13 server_tokens off; 14 15 # 限制请求方法 16 if ($request_method !~ ^(GET|POST|PUT|DELETE|PATCH)$) { 17 return 405; 18 } 19 20 # 限制请求大小 21 client_max_body_size 10m; 22 23 # 速率限制 24 limit_req_zone $binary_remote_addr zone=api:10m rate=10r/s; 25 26 location /api/ { 27 limit_req zone=api burst=20 nodelay; 28 29 proxy_pass http://springboot_cluster; 30 proxy_set_header X-Real-IP $remote_addr; 31 32 # WAF 集成 33 set $waf_enabled 1; 34 if ($http_user_agent ~* (wget|curl|bot|spider)) { 35 set $waf_enabled 0; 36 } 37 } 38 39 # 禁止敏感路径访问 40 location ~* /(\.git|\.env|\.htaccess) { 41 deny all; 42 return 404; 43 } 44} 45
Spring Boot 安全配置
1@Configuration 2@EnableWebSecurity 3public class SecurityConfig extends WebSecurityConfigurerAdapter { 4 5 @Override 6 protected void configure(HttpSecurity http) throws Exception { 7 http.csrf().disable() 8 .authorizeRequests() 9 .antMatchers("/actuator/health").permitAll() 10 .antMatchers("/actuator/info").permitAll() 11 .antMatchers("/api/public/**").permitAll() 12 .anyRequest().authenticated() 13 .and() 14 .sessionManagement() 15 .sessionCreationPolicy(SessionCreationPolicy.STATELESS) 16 .and() 17 .addFilterBefore(jwtFilter(), UsernamePasswordAuthenticationFilter.class); 18 } 19 20 @Bean 21 public FilterRegistrationBean<RequestLoggingFilter> loggingFilter() { 22 FilterRegistrationBean<RequestLoggingFilter> registrationBean = new FilterRegistrationBean<>(); 23 registrationBean.setFilter(new RequestLoggingFilter()); 24 registrationBean.addUrlPatterns("/api/*"); 25 return registrationBean; 26 } 27} 28
6.2 SSL/TLS 配置
Nginx SSL 配置
1server { 2 listen 443 ssl http2; 3 server_name api.example.com; 4 5 # SSL 证书配置 6 ssl_certificate /etc/ssl/certs/example.com.crt; 7 ssl_certificate_key /etc/ssl/private/example.com.key; 8 9 # SSL 优化配置 10 ssl_protocols TLSv1.2 TLSv1.3; 11 ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384; 12 ssl_prefer_server_ciphers off; 13 ssl_session_cache shared:SSL:10m; 14 ssl_session_timeout 10m; 15 16 # HSTS 头 17 add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; 18 19 location / { 20 proxy_pass http://springboot_cluster; 21 proxy_set_header X-Forwarded-Proto https; 22 } 23} 24 25# HTTP 重定向到 HTTPS 26server { 27 listen 80; 28 server_name api.example.com; 29 return 301 https://$server_name$request_uri; 30} 31
第七章:监控与日志管理
7.1 全方位监控配置
Nginx 状态监控
1# 状态监控配置 2server { 3 listen 8081; 4 server_name localhost; 5 6 location /nginx-status { 7 stub_status on; 8 access_log off; 9 allow 127.0.0.1; 10 allow 192.168.1.0/24; 11 deny all; 12 } 13 14 location /server-status { 15 check_status; 16 access_log off; 17 allow 127.0.0.1; 18 allow 192.168.1.0/24; 19 deny all; 20 } 21} 22
Spring Boot 监控端点
1# application-monitor.yml 2management: 3 endpoints: 4 web: 5 exposure: 6 include: health,info,metrics,prometheus 7 base-path: /internal 8 endpoint: 9 health: 10 show-details: always 11 show-components: always 12 group: 13 cluster: 14 include: diskSpace,redis,db 15 metrics: 16 enabled: true 17 metrics: 18 export: 19 prometheus: 20 enabled: true 21 22# 自定义指标 23cluster: 24 metrics: 25 enabled: true 26 request-count: true 27 response-time: true 28
7.2 集中日志管理
Nginx 日志格式优化
1http { 2 log_format main '$remote_addr - $remote_user [$time_local] "$request" ' 3 '$status $body_bytes_sent "$http_referer" ' 4 '"$http_user_agent" "$http_x_forwarded_for" ' 5 'upstream_addr: $upstream_addr ' 6 'upstream_response_time: $upstream_response_time ' 7 'request_time: $request_time'; 8 9 access_log /var/log/nginx/access.log main; 10 error_log /var/log/nginx/error.log warn; 11 12 # 日志轮转 13 open_log_file_cache max=1000 inactive=20s valid=1m min_uses=2; 14} 15
Spring Boot 日志配置
1<!-- logback-spring.xml --> 2<configuration> 3 <springProperty scope="context" name="APP_NAME" source="spring.application.name"/> 4 <springProperty scope="context" name="INSTANCE_ID" source="cluster.instance-id"/> 5 6 <appender name="JSON" class="ch.qos.logback.core.rolling.RollingFileAppender"> 7 <file>/app/logs/${APP_NAME}.log</file> 8 <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> 9 <fileNamePattern>/app/logs/${APP_NAME}.%d{yyyy-MM-dd}.log</fileNamePattern> 10 <maxHistory>30</maxHistory> 11 </rollingPolicy> 12 <encoder class="net.logstash.logback.encoder.LogstashEncoder"> 13 <customFields>{"app":"${APP_NAME}","instance":"${INSTANCE_ID}"}</customFields> 14 </encoder> 15 </appender> 16 17 <root level="INFO"> 18 <appender-ref ref="JSON"/> 19 </root> 20</configuration> 21
第八章:性能调优实战
8.1 Nginx 性能优化
高性能配置模板
1# nginx.conf 性能优化部分 2user nginx; 3worker_processes auto; 4worker_cpu_affinity auto; 5 6error_log /var/log/nginx/error.log warn; 7pid /var/run/nginx.pid; 8 9events { 10 worker_connections 10240; 11 use epoll; 12 multi_accept on; 13} 14 15http { 16 # 基础优化 17 sendfile on; 18 tcp_nopush on; 19 tcp_nodelay on; 20 keepalive_timeout 65; 21 keepalive_requests 1000; 22 types_hash_max_size 2048; 23 server_tokens off; 24 25 # 缓冲区优化 26 client_body_buffer_size 128k; 27 client_max_body_size 100m; 28 client_header_buffer_size 4k; 29 large_client_header_buffers 4 16k; 30 31 # 超时设置 32 client_body_timeout 30s; 33 client_header_timeout 30s; 34 send_timeout 30s; 35 36 # 上游服务器优化 37 proxy_connect_timeout 5s; 38 proxy_send_timeout 60s; 39 proxy_read_timeout 60s; 40 proxy_buffering on; 41 proxy_buffer_size 4k; 42 proxy_buffers 8 4k; 43 44 # 缓存优化 45 open_file_cache max=10000 inactive=30s; 46 open_file_cache_valid 60s; 47 open_file_cache_min_uses 2; 48 open_file_cache_errors on; 49} 50
8.2 Spring Boot 集群优化
应用性能配置
1# application-performance.yml 2server: 3 tomcat: 4 threads: 5 max: 200 6 min-spare: 20 7 max-connections: 10000 8 accept-count: 100 9 compression: 10 enabled: true 11 mime-types: application/json,application/xml,text/html,text/xml,text/plain 12 13spring: 14 datasource: 15 hikari: 16 maximum-pool-size: 20 17 minimum-idle: 10 18 connection-timeout: 30000 19 max-lifetime: 1800000 20 redis: 21 lettuce: 22 pool: 23 max-active: 20 24 max-idle: 10 25 min-idle: 5 26 27# JVM 优化参数 28jvm: 29 options: >- 30 -Xms2g -Xmx2g 31 -XX:+UseG1GC 32 -XX:MaxGCPauseMillis=200 33 -XX:InitiatingHeapOccupancyPercent=45 34 -XX:+UnlockExperimentalVMOptions 35 -XX:+UseContainerSupport 36
第九章:部署与自动化
9.1 Docker Compose 集群部署
完整集群编排文件
1# docker-compose.cluster.yml 2version: '3.8' 3 4services: 5 # Nginx 负载均衡器 6 nginx-lb: 7 image: nginx:1.21-alpine 8 ports: 9 - "80:80" 10 - "443:443" 11 volumes: 12 - ./nginx/nginx.conf:/etc/nginx/nginx.conf 13 - ./nginx/conf.d:/etc/nginx/conf.d 14 - ./ssl:/etc/ssl 15 networks: 16 - app-network 17 deploy: 18 replicas: 2 19 restart_policy: 20 condition: on-failure 21 22 # Spring Boot 应用集群 23 app-node1: 24 build: . 25 environment: 26 - SPRING_PROFILES_ACTIVE=cluster 27 - INSTANCE_ID=node1 28 - SERVER_PORT=8080 29 networks: 30 - app-network 31 deploy: 32 replicas: 3 33 restart_policy: 34 condition: on-failure 35 36 app-node2: 37 build: . 38 environment: 39 - SPRING_PROFILES_ACTIVE=cluster 40 - INSTANCE_ID=node2 41 - SERVER_PORT=8080 42 networks: 43 - app-network 44 deploy: 45 replicas: 3 46 47 # 基础设施 48 redis: 49 image: redis:6.2-alpine 50 networks: 51 - app-network 52 53 mysql: 54 image: mysql:8.0 55 environment: 56 MYSQL_ROOT_PASSWORD: rootpass 57 MYSQL_DATABASE: appdb 58 networks: 59 - app-network 60 61networks: 62 app-network: 63 driver: bridge 64
9.2 CI/CD 流水线配置
GitLab CI 配置
1# .gitlab-ci.yml 2stages: 3 - test 4 - build 5 - deploy 6 7variables: 8 APP_NAME: springboot-cluster 9 REGISTRY_URL: registry.example.com 10 11test: 12 stage: test 13 image: maven:3.8-openjdk-17 14 script: 15 - mvn clean test 16 only: 17 - develop 18 - main 19 20build: 21 stage: build 22 image: docker:latest 23 services: 24 - docker:dind 25 script: 26 - docker build -t $REGISTRY_URL/$APP_NAME:latest . 27 - docker push $REGISTRY_URL/$APP_NAME:latest 28 only: 29 - main 30 31deploy: 32 stage: deploy 33 image: alpine:latest 34 before_script: 35 - apk add --no-cache openssh-client 36 - mkdir -p ~/.ssh 37 - echo "$SSH_PRIVATE_KEY" > ~/.ssh/id_rsa 38 - chmod 600 ~/.ssh/id_rsa 39 script: 40 - ssh -o StrictHostKeyChecking=no deploy@server "cd /opt/cluster && docker-compose pull && docker-compose up -d" 41 only: 42 - main 43
第十章:故障排查与维护
10.1 常见问题解决方案
连接数问题排查
1# 查看 Nginx 连接状态 2netstat -an | grep :80 | wc -l 3 4# 查看 Spring Boot 连接数 5curl -s http://localhost:8080/actuator/metrics | grep tomcat.connections 6 7# 实时监控 8watch "netstat -an | grep :8080 | wc -l" 9
性能问题诊断
1# Nginx 请求统计 2tail -f /var/log/nginx/access.log | awk '{print $1}' | sort | uniq -c | sort -nr 3 4# 响应时间分析 5grep -o 'request_time: [0-9.]*' /var/log/nginx/access.log | sort -n | tail -10 6 7# JVM 内存分析 8docker exec app-node1 jcmd 1 GC.heap_info 9
10.2 自动化维护脚本
健康检查脚本
1#!/bin/bash 2# health-check.sh 3 4NGINX_URL="http://localhost/nginx-health" 5APP_URLS=( 6 "http://192.168.1.101:8080/actuator/health" 7 "http://192.168.1.102:8080/actuator/health" 8 "http://192.168.1.103:8080/actuator/health" 9) 10 11echo "=== 集群健康检查 $(date) ===" 12 13# 检查 Nginx 14echo "检查 Nginx..." 15if curl -f -s $NGINX_URL > /dev/null; then 16 echo "✅ Nginx 正常" 17else 18 echo "❌ Nginx 异常" 19 systemctl restart nginx 20fi 21 22# 检查应用节点 23for url in "${APP_URLS[@]}"; do 24 instance=$(echo $url | cut -d'/' -f3) 25 if curl -f -s $url > /dev/null; then 26 echo "✅ $instance 正常" 27 else 28 echo "❌ $instance 异常" 29 # 自动重启逻辑 30 ssh $instance "docker restart app-container" 31 fi 32done 33 34echo "=== 检查完成 ===" 35
总结
通过本指南,您已经掌握了 Spring Boot 集群集成 Nginx 的完整实战方案。关键要点包括:
- 架构设计:合理的集群架构是成功的基础
- 无状态应用:会话外部化是实现水平扩展的前提
- 负载均衡:选择合适的算法和健康检查策略
- 静态资源分离:提升性能并降低应用服务器压力
- 高可用配置:确保系统的高可靠性和故障恢复能力
- 安全加固:保护集群免受常见攻击
- 监控运维:建立完整的可观测性体系
这套架构方案已经在大规模生产环境中得到验证,能够支撑高并发、高可用的业务场景。根据实际需求调整配置参数,即可构建出适合自己业务的集群架构。
