平时的工作用到了baidu-rpc搭建rpc服务,作为戈君大神的大作,在没有开源的时候,这个c++ 的rpc框架在厂内就已经好评颇多,无论是性能、文档、还是代码注释都很优秀,内部使用范围特别广,17年开源,开源版本叫做brpc,开源后不少大厂都有使用,目前已经进入Apache孵化器,源码以及文档的地址如下:https://github.com/apache/incubator-brpc。
个人对底层的东西比较感兴趣,因此有结合文档和源码深入学习下这个rpc框架的想法,整个brpc代码量不小,很早就开始看了,实话说一开始看其实挺费劲的,不过越往后看越觉得这个框架的博大精深,所以准备把看过的部分总结成文章,今天整理了一部分先发第一篇,算是看源码的随笔吧,第一次写博客,如有错误,还望指正。
brpc作为一个完整的rpc框架,自然同时支持作为Server和作为Client,这篇文章聊的是作为Server的使用方式以及启动Server、开启相应服务的内部处理过程。bprc面向用户的接口还是挺友好的,调用很简单,这里贴一个官方http的demo:
搭建一个rpc Server,概括起来就是新建一个Server对象,设置好参数,往里面添加自己的Service,然后启动,Server可以包含多个Service,而Service又可以包含多个method,具体的某次请求就是针对某个method的,这个demo里的Server有三个Service。
具体怎么使用bprc这里不多说,官方文档有详细说明。因为是从业务使用开始接触这个框架的,所以我打算首先从和实际应用场景最接近的添加服务、启动服务器这块开始入手看源码。brpc里有个Server类,作为服务器的话均是通过这个类作为入口,从rpc服务器的构造过程来说,主要是如下三个过程:
调用Start函数来启动服务器,和Addservice一样,start也有多种调用方式的重载,最终都是调用的StartInternal
在StartInternal函数里,首先是一些准备工作,根据option进行了一些设置,包括ssl设置以及是否创建tls数据、提前启动好需要的bthread(brpc用到的m:n线程库的线程,bthread也是bprc性能优异的关键之一,后面的文章再具体介绍)等。然后就是在指定的ip和端口范围(在范围内不断尝试,成功了就停止继续尝试)上启动监听,一个server也只支持监听一个端口。主要代码如下:
Acceptor顾名思义就是消息的接收器,BuildAcceptor也就是构建接收器,如果为NULL则调用BuildAcceptor
在BuildAcceptor里面,最重要的如下:
首先通过ListProtocols拿到所有注册支持的协议,然后遍历这些协议,通过AddHandler添加,handler是处理message的,注意到这里handler.process都是protocols[i]里面的process_request,也就是对应协议在服务端使用用来处理过接收到的请求的,对应的如果是客户端用的则是process_response。
StartAccept核心内容如下:
brpc是采用epoll来处理事件的,用的是边缘触发,options.on_edge_triggered_events是epoll边缘触发事件到来后的处理函数,也就是OnNewConnections作为事件的处理函数,顾名思义也就是新连接到来后使用的处理函数,这里不展开讲OnNewConnections的具体实现,后面的文章再详细介绍。
关于Socket类型,就是对fd等资源的的封装方便再多线程环境下使用,官方介绍是这样的:
和fd相关的数据均在Socket中,是rpc最复杂的结构之一,这个结构的独特之处在于用64位的SocketId指代Socket对象以方便在多线程环境下使用fd。
Socket::Create函数是根据options新建socket并把id存入第二个参数中,内部最重要的操作就是用options.on_edge_triggered_event所指代的函数进行epoll add,在当前服务端start的场景下,也就是在监听fd上用OnNewConnections注册epoll事件处理新过来的连接,至此启动完成,后续等待epoll事件进行相应处理。
负责第一步处理epoll事件的则是EventDispatcher,是分发epoll event的模块,负责把fd上边缘触发的事件分发给消费者(具体的业务处理函数),可以有多个,分别运行在不同的bthread上,具体的数量取决于参数,它所做的事情就是启动后不断去epoll_wait,获得epoll事件后交由相应函数处理,如果是epoll_in事件,调用Socket::StartInputEvent,如果是epoll_out,调用Socket::HandleEpollOut,简化后的核心代码如下:
StartAccept后,服务器基本就启动完成了。再回到最开始的实例里,最后会调用server.RunUntilAskedToQuit()
RegisterQuitSignalOrDie里主要是用signal函数注册了退出信号,一旦有退出信号s_signal_quit会为true,从而跳出循环并停止server。
brpc作为服务端整个启动过程基本就是这样,后面再写文章继续介绍一下brpc里一些关键的机制和类,以及在fd上收发请求的一些细节。
目录1.往server里添加Service(业务代码)2.设置服务器参数3.启动服务器平时的工作用到了baidu-rpc搭建rpc服务,作为戈君大神的大作,在没有开源的时候,这个c++ 的rpc框架在厂内就已经好评颇多,无论是性能、文档、还是代码注释都很优秀,内部使用范围特别广,17年开源,开源版本叫做brpc,开源后不少大厂都有使用,目前已经进入Apache孵化器,源码以及文档的地址如下:ht...
一.项目简介:
b
rpc
又称为
baidu
-
rpc
,是百度开发一款“远程
过程
调用”网络框架。目前该项目已在github上开源——https://github.com/b
rpc
/b
rpc
。
据目前公开的资料,我们发现百度内部从2010年开始,开发过若干
rpc
框架:ub系列
rpc
(ub
rpc
,nova_pb
rpc
、public_pb
rpc
),hulu-pb
rpc
、sofa-pb
rpc
和本文介绍的
baidu
-
rpc
。从命名来看,我们并不太清楚ub、hulu和sofa是啥,但是可以确认的是我们...
在上一家公司工作的时候,涉及过
RPC
的开发,但仅仅是协作方制定好接口文档,我按照对应的格式去返回数据,对于
RPC
的概念、功能、实现以及各种版本框架的差异几乎没有了解。随着对进程间通信探究的不断深入,对深入了解
RPC
的渴望也愈加浓烈。本文开始,我将对大名鼎鼎的BPRC展开一系列的学习。
首先,我将简要的描述一下我对
RPC
的理解,
RPC
,全称Remote Procedure Call,中文是“远程
过程
调用”,想要了解一个陌生的东西,可以先了解一下它的由来——即在什么背景下产生了这个东西,否则就
《Spark2.1.0之内置
RPC
框架》
《spark2.1.0之
源码
分析——
RPC
配置TransportConf》
《spark2.1.0之
源码
分析——
RPC
客户端工厂TransportClientFactory》
TransportServer是
RPC
框架的
服务端
,可提供高效的、低级别的流
服务
。在说明《Spark2.1.0之内置
RPC
框架》一文...
《Spark2.1.0之内置
RPC
框架》
《spark2.1.0之
源码
分析——
RPC
配置TransportConf》
《spark2.1.0之
源码
分析——
RPC
客户端工厂TransportClientFactory》
《spark2.1.0之
源码
分析——
RPC
服务器
TransportServer》
《spark2.1.0之
源码
分析——
RPC
管道初始化》
使用的工业级
RPC
框架,具有1,000,000多个实例(不计算客户端)和数千种
服务
,在百度内部称为“
baidu
-
rpc
”。 现在只有C ++实现是开源的。
您可以使用它来:
构建可以使用多种协议(在同一端口上)进行对话或访问各种
服务
的
服务器
宁静的http / https,h2 / h2c(与兼容,将开源)。 在b
rpc
中使用http比更友好。
和 ,线程安全,比官方客户端更友好和性能更高。
/ / ,用于构建。
hadoop_
rpc
(可能是开源的)
支持(将开源)
支持,线程安全,比正式客户更友好,性能更高。
百度使用的各种协议: , streaming_
rpc
,hulu_pb
rpc
, sofa_pb
rpc
,nova_pb
rpc
,public_pb
rpc
,ub
rpc
和基于nshead的协议。
使用HTTP + json访问基于协议的协议,可能是另一种语言
b
rpc
数据包处理
过程
前面我们提到b
rpc
会在Server::Start中将listened_fd加入众多EventDispatcher之一,让epoll监听其EPOLLIN事件,我们将从listened_fd的可读事件触发来讲解一个数据包如何被接收 + 处理 + 响应。
OnNewConnections
我们知道Socket::ProcessEvent会调用listened_fd的回调事件:s->_on_edge_triggered_events,此回调函数在Acceptor::StartAcc
2021SC@SDUSC B
RPC
源码
分析(一) 项目综述
2021SC@SDUSC B
RPC
源码
分析(一) 项目综述
目录2021SC@SDUSC B
RPC
源码
分析(一) 项目综述一、B
RPC
介绍1.1
RPC
概述1.2 B
RPC
概述1.3 B
RPC
可以做什么?二、编译2.1 编译前置知识2.2 **Ubuntu的依赖准备**2.3 使用config_b
rpc
.sh编译b
rpc
三、项目分工
一、B
RPC
介绍
1.1
RPC
概述
RPC
是远程
过程
调用(Remote Procedure Call)的缩写形式
文章目录一、成员变量二、构造函数和析构函数2.1 构造函数2.2 析构函数三、内部类3.1 tls锁及用户数据Wrapper3.1 读辅助类ScopedPtr3.3 修改所用的Functor四、内部调用函数4.1 直接读取函数4.2 Wrapper增删函数五、外部调用函数5.1 读函数5.2 写函数六、总结
在
服务端
开发中,我们经常会碰到需要热加载的情况,需要在不影响持续请求的情况下更新数据,双buffer是很常见的一种手段,具体概念这里不过多展开,相关资料很多,在b
rpc
里,有一个叫DoublyBuffe
关于C++11原子操作相关的知识,着实有点晦涩难懂,但这又是看懂B
rpc
源码
必备的知识点之一。在网上查找了很多前人关于这块的解读文章,不同文章之间的解读确有些许出入。本文仅对自己了解和认可的部分做解释和梳理,形成自己的理解。日后发现有错误不足的地方,再做修正补充。
一. 原子性,可见性,内存序的区分
我们以一个最简单的语句x.store(1, memory_order_relaxed);为例,这条...
RPC
(Remote Procedure Call)远程
过程
调用,是一种通过网络从远程计算机程序上请求
服务
,而不需要了解底层网络技术的协议。
RPC
服务器
是提供远程
过程
调用
服务
的
服务器
,主站是指
主要
的
服务器
或者
主要
的站点。在
启动
中,
RPC
服务器
是指正在
启动
或者已经
启动
的提供远程
过程
调用
服务
的
服务器
。下面是主站和
RPC
服务器
启动
的步骤:
1.
启动
主站
```shell
#
启动
httpd
服务
[root@leqingserver ~]# systemctl start httpd
2.
启动
RPC
服务器
```shell
#
启动
CM
RPC
服务
[root@leqingserver ~]# systemctl start cm
rpc