温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

rpc框架yar之源码解析- 入门和原理介绍

发布时间:2020-05-19 19:05:44 来源:网络 阅读:1585 作者:netbird_fly 栏目:web开发

关于rpc的文章,网上的内容很多,但我还是准备写一下,主要是自己的理解吧。算是公众号的第一篇技术类文章吧。

上周给团队小伙伴分享了也是下面基础入门的内容,本文主要结合一个简单框架yar的原理和源码来说明详细情况。

rpc框架yar之源码解析- 入门和原理介绍


RPC的定义

RPC,即 Remote Procedure Call(远程过程调用),调用远程计算机上的服务,就像调用本地服务一样。

RPC可以很好的解耦系统,如WebService就是一种基于Http协议的RPC。


RPC的框架

各种架构都是在一定环境背景下产生的,有跨语言的,java语言的,有php的,有基于http的,有基于http2的。如下:

Thrift, gRPC, rpcx, motan, dubbox

Phprpc, yar, swoole, Hprose 


RPC调用

rpc框架yar之源码解析- 入门和原理介绍

这里以dubbo的架构图为例,dubbo主要分成4个角色:消费者(Consumer),生产者(Provider),监控中心(Monitor),注册中心(Registry)。

Provider: 暴露服务的服务提供方,生产者。 
Consumer: 调用远程服务的服务消费方。 
Registry: 服务注册与发现的注册中心。 
Monitor: 统计服务的调用次数和调用时间的监控中心。


调用方法如下:

0. 服务容器启动,加载,运行服务提供者(server端)。 
1.服务提供者在启动时,向注册中心注册自己提供的服务。 
2.服务消费者在启动时,向注册中心订阅自己所需的服务。 
3.注册中心返回服务提供者地址列表给消费者,如果有变更,注册中心将基于长连接推送变更数据给消费者。 
4.服务消费者,从提供者地址列表中,根据指定的负载均衡算法,选一台提供者进行调用,如果调用失败,再选另一台调用。 
5.服务消费者和提供者,在内存中累计调用次数和调用时间,定时每分钟发送一次统计数据到监控中心。


以上是从网上其他帖子上找的调用内容。基本上涵盖了rpc框架的基本思路,monitor和registry不是必须的,如果有其他方式替代, 也可省略或者换成其他可以实现功能的方式,如集中处理日志。下面是我们在实际使用中用到的内容。


业务背景:在DAU过亿的某博,基础数据独立成平台,这样返回的PC,手机,H5其实是基础数据,要想被手机端所用,实际上需要加工然后传到端上展示。而为了统一化管理,网页版和手机app版尽量使用同一套解析。业务需求产生,在一定的历史背景下,产生了rpc的调用模式。条条大路通罗马,问题不止一个解决方案,我们只是采用了一种,即结合http,nginx ,php-fpm等使用yar这个php扩展模块实现这个业务。


严格意义上讲yar不能独立使用的,没有dubbo,motan等那种自己独立成框架体系。有些部分交给使用者自己实现,如日志记录,我们的日志记录实际与yar关系不大。框架数据传输方式还是借助http,结合nginx,php-fpm等内容,基础还是个http的请求。(curl和sockert两种方式,sockert目前我们没有使用)。没有注册发现服务的具体使用,这个完全由lvs给我们解决,服务的可用完全交给了运维。


了解了各个角色,我们来看下核心内容,Yar实现了rpc的基础部分,即数据的译码/解码和传输,我感觉这两部分是这个框架的核心。下面是流程图:

rpc框架yar之源码解析- 入门和原理介绍


请求过程:

Client需要远程调用的时候,先初始化数据,数据主要包括三个部分header, packager_name,request_body,然后根据配置中的方式从pack_list选择合适的序列化方式(msgpack,json,php)

对request_body进行序列化。 然后进行传输,传输方式 同样是采用工厂方法,从已有的方式中选择Curl/sockert方式进行传输数据,传输数据的过程实际就是发送一个http请求(我们以curl为例)。

服务器端监听端口,底层网络实现都利用现有的nginx, php-fpm。在PHP代码中,实现的地方实例化一个类,然后根据request的内容,解析body,然后去初始化header, 获得packager_name,根据packer_name解析yar_body的内容。


以下是每次request和response的数据情况。以request为例传输的body数据包含三个部分,82byte的头部,packager_name,和经过packager_name序列化的string。当这段数据传到server端,按照固定的结构解析出来即可。


rpc框架yar之源码解析- 入门和原理介绍

PACK过程是对数据作如下处理的过程。以msgpack为例,对中间部分的数据进行序列化。生成最右边的内容(序列化后的字符串有最右有差别,这里只是拿json举例)。

rpc框架yar之源码解析- 入门和原理介绍


传输

yar目前有两种传输方式,这个在之前提到过curl和socket方式。因为socket实际没有用过所以这里主要介绍curl。

curl的模块主要以来底层的CURL模块,主要封装了如下方法。其中multi系列主要是解决并行请求的方案。

rpc框架yar之源码解析- 入门和原理介绍

php_yar_curl_open

这个方法主要是用CURL创建一个连接对象。这里有个复用的机制,当options & 

YAR_PROTOCOL_PERSISTENT(0x1) 为true的时候,会去已经使用的连接中找一下,如果存在并且没有在用则复用。


php_yar_curl_send

这个函数主要是把request需要的数据,转成字符串,然后放在请求的postfield里面。


php_yar_curl_exec

将postfield内容,通过http请求发送出去。获得返回的内容。然后按照上述内容解析出结果。


本来还想分享grpc的protobuf和htt2,鉴于粗浅学习阶段,网上的其他博客文章更详细,这里就不写了,等我实际有自己的理解再说啦。


凡事都没有完美,也碰到过yar的不足之处,比如server的handle方法,解析post数据,执行对应的方法返回都在这里了。没有将请求的实际方法暴露,这样在server端统计起来比较困难。曾试图在源码中加个getCallMethod方法去标记这个内容,不过只是自己玩玩,没有实际应用...


有同学问我为啥我们当时要用yar,也许别的框架也能满足我们的需求,一定的历史背景决定一定的技术架构。技术的选型更多倾向于开发者的水平----即选择自己驾驭的技术,站在巨人的肩膀上展望远处。


向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI