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

关于rpc的文章,网上的内容不少,但我仍是准备写一下,主要是本身的理解吧。算是公众号的第一篇技术类文章吧。php

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

image.png


RPC的定义nginx

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

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


RPC的框架服务器

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

Thrift, gRPC, rpcx, motan, dubbox网络

Phprpc, yar, swoole, Hprose 架构


RPC调用app

image.png

这里以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的基础部分,即数据的译码/解码和传输,我感受这两部分是这个框架的核心。下面是流程图:

image.png


请求过程:

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端,按照固定的结构解析出来便可。


image.png

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

image.png


传输

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

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

image.png

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,也许别的框架也能知足咱们的需求,必定的历史背景决定必定的技术架构。技术的选型更多倾向于开发者的水平----即选择本身驾驭的技术,站在巨人的肩膀上展望远处。

相关文章
相关标签/搜索