Aptos Indexer GRPC Data Service 部署与配置指南:从 YAML 配置、TLS/非 TLS 双端点到 HTTP2 保活与 gRPC Web UI 调试
2026/9/17 5:33:26 网站建设 项目流程

Aptos Indexer GRPC Data Service 部署与配置指南:从 YAML 配置、TLS/非 TLS 双端点到 HTTP2 保活与 gRPC Web UI 调试

【免费下载链接】aptos-coreAptos is a layer 1 blockchain built to support the widespread use of blockchain through better technology and user experience.项目地址: https://gitcode.com/GitHub_Trending/ap/aptos-core

Indexer GRPC data service 是 Aptos Indexer GRPC 体系中面向下游索引器(indexer)提供链上交易流数据的 gRPC 服务,它同时从内存缓存(Redis/InMemory Cache)与冷存储文件库(GCS file store)读取数据,以流式方式持续推送交易。本文基于 ecosystem/indexer-grpc/indexer-grpc-data-service/README.md 及其源码,完整讲解该服务的 YAML 配置逐项语义、GCS 服务账号与启动方式、TLS 与非 TLS 双端点设计、HTTP2 ping 长连接保活机制,以及如何使用 grpcui 在浏览器中调试流式接口,并辅以源码级原理剖析,帮助你快速上手部署与排查。

服务定位:连接"缓存 + 文件库"的数据出口

在整个 Indexer GRPC 生产链路中,data service 处于对外提供数据的出口位置。上游由 cache worker 负责将 fullnode 产生的交易写入 Redis 热缓存,file store worker 负责将数据落盘到 GCS 冷存储;data service 则以只读姿态同时消费这两层存储,为下游索引器提供统一的GetTransactions流式 gRPC 接口。这一点在服务自身描述中写得很明确:Indexer GRPC data service fetches data from both cache and file store(见 indexer-grpc-data-service/Cargo.toml)。

在生产环境中,整个 Indexer GRPC 的启动顺序为:fullnode → cache worker → file store worker → data service(参考 ecosystem/indexer-grpc/README.md 的 General Startup 一节),data service 需要依赖前序组件把数据准备好,尤其是 GCS 冷存储中必须有 file store 元数据(chain_id 等),服务才会真正开始对外提供服务。

前置条件与启动方式

服务账号与 bucket 权限

data service 需要读取 GCS bucket 中的归档交易,因此必须准备:

  1. 一个${file_store_bucket_name}具有read权限的服务账号 JSON 文件(例如xxx.json);
  2. 通过环境变量SERVICE_ACCOUNT指定该服务账号 JSON 文件的路径。

从 GCS file store 实现 可以看到,服务在初始化时会用该服务账号访问 bucket;上游 Indexer GRPC 总览文档也强调,若使用 GCS 文件操作器,服务账号应被授予Object Owner(读写每个文件)与Bucket Owner(校验 bucket 是否存在)两类角色。data service 本身只做读取,因此服务账号具备read权限即可满足其自身职责。

启动命令

服务通过统一的 server framework 启动,入口在 main.rs(解析命令行参数后调用ServerArgs::run::<IndexerGrpcDataServiceConfig>()),启动命令为:

cargo run --release -- -c config.yaml

其中-c指定 YAML 配置文件路径。main.rs在 Unix 平台下还会启用 jemalloc 作为全局内存分配器,适合长时间运行的高吞吐服务。

YAML 配置详解

README 给出了一份可运行的 YAML 示例,逐字段说明如下:

health_check_port: 8083 server_config: whitelisted_auth_tokens: - "token1" - "token2" file_store_config: file_store_type: GcsFileStore gcs_file_store_bucket_name: indexer-grpc-file-store-bucketname data_service_grpc_tls_config: data_service_grpc_listen_address: 0.0.0.0:50052 cert_path: /path/to/cert.cert key_path: /path/to/key.pem data_service_grpc_non_tls_config: data_service_grpc_listen_address: 0.0.0.0:50051 redis_read_replica_address: 127.0.0.1:6379

各配置项在 config.rs 中有严格定义(#[serde(deny_unknown_fields)]意味着未知字段会导致启动报错,配置必须精确):

配置项类型必填说明
health_check_portu16健康检查端口,由 server framework 统一读取(见 server-framework/src/lib.rs),供负载均衡探活使用;多服务同机部署时各配置必须不同
server_config.whitelisted_auth_tokensVec<String>允许消费端点的 token 列表。从源码注释看该字段已标记为Deprecated(废弃),默认空列表
server_config.disable_auth_checkbool废弃字段:若设置则跳过鉴权检查,默认false
server_config.file_store_config枚举交易归档的冷存储配置,file_store_type支持GcsFileStoreLocalFileStore两种
server_config.data_service_grpc_tls_config对象二者至少其一TLS 端点(https)配置,含监听地址、证书与私钥路径
server_config.data_service_grpc_non_tls_config对象二者至少其一非 TLS 端点(http)配置,仅含监听地址
server_config.redis_read_replica_addressRedisUrlRedis 只读副本地址,data service 从该 Redis 读取热缓存
server_config.data_service_response_channel_sizeusize响应 channel 缓冲大小,默认3(见DEFAULT_MAX_RESPONSE_CHANNEL_SIZE
server_config.enable_cache_compressionbool是否读取压缩缓存数据,默认false(对应Base64UncompressedProto格式)
server_config.in_memory_cache_config对象内存缓存配置,默认空配置
server_config.txns_to_strip_filter过滤表达式命中过滤条件的交易会被"剥离"(清除 payload、签名、事件与 writeset 后仍下发给客户端),默认空 OR 过滤(不剥离任何交易),仅用于紧急情况

其中 TLS 与非 TLS 配置在validate()中有一个强制约束:二者至少配置其一,否则直接报错拒绝启动:

if self.data_service_grpc_non_tls_config.is_none() && self.data_service_grpc_tls_config.is_none() { bail!("At least one of data_service_grpc_non_tls_config and data_service_grpc_tls_config must be set"); }

file_store_config 的两种形态

file_store_type通过 serde tag 方式区分(见 indexer-grpc-utils/src/config.rs):

  • GcsFileStore(生产推荐)
    file_store_config: file_store_type: GcsFileStore gcs_file_store_bucket_name: indexer-grpc-file-store-bucketname # 可选:gcs_file_store_bucket_sub_dir: <子目录> # 可选:enable_compression: false

    GCS 冷存储适合生产环境长期归档;README 的总览文档指出生产环境当前依赖 GCS bucket 做冷存储,因此最宜在 GCP 上运行。

  • LocalFileStore(本地调试)
    file_store_config: file_store_type: LocalFileStore local_file_store_path: test_indexer_grpc_filestore

    本地目录即冷存储,适合单机联调,不需要云 bucket 与服务账号。

TLS 与非 TLS 双端点设计

README 专门解释了两个端点的关系:

  • data_service_grpc_tls_config:TLS 加密的 gRPC 端点(https),可以只暴露 TLS 端点
  • data_service_grpc_non_tls_config:无加密的 gRPC 端点(http),也可以只暴露非 TLS 端点

两者采用"非互斥"(non mutual-exclusive)方式引入,是为了避免客户端兼容性问题——在迁移/混合部署阶段,允许服务同时监听两个端口,让不同能力(是否支持 TLS)的客户端各自选择接入。从源码看,两个端点由两个独立 tokio 任务分别拉起,TLS 端会从cert_path/key_path读取 PEM 证书并构造tonic::Identity,两个端点都会注册 gRPC reflection 服务与相同的RawDataServer实现(见 config.rs)。

HTTP2-ping 长连接保活机制

长时间运行的流式连接容易遭遇网络静默中断,README 为此引入HTTP2 ping 主动探测来检测连接是否断开:

  • HTTP2_PING_INTERVAL_DURATION:HTTP2 ping 发送间隔常量,默认 60s
  • HTTP2_PING_TIMEOUT_DURATION:HTTP2 ping 超时常量,默认 10s

两个常量在 config.rs 中硬编码,并在启动 gRPC server 时通过tonic的 builder 生效:

Server::builder() .http2_keepalive_interval(Some(HTTP2_PING_INTERVAL_DURATION)) .http2_keepalive_timeout(Some(HTTP2_PING_TIMEOUT_DURATION)) .add_service(svc_clone) .add_service(reflection_service_clone) .serve(listen_address)

这套机制可以帮助服务端主动"垃圾回收"死连接(garbage collect dead connections),从而及时释放资源。

重要限制:HTTP2 ping 需要链路各层代理都支持 HTTP2 ping 帧。README 明确指出AWS/ALB 等代理可能不支持该特性(因为 ping 帧经过 ALB 时无法透传,导致保活失效),因此在 ALB 之后的部署中需要自行评估健康检查与连接保活方案。

用 grpcui Web UI 调试服务

对于流式接口的日常调试,README 推荐使用grpcui图形化工具。

安装(以 Mac 为例)

brew install grpcui

启动服务

cargo run --release -- -c config.yaml

打开 Web UI

grpcui -plaintext 127.0.0.1:50052

注意:

  • 这里使用的端口必须与配置文件中data_service_grpc_listen_address的端口保持一致
  • -plaintext表示以非 TLS 方式连接,因此该地址应对应data_service_grpc_non_tls_config.data_service_grpc_listen_address(示例中为0.0.0.0:50051)。若该配置被省略、只启用了 TLS 端点,则需要改用 TLS 连接参数并指向 TLS 端口;
  • 由于服务注册了 gRPC reflection,grpcui 可以自动发现aptos.indexer.v1.RawData/GetTransactions等接口并进行流式调用,无需手动指定 proto 文件。

数据读取路径与流式服务原理

结合源码可以更深入地理解 data service 的内部工作方式(核心逻辑位于 service.rs):

双路数据读取:缓存优先、冷存储兜底

get_transactions是流式(server-streaming)gRPC 接口,每个请求都会 spawn 一个data_fetcher_task异步任务,按以下顺序取数:

  1. InMemoryCache 优先:先用内存缓存直接命中一段交易(in_memory_cache.get_transactions(start_version)),命中即返回;
  2. Redis 热缓存:内存未命中则通过CacheOperator批量读取 Redis 中编码的 proto 数据,命中后经spawn_blocking解码(Base64UncompressedProtoLz4CompressedProto,由enable_cache_compression决定)后返回;
  3. File store 冷存储兜底:若 Redis 中的该段数据已被驱逐(CacheEvicted),则回源到 GCS/Local file store 读取,最多重试NUM_DATA_FETCH_RETRIES = 5次。

关键健壮性设计

  • 数据未就绪(AheadOfCache):当请求的版本超出缓存当前头部时,任务休眠AHEAD_OF_CACHE_RETRY_SLEEP_DURATION_MS = 50ms后重试,等待数据追平;
  • 瞬时错误重试:缓存/file store 读取出错时休眠TRANSIENT_DATA_ERROR_RETRY_SLEEP_DURATION_MS = 1000ms后重试;
  • 多任务并行取数:数据被驱逐出缓存时,按每 1000 笔交易一个存储块切分,最多MAX_FETCH_TASKS_PER_REQUEST = 5个任务并行回源;
  • 顺序与去重ensure_sequential_transactions会按版本排序多个批次,合并重叠区间、对完全包含的批次去重,并在发现版本间隙时直接panic,保证下游拿到的数据严格连续;对应的单元测试(test_ensure_sequential_transactions_merges_and_sorts)覆盖了无重叠、完全重叠与部分重叠三种场景(见 service.rs);
  • 慢客户端保护:响应 channel 发送超时为RESPONSE_CHANNEL_SEND_TIMEOUT = 120s,防止慢消费者长期占住服务端任务;连接时长不足 10s 会被计入短连接指标;
  • chain_id 校验:启动取数任务时,会同时读取 file store 元数据与 Redis 中的 chain_id 并比对,不一致时直接返回Chain ID mismatch错误;
  • 交易剥离(stripping):命中txns_to_strip_filter的交易会被清空 payload、签名、events 与 writeset(保留交易骨架与版本号)后再下发,用于应对特定模块交易过大导致的紧急场景;service.rs 中以 sender 地址、module 地址、module 名、函数名为条件的剥离测试均验证了该行为。

可观测性

服务内置 Prometheus 指标(见 metrics.rs 与 service.rs 中的埋点),包括但不限于:

  • CONNECTION_COUNT:接入的连接数;
  • SHORT_CONNECTION_COUNT:短连接(<10s)计数;
  • ERROR_COUNT:按data_fetch_failed/redis_connection_failed/redis_get_chain_id_failed等标签区分的错误计数;
  • LATEST_PROCESSED_VERSION_PER_PROCESSOR/PROCESSED_VERSIONS_COUNT_PER_PROCESSOR/PROCESSED_LATENCY_IN_SECS_PER_PROCESSOR:按处理器维度统计的已处理版本水位、数量与数据延迟;
  • BYTES_READY_TO_TRANSFER_FROM_SERVER/BYTES_READY_TO_TRANSFER_FROM_SERVER_AFTER_STRIPPING:剥离前后的待传输字节量;
  • NUM_TRANSACTIONS_STRIPPED:被剥离交易数。

这些指标配合health_check_port的探活端点,可用于监控大盘与告警配置(仓库的 dashboards 目录中也包含 Indexer GRPC 相关面板定义)。

小结

Indexer GRPC data service 是 Aptos 链上数据低延迟索引出口的关键一环:它通过"内存缓存 → Redis 热缓存 → GCS/本地冷存储"三级读取路径,以流式 gRPC 持续向索引器输送严格有序的交易数据;通过 TLS/非 TLS 双端点设计兼顾安全与兼容,通过 HTTP2 ping 保活主动清理死连接,并通过多级重试、慢客户端保护与交易剥离机制保障生产可用性。部署时只需按本文的 YAML 结构准备好服务账号、bucket、Redis 与配置文件,执行cargo run --release -- -c config.yaml即可启动;调试时借助 grpcui 与内置 reflection 即可快速验证流式接口的行为。

【免费下载链接】aptos-coreAptos is a layer 1 blockchain built to support the widespread use of blockchain through better technology and user experience.项目地址: https://gitcode.com/GitHub_Trending/ap/aptos-core

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询