资讯专栏INFORMATION COLUMN

PHP 教父鸟哥 Yar 的原理分析

B0B0 / 3293人阅读

摘要:下面一起学习下鸟哥的框架。揭开神秘面纱采用客户端服务器模式。在服务器端,进程保持睡眠状态直到调用信息的到达为止。这和我们外网的原理不都一个样么那么我们一起看看高大上的是怎么在玩。整个传输以二进制流的形式传送。

各位老铁在点赞、收藏的时候敢不敢报名小弟的直播分享,绝对有干货,绝对有惊喜!
一次早餐钱的投入,可能是薪资的翻倍,可能是视野的拓展!

PHP 进阶之路 - 亿级 pv 网站架构的技术细节与套路

PHP 进阶之路 - 亿级 pv 网站架构实战之性能压榨

PHP 进阶之路 - 后端多元化之快速切入 Java 开发

模块越来越多,业务越来越复杂,RPC 就上场了,在 PHP 的世界里,鸟哥的作品一直备受广大网友的青睐。下面一起学习下鸟哥的 PRC 框架 Yar 。

揭开 Yar 神秘面纱

RPC 采用客户端/服务器模式。首先,客户机调用进程发送一个有进程参数的调用信息到服务进程,然后等待应答信息。在服务器端,进程保持睡眠状态直到调用信息的到达为止。当一个调用信息到达,服务器获得进程参数,计算结果,发送答复信息,然后等待下一个调用信息,最后,客户端调用进程接收答复信息,获得进程结果,然后调用执行继续进行。
这和我们外网 api 的原理不都一个样么?那么我们一起看看高大上的 Yar 是怎么在玩。

Yar 功能演示

客户端代码,假设该服务设在局域网10.211.55.4

 "http://10.211.55.4/yar/server/RewardScoreService.class.php",
    );
 
    public static function init($server){
        if (array_key_exists($server, self::$rpcConfig)) {
            $uri = self::$rpcConfig[$server];
            return new Yar_Client($uri);
        }
    }
}
 
$RewardScoreService = RpcClient::init("RewardScoreService");
var_dump($RewardScoreService->support(1, 2));

服务器端代码

handle();

访问结果如下

uid = 1, feedId = 2
Yar 远程调用的实现原理

实际呢,yar client 是通过__call这个魔术方法来实现远程调用的,在Yar_client类里面并没有任何方法,当我们在调用一个不存在的方式的时候,就会执行__call方法,这个在框架中非常常见。

Yar 协议分析

在 yar 中规定的传输协议如下图所示,请求体为82个字节的yar_header_t和8字节的打包名称和请求实体yar_request_t,在yar_header_t里面用body_len记录8字节的打包名称+请求实体的长度;返回体类似,只是实体内容的结构体稍微不同,在reval里面才是实际最后客户端需要的结果。

整个传输以二进制流的形式传送。

Yar 数据传输的整体流程分析

yar_transport.h中,定义了yar_transport_t结构体,先不考虑并行处理的接口,以socket传输协议为例子学习,代码简化一些如下:

typedef struct _yar_transport_interface {
    void *data;
    int  (*open)(struct _yar_transport_interface *self, char *address, uint len, long options, char **msg TSRMLS_DC);
    int  (*send)(struct _yar_transport_interface *self, struct _yar_request *request, char **msg TSRMLS_DC);
    struct _yar_response * (*exec)(struct _yar_transport_interface *self, struct _yar_request *request TSRMLS_DC);
    int  (*setopt)(struct _yar_transport_interface *self, long type, void *value, void *addition TSRMLS_DC);
    int  (*calldata)(struct _yar_transport_interface *self, yar_call_data_t *calldata TSRMLS_DC);
    void (*close)(struct _yar_transport_interface *self TSRMLS_DC);
} yar_transport_interface_t;
 
 
typedef struct _yar_transport {
    const char *name;
    struct _yar_transport_interface * (*init)(TSRMLS_D);
    void (*destroy)(yar_transport_interface_t *self TSRMLS_DC);
    yar_transport_multi_t *multi;
} yar_transport_t;

然后在transports/socket.c中定义了yar_transport_socket

yar_transport_t yar_transport_socket = {
    "sock",
    php_yar_socket_init,
    php_yar_socket_destroy,
};

整理了整体的执行流程如下图

Yar 数据的打包和解包

鸟哥在yar_packager.c中首先定义了一个结构体,初始化的时候会把各个yar_packager_t注册到**packagers数组中。

struct _yar_packagers_list {
    unsigned int size;
    unsigned int num;
    yar_packager_t **packagers;
} yar_packagers_list;
typedef struct _yar_packager {
    const char *name;
    int  (*pack) (struct _yar_packager *self, zval *pzval, smart_str *buf, char **msg TSRMLS_DC);
    zval * (*unpack) (struct _yar_packager *self, char *content, size_t len, char **msg TSRMLS_DC);
} yar_packager_t;

然后通过传入的nameyar_packager_tname做比较,相同则返回该实例

PHP_YAR_API yar_packager_t * php_yar_packager_get(char *name, int nlen TSRMLS_DC) /* {{{ */ {
    int i = 0;
    for (;iname, name, nlen) == 0) {
            return yar_packagers_list.packagers[i];
        }
    }
 
    return NULL;
} /* }}} */

亲密接触完毕。纸上得来终觉浅,绝知此事要躬行。这篇博客只能是辅助大家在看源码时一起分析,觉不能抛开源码仅仅看这篇博客。

怎么样才能对这个内容真正的掌握呢,所以我有折腾了一个Java 版本的客户端,这样总算有所收获,这份代码也和我们平常写的业务逻辑还是有些区别,二进制的东西居多,整个过程下来对网络数据的传输有了更深刻的理解和学习哈。

Github 项目地址: https://github.com/zhoumengka...

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/23242.html

相关文章

  • phpcms 里面 Yar 使用

    摘要:的框架的话语言的话首选的当然是鸟哥的,支持并行等等,总之有很多优点。首先查看了鸟哥的文章并行的框架,对的基本原理有了一个认识,做了一个简单的请求页面,具体见鸟哥博客,没问题,接下来就是对现有项目的改造了。最后感谢鸟哥写出这么牛掰的东西。 公司新上了个频道,需要我负责的几个频道提供接口,因为进度比较赶,就直接写了web的 http 接口供同事访问。 后来访问量越来越大,出现了很多问题,...

    chnmagnus 评论0 收藏0
  • 并行RPC框架(Concurrent RPC Framework) Yar Java Client

    摘要:客户端并行调用这两个服务这里的方法的命令皆以原版为准则。回调函数需要继承实现里面定义了两个方法是针对并行调用发出之后立即执行的任务,而则是每个请求之后返回的结果。 简介 Yar 是一个轻量级, 高效的 RPC 框架, 它提供了一种简单方法来让 PHP 项目之间可以互相远程调用对方的本地方法. 并且 Yar 也提供了并行调用的能力. 可以支持同时调用多个远程服务的方法.Yar 鸟哥博客介...

    wh469012917 评论0 收藏0
  • 服务治理深入浅出(2)- 远程方法调用实现

    摘要:需求在了解了前面我们关于服务治理出现的必要性之后。我们知道服务治理是建立在众多服务基础之上的,那么,第一步,打通这些服务是基础,也就是我们常说的远程调用。上面执行远程调用也类似。 需求 在了解了前面我们关于服务治理出现的必要性之后。我们知道服务治理是建立在众多服务基础之上的,那么,第一步,打通这些服务是基础,也就是我们常说的 RPC 远程调用。要像调用本地方法一样调用远程服务器上的方法...

    hidogs 评论0 收藏0
  • 为什么鸟哥说 int 再怎么随机也申请不到奇数地址

    摘要:栈上各个变量申请的内存,返回的地址是这段连续内存的最小的地址。为什么用一个位的十六进制来呢因为个字节,一个字节有位,每位有两个状态,那么就是,也就是。为什么用,纯属演示方便。结构体里的字节对齐以成员中自身对齐值最大的那个值为标准。 原文:我的个人博客 https://mengkang.net/1046.html初中级 phper 有多久没给自己充电了呢,安利一波我的直播 PHP 进阶之...

    klinson 评论0 收藏0
  • SOA面向服务基础

    摘要:面向服务面向服务的基础面向服务的三层应用层,服务层,数据层应用层用于给用户展示,,,,安卓。在服务器端,进程保持睡眠状态直到调用信息到达为止。编译完成,提示我们已经在下了。 面向服务 面向服务的基础 面向服务的三层:应用层,服务层,数据层 * 应用层:用于给用户展示,PC,H5,IOS,安卓。 * 服务层:业务逻辑,提供接口(商品,订单,支付,用户,物流)。 * 数据层:提供数据支持(...

    songze 评论0 收藏0

发表评论

0条评论

B0B0

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<