agentscope-ai / agentscope-ai/agentscope-java
[Bug]: a2a sse接口事件超过1000的时候会导致卡住
- Vorherrschende Sprache
- Java
- Sterne
- 5.6k
- Forks
- 1.3k
- Ø Merge
- 4 T. 12 Std.
- Gemergte PRs (30 T.)
- 77
Beschreibung
# SSE 事件流卡在 1000 个事件问题 —— 根因分析与修复方案
## 1. 问题现象
- 测试脚本稳定复现:SSE 流式事件精确在第 **1000 个事件**处停止。
- 服务端最终报错:`TimeoutException: Did not observe any item or terminal signal within 600000ms`。
- 该问题与事件计数强相关(精确卡在1000),而非偶发网络抖动,多次测试均可复现。
- 已排除的错误方向:
- `JsonRpcTransportWrapper` 的 8192 容量 backpressure buffer(`onBackpressureBuffer` + `BufferOverflowStrategy.ERROR`)—— 容量远大于1000,且策略是抛错而非阻塞,现象不匹配。
## 2. 根因确认
问题根源在第三方闭源依赖 **`io.github.a2asdk:a2a-java-sdk-server-common`**(当前项目通过 `agentscope 2.0.0` 正式版间接引入,确认版本号为 **`0.3.3.Final`**,与之前排查的 RC3 版本一致,因此结论对当前正式版同样适用)。
### 2.1 核心类:`io.a2a.server.events.EventQueue`
通过反编译字节码(`javap -p -v`)确认:
1. **默认队列容量硬编码为 1000**
- 主构造函数:`EventQueue(int queueSize)`,内部创建 `new Semaphore(queueSize, true)`(fair 模式)。
- 子队列(父子关系)构造函数:`EventQueue(EventQueue parent)` 内部硬编码调用 `this(1000)`。
- 字节码证据:`sipush 1000` 出现在该构造函数中。
2. **`enqueueEvent()` 使用无超时的阻塞式 `acquire()`**
```
27: aload_0
28: getfield #39 // semaphore
31: invokevirtual #86 // Semaphore.acquire:()V <-- 无超时阻塞!
34: goto 55
...
55: aload_0
56: getfield #15 // queue: BlockingQueue
59: aload_1
60: invokeinterface #107 // BlockingQueue.add
```
- 每次入队前必须先拿到一个 `Semaphore` 许可;许可总数 = 队列容量(1000)。
- 只有消费者取出一个事件(`dequeueEventItem`)才会 `release()` 一个许可。
- **该 `acquire()` 调用没有超时参数**,如果没有可用许可,会无限期阻塞当前线程。
### 2.2 触发链路
1. Agent 执行过程中通过 `AgentScopeAgentExecutor` → `TaskUpdater` → `EventQueue.enqueueEvent()` 持续产生事件(reasoning/tool/artifact 等)。
2. 事件消费端是 SSE 输出(`JsonRpcTransportWrapper` → 客户端网络连接)。
3. **一旦消费速度跟不上生产速度**(例如客户端网络慢、下游处理阻塞等),未消费事件在队列中堆积。
4. 堆到 1000 个后,第 1001 次 `enqueueEvent()` 在 `semaphore.acquire()` 处**永久阻塞**——生产者线程被卡死,不再产生新事件。
5. 表现为“事件数精确停在1000”,且后续什么都不再发生。
6. 最终触发此前已加的 **30 秒空闲超时兜底机制**(`DynamicModelMiddleware` 中的 `resultFlux.timeout(Duration.ofSeconds(30))`),报错看起来像“模型超时”,但**真正原因是队列阻塞死锁,不是模型响应变慢**。
Beitragsleitfaden
Bewertung
Dieses Issue wurde noch nicht bewertet.