mcpField
A
alpaca-broker-rate-limits-resilience

alpaca-broker-rate-limits-resilience

github.com/alpacahq开发157130 次安装1 周前更新
代码仓库

关于 alpaca-broker-rate-limits-resilience

这是一项面向 Alpaca API 开发者的跨语言技能,适用于批处理、回填和对账任务。内容侧重按速率限制重试、控制并发、处理分页及保障请求可靠性。

主要功能

  1. 01处理速率限制响应头
  2. 02重试与随机退避
  3. 03限制工作池并发
  4. 04循环获取分页数据
  5. 05设置超时并复用连接
  6. 06批处理韧性检查清单

适用场景

  1. 01执行 Alpaca 数据回填
  2. 02对账大量账户数据
  3. 03处理受限流的 API 请求
  4. 04维护可靠的定时任务

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/alpacahq/alpaca-skills --skill alpaca-broker-rate-limits-resilience

安装后在 Claude Code 中输入/alpaca-broker-rate-limits-resilience确认已加载。

附带文件reference.md

详细介绍

Alpaca — 速率限制与弹性

Alpaca 的 API 有速率限制,在高负载下偶尔也会不稳定。任何调用次数超过少量的客户端——尤其是批量任务、历史数据回填和对账扫描——都需要严格控制重试、退避和并发。这些模式属于传输层,适用于任何语言。

请先阅读 alpaca-broker-integration。

1. 速率限制标头——每次响应都要读取

Alpaca 会返回标准标头:

标头含义
X-RateLimit-Limit时间窗口内允许的请求数
X-RateLimit-Remaining当前窗口剩余的请求数
X-RateLimit-Reset窗口重置时的 Unix 时间戳(秒)

每次响应都要解析这些标头,而不只是出错时。 有两种用途:

  • 主动控制: 随着 Remaining 接近零而减慢请求速度,而不是等到被限流。你选择的任何预警阈值都只是自己的起始值,应根据 Limit 推导——Alpaca 没有公布相关阈值。
  • 被动应对: 遇到 429 时,使用 Reset 精确等待至窗口重新开放。

经纪商的限制在 对应方级别生效——覆盖整个集成,而非针对每个终端用户账户,因此你运行的每个进程都共用一个额度。限制按合作伙伴设置,且不会公布;请根据标头作出响应。

沙盒限制远低于生产环境,不能可靠反映生产环境的剩余容量。Alpaca 明确表示 不要对沙盒进行负载测试——应模拟 Alpaca 调用,并让存根模拟从真实生产调用中采样得到的延迟。

2. 重试循环(伪代码)

MAX_ATTEMPTS = 10
INITIAL_DELAY_MS = 1000
MAX_DELAY_MS = 60000
backoff(n) = min(INITIAL_DELAY_MS * 2^(n-1), MAX_DELAY_MS) + random(0, 500)

for attempt in 1..MAX_ATTEMPTS:
    res = http(request)                      # with a sane timeout (see §5)
    limit, remaining, reset_at = parse_rate_headers(res.headers)
    if remaining < low_water(limit): log_warn("approaching rate limit", reset_at)

    if res.status == 429:
        # wait until the window resets, plus a small buffer
        wait = (reset_at - now()) if reset_at else backoff(attempt)
        sleep(max(0, wait) + 1000 + random(0, 500))
        continue

    if res.status in (500, 502, 503, 504) or network_error:
        sleep(backoff(attempt))
        continue

    return res                                # success or non-retryable 4xx
raise last_error

要点:

  • 遇到 429 时,等待至 X-RateLimit-Reset 时间,再额外等待约 1 秒,同时继续采用指数退避——Reset 表示窗口何时滚动,并不保证后续请求不会再次挤满窗口。
  • 网络错误和 5xx 使用 指数退避(base * 2^(attempt-1)),并设置 上限(文档示例的上限为 60s)。base 为 1s、尝试 10 次时,最后的等待时间会达到数分钟——适合后台任务,但对面向用户的调用来说太慢(应减少尝试次数)。
  • 每次等待都加入抖动。 这属于文档建议的一部分,并非额外措施:对应方级别的限制意味着你的所有工作进程会同时遭到限流,否则就会同步重试。
  • 不要重试不可重试的 4xx(400/403/422)——这类错误不会自行消失;应将其反馈出来。

3. 有界并发

并行处理能加快批量任务,但也是触发限流最快的方法。应使用 固定工作进程池,而不是不受限制地扇出请求。

  • 根据 X-RateLimit-Limit 设置工作进程池大小,不要使用固定数字;并记住限制适用于对应方级别:你运行的每个工作进程、定时任务和 Web 进程都会消耗同一份额度。根据观测到的 Remaining 调低并发;通常你自己的下游存储才是更严格的限制因素。
  • 在一次运行过程中缓存每个实体的读取结果(例如账户的购买力,或每个账户的转账列表),避免在批次中的各个项目重复获取相同数据。
  • 若要按项目限制速率,而你又无法轻易协调工作进程池,可在调用之间加入较短的固定休眠时间(例如 100ms)。这种方法虽粗糙,但有效。

4. 分页循环

列表端点使用令牌向前分页——绝不要假设单次响应包含全部结果。

  • 活动记录(/v1/accounts/activities):响应是一个不带分页标头的原始 JSON 数组——将页面中最后一条活动记录的 id 作为 page_token 传回;当返回的页面条数不足时停止。page_size 默认值和最大值均为 100(设置 date 时没有最大值——会返回所有结果);direction 可设为 asc/desc,默认值为 desc。
  • 市场数据 K 线(/v2/stocks/bars):通过响应正文中的 next_page_token 翻页 → 将其作为 page_token 传回。请记住,limit 计数涵盖所有标的,结果按标的再按时间排序,因此 单个页面可能只包含前几个标的——请继续翻页。
  • 将每次页面获取都包装在 §2 所述的重试循环中。
token = null
loop:
    page = fetch(url + (token ? "&page_token="+token : ""))   # via retry loop
    accumulate(page.items)
    if body_token_endpoint:
        token = page.next_page_token
        if not token: break
    else:                              # activities: bare array, no token
        if len(page.items) < page_size: break
        token = page.items[-1].id

5. 超时与批次大小

  • 始终设置 HTTP 超时(15–30s 是合理的起始值,并非 Alpaca 给出的数值)。连接卡住且未设置超时,会阻塞整个工作线程池。(SSE 流是例外——它们本就应保持打开状态;参见 alpaca-broker-sse-events。)
  • 使用共享 HTTP 客户端/连接池,而不是每次请求都创建一个,这样才能使用 keep-alive 并复用连接。
  • **检测市场数据 WebSocket 是否静默,并重新连接和重新订阅。**运行缓慢的客户端会被断开连接,而且 407 slow client 错误“无法保证在断开连接前送达”——因此,已失效的套接字看起来可能与安静的套接字完全相同(参见 alpaca-broker-market-data)。
  • 将对账结果写入自有存储时,应将批量插入拆分成多个块,以避免超出数据库语句大小限制,并确保事务规模合理;应根据自有数据库的表现选择块大小。

6. 批处理/定时任务的弹性检查清单

  • 每次响应都解析限流标头;接近限额时主动发出警告。
  • 遇到 429 → 等待至 X-RateLimit-Reset 指定时间,并额外留出缓冲时间。
  • 对 5xx/网络错误采用带抖动的指数退避;限制延迟时间和尝试次数。
  • 显示不可重试的 4xx 错误,不要重试。
  • 使用有界工作线程池;在每次运行期间缓存重复读取的数据。
  • 持续翻页,直到令牌为空。
  • 每次调用都设置 HTTP 超时;使用共享客户端。
  • 对批量数据库写入进行分块,并确保幂等性(upsert)——参见 alpaca-broker-reconciliation-idempotency。
  • 使用结构化日志,并为每个条目记录跟踪/关联 ID,以便调试部分失败。

**相关技能:**安全地重新运行任务 → alpaca-broker-reconciliation-idempotency;采用这些模式的修复/轮询任务 → alpaca-broker-reconciliation-idempotency;市场数据分页详情 → alpaca-broker-market-data。

评论

支持 Markdown