# 超时和阻塞问题分析与解决方案

## 问题概述

经过全面检查，发现以下几个可能导致超时和阻塞的问题：

## 1. WebClient 连接池配置缺失 ⚠️ 高优先级

### 问题描述
`ScriptClient.java` 中的 WebClient 没有配置底层 HTTP 客户端的连接池参数，可能导致：
- 连接数耗尽，新请求被阻塞
- 连接泄漏
- 超时设置未生效

### 当前代码
```java
this.webClient = WebClient.builder()
        .baseUrl(baseUrl)
        .exchangeStrategies(ExchangeStrategies.builder()
                .codecs(cfg -> cfg.defaultCodecs().maxInMemorySize(2 * 1024 * 1024))
                .build())
        .build();
```

### 解决方案
需要配置 Reactor Netty HttpClient：
```java
HttpClient httpClient = HttpClient.create()
        .option(ChannelOption.CONNECT_TIMEOUT_MILLIS, connectTimeoutMs)
        .responseTimeout(Duration.ofMillis(readTimeoutMs))
        .doOnConnected(conn -> 
            conn.addHandlerLast(new ReadTimeoutHandler(readTimeoutMs, TimeUnit.MILLISECONDS))
                .addHandlerLast(new WriteTimeoutHandler(connectTimeoutMs, TimeUnit.MILLISECONDS)))
        .wiretap(true); // 开启日志追踪

this.webClient = WebClient.builder()
        .baseUrl(baseUrl)
        .clientConnector(new ReactorClientHttpConnector(httpClient))
        .exchangeStrategies(ExchangeStrategies.builder()
                .codecs(cfg -> cfg.defaultCodecs().maxInMemorySize(2 * 1024 * 1024))
                .build())
        .build();
```

## 2. Tomcat 线程池配置缺失 ⚠️ 高优先级

### 问题描述
Spring Boot 内嵌 Tomcat 使用默认线程池配置，可能不足以处理高并发场景。

### 解决方案
在 `application.yml` 中添加：
```yaml
server:
  port: 18080
  tomcat:
    threads:
      max: 200                    # 最大工作线程数
      min-spare: 20               # 最小空闲线程数
    max-connections: 10000        # 最大连接数
    accept-count: 100             # 队列长度
    connection-timeout: 20000     # 连接超时(ms)
  shutdown: graceful              # 优雅关闭
  
spring:
  lifecycle:
    timeout-per-shutdown-phase: 30s  # 关闭超时
```

## 3. WebFlux 配置优化 ⚠️ 中优先级

### 问题描述
如果项目使用了 WebFlux，需要配置 Reactor 线程池。

### 解决方案
在 `application.yml` 中添加：
```yaml
spring:
  webflux:
    # WebFlux 相关配置（如果使用）
    base-path: /
  reactor:
    # Reactor 线程池配置
    netty:
      pool:
        type: elastic  # 使用弹性线程池
```

## 4. 数据库连接池优化 ⚠️ 中优先级

### 当前配置
```yaml
hikari:
  maximum-pool-size: 50
  minimum-idle: 10
  connection-timeout: 30000      # 30秒
  idle-timeout: 600000           # 10分钟
  max-lifetime: 1800000          # 30分钟
```

### 问题
- `connection-timeout` 设置为 30 秒过长，可能导致请求堆积
- MySQL 锁等待超时设置为 30 秒也偏长

### 建议优化
```yaml
hikari:
  maximum-pool-size: 80           # 增加连接池大小
  minimum-idle: 20                # 增加最小空闲连接
  connection-timeout: 10000       # 降低到10秒
  idle-timeout: 300000            # 5分钟
  max-lifetime: 1800000           # 30分钟
  leak-detection-threshold: 30000 # 30秒检测连接泄漏（从60秒降低）
  validation-timeout: 3000        # 降低到3秒
```

同时优化 MySQL 会话参数：
```yaml
datasource:
  url: jdbc:mysql://...?sessionVariables=innodb_lock_wait_timeout=10,wait_timeout=300,interactive_timeout=300
```

## 5. 异步线程池拒绝策略优化 ⚠️ 中优先级

### 当前配置
```java
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
```

### 问题
CallerRunsPolicy 会让调用线程（通常是 HTTP 线程）执行任务，可能导致 HTTP 线程池阻塞。

### 建议
根据业务需求选择：

**方案 A：丢弃策略（不重要的任务）**
```java
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.DiscardOldestPolicy());
```

**方案 B：增加队列并监控（重要任务）**
```java
executor.setQueueCapacity(500);  // 从100增加到500
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.AbortPolicy());
// 添加拒绝处理监控
```

## 6. 事务超时优化 ⚠️ 中优先级

### 问题
部分事务方法可能执行时间过长，持有数据库连接。

### 建议
1. 为不同类型的事务设置不同超时：
```java
@Transactional(timeout = 5)   // 快速查询/更新
@Transactional(timeout = 15)  // 批量操作
@Transactional(timeout = 30)  // 复杂业务逻辑
```

2. 避免在事务中调用外部 HTTP 接口：
```java
// ❌ 不好的做法
@Transactional
public Mono<Result> process() {
    // 事务内调用外部 HTTP
    return externalService.call().map(data -> {
        repository.save(data);  // 持有连接时间过长
    });
}

// ✅ 推荐做法
public Mono<Result> process() {
    // 先调用外部接口
    return externalService.call()
        .flatMap(data -> {
            // 再开启事务保存
            return Mono.fromCallable(() -> saveInTransaction(data))
                .subscribeOn(Schedulers.boundedElastic());
        });
}

@Transactional(timeout = 5)
private Result saveInTransaction(Data data) {
    return repository.save(data);
}
```

## 7. 添加请求超时和监控 ⚠️ 中优先级

### 建议配置
在 `application.yml` 中添加：
```yaml
spring:
  mvc:
    async:
      request-timeout: 60000  # 60秒异步请求超时

management:
  endpoints:
    web:
      exposure:
        include: health,info,metrics,threaddump,heapdump
  metrics:
    enable:
      tomcat: true
      hikaricp: true
      jvm: true
```

## 8. 日志优化建议

添加性能监控日志：
```yaml
logging:
  level:
    reactor.netty: INFO                    # Reactor Netty 日志
    io.netty: INFO                         # Netty 日志
    com.zaxxer.hikari: INFO                # HikariCP 日志
    org.springframework.web.reactive: INFO # WebFlux 日志
```

## 实施优先级

### 立即实施（高优先级）
1. ✅ 配置 WebClient 连接池和超时
2. ✅ 配置 Tomcat 线程池
3. ✅ 优化数据库连接池参数

### 短期实施（中优先级）
4. 优化异步线程池拒绝策略
5. 检查并优化事务边界
6. 添加性能监控端点

### 长期优化
7. 添加分布式追踪（如 Sleuth + Zipkin）
8. 添加断路器（如 Resilience4j）
9. 考虑使用 Redis 缓存热点数据

## 监控建议

### 1. 添加健康检查
```java
@Component
public class CustomHealthIndicator implements HealthIndicator {
    @Override
    public Health health() {
        // 检查数据库连接
        // 检查外部服务
        // 检查线程池状态
        return Health.up().build();
    }
}
```

### 2. 添加性能指标
```java
@Timed(value = "api.calls", description = "API调用耗时")
public Mono<Result> apiMethod() {
    // ...
}
```

### 3. 监控关键指标
- HTTP 线程池使用率
- 数据库连接池使用率
- 异步线程池队列长度
- 外部接口响应时间
- 事务执行时间

## 总结

主要问题集中在：
1. **HTTP 客户端配置不完整** - 导致连接管理问题
2. **服务器线程池未配置** - 默认值可能不适合生产环境
3. **数据库连接和事务管理** - 超时设置偏保守
4. **缺少监控和告警** - 难以及时发现问题

建议按优先级逐步实施优化措施。

