news 2026/9/20 4:45:45

Jina 内部通信协议详解:DataRequest 消息模型与 gRPC 服务接口规范

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Jina 内部通信协议详解:DataRequest 消息模型与 gRPC 服务接口规范

Jina 内部通信协议详解:DataRequest 消息模型与 gRPC 服务接口规范

【免费下载链接】jina☁️ Build multimodal AI applications with cloud-native stack项目地址: https://gitcode.com/gh_mirrors/ji/jina

本指南以 docs/proto/docs.md 生成的 Protocol Buffer 文档为主体,结合仓库源码剖析 Jina 在 Gateway、Executor、Deployment 之间传递请求所依赖的消息定义与 RPC 服务。读完本文,你将完整掌握DataRequestProtoHeaderProtoStatusProtoRouteProto等核心消息的字段语义,理解docs/docs_bytes的序列化分流机制,并能对照源码看懂JinaRPCJinaDataRequestRPC等服务在 jina.proto 与 grpc.py 中的落地实现。

一、协议文档概览:Jina 的通信基石

Jina 是一个以云原生方式构建多模态 AI 应用的框架,Gateway 与 Executor 之间、客户端与 Flow 之间都通过 gRPC 通信,而通信的"语言"就是由 Protobuf 定义的消息结构与服务接口。docs/proto/docs.md 是直接从.proto源文件生成并嵌入文档站的协议参考手册,包含三部分内容:

  • docarray.proto:声明文档数组(DocumentArray)的载体消息DocumentArrayProto
  • jina.proto:Jina 自己的请求/响应消息(DataRequestProto等)以及全部 gRPC 服务;
  • Scalar Value Types:Protobuf 标量类型与各语言类型的映射表。

其中jina.proto是绝对核心,它定义了 Flow 内部"请求在路由上如何被包装、如何携带文档数据、如何记录每个环节的执行状态"。仓库根目录下同时维护了两份同源 proto:docarray_v1/jina.proto 与 docarray_v2/jina.proto,区别仅在与 DocArray 版本兼容性(v1 兼容 DocArray <0.30,v2 兼容 DocArray >=0.30),消息与服务的定义保持一致。

二、核心消息类型逐字段解析

2.1 DataRequestProto:请求的统一载体

DataRequestProto是贯穿 Jina 全链路的最重要消息,客户端发来的文档数组、Executor 执行的参数、路由上的状态信息都被打包进这一个结构:

字段类型Label说明
headerHeaderProtoheader 中包含用户请求定义的元信息
parametersgoogle.protobuf.Struct传给 Executor 的额外 kwargs
routesRouteProtorepeated每个路由节点上的状态信息
dataDataRequestProto.DataContentProto承载 docs 与 groundtruths 的容器

对应的 proto 源码位于 docarray_v2/jina.proto。在 Python 侧,types/request/data.py 中的DataRequest类为它提供了惰性反序列化包装:只有当首次访问data.docs等成员时才触发 protobuf 解析,同时支持从DataRequestProtodictstr(JSON)、bytes四种来源构造请求对象,构造失败会抛出BadRequestType

2.2 HeaderProto:请求元信息与信封机制

HeaderProto描述的是请求的"信封",其生命周期注释清晰地说明了它在 Flow 中的流转规则:

  • Header 的内容由用户请求定义;
  • 会被拷贝到 envelope.header(信封头);
  • Flow 内部操作会修改 envelope.header;
  • 返回时再把 envelope.header 拷贝回 request.header。
字段类型Label说明
request_idstring请求的唯一 ID,相同 ID 的多个请求会被聚合
statusStatusProto状态信息
exec_endpointstringoptional@requests(on='/abc')指定的端点
target_executorstringoptional若设置,请求定向到指定 executor,支持正则字符串
timeoutuint32optional以 epoch 秒计的截止时间,超时后请求应被丢弃

源码见 docarray_v2/jina.proto。target_executor支持正则匹配,是 Jina 实现"请求定向路由"的底层机制。

2.3 StatusProto 与 ExceptionProto:错误传播

StatusProto用于表示一次执行的状态,内部包含状态码枚举与异常详情:

字段类型Label说明
codeStatusProto.StatusCode状态码
descriptionstring首个异常的 error 描述
exceptionStatusProto.ExceptionProto错误详情

StatusCode枚举只有两个取值:SUCCESS = 0ERROR = 1。当发生错误时,ExceptionProto记录完整异常信息:

字段类型Label说明
namestring异常类名
argsstringrepeated传给异常构造函数的参数列表
stacksstringrepeated异常 traceback 栈
executorstring绑定该异常的 Executor 名称(如适用)

在 types/request/init.py 中可以看到这套结构的实际写入逻辑:Request.add_exception()会把异常类名、参数、traceback 栈以及executor.__class__.__name__依次填入header.status,并将code置为ERROR

2.4 RouteProto:路由链路与耗时度量

RouteProto记录消息在 Gateway 视角下的路由路径,其注释给出了关键的时间语义:

start_time在 Gateway 向 Pod 发送消息时设置;end_time在 Gateway 从 Pod 收到消息时设置;因此end_time - start_time包含了 Executor 计算、运行时开销、序列化与网络耗时。

字段类型Label说明
executorstringBasePod 的名称
start_timegoogle.protobuf.TimestampGateway 开始向 Pod 发送的时间
end_timegoogle.protobuf.TimestampGateway 从 Pod 收到消息的时间
statusStatusProto执行状态

由于routesDataRequestProto中是 repeated 字段,一条请求经过多个 Executor 时会累积出完整的路由链路,这也是 Jina 做端到端链路追踪与耗时拆分的原始数据来源。

2.5 EndpointsProto:Executor 能力暴露

EndpointsProto表示 Executor 暴露的一组端点,用于服务发现场景:

字段类型Label说明
endpointsstringrepeatedExecutor 暴露的端点列表

(在 docarray_v2/jina.proto 中该消息还扩展了write_endpoints与按端点记录的输入/输出schemas字段。)

2.6 其余辅助消息

  • JinaInfoProto:携带运行中的系统信息与包版本信息(jinamap)以及环境变量设置(envsmap),由JinaInfoRPC._status方法返回,用于jina ping等健康/信息探测。
  • RelatedEntity:表示一个实体(如 ExecutorRuntime),字段为id(如 pod 名称)、address(IP 或域名,不含端口)、portshard_id(可选,所属分片 ID)。
  • DataRequestProtoWoDataDataRequestProto去掉data字段的轻量版本(保留headerparametersroutes),用于不需要携带文档数据的场景。
  • DataRequestListProto:请求列表,注释明确说明"应当被流式取代"(This should be replaced by streaming),requests为 repeated 的DataRequestProto
  • DocumentArrayProto:定义在docarray.proto中,注释指出它只是"来自 jina._docarray 依赖的占位文件"——真正完整的 DocList/Document 定义由 DocArray 库提供。

三、data 字段的双通道设计:docs 与 docs_bytes

DataRequestProto.DataContentProto使用oneof documents同时声明两个互斥通道:

字段类型说明
docsdocarray.DocumentArrayProto请求中的文档数组(结构化 protobuf)
docs_bytesbytes请求中的文档数组(原始字节)

这是 Jina 针对大数据量传输做的重要优化:文档以 bytes 形式传递时,接收方无需先反序列化整个 protobuf 再读取文档,而是按需、惰性加载。对应逻辑在 types/request/data.py 中:docs属性在首次访问时才检查WhichOneof('documents'),若为docs_bytes则调用DocumentArray.from_bytes(),否则调用from_protobuf()完成反序列化。

四、gRPC 服务定义与源码落地

jina.proto定义了 7 个核心服务,docs.md 中记录了它们的完整方法签名:

服务方法请求类型响应类型说明
JinaRPCCallDataRequestProto(stream)DataRequestProto(stream)流式服务:传入请求,返回带 matches 的请求
JinaDataRequestRPCprocess_dataDataRequestListProtoDataRequestProto向 Executor 传递请求列表
JinaSingleDataRequestRPCprocess_single_dataDataRequestProtoDataRequestProto无需列表时向 Executor 发送单个请求
JinaDiscoverEndpointsRPCendpoint_discoverygoogle.protobuf.EmptyEndpointsProto暴露 Executor 的端点
JinaGatewayDryRunRPCdry_rungoogle.protobuf.EmptyStatusProtoGateway 干跑(连通性验证)
JinaInfoRPC_statusgoogle.protobuf.EmptyJinaInfoProto暴露运行中的 jina 版本与环境信息

服务实现在 serve/runtimes/servers/grpc.py 中有清晰对应:GRPCServer.setup_server()启动grpc.aio.server后,会按 request handler 是否具备相应方法(process_datadry_runendpoint_discoverysnapshot等),把对应 Servicer 逐个注册到同一 gRPC 端口,并启用 gRPC reflection 服务。各方法的具体实现分散于:

  • Gateway 侧:serve/runtimes/gateway/request_handling.py(dry_run_statusendpoint_discoverystream_docprocess_single_data);
  • Worker(Executor)侧:serve/runtimes/worker/request_handling.py(process_dataprocess_single_datastream_docsnapshotrestore等);
  • Head 侧:serve/runtimes/head/request_handling.py(process_dataendpoint_discovery_status)。

docs.md 收录的 7 个服务之外,docarray_v2/jina.proto 还定义了快照/恢复相关的一族服务(JinaExecutorSnapshotJinaExecutorSnapshotProgressJinaExecutorRestoreJinaExecutorRestoreProgressSingleDocumentRequestProto等),这些属于较新的能力扩展。

五、自定义 Serializer:让 gRPC 直接收发 DataRequest

proto/serializer.py 为 gRPC 提供了替代默认序列化器的实现,使线上直接以DataRequest业务对象收发消息。其要点包括:

  • DataRequestProto.SerializeToString/FromString:未解压时直接取内部 buffer,否则SerializePartialToString;同时通过JINA_GRPC_SEND_BYTES/JINA_GRPC_RECV_BYTES环境变量累积统计收发字节数(供监控指标使用);
  • DataRequestListProto.SerializeToString:既能序列化单个DataRequest,也能序列化请求列表,统一打包成DataRequestListProto,从而对上层隐藏MessageListProto的细节;
  • EndpointsProtoStatusProtoJinaInfoProto等则作为占位类,直接委托内部 protobuf 结构完成序列化与反序列化。

六、标量值类型映射表

docs.md 末尾附带了完整的 Protobuf 标量类型与各语言类型对照表,在做跨语言 gRPC 客户端、或解读协议字段时可直接查阅:

| .proto 类型 | 说明 | C++ | Java | Python | Go | C# | PHP | Ruby | | ----------- | ----- | --- | ---- | ------ | -- | -- | --- | ---- | |double| | double | double | float | float64 | double | float | Float | |float| | float | float | float | float32 | float | float | Float | |int32| 变长编码;负数编码效率低,可能为负时改用sint32| int32 | int | int | int32 | int | integer | Bignum 或 Fixnum | |int64| 变长编码;负数编码效率低,可能为负时改用sint64| int64 | long | int/long | int64 | long | integer/string | Bignum | |uint32| 变长编码 | uint32 | int | int/long | uint32 | uint | integer | Bignum 或 Fixnum | |uint64| 变长编码 | uint64 | long | int/long | uint64 | ulong | integer/string | Bignum 或 Fixnum | |sint32| 变长编码的有符号值,对负数编码比 int32 更高效 | int32 | int | int | int32 | int | integer | Bignum 或 Fixnum | |sint64| 变长编码的有符号值,对负数编码比 int64 更高效 | int64 | long | int/long | int64 | long | integer/string | Bignum | |fixed32| 固定 4 字节;值常大于 2^28 时比 uint32 高效 | uint32 | int | int | uint32 | uint | integer | Bignum 或 Fixnum | |fixed64| 固定 8 字节;值常大于 2^56 时比 uint64 高效 | uint64 | long | int/long | uint64 | ulong | integer/string | Bignum | |sfixed32| 固定 4 字节 | int32 | int | int | int32 | int | integer | Bignum 或 Fixnum | |sfixed64| 固定 8 字节 | int64 | long | int/long | int64 | long | integer/string | Bignum | |bool| | bool | boolean | boolean | bool | bool | boolean | TrueClass/FalseClass | |string| 必须包含 UTF-8 编码或 7-bit ASCII 文本 | string | String | str/unicode | string | string | string | String (UTF-8) | |bytes| 可包含任意字节序列 | string | ByteString | str | []byte | ByteString | string | String (ASCII-8BIT) |

七、更新与重新生成协议

jina.protodocarray.proto属于"源文件",jina_pb2.pyjina_pb2_grpc.py等由它们生成。仓库通过 Docker 镜像完成代码生成,避免在本地环境安装多版本 protobuf 工具链:

  • 构建生成镜像(protobuf 3.21 之前的版本)与 3.21+ 版本分别使用 protogen.Dockerfile 和 protogen-3.21.Dockerfile;
  • 更新 DocArray v1 对应代码:docker run -it -v $(pwd)/jina/proto/docarray_v1:/jina/proto jinaai/protogen:local
  • 更新 DocArray >=0.30 对应代码:docker run -it -v $(pwd)/jina/proto/docarray_v2:/jina/proto jinaai/protogen:local

完整步骤见 proto/README.md,而 docs/proto/index.md 展示了如何在文档站中用{include} docs.md把生成的协议文档嵌入页面,同时在仓库根目录运行docker run -v $(pwd)/jina/:/jina/ jinaai/protogen即可一键更新jina的 Protobuf 代码。

结语

jina.proto是 Jina 分布式架构的"神经系统":DataRequestProto定义了请求的统一外形,HeaderProto/RouteProto/StatusProto负责元信息、链路追踪与错误传播,docs/docs_bytes双通道解决了大数据量文档的高效传输,而 7 个 gRPC 服务则支撑起客户端到 Gateway、Gateway 到 Executor 的完整调用链。理解这套协议,是深入阅读 Jina 网关、流式与状态管理等源码的起点。

【免费下载链接】jina☁️ Build multimodal AI applications with cloud-native stack项目地址: https://gitcode.com/gh_mirrors/ji/jina

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

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/20 4:44:46

具身智能从概念到工程落地:学习路线、技术栈与入局指南

发布会散场时&#xff0c;我站在展台旁边看一位工程师反复调试机械臂抓取动作&#xff0c;旁边屏幕上滚动播放着具身智能在工业分拣、家庭服务场景里的演示视频。这一幕放在三年前很难想象&#xff0c;那时候大家聊具身智能&#xff0c;还停留在“机器人能不能学会开个冰箱”的…

作者头像 李华
网站建设 2026/9/20 4:44:39

Codex CLI 接入 Kimi K3 实战:兼容层配置与502排错指南

把 Codex CLI 接到 Kimi K3&#xff0c;听起来是件小事&#xff0c;实际上一路踩下来全是坑。尤其是当你看到unexpected status 502 bad gateway: unknown error, url: http://127.0.0.1:15721/v1/responses这种报错的时候&#xff0c;会忍不住怀疑人生。这篇文章我就把这套“R…

作者头像 李华
网站建设 2026/9/20 4:43:22

Vue3 Suspense深入解析:异步组件与加载状态管理实战

很多人在试用 Vue3 的 Suspense 时&#xff0c;第一反应是“这不就是个 loading 组件吗”&#xff0c;结果一用就发现行为和自己想的不太一样&#xff0c;有些场景明明写了 fallback 却不显示&#xff0c;有些场景加载完了还在闪。这篇文章就专门聊清楚 Suspense 到底是什么、它…

作者头像 李华
网站建设 2026/9/20 4:43:17

基于App Inventor和GPS的课堂点名系统设计与实现

简介&#xff1a;这份PDF为一篇关于App Inventor结合GPS定位技术实现课堂自动点名系统的设计与实现论文&#xff0c;适合移动应用开发学习者、高校教师及教学管理研究者参考。论文分析了传统点名耗时且易代签的痛点&#xff0c;提出教师端与学生端双端口方案&#xff1a;教师端…

作者头像 李华
网站建设 2026/9/20 4:42:15

SAP销售范围报错排查:客户未定义与产品组被替换的解决之道

1. 这个报错在SAP里的真实身份&#xff1a;从错误信息到后台逻辑做SAP业务的人对这类报错多少都有点阴影&#xff0c;尤其是在月底冲销量、大批量建SO的时候突然冒出来一句&#xff1a;客户XXXX未对销售范围XXXX XX XX定义&#xff08;产品组被替换&#xff09;。很多人第一反应…

作者头像 李华