资料介绍
软件简介
swrpc是一个基于swoole开发的高性能rpc包,swrpc提供了注册发现,链路追踪,中间件等等功能,可以很容易集成到第三方框架,如laravel,yii等等。
功能
- 支持多进程模式或协程模式
- 支持同步,异步调用
- 支持自定义中间件
- 支持服务端按类提供对外服务
- 支持链路追踪
- 支持注册服务发现
- 支持客户端负载均衡,包含随机,权重两种模式
- 支持自定义日志,包协议,序列化方式等等
安装
php composer.phar require wuzhc/swprc ~1.0 -vvv
快速体验
假设我们User和School两个模块,为了获得用户学校名称,我们需要在User模块发起rpc请求调用School模块的服务。
School模块
use Swrpc\LogicService;
class SchoolService extends LogicService
{
public function getUserSchool($userID) {
$name = $userID == 123 ? '火星' : '水星';
return $name.'学校';
}
}
School模块将作为rpc服务端,对外提供服务,启动如下:
namespace SwrpcTests;
use Swrpc\Server;
$basePath = dirname(dirname(__FILE__));
require_once $basePath . "/vendor/autoload.php";
$options = [
'enable_coroutine' => true,
'pid_file' => __DIR__ . '/swrpc.pid',
];
$server = new Server('School_Module', '127.0.0.1', 9501, 1, $options);
$server->addService(\SwrpcTests\services\SchoolService::class);
$server->start();
将SchoolService添加到server,server会自动检索类中所有可用的public方法。
User模块
User模块作为客户端,调用School模块服务如下
namespace SwrpcTests;
use Swrpc\Request;
use Swrpc\LogicService;
use Swrpc\Client;
class UserService extends LogicService
{
public function getUserSchoolName()
{
$userID = 123;
$module = 'School_Module'; //请求目标模块名称,需要和服务端定义的一致
$client = Client::create($module, '127.0.0.1', 9501);
return $client->send(Request::create('\SwrpcTests\services\SchoolService_getUserSchool', [$userID]));
}
}
//调用
echo UserService::factory()->getUserSchoolName();
注意:
-
Request.method 为服务类命名 + 下划线 + 方法名,例如上面的
\SwrpcTests\services\SchoolService_getUserSchool
,如果服务类有命名空间,记得一定要带上命名空间
多进程和协程模式
多进程或协程模式需要和swoole配置一致,具体参考swoole配置
多进程模式
创建10进程来处理请求
$options = [ 'worker_num' => 10 'pid_file' => __DIR__ . '/swrpc.pid', ]; $server = new Server('School_Module', '127.0.0.1', 9501, 1, $options);
协程模式
目前swrpc协程模式是运行在单进程的
$options = [ 'enable_coroutine' => true, 'pid_file' => __DIR__ . '/swrpc.pid', ]; $server = new Server('School_Module', '127.0.0.1', 9501, 1, $options);
同步调用和异步调用
在客户端发起同步调用,客户端会一直等待服务端返回结果
$client = \Swrpc\Client::create($module, '127.0.0.1', 9501); return $client->send(SyncRequest::create('SchoolService_getUserSchool', [$userID]));
在客户端发起异步调用,客户端会立马得到响应结果,请求将被swoole的task进程处理
$client = \Swrpc\Client::create($module, '127.0.0.1', 9501); return $client->send(AsyncRequest::create('SchoolService_getUserSchool', [$userID]));
自定义中间件
中间件允许程序可以对请求进行前置操作和后置操作,底层使用了责任链设计模式,所以为了执行下一个中间件,必须返回$next($request)
,如果想提前返回,则返回结果必须是Swrpc\Response
类型
//中间件除了用匿名函数定义,还可以用实现Swrpc\Middlewares\MiddlewareInterface接口的类 $middleware = function (\Swrpc\Request $request, Closure $next) { $start = microtime(true); //前置操作,记录请求开始时间 $result = $next($request); echo '耗时:'.(microtime(true) - $start).PHP_EOL; //后置操作,记录请求结束时间,从而计算请求耗时 return $result; //继续下个中间件的处理 }; $server = new Server('School_Module', '127.0.0.1', 9501, 1, $options); $server->addService(SchoolService::class); $server->addMiddleware($middleware); //添加中间件 $server->start();
如果要提前中止中间件,可以提前在匿名函数或类方法中返回\Swrpc\Response对象,如下
$middleware = function (\Swrpc\Request $request, Closure $next) { if (empty($request->getParams())) { return \Swrpc\Response::error('参数不能为空'); //提前返回,必须是Response类型 } return $next($request); };
服务端按类提供对外服务
从上面的例子中,我们把SchoolService整个类添加的server中,这样server就能对外提供SchoolService类所有public方法的功能。
$server = new Server('School_Module', '127.0.0.1', 9501, 1, $options); $server->addService(SchoolService::class); //提供SchoolService所有public方法功能 $server->addService(AreaService::class); //提供AreaService所有public方法功能 $server->start();
客户端使用参考上面的快速体验
注册服务发现
如果服务端启动的时候有设置注册中心,则启动成功会自动向注册中心注册服务端地址。目前swrpc提供了Consul
作为注册中心,使用如下
$server = new Server('School_Module', '127.0.0.1', 9501, 1, $options); $server->addRegister(new Consul()); $server->addService(SchoolService::class); $server->start();
如上,使用Consul作为服务的注册中心,通过http://127.0.0.1:8500
可以查看注册信息,如果想用etcd等其他注册中心,只要实现Swrpc\Middlewares\RegisterInterface
接口即可,然后在通过$server->addRegister()
添加到server
客户端负载均衡
如果服务端启动多个节点,例如School模块启动3个节点,并且注册到了注册中心,那么我们可以从注册中心获取所有服务端节点信息,然后做一些策略处理。
$register = new Consul(); $client = \Swrpc\Client::createBalancer('School_Module', $register, \Swrpc\Client::STRATEGY_WEIGHT); $result = $client->send(Request::create('SchoolService_getUserSchool', [$userID]);
目前swrpc提供两种简单策略模式,\Swrpc\Client::STRATEGY_WEIGHT权重模式
,\Swrpc\Client::STRATEGY_RANDOM
随机模式
链路追踪
当我们的服务非常多并且需要互相调用时候,如果其中某个调用失败,会导致我们得不到我们想要的结果,而要调试出是哪个环节出了问题也比较麻烦,可能你需要登录每台机器看下有没有错误日志,或者看返回的错误信息是哪个服务提供的。链路追踪记录了整个调用链过程,如果某个环节出错,我们可以快速从调用链得到调用中断地方。
class UserService extends LogicService { public function getUserSchoolName() { $userID = 123; $module = 'School_Module'; //请求目标模块名称,需要和服务端定义的一致 $client = Client::create($module, '127.0.0.1', 9501); return $client->send(Request::create('SchoolService_getUserSchool', [$userID], $this->getTracerContext(__FUNCTION__))); //getTracerContext()用于提供追踪上下文 } } $users = UserService::factory() ->setModule('User_Module') //当前模块,用于调用链的起点 ->setTracerUrl('http://127.0.0.1:9411/api/v2/spans') //zipkin链路追踪地址 ->getUserSchoolName();
如图,User_Module调用Class_Module,Class_Module又去调用School_Module
每个调用还记录响应结果
自定义日志处理器
默认使用Monolog/Logger
作为日志处理器,日志信息会输出到控制台。可根据自己需求覆盖默认处理器,只要日志类 实现Psr\Log\LoggerInterface
即可
use Swrpc\Server; use Monolog\Handler\StreamHandler; use Monolog\Logger; $logger = new Logger('swrpc'); $logger->pushHandler(new StreamHandler(fopen('xxxx.log','w+'), Logger::DEBUG)); $server = new Server('127.0.0.1', 9501, ['enable_coroutine'=>true]); $server->addService(UserService::class); $server->addLogger($logger); //覆盖默认日志处理器 $server->start();
序列化方式
默认使用固定头+包体来解决tcp粘包问题,默认配置为'package_length_type' => 'N'
,'package_body_offset' => 4
默认序列化数据会使用serialize()
,如果swoole版本在4.5以上的自动使用swoole_substr_unserialize(),可以实现的类来覆盖默认配置,只要实现src/Packer/PackerInterface
即可,注意服务端和客户端需要使用一样的协议,否则解析不了。
use Swrpc\Server; $packer = new \Swrpc\Packer\SerializeLengthPacker(); $server = new Server('127.0.0.1', 9501, ['enable_coroutine'=>true]); $server->addService(UserService::class); $server->addPacker($packer); //覆盖默认值
安全证书配置
参考:https://wiki.swoole.com/#/server/setting?id=ssl_cert_file
服务端
$options = [ 'ssl_cert_file' => __DIR__.'/config/ssl.crt', 'ssl_key_file' => __DIR__.'/config/ssl.key', 'pid_file' => __DIR__ . '/swrpc.pid', ]; $server = new Server('School_Module', '127.0.0.1', 9501, $options, SWOOLE_PROCESS, SWOOLE_SOCK_TCP | SWOOLE_SSL); $server->addService(SchoolService::class); $server->start();
注意:
-
文件必须为
PEM
格式,不支持DER
格式,可使用openssl
工具进行转换
测试
使用phpuint实现的简单测试案例,配置文件phpunit.xml
php phpunit.phar tests --debug
phpunit 测试报告
Client (SwrpcTests\Client)
[x] Client connect
[x] Client sync request
[x] Client async request
Packer (SwrpcTests\Packer)
[x] Serialize length pack
[x] Serialize lenght unpack
[x] Serialize eof pack
[x] Serialize eof unpack
Server (SwrpcTests\Server)
[x] Server register to consul
[x] Server unregister from consul
[x] Server add service
[x] Server add middleware
- 220MHz高性能差分振荡器SiT9121 4次下载
- USB数据抓包软件程序下载 7次下载
- 高性能Type-C/DP1.4至HDMI2.0b转换器CS5265AN 20次下载
- 高性能电流模式PWM控制器UC2842B和UC3842B系列 9次下载
- 高性能六轴MEMS运动跟踪装置ICM-20602 14次下载
- 基于ARM的高密度高性能线STM32F103xC 0次下载
- MX25L6445E高性能串行闪存规范文件 20次下载
- 高性能嵌入式堆栈Azure PTOS USBX概述 10次下载
- 高效高性能LED恒流驱动电源芯片AX2028 24次下载
- 高性能低成本的蓝牙模块CSR6576原理图 16次下载
- TQQ7101超高性能BAW双工器的详细数据手册免费下载
- 如何使用KEELOQ3开发工具包作为开发工具来在目标板上仿真和调试固件
- 如何使用高性能工具包作为开发工具在目标板上仿真和调试固件
- OV971高性能视频汽车视觉应用简介.pdf 1次下载
- La、Co代换永磁铁氧体的高性能化与工艺技术
- 带你了解什么是高性能计算(HPC) 277次阅读
- TSMaster RPC 基础入门:编程指导和使用说明 593次阅读
- 什么是HTTP协议?什么是RPC协议?二者如何选择使用? 2304次阅读
- RPC接口和HTTP接口的区别与联系 1660次阅读
- OpenDaylight中的RPC & Notification是什么 811次阅读
- RPC如何在远程过程中调用? 793次阅读
- 浅析OSAT的高性能封装技术 4897次阅读
- 关于HPC的高性能计算测试方法 2112次阅读
- OpenMV Cam上的RPC模块 1302次阅读
- 深入理解RPC自定义网络协议 2384次阅读
- 为什么需要RPC接口 2556次阅读
- 三栅极的应用优势及对高性能FPGA性能的影响以及 1662次阅读
- 中国科学院开发出了多种低功耗小尺寸高性能的气体传感器 1295次阅读
- 什么是RPC?为什么需要RPC? 1.4w次阅读
- 适合高性能FPGA开发的HTG-703 1495次阅读
下载排行
本周
- 1山景DSP芯片AP8248A2数据手册
- 1.06 MB | 532次下载 | 免费
- 2RK3399完整板原理图(支持平板,盒子VR)
- 3.28 MB | 339次下载 | 免费
- 3TC358743XBG评估板参考手册
- 1.36 MB | 330次下载 | 免费
- 4DFM软件使用教程
- 0.84 MB | 295次下载 | 免费
- 5元宇宙深度解析—未来的未来-风口还是泡沫
- 6.40 MB | 227次下载 | 免费
- 6迪文DGUS开发指南
- 31.67 MB | 194次下载 | 免费
- 7元宇宙底层硬件系列报告
- 13.42 MB | 182次下载 | 免费
- 8FP5207XR-G1中文应用手册
- 1.09 MB | 178次下载 | 免费
本月
- 1OrCAD10.5下载OrCAD10.5中文版软件
- 0.00 MB | 234315次下载 | 免费
- 2555集成电路应用800例(新编版)
- 0.00 MB | 33566次下载 | 免费
- 3接口电路图大全
- 未知 | 30323次下载 | 免费
- 4开关电源设计实例指南
- 未知 | 21549次下载 | 免费
- 5电气工程师手册免费下载(新编第二版pdf电子书)
- 0.00 MB | 15349次下载 | 免费
- 6数字电路基础pdf(下载)
- 未知 | 13750次下载 | 免费
- 7电子制作实例集锦 下载
- 未知 | 8113次下载 | 免费
- 8《LED驱动电路设计》 温德尔著
- 0.00 MB | 6656次下载 | 免费
总榜
- 1matlab软件下载入口
- 未知 | 935054次下载 | 免费
- 2protel99se软件下载(可英文版转中文版)
- 78.1 MB | 537798次下载 | 免费
- 3MATLAB 7.1 下载 (含软件介绍)
- 未知 | 420027次下载 | 免费
- 4OrCAD10.5下载OrCAD10.5中文版软件
- 0.00 MB | 234315次下载 | 免费
- 5Altium DXP2002下载入口
- 未知 | 233046次下载 | 免费
- 6电路仿真软件multisim 10.0免费下载
- 340992 | 191187次下载 | 免费
- 7十天学会AVR单片机与C语言视频教程 下载
- 158M | 183279次下载 | 免费
- 8proe5.0野火版下载(中文版免费下载)
- 未知 | 138040次下载 | 免费
评论
查看更多