使用yaf+yar实现基于http的rpc服务

article/2025/9/26 6:25:13

什么是RPC

RPC,全称是Remote Procedure Call,远程服务调用,是一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的协议。简单一点来理解就是网络上的一个节点请求另一个节点提供的服务。

什么是YAF

Yaf,全称 Yet Another Framework,使用C语言编写,是一个以PHP扩展形式提供的PHP开发框架。相比于一般的PHP框架,它更快、更轻便,它提供了Bootstrap、路由、分发、视图、插件,是一个全功能的PHP框架。

YAF框架如何下载安装

什么是YAR

Yar,全称Yet Another RPC framework for PHP, 是一个轻量级, 高效的RPC框架, 它提供了一种简单方法来让PHP项目之间可以互相远程调用对方的本地方法. 并且Yar也提供了并行调用的能力. 可以支持同时调用多个远程服务的方法。

YAR扩展如何安装

YAR文档

准备工作

使用上面的YAF框架安装教程部署2个一模一样的项目,并绑定域名a.myyaf.com做服务端,绑定域名b.myyaf.com做客户端。

服务端实现

0x01,新建application/library/servers/CalculatorServer.php

<?php
namespace Servers;class CalculatorServer {/*** 加法* @param $left* @param $right* @return mixed*/public function plus($left,$right) {return $left + $right;}/*** 减法* @param $left* @param $right* @return mixed*/public function minus($left,$right){return $left - $right;}/*** 乘法* @param $left* @param $right* @return mixed*/public function mul($left,$right){return $left * $right;}/*** 除法* @param $left* @param $right* @return mixed*/public function div($left, $right){return $left / $right;}
}

0x02,新建application/controllers/Rpc.php

<?phpclass RpcController extends \Yaf\Controller_Abstract {public function calculatorAction() {$server = new \Yar_Server(new \MyRpc\Servers\CalculatorServer());$server->handle();return false;}}

使用get方法请求链接,可以查看对应server的接口列表和注释。

客户端实现

0x01,调用远程服务

编辑application\controllers\Index.php

<?php
class IndexController extends \Yaf\Controller_Abstract {public function indexAction() {$client = new \Yar_Client('http://a.myyaf.com/rpc/calculator');$left = 1;$right = 2;$result = $client->plus($left,$right);echo "{$left} + {$right} = {$result}";return false;}
}

访问b.myyaf.com查看下效果

0x02,并行调用远程服务

编辑application\controllers\Index.php,新增loopAction、callBack、errorCallBack三个函数

<?php
class IndexController extends \Yaf\Controller_Abstract {public function loopAction(){\Yar_Concurrent_Client::call('http://a.myyaf.com/rpc/calculator','plus',[1,2]);\Yar_Concurrent_Client::call('http://a.myyaf.com/rpc/calculator','minus',[5,3]);\Yar_Concurrent_Client::call('http://a.myyaf.com/rpc/calculator','mul',[3,4]);\Yar_Concurrent_Client::call('http://a.myyaf.com/rpc/calculator','div',[9,3]);Yar_Concurrent_Client::loop([$this,'callback'], [$this,'errorCallBack']);return false;}public function callBack($retval, $callinfo){echo '调用成功回调<hr/>';}public function errorCallBack($type, $error, $callinfo){echo '调用失败回调<hr/>';}
}

 访问b.myyaf.com/index/loop查看下效果

0x03,并行调用指定回调函数、错误回调函数

上面调用结果是5个调用成功回调,这个是因为\Yar_Concurrent_Client::call未设置回调函数,默认会使用\Yar_Concurrent_Client::loop的回调函数。可以分别指定每个\Yar_Concurrent_Client::call的回调函数、错误回调函数。
<?php
class IndexController extends \Yaf\Controller_Abstract {# 并行调用public function loopAction(){\Yar_Concurrent_Client::call('http://a.myyaf.com/rpc/calculator','plus',[1,2],[$this,'plusCallBack']);\Yar_Concurrent_Client::call('http://a.myyaf.com/rpc/calculator','minus',[5,3],[$this,'minusCallBack']);\Yar_Concurrent_Client::call('http://a.myyaf.com/rpc/calculator','mul',[3,4],[$this,'mulCallBack']);\Yar_Concurrent_Client::call('http://a.myyaf.com/rpc/calculator','div',[9,3],[$this,'divCallBack']);Yar_Concurrent_Client::loop([$this,'callback'], [$this,'errorCallBack']);return false;}public function callBack($retval, $callinfo){echo '调用成功回调<hr/>';}public function errorCallBack($type, $error, $callinfo){echo '调用失败回调<hr/>';}public function plusCallBack($retval, $callinfo){echo "加法回调,结果:{$retval}<hr/>";}public function minusCallBack($retval, $callinfo){echo "减法回调,结果:{$retval}<hr/>";}public function mulCallBack($retval, $callinfo){echo "乘法回调,结果:{$retval}<hr/>";}public function divCallBack($retval, $callinfo){echo "除法回调,结果:{$retval}<hr/>";}
}

再次访问b.myyaf.com/index/loop查看下效果 

0x04,多次调用loop

如果在一次请求里面多次使用loop,后面的loop会携带上次loop的请求结果。

服务端编辑application/library/servers/CalculatorServer.php,新增square函数

<?php
namespace Servers;class CalculatorServer {/*** 加法* @param $left* @param $right* @return mixed*/public function plus($left,$right) {return $left + $right;}/*** 减法* @param $left* @param $right* @return mixed*/public function minus($left,$right){return $left - $right;}/*** 乘法* @param $left* @param $right* @return mixed*/public function mul($left,$right){return $left * $right;}/*** 除法* @param $left* @param $right* @return mixed*/public function div($left, $right){return $left / $right;}/*** 平方* @param $a* @return float|int*/public function square($a){return $a * $a;}
}

 客户端编辑application\controllers\Index.php

<?php
class IndexController extends \Yaf\Controller_Abstract {# 并行调用public function loopAction(){\Yar_Concurrent_Client::call('http://a.myyaf.com/rpc/calculator','plus',[1,2],[$this,'plusCallBack']);\Yar_Concurrent_Client::call('http://a.myyaf.com/rpc/calculator','minus',[5,3],[$this,'minusCallBack']);\Yar_Concurrent_Client::call('http://a.myyaf.com/rpc/calculator','mul',[3,4],[$this,'mulCallBack']);\Yar_Concurrent_Client::call('http://a.myyaf.com/rpc/calculator','div',[9,3],[$this,'divCallBack']);Yar_Concurrent_Client::loop([$this,'callback'], [$this,'errorCallBack']);\Yar_Concurrent_Client::call('http://a.myyaf.com/rpc/calculator','square',[6],[$this,'squareCallBack']);Yar_Concurrent_Client::loop([$this,'callback'], [$this,'errorCallBack']);return false;}public function callBack($retval, $callinfo){echo '调用成功回调<hr/>';}public function errorCallBack($type, $error, $callinfo){echo '调用失败回调<hr/>';}public function plusCallBack($retval, $callinfo){echo "加法回调,结果:{$retval}<hr/>";}public function minusCallBack($retval, $callinfo){echo "减法回调,结果:{$retval}<hr/>";}public function mulCallBack($retval, $callinfo){echo "乘法回调,结果:{$retval}<hr/>";}public function divCallBack($retval, $callinfo){echo "除法回调,结果:{$retval}<hr/>";}public function squareCallBack($retval, $callinfo){echo "平方回调,结果:{$retval}<hr/>";}
}

 可以在loop之前使用\Yar_Concurrent_Client::reset()清空上一次loop的结果

<?php
class IndexController extends \Yaf\Controller_Abstract {# 并行调用public function loopAction(){\Yar_Concurrent_Client::call('http://a.myyaf.com/rpc/calculator','plus',[1,2],[$this,'plusCallBack']);\Yar_Concurrent_Client::call('http://a.myyaf.com/rpc/calculator','minus',[5,3],[$this,'minusCallBack']);\Yar_Concurrent_Client::call('http://a.myyaf.com/rpc/calculator','mul',[3,4],[$this,'mulCallBack']);\Yar_Concurrent_Client::call('http://a.myyaf.com/rpc/calculator','div',[9,3],[$this,'divCallBack']);Yar_Concurrent_Client::loop([$this,'callback'], [$this,'errorCallBack']);Yar_Concurrent_Client::reset();\Yar_Concurrent_Client::call('http://a.myyaf.com/rpc/calculator','square',[6],[$this,'squareCallBack']);Yar_Concurrent_Client::loop([$this,'callback'], [$this,'errorCallBack']);return false;}public function callBack($retval, $callinfo){echo '调用成功回调<hr/>';}public function errorCallBack($type, $error, $callinfo){echo '调用失败回调<hr/>';}public function plusCallBack($retval, $callinfo){echo "加法回调,结果:{$retval}<hr/>";}public function minusCallBack($retval, $callinfo){echo "减法回调,结果:{$retval}<hr/>";}public function mulCallBack($retval, $callinfo){echo "乘法回调,结果:{$retval}<hr/>";}public function divCallBack($retval, $callinfo){echo "除法回调,结果:{$retval}<hr/>";}public function squareCallBack($retval, $callinfo){echo "平方回调,结果:{$retval}<hr/>";}
}

 0x05,运行时配置

yar的配置项包含以下内容:

yar.timeout,处理超时,默认5000ms

yar.connect_timeout,连接超时,默认1000ms

yar.packager,打包方式,有php、json、msgpack三种方式,默认是php,当使用--enable-msgpack构建时默认“msgpack”

yar.debug,默认关闭

yar.content_type,默认是application/octet-stream

yar.allow_persistent,持续连接,默认关闭

接下来,我们来测试下处理超时的情况。

服务端编辑application/library/servers/CalculatorServer.php,修改plus函数

<?php
namespace Servers;class CalculatorServer {/*** 加法* @param $left* @param $right* @return mixed*/public function plus($left,$right) {sleep(5);return $left + $right;}/*** 减法* @param $left* @param $right* @return mixed*/public function minus($left,$right){return $left - $right;}/*** 乘法* @param $left* @param $right* @return mixed*/public function mul($left,$right){return $left * $right;}/*** 除法* @param $left* @param $right* @return mixed*/public function div($left, $right){return $left / $right;}/*** 平方* @param $a* @return float|int*/public function square($a){return $a * $a;}
}

客户端编辑application\controllers\Index.php,修改indexAction函数

<?php
class IndexController extends \Yaf\Controller_Abstract {public function indexAction() {$client = new \Yar_Client('http://a.myyaf.com/rpc/calculator');$client->setOpt(YAR_OPT_CONNECT_TIMEOUT,1);$client->setOpt(YAR_OPT_TIMEOUT,1);$left = 1;$right = 2;$result = $client->plus($left,$right);echo "{$left} + {$right} = {$result}";return false;}}

 并行调用也可以设置配置。

<?php
class IndexController extends \Yaf\Controller_Abstract {# 并行调用public function loopAction(){\Yar_Concurrent_Client::call('http://a.myyaf.com/rpc/calculator','plus',[1,2],[$this,'plusCallBack'],[$this,'plusErrorCallBack'],[YAR_OPT_TIMEOUT=>1,YAR_OPT_CONNECT_TIMEOUT=>1]);\Yar_Concurrent_Client::call('http://a.myyaf.com/rpc/calculator','minus',[5,3],[$this,'minusCallBack']);\Yar_Concurrent_Client::call('http://a.myyaf.com/rpc/calculator','mul',[3,4],[$this,'mulCallBack']);\Yar_Concurrent_Client::call('http://a.myyaf.com/rpc/calculator','div',[9,3],[$this,'divCallBack']);Yar_Concurrent_Client::loop([$this,'callback'], [$this,'errorCallBack']);Yar_Concurrent_Client::reset();\Yar_Concurrent_Client::call('http://a.myyaf.com/rpc/calculator','square',[6],[$this,'squareCallBack']);Yar_Concurrent_Client::loop([$this,'callback'], [$this,'errorCallBack']);return false;}public function callBack($retval, $callinfo){echo '调用成功回调<hr/>';}public function errorCallBack($type, $error, $callinfo){echo '调用失败回调<hr/>';}public function plusCallBack($retval, $callinfo){echo "加法回调,结果:{$retval}<hr/>";}public function plusErrorCallBack($type, $error, $callinfo){echo "加法错误回调:{$error}<hr/>";}public function minusCallBack($retval, $callinfo){echo "减法回调,结果:{$retval}<hr/>";}public function mulCallBack($retval, $callinfo){echo "乘法回调,结果:{$retval}<hr/>";}public function divCallBack($retval, $callinfo){echo "除法回调,结果:{$retval}<hr/>";}public function squareCallBack($retval, $callinfo){echo "平方回调,结果:{$retval}<hr/>";}
}

也可以使用ini_set()设置

ini_set('yar.timeout',1000);
ini_set('yar.connect_timeout',1000);

也可以直接修改php.ini设置

yar.timeout = 1000

yar.connect_time = 1000


http://chatgpt.dhexx.cn/article/WZnxcbrO.shtml

相关文章

yaf yar微服务/hprose微服务 镜像初始化 —— k8s从入门到高并发系列教程 (四)

前面的教程已经在docker镜像 软件 层面上初步安装了企业常用的插件&#xff0c;但目前还没有写任何代码。本教程带你初始化yaf框架&#xff0c;并基于yar框架和hprose跨语言微服务框架打包两个微服务代码&#xff0c;在容器间调用。 yaf是一个用c语言写的&#xff0c;用于php项…

YAR 并行RPC框架研究

前几天,部门召开了PHP技术峰会 学习会议,大家分别对这次会议的PPT 做了简单的介绍, 其中提到了 鸟哥【惠新辰】的一篇PPT《微博LAMP 演变》,如果谁有需要可以去谷歌搜,或者去 http://www.laruence.com/2013/08/15/2913.html 他的博客去看一下,我就不提供下载链接了。 …

Yarn概述

Yarn Yarn是Hadoop的分布式资源调度平台&#xff0c;负责为集群的运算提供运算资源。如果把分布式计算机和单个计算机相对应的话&#xff0c;HDFS就相当于计算机的文件系统&#xff0c;Yarn就是计算机的操作系统&#xff0c;MapReduce就是计算机上的应用程序。 Yarn的基本组成…

Yarn介绍

Yarn介绍 一&#xff0c;介绍二&#xff0c; yarn 框架三&#xff0c;ResourceManager3.1&#xff0c;ApplicationsManager3.2&#xff0c;Scheduler 四&#xff0c;NodeManager五&#xff0c;ApplicationMaster六&#xff0c;客户端提交任务到yarn中运行的流程。 YARN的基本思…

Yarn

应用场景 当部署好hadoop集群后,搭建了YARN集群,开启了hadoop的HDFS和YARN服务,访问主节点IP和8088端口的YARN监控界面,发现这个All Applications界面中的开始执行时间和结束执行时间不对,应该往后加8个小时才对,导致在页面中对任务监控的时候容易出错,所以现在要进行修…

Yar 搭建 RPC 服务

一、安装 Yar pecl install yar pecl install msgpack 二、确保 php 加载 yar 模块 php -m 三、编写服务器端 Server.php &#xff0c; 在浏览器打开 http://.../Server.php 可见API的介绍如下 <?phpclass API {public function some_method($parameter, $options &…

[Yar] yar安装与使用过程中遇到问题总结

yar安装与使用过程中遇到问题总结 Yar 简介官方文档yar安装yar运行时的默认配置yar常量使用范例遇到的问题应用流程 Yar 简介 Yar 是一个轻量级, 高效的RPC框架, 它提供了一种简单方法来让PHP项目之间可以互相远程调用对方的本地方法. 并且Yar也提供了并行调用的能力. 可以支持…

PHP封装curd,ThinkPHP5.0的模型CURD创建Create操作

模型的主要功能包括数据处理和业务逻辑&#xff0c;而这些都离不开数据的CURD操作&#xff0c;因此我们首先来谈下数据的CURD操作&#xff0c;在掌握了数据库Db类的用法后&#xff0c;模型的CURD操作就会很容易理解&#xff0c;因为本质上模型的CURD操作最终调用的还是Db类的操…

浅谈CURD系统和CRQS系统

浅谈CURD系统和CRQS系统 在网上看到关于这个内容的介绍&#xff0c;就想着自己整理一下&#xff0c;方便观看。 三层架构 先从三层架构开始讲&#xff0c;三层架构(3-tier architecture) 通常意义上的三层架构就是将整个业务应用划分为:界面层(User Interface layer)、业务逻辑…

Vue入门之Web端CURD前端项目示例

Vue入门之Web端CURD前端项目示例 随着vue.js越来越火&#xff0c;很多不太懂前端的小伙伴想要入坑。而入坑最好的办法就是上手实际操作&#xff0c;因此本文将重点放在实际操作上&#xff0c;对理论不做过多解释&#xff0c;不明白的地方小伙伴们可以去看官方文档或者相关书籍…

fastadmin一键生成CURD

1.登录后台以后安装在线命令插件 2.CRUD fastadmin自带一个test表可以用来测试&#xff0c;或者是自己在数据库随便新建一个表也行 自定义模块名这样填的话就是在admin->controller下->新建一个名为test文件夹 只写test的话是在 controller 目录下面 然后点击生成命令行…

php跨域curd,SpringBoot+Vue前后端分离(CURD)Demo

我发现我好久没有更新了&#xff0c;写一篇证明我还活着。 既然是前后端分离的话&#xff0c;肯定是要有前端和后端的。 这里前端我使用的VueElementUI,后端采用的是SpringBootMybatisSwagger2。 下面的话&#xff0c;我就做一个简单的Demo吧。 写的不好&#xff0c;请大家各位…

单表CURD操作

该项目纯粹用 Servlet 编写&#xff0c;理解跳转过程。理解原理..... 一、准备数据库脚本 USE test;DROP TABLE IF EXISTS dept;CREATE TABLE dept (deptno int(2) NOT NULL,dname varchar(14) DEFAULT NULL,loc varchar(13) DEFAULT NULL,PRIMARY KEY (DEPTNO) ) ENGINEInnoD…

Avue-curd个性化定制

在使用vue(js)elelment(ui)开发一些后台管理项目的时候&#xff0c;基本会用到 列表页&#xff0c;条件搜索(search),表格数据(table),分页&#xff0c;操作栏的&#xff0c;增、删、改、查几种操作。如下图这样的&#xff1a; 很多的页面都很类似&#xff0c;这里就给大家介绍…

Python简单CURD

python Python的注释模块 python变量 格式化输出 转义字符 与 数据类型 控制台输入 实体类 Student.dy class Emp:def __init__(self,id,name,age,sex,sal):self.id idself.name nameself.age ageself.sex sexself.sal saldef __str__(self):return "学号&#xf…

MySQL常用语句(CURD)

文章目录 一、数据库定义语言&#xff08;DDL&#xff09;1.1 库操作1.2 表操作 二、数据库操纵语言&#xff08;DML&#xff09;2.1 插入 insert2.2 修改 update2.3 删除 delete 三、数据库查询语言&#xff08;DQL&#xff09;3.1 单表查询①查询&#xff1a;select②条件&am…

SpringBoot实现CURD

SpringBoot实现CURD 项目列表 Pom.xml <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"http:/…

thinkphp curd 列表关联展现方式分享

在维护自己的开源框架中&#xff0c;针对后台列表模板&#xff0c;有时候我们需要在一键CURD的情况下&#xff0c;进行多个字段的关联显示&#xff0c;比如用户订单表里面存在user_id字段&#xff0c;那么在显示的时候&#xff0c;我们期望显示出用户的名称&#xff0c;而不是用…

mysql curd_mysql 基础之CURD

原文:mysql 基础之CURD 增删改查基本语法学习 增: insert Insert 3问: 1: 插入哪张表? 2: 插入哪几列? 3: 这几列分别插入什么值? Insert into TableName (列1,列2....列n) Values (值1,值2,....值n) 值 与 列,按顺序,一一对应 特殊: insert语句 允不允许不写列名 答:允许. …

小白入门:什么是CURD?

CRUD是CREATE、READ、UPDATE和DELETE的首字母缩写词&#xff0c;在数据库操作中频繁出现&#xff0c;本文针对小白&#xff0c;如果你已经是开发人员或者对数据库有一定认识的工程师可以默默离开了。让我直接走进CURD的世界。 为什么 CRUD 如此重要&#xff1f; CRUD 经常用于…