服务新版本更新后grpc接口报错 did not read entire message
原因
原来是服务提供方的proto文件有修改,修改了一个接口的入参message结构,增加了一个参数,更新proto文件重新生成protobuf即可
然而,处理完后又有服务出现了新的错误grpc: error unmarshalling request: string field contains invalid UTF-8
如报错所示,字段类型定义与实际使用时的类型不对,再观察,居然是调整了message参数的序号,形如:
message B {
int32 foo = 1;
int32 bar = 2;
}
message A {
...
string arg5 = 5;
repeated B arg6 = 6;
}
被改为了
···
message A {
…
string arg5 = 5;
string arg7 = 6;
repeated B arg6 = 7;
}
···
即修改且重复使用了字段的序号
解决方法
proto3的规范也是改来改去,来回横跳,具体还是要根据当前使用版本确定如何使用
比如 optional,v3.0.0
时被移除,v3.12.0
被重新引入但需要手动启用,同时v3.15.0
时已经可以像proto2一样直接使用
为了确保proto文件能向前向后有较好的兼容性,proto文件要遵循一些基本规则:
- 序号必需是唯一的,可以不连续,尽量是递增的
- 禁止修改已有字段的序号
- 尽量不使用 required,default(proto3已废弃,见参考链接)
同样,更新proto文件时同样有些主要事项注意:
- 可以新增接口,但老系统无法响应
- 可以新增字段,前提是已有字段序号不能改变
- 老系统序列化后的数据可以被新格式解析,但需要自行处理缺省值
- 老系统也可以解析新格式的序列号数据,但新增字段被丢弃
- 字段可以被移除,但最好通过
reserved
字段标记序号被保留或给字段添加OBSOLETE_
前缀进行标记 - int32, uint32, int64, uint64 和 bool类型都是兼容的
- string 和 bytes兼容,如果 bytes 是合法的UTF-8 bytes的话