Spring Boot集群 集成Nginx配置:负载均衡+静态资源分离实战

Spring Boot 集群集成 Nginx:负载均衡 + 静态资源分离实战指南

  • 第一章:架构概述与设计理念
    • [1.1 为什么需要集群化?](#1.1 为什么需要集群化?)
    • [1.2 整体架构设计](#1.2 整体架构设计)
  • [第二章:Spring Boot 应用集群化准备](#第二章:Spring Boot 应用集群化准备)
    • [2.1 应用无状态化改造](#2.1 应用无状态化改造)
    • [2.2 应用配置标准化](#2.2 应用配置标准化)
  • [第三章:Nginx 负载均衡配置详解](#第三章:Nginx 负载均衡配置详解)
    • [3.1 Nginx 安装与基础配置](#3.1 Nginx 安装与基础配置)
    • [3.2 高级负载均衡策略](#3.2 高级负载均衡策略)
  • 第四章:静态资源分离实战
    • [4.1 静态资源配置优化](#4.1 静态资源配置优化)
    • [4.2 CDN 集成配置](#4.2 CDN 集成配置)
  • 第五章:高可用与故障转移
    • [5.1 Nginx 高可用架构](#5.1 Nginx 高可用架构)
    • [5.2 故障转移策略](#5.2 故障转移策略)
  • 第六章:安全配置与优化
    • [6.1 安全加固配置](#6.1 安全加固配置)
    • [6.2 SSL/TLS 配置](#6.2 SSL/TLS 配置)
  • 第七章:监控与日志管理
    • [7.1 全方位监控配置](#7.1 全方位监控配置)
    • [7.2 集中日志管理](#7.2 集中日志管理)
  • 第八章:性能调优实战
    • [8.1 Nginx 性能优化](#8.1 Nginx 性能优化)
    • [8.2 Spring Boot 集群优化](#8.2 Spring Boot 集群优化)
  • 第九章:部署与自动化
    • [9.1 Docker Compose 集群部署](#9.1 Docker Compose 集群部署)
    • [9.2 CI/CD 流水线配置](#9.2 CI/CD 流水线配置)
  • 第十章:故障排查与维护
    • [10.1 常见问题解决方案](#10.1 常见问题解决方案)
    • [10.2 自动化维护脚本](#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 应用无状态化改造

问题分析:有状态应用的挑战

java 复制代码
// 有状态示例 - 会话存储在应用内存中
@Controller
public class UserController {
    // 问题:会话数据存储在单个实例内存中
    private Map<String, UserSession> userSessions = new ConcurrentHashMap<>();
    
    @PostMapping("/login")
    public String login(User user, HttpServletRequest request) {
        // 会话存储在当前实例内存
        UserSession session = new UserSession(user);
        userSessions.put(session.getId(), session);
        request.getSession().setAttribute("sessionId", session.getId());
        return "dashboard";
    }
}

解决方案:外部化会话管理

java 复制代码
// 无状态改造 - 使用 Redis 存储会话
@Configuration
@EnableRedisHttpSession(maxInactiveIntervalInSeconds = 1800)
public class HttpSessionConfig {
    
    @Bean
    public LettuceConnectionFactory connectionFactory() {
        return new LettuceConnectionFactory();
    }
}

// 应用代码无需修改,Spring Session 自动处理
@RestController
public class StatelessController {
    
    @GetMapping("/user/profile")
    public UserProfile getProfile(HttpSession session) {
        // 会话数据存储在 Redis 中,任何实例都可访问
        String userId = (String) session.getAttribute("userId");
        return userService.getProfile(userId);
    }
}

2.2 应用配置标准化

集群化应用配置

yaml 复制代码
# application-cluster.yml
server:
  port: 8080
  servlet:
    session:
      timeout: 30m

spring:
  application:
    name: ecommerce-cluster
  redis:
    host: redis-cluster.redis.svc.cluster.local
    port: 6379
    password: ${REDIS_PASSWORD}
  datasource:
    url: jdbc:mysql://mysql-cluster.mysql.svc.cluster.local:3306/ecommerce
    username: ${DB_USERNAME}
    password: ${DB_PASSWORD}
    hikari:
      maximum-pool-size: 20
      minimum-idle: 5

management:
  endpoints:
    web:
      exposure:
        include: health,info,metrics
  endpoint:
    health:
      show-details: always
      probes:
        enabled: true

# 自定义配置
cluster:
  instance-id: ${INSTANCE_ID:unknown}
  load-balancer:
    health-check-path: /actuator/health

第三章:Nginx 负载均衡配置详解

3.1 Nginx 安装与基础配置

Ubuntu/CentOS 安装

bash 复制代码
# Ubuntu
sudo apt update
sudo apt install nginx

# CentOS
sudo yum install epel-release
sudo yum install nginx

# 启动服务
sudo systemctl start nginx
sudo systemctl enable nginx

# 验证安装
nginx -v

基础负载均衡配置

nginx 复制代码
# /etc/nginx/nginx.conf
http {
    # 定义上游服务器组
    upstream springboot_cluster {
        # 负载均衡算法
        least_conn;  # 最少连接数算法
        
        # 服务器列表
        server 192.168.1.101:8080 weight=3 max_fails=2 fail_timeout=30s;
        server 192.168.1.102:8080 weight=2 max_fails=2 fail_timeout=30s;
        server 192.168.1.103:8080 weight=2 max_fails=2 fail_timeout=30s;
        server 192.168.1.104:8080 weight=1 max_fails=2 fail_timeout=30s;
        
        # 会话保持(可选)
        # sticky cookie srv_id expires=1h domain=.example.com path=/;
    }
    
    server {
        listen 80;
        server_name api.example.com;
        
        location / {
            proxy_pass http://springboot_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;
            
            # 超时设置
            proxy_connect_timeout 30s;
            proxy_send_timeout 30s;
            proxy_read_timeout 30s;
        }
    }
}

3.2 高级负载均衡策略

多种负载均衡算法配置

nginx 复制代码
upstream springboot_cluster {
    # 1. 轮询(默认)
    # 默认算法,无需指定
    
    # 2. 加权轮询
    # server 192.168.1.101:8080 weight=5;
    # server 192.168.1.102:8080 weight=3;
    # server 192.168.1.103:8080 weight=1;
    
    # 3. IP哈希(会话保持)
    ip_hash;
    
    # 4. 最少连接数
    # least_conn;
    
    # 5. 响应时间优先(需要nginx-plus)
    # fair;
    
    server 192.168.1.101:8080;
    server 192.168.1.102:8080;
    server 192.168.1.103:8080;
    
    # 备份服务器
    server 192.168.1.100:8080 backup;
}

健康检查配置

nginx 复制代码
upstream springboot_cluster {
    server 192.168.1.101:8080;
    server 192.168.1.102:8080;
    server 192.168.1.103:8080;
    
    # 健康检查配置
    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;
}

server {
    location /nginx_status {
        check_status;
        access_log off;
        allow 192.168.1.0/24;
        deny all;
    }
}

第四章:静态资源分离实战

4.1 静态资源配置优化

Nginx 静态资源服务配置

nginx 复制代码
# 静态资源服务器配置
server {
    listen 80;
    server_name static.example.com;
    
    # Gzip 压缩
    gzip on;
    gzip_vary on;
    gzip_min_length 1024;
    gzip_types text/plain text/css application/json application/javascript text/xml application/xml image/svg+xml;
    
    # 静态资源路径
    root /var/www/static;
    
    location / {
        # 缓存控制
        expires 1y;
        add_header Cache-Control "public, immutable";
        add_header Access-Control-Allow-Origin "*";
    }
    
    # CSS/JS 文件
    location ~* \.(css|js)$ {
        expires 1y;
        add_header Cache-Control "public, immutable";
    }
    
    # 图片文件
    location ~* \.(jpg|jpeg|png|gif|ico|svg)$ {
        expires 1y;
        add_header Cache-Control "public, immutable";
    }
    
    # 字体文件
    location ~* \.(woff|woff2|ttf|eot)$ {
        expires 1y;
        add_header Cache-Control "public, immutable";
        add_header Access-Control-Allow-Origin "*";
    }
}

Spring Boot 静态资源优化

java 复制代码
@Configuration
public class WebConfig implements WebMvcConfigurer {
    
    @Value("${static.resource.url:https://static.example.com}")
    private String staticResourceUrl;
    
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        // 禁用内置静态资源服务(生产环境)
        // 或者重定向到CDN/静态资源服务器
        registry.addResourceHandler("/static/**")
                .addResourceLocations(staticResourceUrl + "/static/");
                
        registry.addResourceHandler("/webjars/**")
                .addResourceLocations(staticResourceUrl + "/webjars/");
    }
    
    @Bean
    public FilterRegistrationBean<StaticResourceFilter> staticResourceFilter() {
        FilterRegistrationBean<StaticResourceFilter> registrationBean = new FilterRegistrationBean<>();
        registrationBean.setFilter(new StaticResourceFilter());
        registrationBean.addUrlPatterns("*.css", "*.js", "*.png", "*.jpg", "*.gif");
        return registrationBean;
    }
}

4.2 CDN 集成配置

Nginx CDN 回源配置

nginx 复制代码
# CDN 回源服务器配置
server {
    listen 80;
    server_name origin-static.example.com;
    
    # CDN 特定头处理
    set $cdn_origin "";
    if ($http_x_cdn_origin) {
        set $cdn_origin $http_x_cdn_origin;
    }
    
    location /static/ {
        root /var/www;
        
        # 缓存控制(CDN 遵循)
        expires 1y;
        add_header Cache-Control "public, immutable";
        add_header X-Origin "nginx-static-server";
        
        # 防盗链
        valid_referers none blocked server_names *.example.com;
        if ($invalid_referer) {
            return 403;
        }
    }
    
    # 动态内容不缓存
    location ~* \.(do|action|api)$ {
        proxy_pass http://springboot_cluster;
        proxy_set_header X-CDN-Origin $cdn_origin;
    }
}

第五章:高可用与故障转移

5.1 Nginx 高可用架构

主从备份配置

nginx 复制代码
# 主负载均衡器配置
upstream springboot_cluster {
    zone backend 64k;
    state /var/lib/nginx/state/backend.conf;
    
    server 192.168.1.101:8080 resolve;
    server 192.168.1.102:8080 resolve;
    server 192.168.1.103:8080 resolve;
}

# 健康检查增强
server {
    location /health {
        access_log off;
        return 200 "healthy\n";
        add_header Content-Type text/plain;
    }
    
    location /nginx-health {
        check_status;
        access_log off;
    }
}

Keepalived 高可用配置

bash 复制代码
# /etc/keepalived/keepalived.conf
# 主节点配置
vrrp_instance VI_1 {
    state MASTER
    interface eth0
    virtual_router_id 51
    priority 100
    advert_int 1
    
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    
    virtual_ipaddress {
        192.168.1.200/24 dev eth0
    }
    
    track_script {
        chk_nginx
    }
}

vrrp_script chk_nginx {
    script "/usr/bin/killall -0 nginx"
    interval 2
    weight -50
}

5.2 故障转移策略

Spring Boot 健康检查端点

java 复制代码
@Component
public class ClusterHealthIndicator implements HealthIndicator {
    
    @Value("${cluster.instance-id:unknown}")
    private String instanceId;
    
    @Autowired
    private DataSource dataSource;
    
    @Autowired
    private RedisTemplate<String, String> redisTemplate;
    
    @Override
    public Health health() {
        try {
            // 检查数据库连接
            if (!dataSource.getConnection().isValid(5)) {
                return Health.down()
                    .withDetail("database", "unavailable")
                    .withDetail("instance", instanceId)
                    .build();
            }
            
            // 检查Redis连接
            redisTemplate.getConnectionFactory().getConnection().ping();
            
            // 检查磁盘空间
            File root = new File("/");
            long freeSpace = root.getFreeSpace();
            long totalSpace = root.getTotalSpace();
            double freePercent = (double) freeSpace / totalSpace * 100;
            
            if (freePercent < 10) {
                return Health.down()
                    .withDetail("disk", "low space: " + freePercent + "% free")
                    .build();
            }
            
            return Health.up()
                .withDetail("instance", instanceId)
                .withDetail("disk", String.format("%.2f%% free", freePercent))
                .build();
                
        } catch (Exception e) {
            return Health.down(e)
                .withDetail("instance", instanceId)
                .build();
        }
    }
}

第六章:安全配置与优化

6.1 安全加固配置

Nginx 安全配置

nginx 复制代码
server {
    listen 80;
    server_name api.example.com;
    
    # 安全头设置
    add_header X-Frame-Options "SAMEORIGIN" always;
    add_header X-XSS-Protection "1; mode=block" always;
    add_header X-Content-Type-Options "nosniff" always;
    add_header Referrer-Policy "no-referrer-when-downgrade" always;
    add_header Content-Security-Policy "default-src 'self' http: https: data: blob: 'unsafe-inline'" always;
    
    # 隐藏Nginx版本号
    server_tokens off;
    
    # 限制请求方法
    if ($request_method !~ ^(GET|POST|PUT|DELETE|PATCH)$) {
        return 405;
    }
    
    # 限制请求大小
    client_max_body_size 10m;
    
    # 速率限制
    limit_req_zone $binary_remote_addr zone=api:10m rate=10r/s;
    
    location /api/ {
        limit_req zone=api burst=20 nodelay;
        
        proxy_pass http://springboot_cluster;
        proxy_set_header X-Real-IP $remote_addr;
        
        # WAF 集成
        set $waf_enabled 1;
        if ($http_user_agent ~* (wget|curl|bot|spider)) {
            set $waf_enabled 0;
        }
    }
    
    # 禁止敏感路径访问
    location ~* /(\.git|\.env|\.htaccess) {
        deny all;
        return 404;
    }
}

Spring Boot 安全配置

java 复制代码
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.csrf().disable()
            .authorizeRequests()
            .antMatchers("/actuator/health").permitAll()
            .antMatchers("/actuator/info").permitAll()
            .antMatchers("/api/public/**").permitAll()
            .anyRequest().authenticated()
            .and()
            .sessionManagement()
            .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
            .and()
            .addFilterBefore(jwtFilter(), UsernamePasswordAuthenticationFilter.class);
    }
    
    @Bean
    public FilterRegistrationBean<RequestLoggingFilter> loggingFilter() {
        FilterRegistrationBean<RequestLoggingFilter> registrationBean = new FilterRegistrationBean<>();
        registrationBean.setFilter(new RequestLoggingFilter());
        registrationBean.addUrlPatterns("/api/*");
        return registrationBean;
    }
}

6.2 SSL/TLS 配置

Nginx SSL 配置

nginx 复制代码
server {
    listen 443 ssl http2;
    server_name api.example.com;
    
    # SSL 证书配置
    ssl_certificate /etc/ssl/certs/example.com.crt;
    ssl_certificate_key /etc/ssl/private/example.com.key;
    
    # SSL 优化配置
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384;
    ssl_prefer_server_ciphers off;
    ssl_session_cache shared:SSL:10m;
    ssl_session_timeout 10m;
    
    # HSTS 头
    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
    
    location / {
        proxy_pass http://springboot_cluster;
        proxy_set_header X-Forwarded-Proto https;
    }
}

# HTTP 重定向到 HTTPS
server {
    listen 80;
    server_name api.example.com;
    return 301 https://$server_name$request_uri;
}

第七章:监控与日志管理

7.1 全方位监控配置

Nginx 状态监控

nginx 复制代码
# 状态监控配置
server {
    listen 8081;
    server_name localhost;
    
    location /nginx-status {
        stub_status on;
        access_log off;
        allow 127.0.0.1;
        allow 192.168.1.0/24;
        deny all;
    }
    
    location /server-status {
        check_status;
        access_log off;
        allow 127.0.0.1;
        allow 192.168.1.0/24;
        deny all;
    }
}

Spring Boot 监控端点

yaml 复制代码
# application-monitor.yml
management:
  endpoints:
    web:
      exposure:
        include: health,info,metrics,prometheus
      base-path: /internal
  endpoint:
    health:
      show-details: always
      show-components: always
      group:
        cluster:
          include: diskSpace,redis,db
    metrics:
      enabled: true
  metrics:
    export:
      prometheus:
        enabled: true

# 自定义指标
cluster:
  metrics:
    enabled: true
    request-count: true
    response-time: true

7.2 集中日志管理

Nginx 日志格式优化

nginx 复制代码
http {
    log_format main '$remote_addr - $remote_user [$time_local] "$request" '
                    '$status $body_bytes_sent "$http_referer" '
                    '"$http_user_agent" "$http_x_forwarded_for" '
                    'upstream_addr: $upstream_addr '
                    'upstream_response_time: $upstream_response_time '
                    'request_time: $request_time';
    
    access_log /var/log/nginx/access.log main;
    error_log /var/log/nginx/error.log warn;
    
    # 日志轮转
    open_log_file_cache max=1000 inactive=20s valid=1m min_uses=2;
}

Spring Boot 日志配置

xml 复制代码
<!-- logback-spring.xml -->
<configuration>
    <springProperty scope="context" name="APP_NAME" source="spring.application.name"/>
    <springProperty scope="context" name="INSTANCE_ID" source="cluster.instance-id"/>
    
    <appender name="JSON" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>/app/logs/${APP_NAME}.log</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>/app/logs/${APP_NAME}.%d{yyyy-MM-dd}.log</fileNamePattern>
            <maxHistory>30</maxHistory>
        </rollingPolicy>
        <encoder class="net.logstash.logback.encoder.LogstashEncoder">
            <customFields>{"app":"${APP_NAME}","instance":"${INSTANCE_ID}"}</customFields>
        </encoder>
    </appender>
    
    <root level="INFO">
        <appender-ref ref="JSON"/>
    </root>
</configuration>

第八章:性能调优实战

8.1 Nginx 性能优化

高性能配置模板

nginx 复制代码
# nginx.conf 性能优化部分
user nginx;
worker_processes auto;
worker_cpu_affinity auto;

error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;

events {
    worker_connections 10240;
    use epoll;
    multi_accept on;
}

http {
    # 基础优化
    sendfile on;
    tcp_nopush on;
    tcp_nodelay on;
    keepalive_timeout 65;
    keepalive_requests 1000;
    types_hash_max_size 2048;
    server_tokens off;
    
    # 缓冲区优化
    client_body_buffer_size 128k;
    client_max_body_size 100m;
    client_header_buffer_size 4k;
    large_client_header_buffers 4 16k;
    
    # 超时设置
    client_body_timeout 30s;
    client_header_timeout 30s;
    send_timeout 30s;
    
    # 上游服务器优化
    proxy_connect_timeout 5s;
    proxy_send_timeout 60s;
    proxy_read_timeout 60s;
    proxy_buffering on;
    proxy_buffer_size 4k;
    proxy_buffers 8 4k;
    
    # 缓存优化
    open_file_cache max=10000 inactive=30s;
    open_file_cache_valid 60s;
    open_file_cache_min_uses 2;
    open_file_cache_errors on;
}

8.2 Spring Boot 集群优化

应用性能配置

yaml 复制代码
# application-performance.yml
server:
  tomcat:
    threads:
      max: 200
      min-spare: 20
    max-connections: 10000
    accept-count: 100
  compression:
    enabled: true
    mime-types: application/json,application/xml,text/html,text/xml,text/plain

spring:
  datasource:
    hikari:
      maximum-pool-size: 20
      minimum-idle: 10
      connection-timeout: 30000
      max-lifetime: 1800000
  redis:
    lettuce:
      pool:
        max-active: 20
        max-idle: 10
        min-idle: 5

# JVM 优化参数
jvm:
  options: >-
    -Xms2g -Xmx2g 
    -XX:+UseG1GC 
    -XX:MaxGCPauseMillis=200 
    -XX:InitiatingHeapOccupancyPercent=45 
    -XX:+UnlockExperimentalVMOptions 
    -XX:+UseContainerSupport

第九章:部署与自动化

9.1 Docker Compose 集群部署

完整集群编排文件

yaml 复制代码
# docker-compose.cluster.yml
version: '3.8'

services:
  # Nginx 负载均衡器
  nginx-lb:
    image: nginx:1.21-alpine
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./nginx/nginx.conf:/etc/nginx/nginx.conf
      - ./nginx/conf.d:/etc/nginx/conf.d
      - ./ssl:/etc/ssl
    networks:
      - app-network
    deploy:
      replicas: 2
      restart_policy:
        condition: on-failure

  # Spring Boot 应用集群
  app-node1:
    build: .
    environment:
      - SPRING_PROFILES_ACTIVE=cluster
      - INSTANCE_ID=node1
      - SERVER_PORT=8080
    networks:
      - app-network
    deploy:
      replicas: 3
      restart_policy:
        condition: on-failure

  app-node2:
    build: .
    environment:
      - SPRING_PROFILES_ACTIVE=cluster
      - INSTANCE_ID=node2
      - SERVER_PORT=8080
    networks:
      - app-network
    deploy:
      replicas: 3

  # 基础设施
  redis:
    image: redis:6.2-alpine
    networks:
      - app-network

  mysql:
    image: mysql:8.0
    environment:
      MYSQL_ROOT_PASSWORD: rootpass
      MYSQL_DATABASE: appdb
    networks:
      - app-network

networks:
  app-network:
    driver: bridge

9.2 CI/CD 流水线配置

GitLab CI 配置

yaml 复制代码
# .gitlab-ci.yml
stages:
  - test
  - build
  - deploy

variables:
  APP_NAME: springboot-cluster
  REGISTRY_URL: registry.example.com

test:
  stage: test
  image: maven:3.8-openjdk-17
  script:
    - mvn clean test
  only:
    - develop
    - main

build:
  stage: build
  image: docker:latest
  services:
    - docker:dind
  script:
    - docker build -t $REGISTRY_URL/$APP_NAME:latest .
    - docker push $REGISTRY_URL/$APP_NAME:latest
  only:
    - main

deploy:
  stage: deploy
  image: alpine:latest
  before_script:
    - apk add --no-cache openssh-client
    - mkdir -p ~/.ssh
    - echo "$SSH_PRIVATE_KEY" > ~/.ssh/id_rsa
    - chmod 600 ~/.ssh/id_rsa
  script:
    - ssh -o StrictHostKeyChecking=no deploy@server "cd /opt/cluster && docker-compose pull && docker-compose up -d"
  only:
    - main

第十章:故障排查与维护

10.1 常见问题解决方案

连接数问题排查

bash 复制代码
# 查看 Nginx 连接状态
netstat -an | grep :80 | wc -l

# 查看 Spring Boot 连接数
curl -s http://localhost:8080/actuator/metrics | grep tomcat.connections

# 实时监控
watch "netstat -an | grep :8080 | wc -l"

性能问题诊断

bash 复制代码
# Nginx 请求统计
tail -f /var/log/nginx/access.log | awk '{print $1}' | sort | uniq -c | sort -nr

# 响应时间分析
grep -o 'request_time: [0-9.]*' /var/log/nginx/access.log | sort -n | tail -10

# JVM 内存分析
docker exec app-node1 jcmd 1 GC.heap_info

10.2 自动化维护脚本

健康检查脚本

bash 复制代码
#!/bin/bash
# health-check.sh

NGINX_URL="http://localhost/nginx-health"
APP_URLS=(
  "http://192.168.1.101:8080/actuator/health"
  "http://192.168.1.102:8080/actuator/health"
  "http://192.168.1.103:8080/actuator/health"
)

echo "=== 集群健康检查 $(date) ==="

# 检查 Nginx
echo "检查 Nginx..."
if curl -f -s $NGINX_URL > /dev/null; then
  echo "✅ Nginx 正常"
else
  echo "❌ Nginx 异常"
  systemctl restart nginx
fi

# 检查应用节点
for url in "${APP_URLS[@]}"; do
  instance=$(echo $url | cut -d'/' -f3)
  if curl -f -s $url > /dev/null; then
    echo "✅ $instance 正常"
  else
    echo "❌ $instance 异常"
    # 自动重启逻辑
    ssh $instance "docker restart app-container"
  fi
done

echo "=== 检查完成 ==="

总结

通过本指南,您已经掌握了 Spring Boot 集群集成 Nginx 的完整实战方案。关键要点包括:

  1. 架构设计:合理的集群架构是成功的基础
  2. 无状态应用:会话外部化是实现水平扩展的前提
  3. 负载均衡:选择合适的算法和健康检查策略
  4. 静态资源分离:提升性能并降低应用服务器压力
  5. 高可用配置:确保系统的高可靠性和故障恢复能力
  6. 安全加固:保护集群免受常见攻击
  7. 监控运维:建立完整的可观测性体系
    这套架构方案已经在大规模生产环境中得到验证,能够支撑高并发、高可用的业务场景。根据实际需求调整配置参数,即可构建出适合自己业务的集群架构。
相关推荐
一叶飘零_sweeeet2 小时前
攻克 大 Excel 上传难题:从异步处理到并发去重的全链路解决方案
java·excel·大文件上传
huan19933 小时前
Java中实现html转pdf
java
绝无仅有3 小时前
MySQL 面试题及详细解答(二)
后端·面试·github
野犬寒鸦3 小时前
从零起步学习Redis || 第二章:Redis中数据类型的深层剖析讲解(下)
java·redis·后端·算法·哈希算法
王者鳜錸3 小时前
方言普通话识别大模型,支持中英+202种方言识别
java·vue·语音识别
haokan_Jia3 小时前
【springboot的分页功能TableDataInfo,有时候需要复杂的分页实现,怎么办呢?】
java·spring boot·后端
Terio_my3 小时前
Java 后端面试技术文档(参考)
java·开发语言·面试
今晚务必早点睡3 小时前
前端缓存好还是后端缓存好?缓存方案实例直接用
前端·后端·缓存