区块链中文技术社区

eRPC — 容错 evm rpc 代理

介绍

eRPC 是一种容错 EVM RPC 代理和永久缓存解决方案。它在构建时充分考虑了读取密集型用例,例如数据索引和高负载前端使用。

doc: https://docs.erpc.cloud/
github: https://github.com/erpc/erpc

为什么选择 eRPC?

以下是构建 eRPC 的主要原因:

特征

eRPC 可以在两个主要领域提供帮助:

与更传统的 LB 解决方案(ALB、K8S 服务等)相比,eRPC 将提供以 EVM 为中心的功能,例如:

缓存存储类型

  1. memory: 主要用于本地测试,或者不需要缓存太多数据
  2. redis:当您需要使用驱逐策略(例如一定量的内存)临时存储缓存数据时,Redis 很有用
  3. postgresql:当您需要永久存储缓存数据(无需 TTL,即永远)时很有用
  4. dynamodb:当您需要可扩展(与 Postgres 相比)的永久缓存并且更省存储成本

配置相关

配置实例

# 日志级别有助于调试或错误检测:
# - debug: 实际请求和响应的信息,以及有关速率限制的决策等.
# - info: 通常会打印成功路径,并且可能会对每个请求打印 1 个日志,以表明成功或失败.
# - warn: 这些问题不会导致最终用户出现问题,但可能表示数据降级或缓存数据库出现故障等问题.
# - error: 这些问题会对最终用户产生影响,例如配置错误.
logLevel: warn
 
# ERPC 中有各种数据库用例,例如缓存、动态配置、速率限制持久性等.
database:
  # `evmJsonRpcCache` 定义缓存 JSON-RPC 调用的目标,面向任何 EVM 架构上游.
  # 该数据库在关键路径上是非阻塞的,并且被用作尽力而为.
  # 确保存储要求满足你的使用情况,例如在 Arbitrum 上缓存 7000 万个区块 + 1000 万个交易 + 1000 万条记录需要 200GB 的存储空间.
  evmJsonRpcCache:
    # Refer to "Database" section for more details.
    # 请注意,如果表、模式和索引不存在,将自动创建.
    driver: postgresql
    postgresql:
      connectionUri: >-
        postgres://YOUR_USERNAME_HERE:YOUR_PASSWORD_HERE@your.postgres.hostname.here.com:5432/your_database_name
      table: rpc_cache
 
# eRPC 监听请求的主服务器.
server:
  listenV4: true
  httpHostV4: "0.0.0.0"
  listenV6: false
  httpHostV6: "[::]"
  httpPort: 4000
  maxTimeout: 30s
 
# 可选的 Prometheus 指标服务器.
metrics:
  enabled: true
  listenV4: true
  hostV4: "0.0.0.0"
  listenV6: false
  hostV6: "[::]"
  port: 4001
 
# 每个项目都是网络和上游的集合。
# 例如“后端”、“索引器”、“前端”,如果您只想使用 1 个项目,则可以将其命名为“main”
# 多个项目的主要目的是不同的故障安全策略(更积极且成本更高,或成本更低且更容易出错)
projects:
  - id: main
 
    # 您可以选择为每个项目定义一个自行设定的速率限制预算
    # 如果您想限制每秒的请求数或每日限额,这将非常有用。
    rateLimitBudget: frontend-budget
 
    # 此数组配置特定于网络(又称特定于链)的功能。
    # 对于每个网络,“架构”和相应的网络 ID(例如 evm.chainId)都是必需的。
    # 请记住,定义网络是可选的,因此仅当您想覆盖默认值时才提供这些。
    networks:
      - architecture: evm
        evm:
          chainId: 1
        # 有关更多详细信息,请参阅“故障安全”部分。
        # 在网络级别,“超时”适用于请求的整个生命周期(包括多次重试)
        failsafe:
          timeout:
            duration: 30s
          retry:
            maxCount: 3
            delay: 500ms
            backoffMaxDelay: 10s
            backoffFactor: 0.3
            jitter: 500ms
          # 强烈建议在网络级别定义“对冲”,因为如果上游 A 对某个特定请求的响应速度较慢,
          # 它可以向上游 B 启动一个新的并行对冲请求,以响应速度更快的一方为准。
          hedge:
            delay: 3000ms
            maxCount: 2
          circuitBreaker:
            failureThresholdCount: 30
            failureThresholdCapacity: 100
            halfOpenAfter: 60s
            successThresholdCount: 8
            successThresholdCapacity: 10
      - architecture: evm
        evm:
          chainId: 42161
        failsafe:
          timeout:
            duration: 30s
          retry:
            maxCount: 5
            delay: 500ms
            backoffMaxDelay: 10s
            backoffFactor: 0.3
            jitter: 200ms
          hedge:
            delay: 1000ms
            maxCount: 2
 
    # 每个上游支持 1 个或多个网络(chains)
    upstreams:
      - id: blastapi-chain-42161
        type: evm
        endpoint: https://arbitrum-one.blastapi.io/xxxxxxx-xxxxxx-xxxxxxx
        # 定义处理上游请求时使用哪个upstream
        rateLimitBudget: global-blast
        # chainId 是可选的,将从端点(eth_chainId)检测,但建议明确设置它,以便更快地初始化。
        evm:
          chainId: 42161
        # 哪些方法绝不能发送到上游:
        ignoreMethods:
          - "alchemy_*"
          - "eth_traceTransaction"
        # 请参阅“故障保护”部分以了解更多详细信息:
        failsafe:
          timeout:
            duration: 15s
          retry:
            maxCount: 2
            delay: 1000ms
            backoffMaxDelay: 10s
            backoffFactor: 0.3
            jitter: 500ms
      - id: blastapi-chain-1
        type: evm
        endpoint: https://eth-mainnet.blastapi.io/xxxxxxx-xxxxxx-xxxxxxx
        rateLimitBudget: global-blast
        evm:
          chainId: 1
        failsafe:
          timeout:
            duration: 15s
          retry:
            maxCount: 2
            delay: 1000ms
            backoffMaxDelay: 10s
            backoffFactor: 0.3
            jitter: 500ms
      - id: quiknode-chain-42161
        type: evm
        endpoint: https://xxxxxx-xxxxxx.arbitrum-mainnet.quiknode.pro/xxxxxxxxxxxxxxxxxxxxxxxx/
        rateLimitBudget: global-quicknode
        # 您可以禁用自动忽略不受支持的方法,而是明确定义它们.
        # 如果提供程序(例如 dRPC)与“不支持的方法”响应不一致,这将很有用.
        autoIgnoreUnsupportedMethods: false
        # 要允许自动批处理上游请求,请使用以下设置.
        # 请记住,如果“supportsBatch”为 false,您仍然可以向 eRPC 发送批量请求
        # 但它们将作为单独的请求发送到上游.
        jsonRpc:
          supportsBatch: true
          batchMaxSize: 10
          batchMaxWait: 100ms
        evm:
          chainId: 42161
        failsafe:
          timeout:
            duration: 15s
          retry:
            maxCount: 2
            delay: 1000ms
            backoffMaxDelay: 10s
            backoffFactor: 0.3
            jitter: 500ms
 
        # “id” 是区分日志和指标的唯一标识符.
      - id: alchemy-multi-chain-example
        # 对于某些已知提供商(例如 Alchemy),您可以使用自定义协议名称
        # 它允许单个上游导入该提供商支持的“所有链”。
        # 请注意,这些链在 repo 中是硬编码的,因此如果它们支持新的链,则必须更新 eRPC。
        endpoint: alchemy://XXXX_YOUR_ALCHEMY_API_KEY_HERE_XXXX
        rateLimitBudget: global
        failsafe:
          timeout:
            duration: 15s
          retry:
            maxCount: 2
            delay: 1000ms
            backoffMaxDelay: 10s
            backoffFactor: 0.3
            jitter: 500ms
 
# 速率限制器允许您为上游创建“共享”预算。
# 例如上游 A 和 B 可以使用相同的预算,这意味着它们两者加起来不得超过定义的限制。
rateLimiters:
  budgets:
    - id: default-budget
      rules:
        - method: "*"
          maxCount: 10000
          period: 1s
    - id: global-blast
      rules:
        - method: "*"
          maxCount: 1000
          period: 1s
    - id: global-quicknode
      rules:
        - method: "*"
          maxCount: 300
          period: 1s
    - id: frontend-budget
      rules:
        - method: "*"
          maxCount: 500
          period: 1s

部署测试

TODO

性能对比分析

TODO

当前页面是本站的「Google AMP」版。查看和发表评论请点击:完整版 »