# M1.6 Workstream 4: Multi-Instance Orchestration Design

**版本**: v1.0.0  
**日期**: 2025-10-09  
**负责人**: Strategy Platform Team  
**依赖文档**: `IMPLEMENTATION_PLAN.md`, `ARCHITECTURE_DESIGN.md`, `M16_INCREMENTAL_GRID_DESIGN.md`, `M16_PLACEMENT_THROTTLING_DESIGN.md`

---

## 1. 背景与目标

- 支持同一 Runner 进程内运行多个 Grid 实例（多账户、多标的、内外圈策略）。  
- 解决当前单实例架构无法分层挂单、无法差异化限流的问题。  
- 为后续多 venue / 多策略协同奠定基础。

---

## 2. 核心组件

| 组件 | 说明 |
|------|------|
| `GridFleetManager` | 负责实例生命周期管理（启动/停止/热更新）、调度、监控。 |
| `GridInstance` | 包含 `GridMaker`、`ShadowBook`、`timers`、`metrics` 等封装。 |
| `FleetConfig` | `grid.instances[]` schema（参见 §3），支持 per-instance 参数。 |
| `InstanceRegistry` | 映射 `(accountId, symbol)` → `GridInstance`，提供迭代、查找。 |
| `GlobalOrderCoordinator` 扩展 | 跨实例 STP、冲突检测、节流。 |
| `FleetController` | CLI/REST 控制接口（list/scale/degrade）。 |

---

## 3. 配置 Schema

```yaml
grid:
  enabled: true
  instances:
    - id: btc-inner
      account_id: maker-inner
      symbol: BTC
      grid_step_bps: 2
      grid_range_bps: 120
      base_clip_usd: 80
      max_layers: 14
      adaptive:
        enabled: true
        min_grid_step_bps: 1.5
        max_grid_step_bps: 20
        post_only_cushion_bps: 0.5
        min_layers: 12
        tick_interval_ms: 30000
        fill_starvation_threshold: { ticks: 4, compress_factor: 0.5 }
    - id: btc-outer
      account_id: maker-outer
      symbol: BTC
      grid_step_bps: 8
      grid_range_bps: 200
      base_clip_usd: 100
      max_layers: 10
      adaptive:
        enabled: true
        min_grid_step_bps: 6
        max_grid_step_bps: 60
        post_only_cushion_bps: 2
        min_layers: 8
```

### 3.1 Schema 说明
- `id`：唯一实例 ID，用于日志/指标/运维命令。  
- `account_id`：会在 AdapterRegistry 中查找对应账户；必须配对成功。  
- `symbol`：允许多个实例操作同一 symbol（需 STP 控制）。  
- 其余字段与现有 `grid` 配置一致，`adaptive` 支持新增字段：  
  - `fill_starvation_threshold.ticks`: 连续无成交的 tick 数。  
  - `compress_factor`: 步长压缩比例（例如 0.5 → 减半）。  
- 如果 `grid.instances` 缺失，则回退到旧的单实例配置（兼容性）。

---

## 4. GridFleetManager 设计

### 4.1 数据结构

```ts
interface GridInstanceContext {
  id: string;
  symbol: string;
  accountId: string;
  maker: GridMaker;
  shadowBook: ShadowBook;
  timers: {
    tick: NodeJS.Timeout;
    status: NodeJS.Timeout;
  };
  metrics: GridInstanceMetrics;
  state: "initializing" | "running" | "paused" | "degraded" | "stopped";
  lastConfigHash: string;
}
```

### 4.2 生命周期

1. **create**  
   - 构建 ShadowBook、GridMaker、Hedge/Fills handler。  
   - 注册到 `InstanceRegistry` 并启动 timers。  
   - 记录 metrics：`grid_instance_state{id="...", state="initializing"}`。
2. **start**  
   - 调用 `GridMaker.initialize()`；成功后状态切换为 `running`。  
3. **pause**  
   - 停止 timers，调用 `GridMaker.shutdown()`，保留配置。  
4. **resume**  
   - 重新启动 timers，视需要重新初始化。  
5. **degrade**  
   - 进入“保守模式”——例如仅留 4 层、步长放大、停止自适应。  
6. **destroy**  
   - 停止 timers、注销 handlers、释放资源。

### 4.3 热更新

- 新配置进来后，计算 `hash(instanceConfig)`：  
  - 若 hash 未变化→忽略。  
  - 若变化→调用 `instance.update(newConfig)`：  
    1. 暂停当前实例；  
    2. 应用新配置（重建 GridMaker/ShadowBook）；  
    3. 重新启动。  
- 更新过程中需确保全局 STP/节流不会误判（详见 §5）。

---

## 5. GlobalOrderCoordinator 扩展

### 5.1 目标
- 同一 symbol、不同实例之间禁止互相吃单（STP）。  
- 对共享账户的实例合并限流（如 `maker-inner` / `maker-outer` 使用同一 API 限额）。  
- 实例级别的订单统计用于填充 metrics。

### 5.2 实现

- OrderId 索引改为 `(accountId, symbol, clientId)` 复合键。  
- 在 `registerOrder` 时追加实例 ID，检测 `conflicts` 时排除相同实例 / 允许不同 symbol。  
- 提供接口 `coordinator.getAccountLoad(accountId)`，供节流模块查询。  
- 新增指标：  
  - `stp_conflicts_total{instance}`  
  - `account_order_load{accountId}`  
- STP 冲突触发时，使用 `fleet.degrade(instanceId, reason="stp_conflict")` 或回退自适应。

---

## 6. 监控与指标

| 指标 | 说明 |
|------|------|
| `grid_instance_state{instance}` | `initializing/running/paused/degraded/stopped` |
| `grid_active_orders{instance}` | 当前活跃订单数 |
| `grid_pending_levels{instance}` | reconcile 后未补足的层数 |
| `grid_fill_interval_seconds{instance}` | 平均成交间隔 |
| `grid_step_bps{instance}` | 当前步长指标（Expose via Gauge） |
| `order_gateway_queue_depth{accountId}` | WS 队列深度（Placement Throttling 依赖） |

告警建议：
- `grid_instance_state != running` 持续 > 60s。  
- `grid_pending_levels > 2` 持续 > 2 tick。  
- `order_gateway_queue_depth > 40` 持续 > 5s。  
- `stp_conflicts_total` 突然增加。

---

## 7. 运维接口（FleetController）

| 命令 | 描述 |
|------|------|
| `GET /api/fleet/instances` | 列出所有实例状态、当前配置 hash、活跃订单数 |
| `POST /api/fleet/instances/{id}/pause` | 暂停实例（保留订单） |
| `POST /api/fleet/instances/{id}/resume` | 恢复实例 |
| `POST /api/fleet/instances/{id}/degrade` | 进入保守模式（参数：步长放大倍数、保留层数） |
| `POST /api/fleet/instances/{id}/shutdown` | 停止并撤销所有订单 |
| `POST /api/fleet/reload` | 重新加载配置（wrapper of config reload） |

接口需经过认证（与 Kill-switch 相同机制），并写入审计日志。

---

## 8. 与 M16 其他 Workstream 的关系

- 与 Workstream 1（增量网格）共享 `reconcileGrid`、实例级 metrics。  
- 与 Workstream 2（节流 2.0）共享 rate limiter（按 account/instance 聚合）。  
- 与 Workstream 3（成交驱动压缩）需要同步 `fill_starvation_threshold` 配置。  
- 在极限贴盘口实验中，可通过多实例策略（内圈 vs 外圈）开展分层测试。

---

## 9. 风险与缓解

| 风险 | 描述 | 缓解策略 |
|------|------|-----------|
| STP/限流复杂度上升 | 多实例同时下单造成冲突或超限 | 统一通过 coordinator + rate limiter，必要时设置硬阈值 |
| 热更新中断 | 更新流程出现异常导致实例停滞 | 引入事务化流程：先创建新实例，成功后替换旧实例 |
| 指标压力 | 多实例指标数倍增 | 聚合指标支持 `cluster` 标签，Grafana 通过 regex 过滤 |

---

## 10. 实施步骤

1. 扩展配置解析（zod schema + 文档更新）。  
2. 实现 `GridFleetManager` 与 `GridInstance`。  
3. 修改 Runner (`apps/runner/src/index.ts`) 以实例化 Fleet。  
4. 升级 GlobalOrderCoordinator。  
5. 与 Placement Throttling 集成（共享 rate limiter）。  
6. 补充指标/运维接口/测试。  
7. 回归单实例模式确保兼容。  
8. 金丝雀：1 内圈 + 1 外圈实例，观测 24 小时后推广。

---

## 11. 测试计划

- 单元测试：实例创建/更新/销毁、STP 冲突检测、rate limiter 分配。  
- 集成测试：Mock 2 个实例，验证填充订单、增量补单、节流逻辑。  
- 压测：模拟 10+ 实例并发下单，评估指标采集和限流表现。  
- 金丝雀指标：`grid_instance_state`, `grid_pending_levels`, `order_gateway_queue_depth`, `placement_latency_p95`.
