Skip to main content

路由

Arc 使用两层路由架构:
  • 快速路径:无分配 radix 树(arc-router)在热路径把原始 URL 映射到 route ID。
  • 完整匹配:多维路由器(arc-core)进一步按 host、method、header、cookie、query 条件决策最终路由。

路径模式

匹配前会去掉 query string 和 fragment。路由匹配复杂度 O(log n),且不需要加锁。

匹配谓词

除路径外,还可以按以下维度匹配:
路由上的谓词是“全部满足”关系。命中顺序上,第一个匹配成功的路由会生效。

路由优先级

优先级规则如下:
  1. 精确路径优先于通配路径
  2. 长路径优先于短路径
  3. 更具体的段匹配优先于深通配
  4. 同一优先级下,按声明顺序决定

请求重写

在转发前重写 URL:

Header 变更

转发到上游前可增加、覆盖或移除 Header:

重定向

无需访问上游,直接返回重定向:

重试策略

自动重试失败的上游请求:

流量镜像

流量镜像会把请求副本(全量或采样)发送到影子上游。主请求路径不会被镜像阻塞,镜像任务以 fire-and-forget 方式入队。

基础镜像

高级镜像(采样 + 差异比对)

全局镜像策略

可设置镜像任务内存预算:
超过 max_queue_bytes 时,新镜像任务会直接丢弃,主请求不受影响。

镜像内部流程

  1. 主请求收到上游响应后,调用 submit_all 提交镜像目标
  2. 每个目标执行:采样判断(无锁 PRNG)→ 内存预留(CAS)→ 非阻塞入队
  3. 如果队列锁竞争,任务会直接丢弃,调用方不会阻塞
  4. worker 线程消费任务并执行:请求变换 → 建连 → 收发 → 可选比对
镜像连接统一使用 Connection: close,避免影子连接长期挂起。

相关指标


流量分流

按权重把流量分配到多个上游:
分流使用配置 key 做一致性哈希,因此同一客户端在多次请求中会稳定落到同一上游。

插件

Arc 支持 WASM 与 Rhai 插件,可在请求生命周期指定阶段执行。

WASM 插件

WASM 插件是从磁盘加载的 WebAssembly 模块。Arc 使用 Wasmtime + epoch 超时机制约束单次调用 CPU 预算:
on_request ABI 会接收请求方法和路径,返回值决定处理结果:

Rhai 脚本

Rhai 脚本可内联编写,并通过最大操作数做限制:

绑定插件到路由

同一路由同一阶段的多个插件会按声明顺序执行。 可用阶段:

插件隔离

每个 worker 拥有独立的 Wasmtime 实例池,插件实例不会跨 worker 共享。WASM 执行超过 budget 会被中断,并返回 500。插件内部 panic 会被捕获并计数。

故障排查

Arc 按具体性排序:精确路径优先于通配,长路径优先于短路径。若多个路由同时满足,会选择更具体的一条。建议给每条路由配置 name,并通过 /metricsarc_route_requests_total{route="..."} 观察实际命中;也可以调用 control plane 的 GET /v1/config 检查编译后的路由顺序。
请确认使用 {param} 语法(例如 /users/{id})。重写规则中可通过 $param 取值。* 是通配,不会捕获变量;尾部捕获请用 {*rest}
重点检查 rate_limit.key。默认 client_ip 是按 IP 单独限流。如果需要全局共享桶,可使用 key: { by: route } 或多行写法 key:\n by: route。同时可适当提高 burst 吸收短时突发。
查看 /metricsarc_mirror_queue_full_total。如果该值增长,说明镜像队列(默认 50MB)已满,可降低 sample 或提高 max_queue_bytes。若 arc_mirror_upstream_error_total 增长,说明镜像上游不可达。
权重是相对值,不是百分比。[{upstream: a, weight: 1}, {upstream: b, weight: 3}] 表示 25%/75%。分流在小样本下会有抖动,样本足够大才会收敛。
单次执行受 plugins.wasm[].budget 限制。若业务逻辑确实更重,请提高预算。可通过 /metricsarc_plugin_timeout_total 确认是否为预算超时导致。