You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Protobuf Any类型UnmarshalNew报错‘proto: not found’的解决方法

问题描述

我有一个使用Any类型的Protobuf API,定义如下:

message Document {
    DocumentMeta meta = 1;
    bytes data = 2;
    google.protobuf.Any details = 3;
}

客户端创建Dog消息并序列化为details字段:

dog1 := events2.Dog{
    Name: "Leo",
    Id:   1,
}
var dst anypb.Any
err = anypb.MarshalFrom(&dst, &dog1, proto.MarshalOptions{})

服务端已复制包含Dog定义的.pb文件并生成对应的Go文件,打印Document时能看到正确信息:

Any:type_url:"type.googleapis.com/com.test.eventbus.pb.events.Dog" value:"\n\x03Leo\x10\x01"

但服务端使用anypb.UnmarshalNew反序列化时未指定具体类型(需支持客户端动态传入启动时未定义的消息类型),代码如下:

basicDog, err := anypb.UnmarshalNew(doc.GetDetails(), proto.UnmarshalOptions{})

此时报错proto: not found。客户端会生成新的proto文件及对应的Go文件并复制到服务端,请问如何在服务端使用这些文件完成Any类型的反序列化?

解决方案

要实现动态反序列化google.protobuf.Any类型,核心是让Protobuf的类型注册表能识别客户端传入的新消息类型,具体步骤如下:

1. 确保生成的Go代码自动注册类型

用protoc-gen-go生成Go代码时,默认会在init()函数中将消息类型注册到全局类型注册表。检查生成的dog.pb.go文件,确认存在类似以下的注册逻辑:

func init() {
    proto.RegisterType((*Dog)(nil), "com.test.eventbus.pb.events.Dog")
}

如果没有,重新执行生成命令确保参数正确:

protoc --go_out=. --go_opt=paths=source_relative your_proto_file.proto

2. 处理运行时新增的消息类型

如果客户端是在服务端启动后才推送新的Go文件,有两种处理方式:

  • 编译为Go插件动态加载:将新增的消息类型编译成.so插件文件,服务端运行时加载插件,插件的init()函数会自动注册类型到全局注册表。
    编译插件命令:
    go build -buildmode=plugin -o dog_plugin.so dog.pb.go
    
    服务端加载插件代码:
    plugin, err := plugin.Open("dog_plugin.so")
    if err != nil {
        // 处理加载错误
    }
    // 插件加载完成后,类型已自动注册
    
  • 重启服务加载新代码:若允许服务重启,将新Go文件放入服务端代码目录后,重新编译启动服务,新类型的init()函数会执行并完成注册。

3. 完成反序列化

类型注册后,直接使用anypb.UnmarshalNew即可完成动态反序列化。如果需要更精细化的类型管理,也可以自定义类型注册表:

// 创建自定义注册表并添加目标类型
reg := proto.NewRegistry()
reg.RegisterType((*events2.Dog)(nil), "com.test.eventbus.pb.events.Dog")

// 使用自定义注册表反序列化
opts := proto.UnmarshalOptions{
    Registry: reg,
}
basicDog, err := anypb.UnmarshalNew(doc.GetDetails(), opts)

核心原理

google.protobuf.Any的反序列化依赖Protobuf类型注册表,type_url中的类型名称必须与注册表中注册的完全匹配(包含完整包名)。只有类型被成功注册后,UnmarshalNew才能通过type_url找到对应的消息类型,完成反序列化。

内容的提问来源于stack exchange,提问作者uzumas

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.21 22:15:36