最近在项目中遇到了一个奇怪的 coredump 问题,排查过程并不顺利。经过不断分析,找到了一个复现的步骤,经过合理猜测和谨慎验证,最终才定位到原因。
复盘下来,发现这类 coredump 问题确实比较罕见,排查起来也不是很容易。只有项目代码编译依赖管理不是很合理的时候,才可能出现。另外,在复盘过程中,对这里的 coredump 以及 C++ 对象内存分布也有了更多理解。于是整理一篇文章,如有错误,欢迎指正。
某次变更,在服务 A 的 service.proto
文件中,对某个 rpc 请求参数增加了一个字段(比如下面的 age):
service Greeter {
rpc SayHello (HelloRequest) returns (HelloReply) {}
}
message HelloRequest {
string name = 1;
string age = 2; // 增加了参数
}
message HelloReply {
string message = 1;
}
然后增加了这个字段的相关逻辑,随后编译上线了该模块。我们知道在微服务架构中,经常有多个服务共用同一个 proto 对象。如果要修改 proto 的话,一般都是增加字段,这样对调用方和被调用方都是兼容的。这里服务 A 上线后,用新的 proto ,其他用到这个 proto 的服务在重新编译前都会用老的版本,这样不会有问题。其实严格来说这样也是可能有问题的,之前踩过坑,主要是 Merge 的兼容问题,可以参考我之前的文章 Protobuf 序列化消息引起的存储失败问题分析。
正常来说,如果其他服务想更新 proto ,只需要重新编译就能用到新的 proto ,肯定不会有问题。不过这次就出问题了,服务 A 的 proto 增加字段上线后,其他通过 client 调用 A 的服务,只要重新编译上线,就会 coredump。
这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。
V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。
V2EX is a community of developers, designers and creative people.