Dora RPC

简介(Introduction)

Dora RPC 是一款基础于Swoole定长包头通讯协议的最精简的RPC, 用于复杂项目前后端分离,分离后项目都通过API工作可更好的跟踪、升级、维护及管理。

问题提交: Issue

For complex projects separation, the project can be better maintained by the API project management.

Dora RPC is an Basic Swoole Fixed Header TCP Proctol tiny RPC

Now support an simple PHP version

If you find something wrong,please submit an issue

add the http protocol and KeepAlive for the other program language

设计思路(Design)

功能支持(Function)

支持单API调用,多API并发调用

支持同步调用,异步任务下发不等待结果,异步任务下发统一拿回结果

其他相关知识请参考Swoole扩展

客户端长链接,请求完毕后仍旧保留,减少握手消耗

guid收发一致性检测,避免发送和接收数据不一致

基于redis制作的服务发现

Single API RPC \ Multi API Concurrent RPC

Asynchronous,synchronization no need result, synchronization get result by manual

Please visit Swoole official for further infomation

keep the connection of client after the request finishe

check the guid when the sendrecive

service discovery.

base on Redis. Service discovery for High available

请安装依赖(depend)

Swoole 1.8.x+

PHP 5.4+

zlib for compress packet

##Installation

composer require "xcl3721/dora-rpc"

文件功能简介(File)

dora-rpc/src/Client.php

使用最简单的方式实现的客户端,通过这个框架可以轻松实现PHP的伪多线程,通过分布式加快接口响应速度及高可用

an simple client,it's easy adn simply to implement the multi fake thread,you can speed up you API by this distribute RPC

dora-rpc/src/BackEndServer.php

API服务端

目前需要继承才能使用,继承后请实现dowork,这个函数是实际处理任务的函数参数为提交参数

做这个只是为了减少大家启用RPC的开发时间

开启服务发现功能,服务端在启动的时候,如果指定redis配置则会自动将当前服务器信息注册到Redis上

返回结果是一个数组 分两部分,第一层是通讯状态code,第二层是处理状态 code

a powerful API server

you must extends the swserver and implement dowork function

it's use for decrease the dev cycle

when you setup the redis config the server will register this server to the redis for service discovery

the result will be a two-level arrayfirst is communicate state 'code field' ,second is dowork state

dora-rpc/src/Monitor.php

服务发现客户端,通过扫描Redis获取到所有可用后端服务列表,并生成配置到指定路径

an discovery controller client that:scan all the redis and get the list of available service and general config file to special path

dora-rpc/src/groupclient.php (combined to client.php)

服务发现monitor进程产生的配置可以用这个客户端直接引用,请求时可以指定使用哪个组的服务

an client for service discovery (monitor general the config from redis) that you can use the config directly

使用方法(Example)

任务下发模式介绍(task deploy mode)

0 sync wait result 同步下发任务阻塞等待结果返回

1 async no need result 下发异步任务,下发成功返回下发成功提示,不等待任务处理结果

2 async get result by getAsyncData function 下发异步任务,下发成功返回下发成功提示,可以在后续调用getAsyncData 获取所有下发的异步结果

TCP客户端(TCP Client)

$config = include("client.conf.php");

//define the mode

$mode = array("type" => 1, "group" => "group1");

$maxrequest = 0;

//new obj

$obj = new \DoraRPC\Client($config);

//change connect mode

$obj->changeMode($mode);

for ($i = 0; $i < 10000; $i++) {

//echo $i . PHP_EOL;

//single

$time = microtime(true);

//single && sync

$ret = $obj->singleAPI("/module_a/abc" . $i, array("mark" => 234, "foo" => $i), \DoraRPC\DoraConst::SW_MODE_WAITRESULT, 1);

var_dump("single sync", $ret);

//single call && async

$ret = $obj->singleAPI("/module_b/abc" . $i, array("yes" => 21321, "foo" => $i), \DoraRPC\DoraConst::SW_MODE_NORESULT, 1);

var_dump("single async", $ret);

//single call && async

$ret = $obj->singleAPI("/module_c/abd" . $i, array("yes" => 233, "foo" => $i), \DoraRPC\DoraConst::SW_MODE_ASYNCRESULT, 1);

var_dump("single async result", $ret);

//multi

//multi && sync

$data = array(

"oak" => array("name" => "/module_c/dd" . $i, "param" => array("uid" => "ff")),

"cd" => array("name" => "/module_f/ef" . $i, "param" => array("pathid" => "fds")),

);

$ret = $obj->multiAPI($data, \DoraRPC\DoraConst::SW_MODE_WAITRESULT, 1);

var_dump("multi sync", $ret);

//multi && async

$data = array(

"oak" => array("name" => "/module_d/oakdf" . $i, "param" => array("dsaf" => "32111321")),

"cd" => array("name" => "/module_e/oakdfff" . $i, "param" => array("codo" => "f11ds")),

);

$ret = $obj->multiAPI($data, \DoraRPC\DoraConst::SW_MODE_NORESULT, 1);

var_dump("multi async", $ret);

//multi && async

$data = array(

"oak" => array("name" => "/module_a/oakdf" . $i, "param" => array("dsaf" => "11")),

"cd" => array("name" => "/module_b/oakdfff" . $i, "param" => array("codo" => "f11ds")),

);

$ret = $obj->multiAPI($data, \DoraRPC\DoraConst::SW_MODE_ASYNCRESULT, 1);

var_dump("multi async result", $ret);

//get all the async result

$data = $obj->getAsyncData();

var_dump("allresult", $data);

//compare each request

$time = bcsub(microtime(true), $time, 5);

if ($time > $maxrequest) {

$maxrequest = $time;

}

echo $i . " cost:" . $time . PHP_EOL;

}

echo "max:" . $maxrequest . PHP_EOL;

HTTP客户端(Http Client)

http protocol for the other language use performance is common.suggest used tcp client

for ($i = 0; $i < 10000; $i++) {

$time = microtime(true);

//mutil call sync wait result

$data = array(

"guid" => md5(mt_rand(1000000, 9999999) . mt_rand(1000000, 9999999) . microtime(true)),

"api" => array(

"oak" => array("name" => "/module_d/oakdf", "param" => array("dsaf" => "32111321")),

"cd" => array("name" => "/module_e/oakdfff", "param" => array("codo" => "f11ds")),

)

,

);

$data_string = "params=" . urlencode(json_encode($data));

$ch = curl_init('http://127.0.0.1:9566/api/multisync');

curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");

curl_setopt($ch, CURLOPT_POSTFIELDS, $data_string);

curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

curl_setopt($ch, CURLOPT_HTTPHEADER, array(

'Connection: Keep-Alive',

'Keep-Alive: 300',

)

);

$result = curl_exec($ch);

var_dump(json_decode($result, true));

//multi call no wait result

$data = array(

"guid" => md5(mt_rand(1000000, 9999999) . mt_rand(1000000, 9999999) . microtime(true)),

"api" => array(

"oak" => array("name" => "/module_d/oakdf", "param" => array("dsaf" => "32111321")),

"cd" => array("name" => "/module_e/oakdfff", "param" => array("codo" => "f11ds")),

)

,

);

$data_string = "params=" . urlencode(json_encode($data));

$ch = curl_init('http://127.0.0.1:9566/api/multinoresult');

curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");

curl_setopt($ch, CURLOPT_POSTFIELDS, $data_string);

curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

curl_setopt($ch, CURLOPT_HTTPHEADER, array(

'Connection: Keep-Alive',

'Keep-Alive: 300',

)

);

$result = curl_exec($ch);

var_dump(json_decode($result, true));

$time = bcsub(microtime(true), $time, 5);

if ($time > $maxrequest) {

$maxrequest = $time;

}

echo $i . " cost:" . $time . PHP_EOL;

//var_dump($ret);

}

echo "max:" . $maxrequest . PHP_EOL;

服务端(Server)

class Server extends DoraRPCServer {

//all of this config for optimize performance

//以下配置为优化服务性能用,请实际压测调试

protected $externalConfig = array(

//to improve the accept performance ,suggest the number of cpu X 2

//如果想提高请求接收能力,更改这个,推荐cpu个数x2

'reactor_num' => 32,

//packet decode process,change by condition

//包处理进程,根据情况调整数量

'worker_num' => 40,

//the number of task logical process progcessor run you business code

//实际业务处理进程,根据需要进行调整

'task_worker_num' => 20,

);

function initServer($server){

//the callback of the server init 附加服务初始化

//such as swoole atomic table or buffer 可以放置swoole的计数器,table等

}

function doWork($param){

//process you logical 业务实际处理代码仍这里

//return the result 使用return返回处理结果

return array("hehe"=>"ohyes");

}

function initTask($server, $worker_id){

//require_once() 你要加载的处理方法函数等 what's you want load (such as framework init)

}

}

$res = new Server();

###客户端监控器(Client Local Monitor)

include "src/Doraconst.php";

include "src/Packet.php";

include "src/Monitor.php";

//redis for service discovery register

//when you on product env please prepare more redis to registe service for high available

$redisconfig = array(

array(//first reporter

"ip" => "127.0.0.1",

"port" => "6379",

),

array(//next reporter

"ip" => "127.0.0.1",

"port" => "6379",

),

);

//ok start server

$res = new \DoraRPC\Monitor("0.0.0.0", 9569, $redisconfig, "./client.conf.php");

//this server will auto get the node server list from redis and general the client config on special path

以上代码测试方法

include以上两个文件,使用命令行启动即可(客户端支持在apache nginx fpm内执行,服务端只支持命令行启动)

php democlient.php

php demoserver.php

错误码及含义(Error Code)

0 Success work

100001 async task success

100002 unknow task type

100003 you must fill the api parameter on you request

100005 Signed check error

100006 Pack decode type wrong

100007 socket error the recive packet length is wrong

100008 the return guid wrong may be the socket trasfer wrong data

100009 the recive wrong or timeout

100010 there is no server can connect

100011 unknow cmd of controlle

100012 Get Async Result Fail: Client Closed.

100099 unknow communicate mode have been set

100100 guid wront please retry..

性能(Performance)

Mac I7 Intel 2.2Mhz

Vagrant with Vm 1 Core

1G Memory

with example code (loop forever)

测试结果Result

Network Cost:0.002~0.004/sec Per Request

CPU 10~25% 以上还有很大优化空间 There is still a lot of optimization space

Optimize performance性能优化

vim demoserver.php

to see $externalConfig var

and swoole offcial document

如果想优化性能请参考以上文件的$externalConfig配置

Server Config Optimize

License授权

Apache

QQ Group

QQ Group:346840633

php微服务rpc选择,Dora RPC:PHP 的分布式 RPC,支持微服务、服务发现相关推荐

  1. 微支付基础:为什么支付宝、微信不可能支持微支付?

    在科普微支付的过程中,有一个问题同样被问及较多,而且大部分提问者都是工程技术人员,那就是:要支持微支付的功能,为什么一定要使用BitcoinSV,我不能使用支付宝.微信提供的支付接口?更或者,我自己开 ...

  2. 售后支持领域的服务指标

    01|背景 目前市场上对于数据分析的概念知识讲解较多,对某一个领域或者某个具体场景的分析较少.笔者目前从事售后支持工作有一段时间,希望能借此文章对售后支持领域的服务指标进行梳理,以期待不断完善自己的技 ...

  3. 检测设备是否支持Google Play服务

    在使用Google Play服务之前,需要判断当前的设备是否支持Google Play服务,Google官方提供了两种方法来进行判断 一.使用GoogleAPiClient类访问Google Play ...

  4. .NET Core微服务之服务间的调用方式(REST and RPC)

    一.REST or RPC ? 1.1 REST & RPC 微服务之间的接口调用通常包含两个部分,序列化和通信协议.常见的序列化协议包括json.xml.hession.protobuf.t ...

  5. 服务中没有listen_Go语言微服务框架实战:2.Go语言实现RPC编程绍

    Go语言实现RPC编程 @author:Davie 版权所有:北京千锋互联科技有限公司 上节课我们对RPC知识做了介绍,讲解了RPC的原理,通过图示方式讲解了RPC的内部执行过程.本节课,我们继续来学 ...

  6. rpc wmi 服务不可用_golang 基础(5) RPC

    ![golang_real.jpg](https://upload-images.jianshu.io/upload_images/8207483-659e64f6f71b221d.jpg?image ...

  7. 腾讯QQ团队开源分布式后台毫秒服务引擎全解析:引擎架构、RPC、灰度……

    腾讯QQ团队将于12月4日开源一个服务开发运营框架,叫做毫秒服务引擎(Mass Service Engine in Cluster,MSEC),它集RPC.名字发现服务.负载均衡.业务监控.灰度发布. ...

  8. 企业信息化建设中微服务架构选择的必要性

    目前大型或者超大型企业的IT平台都是烟囱式的系统架构,缘由是企业内部为了迎合业务发展不停地打造各种系统,也导致各系统间的重复功能建设和维护带来的重复投资.重复投资不仅消耗了人力.财力还有时间.但打通烟 ...

  9. voyage java_GitHub - yezilong9/voyage: 采用Java实现的基于netty轻量的高性能分布式RPC服务框架...

    Voyage Overview 采用Java实现的基于netty轻量的高性能分布式RPC服务框架.实现了RPC的基本功能,开发者也可以自定义扩展,简单,易用,高效. Features 服务端支持注解配 ...

最新文章

  1. Lua中的字符串函数库
  2. mybatis使用foreach实现sql的in查询
  3. Dojo EnhancedGrid Pagination
  4. 2.6 MYSQL的输出格式
  5. 漫水填充及Photoshop中魔术棒选择工具的实现
  6. mac mysql 移动硬盘_MAC一些高能过程记录(一些没必要的坑)
  7. 中油即时通信电脑版_市场营销之即时通讯营销
  8. bat循环导oracle,Oracle备份恢复与批处理文件实操
  9. 通过js动态设置select中option选中
  10. 10硬盘锁怎么解除_鉴定二手iPad是否拼装,扩容,隐藏ID锁的详细方法
  11. HDU 5015 233 Matrix 矩阵快速幂
  12. javascript实现继承的几种主要方法
  13. 计算机CPU核的位数,如何查cpu位数
  14. 项目成本管理:成本与成本管理概念
  15. app营销实训报告_市场营销模拟软件实训报告
  16. 爱快做无线打印服务器,听说爱快路由器也支持NAS了?
  17. ipv6地址分类 java_IPv6的本地联网地址计算方法详解
  18. EasySwoole 基础入门
  19. getsockopt
  20. 在jupter中利用Python编程查看pkl文件内容的步骤

热门文章

  1. R语言临床诊断试验的ROC分析方法示例
  2. ML基石_11_HazardOfOverfitting
  3. 中文语境下的手机号识别
  4. 基因测序的回顾与展望
  5. Corrigendum: A window into third generation sequencing
  6. Basic local alignment search tool (BLAST)
  7. php redis 二进制,php-redis扩展
  8. ubuntu 安装 python3.6.8
  9. 【多标签文本分类】融合CNN-SAM与GAT的多标签文本分类模型
  10. js、css分别实现元素水平垂直居中