转载自:https://www.jianshu.com/p/124dc2c7d9d3

RPC是个老概念,五花八门的实现非常多。在14年我刚转到基础架构部时,其实是不想做RPC框架的。我的想法可能和很多工程师一样:之前做了那么多系统,现在就让我来搞个编程框架?而且这能做出什么花头?但事实很快证明我错了,编程上的事真的需要实践,否则看问题就很浅。像搞深度学习,vgg rcnn gan嘴上可以说得不停,但只要没在真正严肃的项目中调过参数,你就是门外汉。

RPC的深度在于现代的互联网公司中几乎所有服务都是使用RPC的,大部分工程师和它打交道。如果你能看到其中的痛点,提高了效率,那么整个公司的开发效率都会有明显的提升。大家都是从学生时代过来的,心里清楚一个东西在正确的条件下正确运行很容易,但要在所有情况下能正确运行就非常困难。前两天我修了个问题:brpc在fedora 26下一个weak function莫名其妙地没有被tcmalloc中的对应版本覆盖,导致heap profiler启用不了,ubuntu,centos下都是好的。这种问题往往和系统或ld有关,要精确定位很麻烦,最后我找到了一个workaround。但这个事情耗了我几个小时,因为需要在很多系统上验证没有regression。RPC里大量此类东西,虽然麻烦但能提高用户体验。那个问题其实和brpc对tcmalloc的支持方式有关,brpc默认不链接tcmalloc,但用户在程序中链接tcmalloc后,我们希望cpu和heap profiler要自动开启(这两个功能依赖tcmalloc的API),同时用户不用重编brpc。所以我们得在brpc中动态判定是否链接了tcmalloc,这就没那么容易了。对我们很麻烦,但用户的体验更好了,甚至用户会觉得理所当然。

知识是需要大量实践的,你也许可以在正确的条件下用dlsym有效地覆盖一个glibc中的函数,但你可能不知道dlsym在有多版本符号存在时可能无效,或dlsym和一些库合用时(比如用于展开栈的libunwind)会死锁,或dlsym对静态链接是无效的除非编译加了-rdynamic。你也许可以基于一些上下文切换库三下五除二搞出个libcoroutine,但你可能不知道的是JNI会检查stack layout而不能使用自定义栈,或程序运行在valgrind中需要注册栈地址才不会报错,或一个栈跑到另一个LWP上展开时会触发gcc4以上版本的thread-local误优化。这些知识,成千上万条这种知识,通过实践才会深深地刻画在脑中,构成一个工程师真正的竞争力。

我一直坚信所有的用户体验都是端到端的,只有站在用户的角度,把整个流程以既高效又不失扩展性的方式走通,才是最好的选择。良好的文档正是这种理念的体现:给新用户铺好路能快速上手,让老用户知其所以然更上一层楼。这种想法也体现在代码中的方方面面:每个选项都有合理的默认值,用户不设也能用;在注释中提示best practice,避免用户走弯路;用户界面、日志内容不啰嗦,让用户一眼看清楚问题的全貌。不做并不意味着我们没能力做,而是早已被事实证明可能出现非常subtle的bug而被淘汰掉的选择。知道的越多,你就越会有一种责任感,需要帮助用户修一条好路,避免陷到你已经踩过的成百上千个坑中。

说到性能,RPC的性能评估其实很像VC投资初创公司:每家都在说自己的东西好,并能拿出数据,可真的好不好天晓得。所以VC只能看团队,查背景,凭感觉,这钱花出去了能不能拿回来心里都慌的很。RPC其实也这样,每个实现都有大量独特的设计和接口,用户不太可能轻易地从一个RPC切换到另一个RPC,并在完全相同的环境下进行对比。每个RPC实现都在说自己高性能,轻量级。这是个自卖自夸的游戏,用户只能看脸。但就像我们奇怪古人连那么简单的东西都不知道一样,人的认知就是这样,内行的常识可能对外行非常困难,甚至这个常识非常简单。在很多年以前,我们对“高性能”的认识还停留在“极限QPS”和“延时”两个维度的时候,被一个复杂系统中的拥塞问题搞的焦头烂额,大家就觉得莫名其妙啊,每个环节都很快,这延时怎么就哗哗哗地涨上去了。最后在反反复复的思考和分析后才发现,QPS和延时的乘积与程序的最大服务能力紧密相连。我们搞了个概念叫volume,发现串行系统的volume可以相加,并行系统的volume可以求min,然后一层层地迭代上去从而计算出复杂系统同时能处理的最大请求数,并解决了拥塞问题。

不过就是个乘法。

今天我们知道这个原理是little's law,tcp中的BDP也是类似的道理。我们在文档中描述了相关的知识。但即使是这样,根据我们在百度内的支持经验(没人会否认百度研发的整体素质吧),大部分RPC的用户对这个乘法理解还是有困难的,更别提理解串行相加,并行求min,在系统设计中活学活用了。一个乘法尚且同此,更深入的可想而知。普通用户是很难看明白性能测试的道道的。我们团队里有个老梗:“处处是热点,处处不是瓶颈”。这说的是如果整个程序写的都很粗暴,不考虑性能,最后用profiler一跑,发现每个点都只有1%,2%,然后得出结论,“性能非常好,优化空间已经不大”。但实际上你去分析下hot path,会发现有太多可以大幅提高的点了。性能就是这样,设计确保了流程是最优化的,但实现也非常重要,细节全靠抠。brpc上关键路径上的代码多一次new都需要讨论,最热的路径上甚至不允许出现申明一个可能无用的空std::string,因为老版本glibc中的空string是要加引用计数的,对cache有影响。

抠细节的背后需要工程师对性能的深入理解。一个函数的性能是可以估算出来的,测试只是验证。如果不符合预期,你就要深入地去看,最终理解背后的原因。为什么一次激烈的cacheline同步大约是700ns?或是一次调度延时至少是3us,99%以内是20us?或是linux下的timed condition有60us的延时?或是一次上下文切换可以在200ns内做完?或是无竞争的mutex可以实现为两条20ns左右wait-free的原子指令?掌握了这些知识,你才能抓大放小,把精力放在最关键的事情上,并把它做到世界上最好的水平。

但即使到现在,brpc中仍然有一些极具挑战性的问题,比如bthread的调度如何能更好地保持cache locality,如何在NUMA机器上跑得更好,如何尽量消除内核调度的延时,如何更高效率地重用栈...如此种种。我们把brpc开源出来,正是为了让感兴趣的伙伴一起加入进来,做出一个更上一层楼的RPC框架。与大家共勉。

转:brpc的研发经历的更多相关文章

  1. paper 59:招聘

     借Valse宝地发条招聘广告:D[腾讯优图]技术大咖招聘 欢迎各位技术大咖尤其应届优秀毕业生投递简历.简历投递:youtu@tencent.com简历投递,邮件标题请按照以下格式:[腾讯_上海_招聘 ...

  2. 25.创业真的需要app吗?真的需要外包吗?

    两个星期前,一名亲戚的朋友打算投入自己的二十多万元去搞个摄影社交app,问我有没有靠谱的外包推荐,我赶紧劝住他,现在app的成本已经非常高了,初期的研发就要十几万,加上后期的推广(每个用户成本大概2元 ...

  3. 我们正在招聘java工程师,想来美团工作吗?

    我们希望你有? 1.3年以上Java服务器开发经验,精通Java及面向对象设计开发,熟悉主流web框架 2.熟悉网络编程,熟悉TCP/IP协议,熟悉互联网应用协议 3.有大规模分布式系统设计与开发经验 ...

  4. [Kingdom Rush]团队分享:如何做塔防手游

    转自:http://www.gamelook.com.cn/2015/03/207324 GameLook报道/2014年11月,乌拉圭开发商Ironhide Studios发布的<Kingdo ...

  5. 一文读懂NodeJS全栈开发利器:CabloyJS(万字长文)

    目录 0 修订 0.1 修订说明 0.2 修订历史 1 基本概念 1.1 CabloyJS是什么 1.2 CabloyJS核心解决什么问题 1.3 CabloyJS的开发历程 2 数据版本与开发流程 ...

  6. 关于nlp的一些探索

    深度学习,知识图谱,nlp学习经历                          获取信息来源:英文paper研读,吴恩达公开课,Hiton公开课,北大nlp教材,英文最新学术论文,中科院院士技术 ...

  7. DataPipeline CTO 陈肃:我们花了3年时间,重新定义数据集成

    目前,中国企业在大数据流通.交换.利用等方面仍处于起步阶段,但是企业应用数据集成市场却是庞大的.根据 Forrester 数据看来,2017 年全球数据应用集成市场纯软件规模是 320 亿美元,如果包 ...

  8. 嵌入式开发—C语言面试题

    嵌入式开发—C语言面试题 源地址:http://blog.csdn.net/xdx2ct1314/article/details/7358929   1. 用预处理指令#define 声明一个常数,用 ...

  9. software engineer's resume(帮助你写程序员简历)

    关键词 参考 简历模板 参考 下面开始是正文(关键词原文) 介绍 本项目由海外兔 (https://osjobs.net) 维护,海外兔团队由一线互联网面试官组成,提供海内外公司一对一入职套餐以及算法 ...

随机推荐

  1. 发布新版首页“外婆新家”升级版:全新的UI,熟悉的味道

    在7月30日我们我们忐忑不安地发布了新版网站首页,发布后迎接我们的不是新颜新风貌的惊喜,而是我们最担心的残酷现实——“让我们等这么多年,等来的就是这个新的丑容颜”,在大家的批评声中我们深深地认识到我们 ...

  2. SqlServer 版本号

    RTM (no SP) SP1 SP2 SP3 SP4 SQL Server 2014      codename Hekaton  12.00.2000.8 SQL Server 2012      ...

  3. java Hibernate 用法

    Hibernate 用法总结: import java.io.Serializable; import java.sql.SQLException; import java.util.Collecti ...

  4. 手把手mc开服教学(内置开服核心)

    QQ交流群:1125669835 mc开服教程 首先我们需要下载一个开服核心,然后把服务器核心放在一个空文件夹里(这是我的开服核心) 然后再打开(感jio这是废话,要耐心等待......) 然后你会发 ...

  5. 初识ABP vNext(3):vue对接ABP基本思路

    目录 前言 开始 登录 权限 本地化 创建项目 ABP vue-element-admin 最后 前言 上一篇介绍了ABP的启动模板以及AbpHelper工具的基本使用,这一篇将进入项目实战部分.因为 ...

  6. CODING DevOps 微服务项目实战系列第一课,明天等你

    CODING DevOps 微服务项目实战系列第一课<DevOps 微服务项目实战:DevOps 初体验>将由 CODING DevOps 开发工程师 王宽老师 向大家介绍 DevOps ...

  7. DML语言(数据操纵语言)

    #DML语言/*数据操作语言:插入:insert修改:update删除:delete */ #一.插入语句#方式一:经典的插入/*语法:insert into 表名(列名,...) values(值1 ...

  8. maatwebsite lost precision when export long integer data

    Maatwebsite would lost precision when export long integer data, no matter string or int storaged in ...

  9. 浅谈AQS原理

    一.AQS介绍 AQS,即AbstractQueuedSynchronizer, 抽象队列同步器,它是Java多线程模块用来构建锁和其他同步组件的基础框架.来看下同步组件对AQS的使用: AQS是一个 ...

  10. express-session中的saveUninitialized和resave

    app.use(session({ name: config.session.name, secret: config.session.secret, resave: true, saveUninit ...