Web开发

首页 » 常识 » 诊断 » 一文get转转RPC框架开发实战经验
TUhjnbcbe - 2022/5/31 19:24:00
嘉宾

王建新      编辑

严强  

随着公司规模的扩大以及业务量与用户量的激增,为了满足系统高可用、高并发的要求,单体应用逐步演化为服务/微服务的架构模式。此时,我们急需一种高效的应用程序之间的通讯手段来满足这种需求,因此RPC得以大显身手。

RPC即远程过程调用协议(RemoteProcedureCallProtocol),可以让我们像调用本地对象一样发起远程调用。RPC凭借其强大的治理功能,成为解决分布式系统通信问题的一大利器。

然而,怎样选择一个合适的RPC框架依然是个令人困扰的问题。虽然社区里已经有很多开源的RPC项目,它们简单易用,但从框架特性、性能、成熟度、技术支持、社区活跃度等等方面综合考虑,适合自己的却很少。而开发一个完整的RPC框架,对于大部分中小团队来说,人力成本和时间成本都是无法接受的。

到底该如何选择一套适合自己的RPC框架?自研RPC框架的过程中遇到困难该如何破解?从事RPC框架的开发怎样才能少走弯路?针对以上问题,我们邀请了转转架构部服务治理负责人王建新老师,来和大家一起谈谈转转RPC框架的进化史,以及RPC开发和个人成长的经验,希望能给大家在工作和个人成长上带来帮助。

同时王建新老师还在QCon+案例研习社专题中为大家带来了[转转分布式锁原理及最佳实践]的分享,欢迎收看!

以下是对王建新老师的专访:

    InfoQ:先和大家聊聊你在转转目前负责什么工作吧。  

王建新:我目前在转转主要负责服务治理相关的工作,主要以RPC框架为核心,还有其周边的一些配套系统,包括注册中心、配置中心、分布式调用跟踪系统等。同时我也负责其他一些中间件的开发工作,例如Codis分布式锁、线程池监控、数据库连接池监控等。

    InfoQ:既然有了HTTP,为什么还需要RPC框架呢?  

王建新:仅从通信的角度来讲,直接使用HttpClient和RPC框架是没有什么区别的,而且有的RPC框架底层还支持使用HTTP协议进行通信,比如SpringCloudFeign和Dubbo。RPC框架的侧重点在于,它不仅仅是为了通信,还是为了更简单、更易用地通信。RPC框架通过动态代理技术,实现了调用远程方法和调用本地方法同样的体验,不需要手动构造请求体,也不需要考虑参数和返回值的序列化,这一切都被RPC框架进行了很好地封装。

许多RPC框架都设计了私有的通信协议,和HTTP协议相比更加紧凑,传输数据量更小,请求耗时更短。在某些复杂链路中可能会有几千次的RPC请求,高性能的RPC框架对效率的提升是很可观的。而且私有的RPC协议往往支持连接的多路复用,减少连接数量,节省系统资源。

RPC框架内部往往也集成了更多的高级功能,比如Router、Filter、LoadBalance等,并且允许用户自由扩展,以实现更加高级的功能。更完善一些的系统还包括监控、分布式调用跟踪、统一服务治理平台等。可以说RPC框架并不是仅仅为了满足通信的需求,更是可以提供一个体系支撑。

    InfoQ:开发一个完整的RPC框架人力成本和时间成本都是很高的,转转是基于什么样的考虑选择自研RPC框架而不是采用开源框架呢?  

王建新:我认为中间件的选型是开发还是自研,其实并没有什么银弹,一切都要从公司的实际情况出发。转转的RPC框架继承自58的RPC框架,转转是从58独立出来的,虽然在业务上已经没有太多交集,但是在技术上仍然藕断丝连。许多转转的服务仍然依赖58的服务,这就要求转转的RPC框架必须保持和58的RPC框架在协议上的一致性。而RPC框架的API更是和业务代码高度融合,因此我们无法抛弃现有的RPC框架而选择开源实现。

另外从技术角度来看,转转架构部也有实力进行RPC框架的自研。团队自研中间件不仅更能贴合自身的实际应用场景进行高度定制化的开发,在进行问题排查时也更能得心应手,毕竟每一行代码都很熟悉。而开源RPC框架为了满足各种各样不同的需求,就会产生一定的弊端,比如在功能上有些过于丰富,代码量巨大,引入公司内部使用时遇到问题更不容易排查等等。

    InfoQ:在RPC框架重构过程中你面临的最大困难是什么?是通过怎样的努力解决的?有哪些沉淀和启发?  

王建新:RPC框架重构面临的最大困难就是兼容问题。我们要保证RPC框架的新增功能尽量不破坏现有的API,如果确实无法避免不兼容的情况出现,也要尽量减少对业务的影响,减少RD的修改成本。

对于已知的不兼容情况,在发版之前,我们会对全公司的代码仓库进行扫描,提前通知服务负责人,并给出解决方案。对于无法提前预料的不兼容情况,我们先对服务进行等级划分,从重要到不重要分为A、B、C、D、E、F六个等级。每个等级的POM文件使用不同版本的parent,在parent中规定了RPC框架的版本号。工程效率部门在进行项目编译时,禁止直接在项目中指定RPC框架的版本号。

这种技术方案可以实现RPC框架的无感知升级,每次进行RPC框架发版都从不重要的服务开始进行灰度发布,逐渐过渡到重要的服务。如果有不兼容的情况或者出现bug,也能在低等级的服务上提前发现,减少损失。

RPC框架作为公司的基础设施,可谓牵一发而动全身。在转转RPC框架升级过程中,我们也曾遇到过线上事故。事后我们进行了深入思考、复盘,制定了一系列的流程规范(包括上述的服务等级划分)以及出现事故后的快速响应机制,来避免下一次事故的发生,并能够做到及时止损。

我认为技术手段能解决的问题,往往不是问题,比技术更难的是人的问题。RPC框架出现不兼容,对RD的工作或多或少都会造成影响。如何照顾到RD的情绪、如何说服RD从过期的API迁移到新版API,这些问题更加考验个人的智慧和能力。沟通的方式和方法往往比技术问题更重要。

    InfoQ:目前在工作中取得了怎样的成果呢?和大家分享一下成功经验吧。  

王建新:通过个人和团队的努力,我们主要取得以下几个方面的成果:

首先是转转RPC框架的稳定性获得了不小的提升。这体现在底层通信Netty化、服务端优雅关闭、连接数量优化和服务端线程模型优化、日志规范化,以及心跳保活、权重、预热与动态权重这些方面。同时在过程中也修复了一些隐藏的多线程安全问题。

其次,转转RPC框架的易用性和扩展性的提升。我们在协议兼容的基础上,对RPC框架的整体架构和API进行了重构。整体架构上,我们抽象出核心逻辑,开放扩展接口,增强了健壮性、扩展性,使架构层次更加分明;API上,从面向过程重构到面向对象,增强了RPC框架的易用性。

再就是实现了转转全链路标签路由功能。标签路由功能的推出需要架构部、工程效率和运维三部门联合才能完成,开发完成后的推广还需要业务部门的配合,可以说是多部门协作项目的成功典范。转转的全链路标签路由不仅可以在RPC调用之间进行路由,同样可以在MQ的生产和消费时进行路由。在标签路由项目完成后,转转测试环境的搭建耗时从1~2天缩减至5分钟。

同样借助于标签路由功能,我们完成了线上压测流量的隔离。在标签路由功能上线之后,链路变得更加复杂了,排查问题的难度也提高了。基于这个问题,我们又开发了分布式全链路跟踪系统,实现了调用链路的可视化,大大降低了排查问题的难度。

最后,我们对转转注册中心也进行了重构。重构后的转转注册中心逻辑更简单,链路更短,健壮性更强,能满足转转在未来相当长一段时间内的业务需求。

这里为大家简单介绍一下转转的标签路由功能:

在没有标签路由功能之前,搭建一个测试环境,我们需要部署从第一个被测的服务到最后一个被测服务链路中的所有服务,哪怕中间所经过的服务并未修改。服务之间的RPC调用并没有通过注册中心进行注册与发现,而是通过修改Host文件的方式将服务域名指向.0.0.1。MQ则通过添加topic前缀的方式与稳定环境的topic进行区分。

如下图所示的动态环境,需要修改Host文件,将A.zhuaninc.

1
查看完整版本: 一文get转转RPC框架开发实战经验