2019-01-29关于Rpc(PHP版)

RPC(PHP版)
php可以通过安装官方手册推荐的Yar
class PAppService{
public function getTopUsers($pid,$duration=0){
return $pid;
}
public function tes($param){
return $param;
}
}
class TestController(){
function actionServer(){
$service = new Yar_Server(new PAppService()); //pappservice里的函数都被注册了,客户端直接调用
$service->handle();
}
}


客户端
function callback($info){
print_r($info);
}
Yar_Concurrent_Client::call("http://zrb-t162.zhenrongbao.com/test/server?asdf=23", "gettopusers", array(1,1),'callback');
Yar_Concurrent_Client::call("http://zrb-t162.zhenrongbao.com/test/server", "tes", array(['dd'=>2,'ee'=>'ewer'])); //地址、函数、参数、回调函数(和ajax的回调异曲同工)
Yar_Concurrent_Client::loop(); //并发请求
?>
作者:yeyue_zar
来源:CSDN
原文:https://blog.csdn.net/yeyue_zar/article/details/70175936
版权声明:本文为博主原创文章,转载请附上博文链接!
Yar异步调用的超时时间问题以及解决方案

问题
由于具体业务功能需要,需要采用并行异步的方式调用方法。
但是业务上要求每个被调用的方法的执行时间最多60秒,这就导致采用Yar的调用一直是timeout.
Yar_Concurrent_Client::loop(): select timeout 5000ms reached
解决方案
1.修改配置文件
Yar扩展的配置项如下
yar.packager php
yar.debug
yar.connect_timeout
yar.timeout
yar.expose_info
所以,采用ini_set()方法实现对php.ini的动态修改,实现修改yar.timeout,完成超时时间的配置问题。
ini_set("yar.timeout",60000);
1
2.方法参数设置
实际上这个方法在事例代码中是存在。
Yar_Concurrent_Client::call(“http://host/api/“, “some_method”, array(“parameters”), “callback”, NULL, array(YAR_OPT_TIMEOUT=>1));
在这里配置第五个参数,设置YAR_OPT_TIMEOUT.
我在这里遇到的问题是,callback函数一直找不到,所以采用的是第一个方法。
---------------------
作者:小雨同学_
来源:CSDN
原文:https://blog.csdn.net/diandianxiyu_geek/article/details/53038407
版权声明:本文为博主原创文章,转载请附上博文链接!
rpc框架yar之源码解析- 入门和原理介绍
上周给团队小伙伴分享了也是下面基础入门的内容,本文主要结合一个简单框架yar的原理和源码来说明详细情况。
2019-01-29关于Rpc(PHP版)
文章图片
RPC的定义
RPC,即 Remote Procedure Call(远程过程调用),调用远程计算机上的服务,就像调用本地服务一样。
RPC可以很好的解耦系统,如WebService就是一种基于Http协议的RPC。
RPC的框架
各种架构都是在一定环境背景下产生的,有跨语言的,java语言的,有php的,有基于http的,有基于http2的。如下:
Thrift, gRPC, rpcx, motan, dubbox
Phprpc, yar, swoole, Hprose
RPC调用
2019-01-29关于Rpc(PHP版)
文章图片
这里以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的基础部分,即数据的译码/解码和传输,我感觉这两部分是这个框架的核心。下面是流程图:
2019-01-29关于Rpc(PHP版)
文章图片
请求过程:
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端,按照固定的结构解析出来即可。
2019-01-29关于Rpc(PHP版)
文章图片
PACK过程是对数据作如下处理的过程。以msgpack为例,对中间部分的数据进行序列化。生成最右边的内容(序列化后的字符串有最右有差别,这里只是拿json举例)。
2019-01-29关于Rpc(PHP版)
文章图片
传输
yar目前有两种传输方式,这个在之前提到过curl和socket方式。因为socket实际没有用过所以这里主要介绍curl。
curl的模块主要以来底层的CURL模块,主要封装了如下方法。其中multi系列主要是解决并行请求的方案。
2019-01-29关于Rpc(PHP版)
文章图片
php_yar_curl_open
这个方法主要是用CURL创建一个连接对象。这里有个复用的机制,当options &
YAR_PROTOCOL_PERSISTENT(0x1) 为true的时候,会去已经使用的连接中找一下,如果存在并且没有在用则复用。
php_yar_curl_send
这个函数主要是把request需要的数据,转成字符串,然后放在请求的postfield里面。
php_yar_curl_exec
将postfield内容,通过http请求发送出去。获得返回的内容。然后按照上述内容解析出结果


谁能用通俗的语言解释一下什么是 RPC 框架?
作者:得闲野鹤
链接:https://www.zhihu.com/question/25536695/answer/154614906
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
我们在做一个访问量不大的项目的时候,一台服务器部署上一个应用+数据库也就够了.
那么访问量稍微大一点之后呢,为了解决用户反馈的卡,反应慢的情况,我们就上集群.架设nginx,部署多个服务,由nginx负责把请求转发到其他服务上,这样就解决了用户说的卡慢问题.
过了一段时间之后呢,我们发现数据库已经扛不住了,应用服务完好,数据库有时候宕机. 那这个时候呢,我们就上数据库读写分离,再架设几台数据库服务器,做主从,做分库分表. 然后数据库也不宕机了,服务又恢复了流畅.
又过了一段时间,公司事业增增日上,服务访问量越来越高,且大部分都是查询, 吸取之前宕机且为了办证数据库的健壮性,我们这个时候又加上了缓存, 把用户高频次访问的数据放到缓存里.
后来,项目功能越来越多,整个项目也愈发庞大,修改一个类就需要全盘上传,切换nginx重启,这样的发布流程越来越长,越来越繁杂.然后我们开始把模块拆分,用户信息分个项目,订单系统分一个项目.这样就达到了,用户模块代码修改的时候,只需要更新用户信息服务就好了.但是还是需要切换顶层的nginx.把要重启的服务的流量切到可用服务上. 这个时候我们就想到了RPC
那么RPC解决了什么呢? 所有的服务在启动的时候注册到一个注册机里面,然后顶层处理在接收到nginx的请求时,去注册机找一个可用的服务,并调用接口. 这样子呢,在不加新功能的时候,顶层处理服务我们就不需要动了? 那修改了用户信息项目的时候,我们只需要一个个更新用户信息项目的服务群就好了?
这样的话,无论是扩展还是服务的健壮性都妥妥的了?
作者:知乎用户
链接:https://www.zhihu.com/question/25536695/answer/417707733
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
2019-01-29关于Rpc(PHP版)
文章图片
随着企业 IT 服务的不断发展,单台服务器逐渐无法承受用户日益增长的请求压力时,就需要多台服务器联合起来构成「服务集群」共同对外提供服务。同时业务服务会随着产品需求的增多越来越肿,架构上必须进行服务拆分,一个完整的大型服务会被打散成很多很多独立的小服务,每个小服务会由独立的进程去管理来对外提供服务,这就是「微服务」。
当用户的请求到来时,我们需要将用户的请求分散到多个服务去各自处理,然后又需要将这些子服务的结果汇总起来呈现给用户。那么服务之间该使用何种方式进行交互就是需要解决的核心问题。RPC 就是为解决服务之间信息交互而发明和存在的。
什么是 RPC ?
RPC (Remote Procedure Call)即远程过程调用,是分布式系统常见的一种通信方法,已经有 40 多年历史。当两个物理分离的子系统需要建立逻辑上的关联时,RPC 是牵线搭桥的常见技术手段之一。除 RPC 之外,常见的多系统数据交互方案还有分布式消息队列、HTTP 请求调用、数据库和分布式缓存等。
< img src="https://pic3.zhimg.com/v2-b01ff9341109bc0da2a0d2dc5a6c7c9e_b.jpg" data-caption="" data-size="normal" data-rawwidth="936" data-rawheight="377" data-default-watermark-src="https://pic3.zhimg.com/v2-b01ff9341109bc0da2a0d2dc5a6c7c9e_b.jpg" class="origin_image zh-lightbox-thumb" width="936" data-original="https://pic3.zhimg.com/v2-b01ff9341109bc0da2a0d2dc5a6c7c9e_r.jpg">
2019-01-29关于Rpc(PHP版)
文章图片
其中 RPC 和 HTTP 调用是没有经过中间件的,它们是端到端系统的直接数据交互。HTTP 调用其实也可以看成是一种特殊的 RPC,只不过传统意义上的 RPC 是指长连接数据交互,而 HTTP 一般是指即用即走的短链接。
RPC 在我们熟知的各种中间件中都有它的身影。Nginx/Redis/MySQL/Dubbo/Hadoop/Spark/Tensorflow 等重量级开源产品都是在 RPC 技术的基础上构建出来的,我们这里说的 RPC 指的是广义的 RPC,也就是分布式系统的通信技术。RPC 在技术中的地位好比我们身边的空气,它无处不在,但是又有很多人根本不知道它的存在。
Nginx 与 RPC
Ngnix 是互联网企业使用最为广泛的代理服务器。它可以为后端分布式服务提供负载均衡的功能,它可以将后端多个服务地址聚合为单个地址来对外提供服务。如图,Django 是 Python 技术栈最流行的 Web 框架。
< img src="https://pic4.zhimg.com/v2-7fb2b07eb635158ed3c7f0c70d39cf37_b.jpg" data-caption="" data-size="normal" data-rawwidth="500" data-rawheight="259" data-default-watermark-src="https://pic4.zhimg.com/v2-7fb2b07eb635158ed3c7f0c70d39cf37_b.jpg" class="origin_image zh-lightbox-thumb" width="500" data-original="https://pic4.zhimg.com/v2-7fb2b07eb635158ed3c7f0c70d39cf37_r.jpg">
2019-01-29关于Rpc(PHP版)
文章图片
Nginx 和后端服务之间的交互在本质上也可以理解为 RPC 数据交互。也许你会争辩说 Nginx 和后端服务之间使用的是 HTTP 协议,走的是短连接,严格上不能算是 RPC 调用。
< img src="https://pic1.zhimg.com/v2-8644100f3b20a4bbd8315947ea8a2b78_b.jpg" data-caption="" data-size="normal" data-rawwidth="663" data-rawheight="268" data-default-watermark-src="https://pic1.zhimg.com/v2-8644100f3b20a4bbd8315947ea8a2b78_b.jpg" class="origin_image zh-lightbox-thumb" width="663" data-original="https://pic1.zhimg.com/v2-8644100f3b20a4bbd8315947ea8a2b78_r.jpg">
2019-01-29关于Rpc(PHP版)
文章图片
你说的没错,不过 Nginx 和后端服务之间还可以走其它的协议,比如 uwsgi 协议、fastcgi 协议等,这两个协议都是采用了比 HTTP 协议更加节省流量的二进制协议。如上图所示,uWSGI 是著名的 Python 容器,使用它可以启动 uwsgi 协议的服务器对外提供服务。
uwsgi 通讯协议在 Python 语言体系里使用非常普遍,如果一个企业内部使用 Python 语言栈搭建 Web 服务,那么他们在生产环境部署 Python 应用的时候不是在使用 HTTP 协议就是在使用 uwsgi 协议来和 Nginx 之间建立通讯。
< img src="https://pic2.zhimg.com/v2-c629b3aee108d18d35dec35b5c96f3a5_b.jpg" data-caption="" data-size="normal" data-rawwidth="536" data-rawheight="269" data-default-watermark-src="https://pic2.zhimg.com/v2-c629b3aee108d18d35dec35b5c96f3a5_b.jpg" class="origin_image zh-lightbox-thumb" width="536" data-original="https://pic2.zhimg.com/v2-c629b3aee108d18d35dec35b5c96f3a5_r.jpg">
2019-01-29关于Rpc(PHP版)
文章图片
Fastcgi 协议在 PHP 语言体系里非常常见,Nginx 和 PHP-fpm 进程之间一般较常使用 Fastcgi 协议进行通讯。
Hadoop 与 RPC
在大数据技术领域,RPC 也占据了非常重要的地位。大数据领域广泛应用了非常多的分布式技术,分布式意味着节点的物理隔离,隔离意味着需要通信,通信意味着 RPC 的存在。大数据需要通信的量比业务系统更加庞大,所以在数据通信优化上做的更深。
< img src="https://pic4.zhimg.com/v2-bd9467da853bed45395f61393c3d51ef_b.jpg" data-caption="" data-size="normal" data-rawwidth="592" data-rawheight="255" data-default-watermark-src="https://pic4.zhimg.com/v2-bd9467da853bed45395f61393c3d51ef_b.jpg" class="origin_image zh-lightbox-thumb" width="592" data-original="https://pic4.zhimg.com/v2-bd9467da853bed45395f61393c3d51ef_r.jpg">
2019-01-29关于Rpc(PHP版)
文章图片
比如最常见的 Hadoop 文件系统 hdfs,一般包括一个 NameNode 和多个 DataNode,NameNode 和 DataNode 之间就是通过一种称为 Hadoop RPC 的二进制协议进行通讯。
TensorFlow 与 RPC
在人工智能领域,RPC 也很重要,著名的 TensorFlow 框架如果需要处理上亿的数据,就需要依靠分布式计算力,需要集群化,当多个分布式节点需要集体智慧时,就必须引入 RPC 技术进行通讯。Tensorflow Cluster 的 RPC 通讯框架使用了 Google 内部自研的 gRPC 框架。
< img src="https://pic4.zhimg.com/v2-45b9ad132b930d6bc13885e7d8803233_b.jpg" data-caption="" data-size="normal" data-rawwidth="728" data-rawheight="280" data-default-watermark-src="https://pic4.zhimg.com/v2-45b9ad132b930d6bc13885e7d8803233_b.jpg" class="origin_image zh-lightbox-thumb" width="728" data-original="https://pic4.zhimg.com/v2-45b9ad132b930d6bc13885e7d8803233_r.jpg">
2019-01-29关于Rpc(PHP版)
文章图片
HTTP 调用其实也是一种特殊的 RPC
HTTP1.0 协议时,HTTP 调用还只能是短链接调用,一个请求来回之后连接就会关闭。HTTP1.1 在 HTTP1.0 协议的基础上进行了改进,引入了 KeepAlive 特性可以保持 HTTP 连接长时间不断开,以便在同一个连接之上进行多次连续的请求,进一步拉近了 HTTP 和 RPC 之间的距离。
【2019-01-29关于Rpc(PHP版)】< img src="https://pic2.zhimg.com/v2-b736ea583c47ee3f67ec2376152251a9_b.jpg" data-caption="" data-size="normal" data-rawwidth="1140" data-rawheight="618" data-default-watermark-src="https://pic2.zhimg.com/v2-b736ea583c47ee3f67ec2376152251a9_b.jpg" class="origin_image zh-lightbox-thumb" width="1140" data-original="https://pic2.zhimg.com/v2-b736ea583c47ee3f67ec2376152251a9_r.jpg">
2019-01-29关于Rpc(PHP版)
文章图片
当 HTTP 协议进化到 2.0 之后,Google 开源了一个建立在 HTTP2.0 协议之上的通信框架直接取名为 gRPC,也就是 Google RPC,这时 HTTP 和 RPC 之间已经没有非常明显的界限了。所以在后文我们不再明确强调 RPC 和 HTTP 请求调用之间的细微区别了,直接统一称之为 RPC。
< img src="https://pic1.zhimg.com/v2-aec06c8c9ce542630658729144c2b1e0_b.jpg" data-caption="" data-size="normal" data-rawwidth="429" data-rawheight="314" data-default-watermark-src="https://pic1.zhimg.com/v2-aec06c8c9ce542630658729144c2b1e0_b.jpg" class="origin_image zh-lightbox-thumb" width="429" data-original="https://pic1.zhimg.com/v2-aec06c8c9ce542630658729144c2b1e0_r.jpg">
2019-01-29关于Rpc(PHP版)
文章图片
HTTP VS RPC (普通话 VS 方言)
HTTP 与 RPC 的关系就好比普通话与方言的关系。要进行跨企业服务调用时,往往都是通过 HTTP API,也就是普通话,虽然效率不高,但是通用,没有太多沟通的学习成本。但是在企业内部还是 RPC 更加高效,同一个企业公用一套方言进行高效率的交流,要比通用的 HTTP 协议来交流更加节省资源。整个中国有非常多的方言,正如有很多的企业内部服务各有自己的一套交互协议一样。虽然国家一直在提倡使用普通话交流,但是这么多年过去了,你回一趟家乡探个亲什么的就会发现身边的人还是流行说方言。
如果再深入一点说,普通话本质上也是一种方言,只不过它是官方的方言,使用最为广泛的方言,相比而言其它方言都是小语种,小语种之中也会有几个使用比较广泛比较特色的方言占比也会比较大。这就好比开源 RPC 协议中 Protobuf 和 Thrift 一样,它们两应该是 RPC 协议中使用最为广泛的两个。
RPC 与分布式系统交互方案
如果两个子系统没有在网络上进行分离,而是运行在同一个操作系统实例之上的两个进程时,它们之间的通信手段还可以更加丰富。除了以上提到的几种分布式解决方案之外,还有共享内存、信号量、文件系统、内核消息队列、管道等,本质上都是通过操作系统内核机制来进行数据和消息的交互而无须经过网络协议栈。
但在现代企业服务中,这种单机应用已经非常少见了,因为单机应用意味着单点故障 —— “一人摔跤全家跌倒”。业务子系统往往都需要经物理网络栈进行隔离,因此分布式解决方案在要求高可用无间断服务的企业环境里便大有作为,这也让 RPC 迎来自己大放异彩的时代。
前文提到的分布式子系统交互方案,除了 RPC 技术之外还有数据库、消息队列和缓存。但其实这三者本质上是 RPC 技术的一个应用组合。我们可以将数据库服务理解为下面这张图:
< img src="https://pic1.zhimg.com/v2-59ebb1c5d5a7b9537fe18ffc3cc6ced8_b.jpg" data-caption="" data-size="normal" data-rawwidth="528" data-rawheight="125" data-default-watermark-src="https://pic1.zhimg.com/v2-59ebb1c5d5a7b9537fe18ffc3cc6ced8_b.jpg" class="origin_image zh-lightbox-thumb" width="528" data-original="https://pic1.zhimg.com/v2-59ebb1c5d5a7b9537fe18ffc3cc6ced8_r.jpg">
2019-01-29关于Rpc(PHP版)
文章图片
可以看出,子系统和数据库之间的交互也是通过 RPC 进行的,只不过这里是三个子系统之间复杂的组合消息交互罢了。如果再深入进去,你会发现,这里的数据库不是那种单机数据库,而是具备主从复制功能的数据库,比如 MySQL。在互联网企业里一般都会使用这种主从读写分离的数据库。一个业务子系统将数据写往主库,主库再将数据同步到从库,然后另一个业务子系统又从库里将数据取出来。这时又可以进一步将它们看成是四个子系统之间进行的更加复杂的 RPC 数据交互。
< img src="https://pic4.zhimg.com/v2-a2fc0676fcfec2c2111351a62cc3616b_b.jpg" data-caption="" data-size="normal" data-rawwidth="674" data-rawheight="125" data-default-watermark-src="https://pic4.zhimg.com/v2-a2fc0676fcfec2c2111351a62cc3616b_b.jpg" class="origin_image zh-lightbox-thumb" width="674" data-original="https://pic4.zhimg.com/v2-a2fc0676fcfec2c2111351a62cc3616b_r.jpg">
2019-01-29关于Rpc(PHP版)
文章图片

    推荐阅读