惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Recent Commits to openclaw:main
Recent Commits to openclaw:main
L
LangChain Blog
月光博客
月光博客
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
博客园 - 【当耐特】
宝玉的分享
宝玉的分享
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
Last Week in AI
Last Week in AI
人人都是产品经理
人人都是产品经理
博客园_首页
T
Tailwind CSS Blog
P
Proofpoint News Feed
雷峰网
雷峰网
D
Darknet – Hacking Tools, Hacker News & Cyber Security
IT之家
IT之家
V
Vulnerabilities – Threatpost
阮一峰的网络日志
阮一峰的网络日志
C
CERT Recently Published Vulnerability Notes
Attack and Defense Labs
Attack and Defense Labs
S
Schneier on Security
Security Archives - TechRepublic
Security Archives - TechRepublic
L
Lohrmann on Cybersecurity
V
Visual Studio Blog
云风的 BLOG
云风的 BLOG
WordPress大学
WordPress大学
The Register - Security
The Register - Security
N
Netflix TechBlog - Medium
Hugging Face - Blog
Hugging Face - Blog
Project Zero
Project Zero
博客园 - 叶小钗
F
Full Disclosure
大猫的无限游戏
大猫的无限游戏
Latest news
Latest news
S
SegmentFault 最新的问题
C
Cyber Attacks, Cyber Crime and Cyber Security
Google Online Security Blog
Google Online Security Blog
Recorded Future
Recorded Future
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
Hacker News - Newest:
Hacker News - Newest: "LLM"
腾讯CDC
L
LINUX DO - 最新话题
Google DeepMind News
Google DeepMind News
P
Privacy International News Feed
I
InfoQ
F
Fortinet All Blogs
Vercel News
Vercel News
H
Hackread – Cybersecurity News, Data Breaches, AI and More
T
Threatpost
T
Tenable Blog
B
Blog RSS Feed

文章列表 - 她和她的猫

使用小鹤双拼一个月 折腾 Hugo PaperMod 主题 去长鹿旅游休博园 1Password 自动化登录堡垒机 深入 Hyperf:Inject 注解是如何工作的? 译|理解容器镜像层 使用 Rust 实现高性能预写日志(Write Ahead Log) 译|使用 Linux 命名空间隔离系统 深入 Hyperf:HTTP 服务是如何处理请求的? Linux 文件权限学习笔记 译|了解 Bitcask:基于日志结构的 KV 存储引擎 还原 SM2 压缩公钥的几种方法 深入 Hyperf:HTTP 服务启动时发生了什么? 一次 Hyperf 注解失效问题分析 将博客迁移到又拍云 译|PHP 7 新的 Hashtable 实现 排查 ES 查询问题:深入了解 json_encode() 函数 浅析 Redlock 分布式锁实现原理 Yar 源码阅读笔记:RPC 服务端 Yar 源码阅读笔记:客户端的并行调用 Yar 源码阅读笔记:客户端的同步调用 Yar 源码阅读笔记:数据传输模块 Yar 源码阅读笔记:消息编码模块 Yar 源码阅读笔记:RPC 通信协议 PHP 8 新特性介绍 基于 OpenSSL 实现国密 SM4 加解密 PHP 源码阅读笔记:编译与调试 PHP 什么是惊群问题 大端模式和小端模式 基于 GitHub Actions 定时推送网址到百度站长平台 聊聊五种 I/O 模型 Workerman 源码分析:文件上传 浅入浅出 HTTP 协议 PHP 网络编程:构建 MySQL 蜜罐获取攻击者微信 ID 使用 Workerman 接入 Bilibili 直播弹幕协议 使用 GitHub Actions 自动部署 Hexo 什么是二进制安全 【转载】PHP 程序员进阶之路 优化 Workerman 检查主进程是否存活的逻辑 基于 Redis 实现分布式锁 《PHP 实现 Base64 编码/解码》笔记 PHP 多进程下载必应壁纸 基于 Redis 实现延迟队列 【转载】PHP 实现 Base64 编码/解码 使用 MySQL FIELD() 函数自定义排序规则 Laravel 的 Facades 实现原理 C语言单链表实现约瑟夫环 数据结构学习笔记:顺序栈和链栈(C语言) 使用 QueryList + Redis 下载壁纸 在 Laravel 登录/注册中使用 mews/captcha 扩展包 使用 mews/captcha 扩展包为 Laravel 应用添加图片验证码 给 YOURLS 短网址系统编写插件《批量生成短网址》 给 YOURLS 短网址系统编写插件《Hello World!》 PHP 7.1 使用 json_encode 函数造成浮点类型数据出现精度问题 Laravel 授权策略(Policy)的基本使用 Ubuntu 系统下 WiFi 频繁掉线解决方法 Laravel 应用部署到 Nginx 服务器上的第一个坑 Ubuntu 16.04 LST 安装 Redis 和 Composer PHP 采集逐浪小说章节列表 Nginx 环境 SSL 强制 HTTP 301 跳转到 HTTPS 【工作&生活】第一周 ServiceStack.Redis 与多线程 Count the number of Duplicates C# Base64 加密及解密 ASP.NET MVC 使用动态类型传递数据 Django 使用 order_by() 对数据进行排序操作 ASP.NET + jQuery + AJAX 实现用户登录 ASP.NET 从客户端中检测到有潜在危险的 Request.Form 值 ASP.NET 使用 FormData 实现 AJAX 上传图片 Python 使用 BeautifulSoup 抓取网页 贪心算法之字符串的完美度 一言不和就造轮子之 CookieHelper ASP.NET 上传图片 DBHelper 类 C# 捕获屏幕源码 用 JavaScript 做一些有趣的事情 第一篇文章 好久不见。 如何防止非法调用 PHP 文件 清明小记。 PHP 生成随机字符串 Z-Blog PHP 程序做 301 跳转 PHP 处理数组常用的几个函数 Sublime Text 3 快捷键总结 PHP 使用 file_get_contents() 函数实现采集网页 使用 C# 编写学生信息管理系统 终于到了。 zblog报错: magic_quotes_gpc 和 safe_mode 世事无常。 如何使用 PHP 上传文件 安卓手机编写和运行 PHP 程序的软件 使用 AJAX 刷新、验证 PHP 图片验证码 PHP 生成图片验证码 PHP 之 session 的使用方法 PHP 之 cookie 的使用方法 PHP 实现分页原理详解 Thinkphp 框架中系统常量在 Js 文件中不解析的解决方法
Yar 源码阅读笔记:开篇
她和她的猫 · 2021-10-17 · via 文章列表 - 她和她的猫

前言

本文是 Yar 源码系列的第一篇文章,主要介绍 Yar 以及服务端、客户端的基本使用,详细的源码分析会放在后续的文章中。

我从 8 月初开始阅读 《PHP 7底层设计与源码实现》这本书,直到前一阵子才看完,算是通读了一遍。看完之后总想着动手实操一番,将书中的理论知识赋予实践,做到理论实践相结合。

在挑选研究项目的时候,有以下几个可选项:

Swoole/Swow 是 PHP 高性能协程的网络通信引擎,从语言上来讲,前者由 C++ 编写,后者主要由 C 语言编写,一部分逻辑用 PHP 实现。从编码风格、代码实现来说,我更喜欢后者,虽然公司主要用的 Swoole 框架…

没有选 Swoole/Swow 的原因是,这两个项目包含了网络编程、并发编程、多进程/线程、进程间通信等多项技术,它们支持的功能特性也非常多,讲清楚这些功能的实现也需要花费不少的功夫,不符合我们小而美的目标。

所以在权衡了一阵之后,最终选择了 Yar。

Yar 介绍

Yar(yet another RPC framework,)是鸟哥(laruence)在 2012 年开发的一个轻量级的并行 RPC 框架,支持多种编码方式(JSON、msgpack、PHP)及 HTTP、TCP 两种数据传输方式,最重要的是支持并行调用,可以让多个数据源并行处理,从而提高系统的性能。

Yar 服务端

下面是一个 Yar 服务端的例子:

class User
{
    /**
     * 用户登录
     * @param string $username 用户名
     * @param string $password 密码
     * @return string
     */
    public function login(string $username, string $password): string
    {
        return 'success';
    }
}

$server = new Yar_Server(new User());
$server->handle();

在上面的例子中,定义了一个 User 类,并简单地实现了一个 login 方法,然后实例化 User 类并传入到 Yar_Server 的构造函数中,随后调用 Server 中的 handle 方法,处理即将到来的请求。

在 handle 方法中,通过判断请求方式执行不同的操作。

当请求方式为 POST 时,将会执行 RPC 远程服务 的逻辑:对请求数据进行解析、校验,拿到被调用的方法名称及参数后,执行该方法并响应结果。

当请求方式为非 POST 方式时,输出 RPC 服务的 API 信息。如果在 php.ini 中设置了 yar.expose_info = 0,表示不公开信息,将会抛出 “不允许访问服务信息” 的异常。

将上述的例子保存为 server.php,然后执行 php -S 127.0.0.1:3000 启动 PHP 自带的 Web 服务。

在浏览器中输入 http://127.0.0.1:3000 ,打开服务端 API 信息页面:

从页面中我们可以看到这个 RPC 服务支持的方法列表及方法名称、参数、注释信息。

Yar 客户端

Yar 客户端支持同步调用、并行调用两种方式。

  • 同步调用也就是串行调用,必须前一个请求执行完才能执行下一个请求,不能充分的利用系统资源。
  • 并行调用顾名思义就是能够同时执行多个请求,不需要等待某个请求结束再执行,请求完成后会运行指定的回调函数。

当然,客户端还支持一些其它的特性,例如:请求持久化、自定义 DNS、HTTP 代理等,这些特性的使用方法可以在官方文档中找到,这里就不赘述了。

同步调用

Yar 的同步调用非常简单,就像调用本地方法一样:

// 实例化客户端
$client = new Yar_Client("http://127.0.0.1:3000/server.php");

// 设置超时时间
$client->SetOpt(YAR_OPT_CONNECT_TIMEOUT, 1000);

// 调用 login 方法
$result = $client->login("her-cat", "123456");

var_dump($result);


// 输出:string(7) "success"

并行调用

并行调用的使用方式跟同步调用有一点点区别,调用远程方法时需要通过并行客户端中的 call 方法,并传入相应的回调函数,当请求完成时就会调用该回调函数。

function callback($ret, $callInfo) {
    var_dump($ret, $callInfo);
}

function error_callback($type, $error, $callInfo) {
    error_log($error);
}

$url = 'http://127.0.0.1:3000/server.php';

Yar_Concurrent_Client::call($url, 'login', ['her-cat', '123456'], 'callback', 'error_callback');
Yar_Concurrent_Client::call($url, 'login', ['her-cat', '123456'], 'callback', 'error_callback');
Yar_Concurrent_Client::call($url, 'login', ['her-cat', '123456'], 'callback', 'error_callback', [YAR_OPT_TIMEOUT => 1]);

Yar_Concurrent_Client::loop();

可以看到传入的参数除了 callback 以外,还传入了 error_callback 回调函数,当服务端执行方法的过程中发生了错误,就会运行 error_callback 回调函数。

总结

到这里本文就结束了,后续就会开始从源码的角度去分析这些功能是如何实现的。

Goodbye~