Yar – 并行的RPC框架(Concurrent RPC framework)

Yar(yet another RPC framework, 教主问我为啥都是Ya打头, 呵呵, 因为这样名字好起)是我在3个多月前, 为了解决一个实际的问题, 而开发的一个PHP扩展的, RPC框架, 和现有的RPC框架(xml-rpc, soap)不同, 这是一个轻量级的框架, 支持多种打包协议(msgpack, json, php), 并且最重要的一个特点是, 它是可并行化的..

考虑如下的场景:

传统的Web应用, 一个进程, 一个请求, 天经地义. 然而, 当一个请求的处理中, 涉及到多出数据源, 并且他们之间具有一定的不依赖性.

还是传统的Web应用, 一个应用随着业务快速增长, 开发人员的流转, 就会慢慢的进入一个恶性循环, 代码量上只有加法没有了减法. 因为随着系统变复杂, 牵一发就会动全局, 而新来的维护者, 对原有的体系并没有那么多时间给他让他全面掌握. 即使有这么多时间, 要想掌握以前那么多的维护者的思维的结合, 也不是一件容易的事情…

那么, 长次以往, 这个系统将会越来越不可维护…. 到一个大型应用进入这个恶性循环, 那么等待他的只有重构了.

那么, 能不能对这个系统做解耦呢?

我们已经做了很多解耦了, 数据, 中间件, 业务, 逻辑, 等等, 各种分层. 但到Web应用这块, 还能怎么分呢, MVC我们已经做过了….

基于此, Yar或许能解决你遇到的这俩个问题…

Yar是一个非常轻量级的RPC框架, 我在实现Yar的时候, 追求了极致的轻量级, 它使用非常简单, 对于Server端:

<ol><li><span class="sh_symbol"><?php</span></li><li><span class="sh_keyword">class</span> API <span class="sh_cbracket">{</span></li><li>    <span class="sh_comment">/**</span></li><li><span class="sh_comment">     * the doc info will be generated automatically into service info page.</span></li><li><span class="sh_comment">     * </span><span class="sh_type">@params</span></li><li><span class="sh_comment">     * </span><span class="sh_type">@return</span></li><li><span class="sh_comment">     */</span></li><li>    public <span class="sh_keyword">function</span> <span class="sh_function">api</span><span class="sh_symbol">(</span><span class="sh_variable">$parameter</span><span class="sh_symbol">,</span> <span class="sh_variable">$option</span> <span class="sh_symbol">=</span> <span class="sh_string">"foo"</span><span class="sh_symbol">)</span> <span class="sh_cbracket">{</span></li><li>    <span class="sh_cbracket">}</span></li><li> </li><li>    protected <span class="sh_keyword">function</span> <span class="sh_function">client_can_not_see</span><span class="sh_symbol">()</span> <span class="sh_cbracket">{</span></li><li>    <span class="sh_cbracket">}</span></li><li><span class="sh_cbracket">}</span></li><li> </li><li><span class="sh_variable">$service</span> <span class="sh_symbol">=</span> <span class="sh_keyword">new</span> <span class="sh_function">Yar_Server</span><span class="sh_symbol">(</span><span class="sh_keyword">new</span> <span class="sh_function">API</span><span class="sh_symbol">());</span></li><li><span class="sh_variable">$service</span><span class="sh_symbol">-></span><span class="sh_function">handle</span><span class="sh_symbol">();</span></li><li><span class="sh_symbol">?></span></li></ol>

和Soap使用方法很相像吧? 是的, 就这样, 你的API类就可以对外提供服务了..

Yar为了方便开发, 把文档和接口绑定到了一起, 对于上面的例子, 如果我们是简单的GET请求这个接口地址的话, 我们就会看到如下的信息页面:

这样, 我们可以在注释中,把接口的信息标注好, 就可以让文档和接口在一起了.

而对于Client端来说, 简单的串行调用, 会非常之简单:

<ol><li><span class="sh_symbol"><?php</span></li><li><span class="sh_variable">$client</span> <span class="sh_symbol">=</span> <span class="sh_keyword">new</span> <span class="sh_function">Yar_Client</span><span class="sh_symbol">(</span><span class="sh_string">"http://host/api/"</span><span class="sh_symbol">);</span></li><li><span class="sh_variable">$result</span> <span class="sh_symbol">=</span> <span class="sh_variable">$client</span><span class="sh_symbol">-></span><span class="sh_function">api</span><span class="sh_symbol">(</span><span class="sh_string">"parameter);</span></li><li><span class="sh_string">?></span></li></ol>

这样一来, 如果你有多个服务, 你只需要一个client.

那么, 最激动人心的并行化调用呢?

<ol><li><span class="sh_symbol"><?php</span></li><li><span class="sh_keyword">function</span> <span class="sh_function">callback</span><span class="sh_symbol">(</span><span class="sh_variable">$retval</span><span class="sh_symbol">,</span> <span class="sh_variable">$callinfo</span><span class="sh_symbol">)</span> <span class="sh_cbracket">{</span></li><li>     <span class="sh_function">var_dump</span><span class="sh_symbol">(</span><span class="sh_variable">$retval</span><span class="sh_symbol">);</span></li><li><span class="sh_cbracket">}</span></li><li> </li><li>Yar_Concurrent_Client<span class="sh_symbol">::</span><span class="sh_function">call</span><span class="sh_symbol">(</span><span class="sh_string">"http://host/api/"</span><span class="sh_symbol">,</span> <span class="sh_string">"api"</span><span class="sh_symbol">,</span> <span class="sh_keyword">array</span><span class="sh_symbol">(</span><span class="sh_string">"parameters"</span><span class="sh_symbol">),</span> <span class="sh_string">"callback"</span><span class="sh_symbol">);</span></li><li>Yar_Concurrent_Client<span class="sh_symbol">::</span><span class="sh_function">call</span><span class="sh_symbol">(</span><span class="sh_string">"http://host/api/"</span><span class="sh_symbol">,</span> <span class="sh_string">"api"</span><span class="sh_symbol">,</span> <span class="sh_keyword">array</span><span class="sh_symbol">(</span><span class="sh_string">"parameters"</span><span class="sh_symbol">),</span> <span class="sh_string">"callback"</span><span class="sh_symbol">);</span></li><li>Yar_Concurrent_Client<span class="sh_symbol">::</span><span class="sh_function">call</span><span class="sh_symbol">(</span><span class="sh_string">"http://host/api/"</span><span class="sh_symbol">,</span> <span class="sh_string">"api"</span><span class="sh_symbol">,</span> <span class="sh_keyword">array</span><span class="sh_symbol">(</span><span class="sh_string">"parameters"</span><span class="sh_symbol">),</span> <span class="sh_string">"callback"</span><span class="sh_symbol">);</span></li><li>Yar_Concurrent_Client<span class="sh_symbol">::</span><span class="sh_function">call</span><span class="sh_symbol">(</span><span class="sh_string">"http://host/api/"</span><span class="sh_symbol">,</span> <span class="sh_string">"api"</span><span class="sh_symbol">,</span> <span class="sh_keyword">array</span><span class="sh_symbol">(</span><span class="sh_string">"parameters"</span><span class="sh_symbol">),</span> <span class="sh_string">"callback"</span><span class="sh_symbol">);</span></li><li>Yar_Concurrent_Client<span class="sh_symbol">::</span><span class="sh_function">loop</span><span class="sh_symbol">();</span> <span class="sh_comment">//send</span></li><li><span class="sh_symbol">?></span></li></ol>

这样, 所有的请求会一次发出, 只要有任何一个请求完成, 回调函数”callback”就会被立即调用.

这里还有一个细节, Yar见缝插针的不会浪费任何时间, 在这些请求发送完成以后, Yar会调用一次callback, 和普通的请求返回回调不同, 这次的调用的$callinfo参数为空.

这样一来, 我们就可以先发送请求, 然后再第一次回调, 继续做我们当前进程的工作, 等所有工作结束以后, 再交给Yar去获取并行RPC的响应.

<ol><li><span class="sh_symbol"><?php</span></li><li><span class="sh_keyword">function</span> <span class="sh_function">callback</span><span class="sh_symbol">(</span><span class="sh_variable">$retval</span><span class="sh_symbol">,</span> <span class="sh_variable">$callinfo</span><span class="sh_symbol">)</span> <span class="sh_cbracket">{</span></li><li>    <span class="sh_keyword">if</span> <span class="sh_symbol">(</span><span class="sh_variable">$callinfo</span> <span class="sh_symbol">==</span> NULL<span class="sh_symbol">)</span> <span class="sh_cbracket">{</span></li><li>       <span class="sh_comment">//做本地的逻辑</span></li><li>       <span class="sh_keyword">return</span> TRUE<span class="sh_symbol">;</span></li><li>    <span class="sh_cbracket">}</span></li><li> </li><li>     <span class="sh_comment">//RPC请求返回, 返回值在$retval</span></li><li><span class="sh_cbracket">}</span></li></ol>

有了这些, 我们就可以把一个Web应用中, 多个数据源并行处理, 从而也能把这些逻辑解耦, 分开部署…

当然Yar目前还在试用阶段, 所以还没有发布任何一个包(Yar at PECL), 但是有兴趣的同学可以现在就把代码clone下去试用哦(虽然没有正式投入试用, 不过已经经过了验证).

Yar: Yar at Github

PS, 如果要使用Msgpack(一个高效的二进制打包协议)做为打包协议, 需要单独安装Msgpack扩展(Msgpack), 这个扩展目前也是我在维护, 我会在近几天把他在PECL上发布, 尽请期待.


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值