# 实时分析调度器设计方案

## 概述

每个规则根据窗口类型（滚动、滑动、会话）独立管理下次运行时间，而不是所有规则统一每30秒执行一次。

## 核心设计

### 1. 窗口类型与执行间隔映射

| 窗口类型 | 配置参数 | 执行间隔 | 示例 |
|---------|---------|---------|------|
| **TUMBLE**<br/>滚动窗口 | `tumble_window_size` + `tumble_window_size_unit` | 等于窗口大小 | 窗口5分钟 → 每5分钟执行 |
| **HOP**<br/>滑动窗口 | `hop_slide` + `hop_slide_unit` | 等于滑动步长 | 步长5分钟 → 每5分钟执行 |
| **SESSION**<br/>会话窗口 | `session_window_size` + `session_window_size_unit` | 等于会话超时时间 | 超时30分钟 → 每30分钟执行 |
| **NONE**<br/>无窗口 | - | 默认30秒 | 每30秒执行 |

### 2. 执行流程

```
┌─────────────────────────────────────────────────────────────┐
│ 应用启动                                            │
│  └─> initAllRules()                                 │
│       └─> 加载所有实时规则                          │
│       └─> 为每个规则初始化下次执行时间（Redis）        │
└─────────────────────────────────────────────────────────────┘
                           │
                           ▼
┌─────────────────────────────────────────────────────────────┐
│ 定时调度（每10秒检查一次）                            │
│  └─> checkAndExecuteRules()                         │
│       └─> 查询所有实时规则                         │
│       └─> 对每个规则：                                 │
│           ├─> 获取下次执行时间（Redis）                  │
│           ├─> 判断是否到执行时间                       │
│           │   ├─> 是 → 执行规则 → 更新下次执行时间      │
│           │   └─> 否 → 跳过                         │
│           └─> 继续下一个规则                         │
└─────────────────────────────────────────────────────────────┘
```

### 3. 时间计算逻辑

#### TUMBLE（滚动窗口）
```
下次执行时间 = 当前时间 + 窗口大小
```

**示例**：
- 窗口大小：5分钟
- 执行时间：10:00:00
- 下次执行：10:05:00

#### HOP（滑动窗口）
```
下次执行时间 = 当前时间 + 滑动步长
```

**示例**：
- 窗口大小：10分钟，步长：5分钟
- 执行时间：10:00:00
- 下次执行：10:05:00

#### SESSION（会话窗口）
```
下次执行时间 = 当前时间 + 会话超时时间
```

**示例**：
- 会话超时：30分钟
- 执行时间：10:00:00
- 下次执行：10:30:00

## 数据结构

### Redis Key 设计

```
rule:next_execute:{ruleId}
```

**示例**：
```
rule:next_execute:rule-001 -> "2026-02-27 10:30:00"
rule:next_execute:rule-002 -> "2026-02-27 10:00:00"
```

**过期时间**：30天

## 配置示例

### application.yml

```yaml
spring:
  redis:
    host: localhost
    port: 6379
    password:
    database: 0
    timeout: 3000

analysis:
  realtime:
    enabled: true
    # 检查间隔（秒） - 频率越高越精确，但消耗资源
    check-interval-seconds: 10
  offline:
    enabled: true
    cron-expression: "0 0 */1 * * ?"
```

### pom.xml（添加Redis依赖）

```xml
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
```

## 核心组件

### 1. RuleExecutionTimeService
规则执行时间管理服务接口，负责：
- 获取规则下次执行时间
- 更新规则下次执行时间（根据窗口类型计算）
- 初始化规则执行时间
- 删除规则执行时间

### 2. RuleExecutionTimeServiceImpl
规则执行时间管理服务实现（基于Redis），核心方法：
- `calculateTumbleNextExecuteTime()`: 计算滚动窗口下次执行时间
- `calculateHopNextExecuteTime()`: 计算滑动窗口下次执行时间
- `calculateSessionNextExecuteTime()`: 计算会话窗口下次执行时间

### 3. RealtimeAnalysisScheduler
实时分析调度器，核心逻辑：
- 应用启动时初始化所有规则执行时间
- 每10秒检查一次规则是否需要执行
- 根据窗口类型独立计算下次执行时间

## 日志示例

### 初始化日志
```
INFO  - ========== 初始化实时分析调度器 ==========
INFO  - 查询到 3 个实时分析规则
INFO  - 初始化规则: ruleId=001, ruleName=暴力破解检测, windowType=HOP, nextExecuteTime=2026-02-27 10:05:00
INFO  - 初始化规则: ruleId=002, ruleName=端口扫描检测, windowType=TUMBLE, nextExecuteTime=2026-02-27 10:05:00
INFO  - 初始化规则: ruleId=003, ruleName=会话异常检测, windowType=SESSION, nextExecuteTime=2026-02-27 10:30:00
INFO  - ========== 实时分析调度器初始化完成 ==========
```

### 执行日志
```
INFO  - 执行规则: ruleId=001, ruleName=暴力破解检测, nextTime=2026-02-27 10:05:00, now=2026-02-27 10:05:00
INFO  - 滑动窗口下次执行时间: 步长=5m，nextTime=2026-02-27 10:10:00
INFO  - 更新规则下次执行时间，ruleId=001, ruleName=暴力破解检测, windowType=HOP, nextExecuteTime=2026-02-27 10:10:00
INFO  - 本次调度执行规则数: 1, 跳过规则数: 2
```

## 优势

1. ✅ **独立周期**：每个规则根据窗口类型独立配置执行周期
2. ✅ **高性能**：Redis缓存，每次检查只需毫秒级
3. ✅ **分布式支持**：多节点共享Redis，避免重复执行
4. ✅ **动态调整**：运行时修改窗口配置，下次执行自动生效
5. ✅ **资源优化**：避免低频规则频繁执行浪费资源

## 注意事项

1. **Redis依赖**：需要安装并启动Redis服务
2. **时间精度**：调度检查间隔默认10秒，可根据需要调整
3. **窗口配置**：规则必须配置窗口类型和大小参数
4. **异常恢复**：应用重启后，Redis中记录的执行时间保持不变
5. **并发控制**：同一规则同时只能有一个实例在执行
