查看原文
其他

从旁观者到committer,我与brpc的故事

编程往事 2022-08-22

Editor's Note

上个月我成为了brpc项目的committer,这是我发表在apache brpc公众号里面的自述。在调整了文章结构后,重发到我的公众号中。

The following article is from apache brpc Author 谭中意

Apache是知名的开源软件基金会,旗下管理着众多流行的开源项目。如果你有给开源项目贡献过代码,那么你就可以称得上是一名开源项目的contributor。而committer则更进一步,这个是Apache基金会官方认可的头衔,表达了对于某个项目的活跃贡献者的一种认可。brpc开源后被捐献给了Apache基金会孵化,所以brpc也是Apache所管理的众多开源项目中的一员。今年9月,通过brpc的PPMC的票选,我成为了brpc项目的新晋committer,下面我来谈谈我和brpc的故事。

早在2017年我就开始关注C++的开源RPC框架,当时只有Facebook的thrift和Google的grpc相对出名。但也没有到一统江湖的地步。这和Dubbo在Java领域的影响力还有很大差距。在每个重度使用C++的公司中,几乎都有自己的RPC框架,腾讯也不例外。在腾讯甚至几乎每个部门都有自己的RPC框架,SNG的spp,WXG的srvkit,MIG的taf(开源版名为tars),我之前所在的部门,也有名为middle的rpc框架。若干年后,腾讯内部出现trpc,这已经是brpc开源之后的事了(据说trpc从brpc中借鉴了很多设计)。同年,百度开源了brpc。但当时的我并没过多关注,总感觉国内的开源项目和国际上互联网巨头作品可能还是有不少差距。时间到了2018年,在腾讯带我们干活的组内骨干跟我们说:“别老看业务代码,可以学习一下百度开源的brpc。”但后来我还是忙于做业务,最终也没有把这句话放到心上。

2018年我由于个人原因,从深圳来到北京。也跳槽去了百度,但是也没有过多接触brpc,因为我当时我在的团队(百度凤巢检索端)历史包袱严重,也有一套自己的RPC框架。所以我再一次和brpc失之交臂。但是我在学习本部门框架过程中,还是积累了很多通用知识的,为后来学习其他RPC框架也做了铺垫。另外当时我也有点私心,感觉brpc是开源的,什么时候学习都不着急,反而公司内部闭源的代码,是我在外面学不到的,所以当时精力主要做学习内部代码。

我真正开始深入学习brpc是在2020年,没错,我再一次换了工作。彼时由于工作关系,我开始频繁使用brpc。我这才发现一个现代的RPC框架,和我之前看的RPC框架,在设计上有很大不同。一改我对于国产C++ RPC框架的偏见。

陆陆续续发现很多让我喜欢的框架特性,比如:bthread:类似Go语言中Goroutine的M:N的用户级线程库。可以极为方便地实现并行调度。请求处理的网络模型可以不再是一个请求在一个线程中处理的传统模式。

单端口多协议的支持:一个RPC框架支持多种网络协议并不稀奇,但是很多框架做法都是为每种协议单独起一个监听端口。brpc用极低的开销实现了单个端口支持多种协议,这给日常开发工作带来极大便利。比如尽管你需要开发一个baidu_std服务,你仍然可以用curl发一个http+json的请求去自测,而无需一个特殊的client。

除此之外他还有丰富的配套工具链:brpc提供了很多工具以及内置服务。我个最常用的就是rpc_replay这个流量采样和回放工具。将线上流量进行采样,然后在开发或测试环境进行回放,可以极大地提高测试的真实性,尤其是对于请求字段比较多且复杂的情况(比如一个巨大的PB),自己构造参数会极为不便。除了工具之外,每个brpc服务启动后都会有一个内置服务的网页,通过这个网页可以方便地查看到服务当前的状态信息,甚至可以做profile。

去年我在github上通过提issue咨询过很多使用上的问题。与此同时我也开始阅读brpc源码。并在这个学习过程之中,输出了一些网络文章,算是对于brpc的传播尽过绵薄之力。

后来我开始尝试给brpc项目本身做贡献。一开始我只是发现了一些brpc文档以及代码注释中的错误,然后提交了修改PR。后面渐渐地做了一些代码bug修复和功能增强的工作。

比如我发现brpc的Channel在发送HTTP请求的时候,如果controller的http_request().uri()中未指定域名或IP的时候,那么发送出去的HTTP header中的Host字段,会默认用对端Server的ip:port 作为Host字段的值。但是在Channel是用域名做的初始化的时候,这样的处理并不友好。因为Nginx或Apache这种Web Server都有VirtualHost的功能,即同一个IP+端口上通过不同的域名(Host字段)路由到不同的服务上。后来我做了修改,当Channel是用域名初始化的时候,如果发送请求的时候uri没有指定域名,则用初始化的域名和端口来填充Host,而非ip和端口。这个PR也是历尽艰辛,和负责代码review的同学你来我往多个回合,最终合并。

日拱一卒,功不唐捐。8月下旬,brpc社区负责人谭中意联系到我,表达了对我之前工作的认可,希望我继续努力,为社区做贡献。9月份,在被merge了几个PR之后,中意再次联系到我,说我的工作得到大家认可,他会发起一轮投票,投票通过我就会成为committer。几天后,我成为了brpc社区新的committer。其实我真正开始使用和学习brpc也不过只有一年的时间,我当然也称不上是精通brpc。我还差得很远,感谢大家对我的认可,未来我会继续努力。

在参与贡献的过程之中,对brpc以及开源项目我也有了更深刻的认识。brpc已经不是 baidu rpc,而是better rpc。committer们身处不同公司,但都为了一件事而努力,这种精神让人钦佩。另外就是Apache社区有一句话是“社区重于代码”,所以在勤勤恳恳地维护代码以后,维护社区也同样重要。比如积极解决issue中别人的提问以及参与内部讨论等等。

成为committer之后,很多之前只听过名字的大神,我第一次感觉距离这么近。即感到荣幸,也感到惶恐。从旁观者到committer,想来奇妙。

往期推荐

bthread源码剖析: 基本概念与TaskControl初始化
bthread源码剖析: 工作窃取与run_main_task()
bthread源码剖析: bthread上下文的创建
人生是一条蛇,它咬着自己的尾巴
C++ STL容器如何解决线程安全的问题?


您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存