关于RPC框架的思考

2020-10-18

Why RPC

对比 HTTP+JSON 的方案,使用成熟的 RPC 框架有何优势?如果只是想要简单的服务间通信功能,RPC 框架和 HTTP+JSON 并没有什么本质上的区别。至于常常提到的 RPC 更高效, protocol buffer 序列化格式传输数据量小之类的性能优势。不可否认在大公司,数据流量大的场景下抠这些性能是有意义的。但是扪心自问,自己的服务 QPS 有这么高吗?

那么在排除性能优势之后,还有什么使用 RPC 框架的理由呢?答案是:服务治理功能集成。

服务治理

服务治理是指在微服务架构下为了方便运维和保障服务稳定性所采取的一些手段,包括大家耳熟能祥的,熔断,限流,降级,tracing,monitor,log。HTTP+JSON 其实也能做这些,但是给原始的 HTTP+JSON 穿上这些衣服之后你就得到了一个自研的RPC框架。至于这个过程是重新发明轮子还是重新造轮子就不好说了。

自研 VS 开源

论证完采用 RPC 框架的必要性之后,再来谈谈自研还是开源的问题。上面提到的服务治理功能,可能暂时并不全部需要,或者说开源的 RPC 框架设计考虑的适用场景并不满足自己的需求。开源成熟的 RPC 框架为了尽可能的普适性不可避免的有其复杂性所在,学习使用都有成本,后期是否方便二次开发是个问题。比如 gRPC,到现在我都不太能接受它基于 HTTP/2,同时 Roadmap 里有太多和 Envoy+lstio 耦合的功能。

比较理想的是自研框架可以结合公司已有的基础设施,保持核心设计的简单性,慢慢往里面加自己想要的功能。这就涉及到 RPC 框架核心设计的扩展性,比如能否方便的加 tracing ID 集成分布式追踪系统,能否方便的加 context 做超时联动。

如果在设计之初并没有类似 header 的概念,业务服务函数接口并没有预留这些参数的位置,那么就很难传递下去。动态语言还可以通过 monkey patch 的魔法搞定,静态语言就只有thread local 这种隐式传递的方式,但是 thread local 是很容易坑的方式,如果调用链中存在异步,很容易出现没有传递下去或者串上下文的问题。成熟的框架都会预留这些可扩展的空间,已有的集成的功能也能满足很长一段时间的需求。

我是比较反对以自己场景的特殊性来造轮子,即使很特殊也可以给开源提 PR,不能总是白嫖社区嘛。如果是为了 KPI 就另说了。

生态红利

围绕在 gRPC 的生态,社区贡献了各种工具和 Gateway 等等,都是可以享受的开源红利。现在可能用不上,真的需要就可以节省很大力气。

总结

综上所述,采用成熟的 RPC 框架是省时省力的方案,里面凝结了社区大佬们的智慧结晶。借用炒股的一句话,「不要试图打败市场」。