【大厂文章学习】合并编译的学习与思考
【微信文章】字节跳动合并编译实践通过将微服务转换为本地函数调用的方式优化函数耗时和容器资源。
文章主要内容
合并编译是什么?解决了什么问题?有什么挑战?适用于哪些情况?
合并编译是什么: 就是将存在上下游依赖的服务由分开编译部署的方式,改成了合并编译部署。
解决了什么问题: 最大的优化来自于 远程调用rpc通过合并编译变成了本地function call后不存在序列化和反序列化的开销,因此可以节约中的容器资源,大部分是CPU资源上的节约。
主要挑战: 如图中所示:在带来CPU节约的同时,也带来了两个服务合并的弊端,比如说:服务隔离、版本管理、研发流程等上。 此外,由于将RPC改成本地function call需要在编译时生成并改写代码,因此只有部分框架的服务才支持,比如文中的kitex
框架。
适用于哪些情况:
合并编译主要解决微服务过微带来的性能问题,其收益公式如下
DownstreamQuota 指下游服务的资源申请量;MergeRatio 指合并的比例;Codec Ratio 指编解码的开销;ServiceGovernaceRatio 指服务治理的开销。
由收益公式可以看出合并编译应该聚焦于 「资源量大、调用关系密切、编解码开销大」 的服务,才能够拿到较大的收益。
此外,合并的同时不能影响业务稳定性,因此对于容器资源利用充分(CPU、内存、磁盘)的服务也不太适用!
思考
”微服务“的概念兴起之后,处于种种原因大家很喜欢将大服务拆分成”微服务“并且上云。天下大势合久必分、分久必合,在”微服务“流行起来之后,大家逐渐发现 微服务 没有想象中的那么美好,资源并没有那么节省、服务之间的拆分处理如何控制等等,因此目前也有了一些声音表示要将微服务回归单体,比如:微服务回归单体,代码行数减少75%,性能提升1300%-腾讯云开发者社区-腾讯云。
服务从单体迁移到微服务需要大量成本,从微服务迁移回单体也不是免费的, 合并编译为我们提供了一种思路:在业务开发的时候不需要改动代码,只需要在编译的时候将需要合并的两个服务通过代码生成等相关的技术合并到一起即可。通过这样巧妙的思路,可以达到“免费”的“微服务回归单体”的目的,同时,由于没有rpc带来的序列化和反序列化开销,对于耗时、总体的CPU消耗等都有不同程度的好处。
但是与此同时我们也需要注意到:
- 这种方式只支持某些特定框架开发的服务,不能适用于全部的业务。
- 微服务可以达到服务之间的完全隔离,即一个服务的崩溃不会影响到另一个服务,如果将分布式改成单体,那么 两个服务的资源是无法完全隔离开的(内存、磁盘、CPU)
- 对基建的影响:监控接入、日志采集系统、路由层的限流组件(服务合并之后,中间少了路由,没办法进行外部限流了)等系统的运作方式都需要适应性的修改。