PHP远程调用, 为何须要使用RPC

前言

 

一个项目,从开始到版本更新,一直到最后的版本维护。功能在不断增多,对应的代码量也在不断增长,也就意味着项目变得更不可维护,这时候,咱们须要用拆分的方式将一个项目打散,以便开发团队更好的对项目进行维护。php

分模块

这个阶段,通常也是项目的初级阶段,因为人手不够,一个服务端的接口项目只有一个开发进行维护,根据开发的习惯,会把项目分红若干个模块进行开发,在一个项目下进行部署。编程

这样作的缺点在于项目会随着版本更新而变得不可维护。json

分项目

随着每一个模块功能的不断完善,代码变得更加臃肿。这时候须要对项目进行拆分,好比上面的图,分红用户体系项目、支付体系项目。api

CURL

开始你们会采用CURL的方式对外部资源进行访问。服务器

好比某短信平台SDK,好比各大第三方提供的SDK,纠结到源码发现都是直接采用CURL函数的方式进行访问。网络

优势在于没有环境要求,能直接用。
缺点在于并发访问的资源占用问题。并发

//新浪微博SDK的http请求部分源码

 /**

     * Make an HTTP request

     *

     * @return string API results

     * @ignore

     */

    function http($url, $method, $postfields = NULL, $headers = array()) {

        $this->http_info = array();       

        $ci = curl_init();       

        /* Curl settings */

        curl_setopt($ci, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);

        curl_setopt($ci, CURLOPT_USERAGENT, $this->useragent);

        curl_setopt($ci, CURLOPT_CONNECTTIMEOUT, $this->connecttimeout);

        curl_setopt($ci, CURLOPT_TIMEOUT, $this->timeout);

        curl_setopt($ci, CURLOPT_RETURNTRANSFER, TRUE);

        curl_setopt($ci, CURLOPT_ENCODING, "");

        curl_setopt($ci, CURLOPT_SSL_VERIFYPEER, $this->ssl_verifypeer);       

        if (version_compare(phpversion(), '5.4.0', '<')) {

            curl_setopt($ci, CURLOPT_SSL_VERIFYHOST, 1);

        } else {

            curl_setopt($ci, CURLOPT_SSL_VERIFYHOST, 2);

        }

        curl_setopt($ci, CURLOPT_HEADERFUNCTION, array($this, 'getHeader'));

        curl_setopt($ci, CURLOPT_HEADER, FALSE);       

        switch ($method) {           

        case 'POST':

                curl_setopt($ci, CURLOPT_POST, TRUE);               

                if (!empty($postfields)) {

                    curl_setopt($ci, CURLOPT_POSTFIELDS, $postfields);                   

                    $this->postdata = $postfields;

                }               

                break;           

                case 'DELETE':

                curl_setopt($ci, CURLOPT_CUSTOMREQUEST, 'DELETE');               

                if (!empty($postfields)) {                   

                $url = "{$url}?{$postfields}";

                }

        }        if ( isset($this->access_token) && $this->access_token )           

        $headers[] = "Authorization: OAuth2 ".$this->access_token;       

        if ( !empty($this->remote_ip) ) {           

        if ( defined('SAE_ACCESSKEY') ) {               

        $headers[] = "SaeRemoteIP: " . $this->remote_ip;

            } else {               

            $headers[] = "API-RemoteIP: " . $this->remote_ip;

            }

        } else {           

        if ( !defined('SAE_ACCESSKEY') ) {//               

        $headers[] = "API-RemoteIP: " . $_SERVER['REMOTE_ADDR'];

            }

        }

        curl_setopt($ci, CURLOPT_URL, $url );

        curl_setopt($ci, CURLOPT_HTTPHEADER, $headers );

        curl_setopt($ci, CURLINFO_HEADER_OUT, TRUE );       

        $response = curl_exec($ci);       

        $this->http_code = curl_getinfo($ci, CURLINFO_HTTP_CODE);       

        $this->http_info = array_merge($this->http_info, curl_getinfo($ci));       

        $this->url = $url;       

        if ($this->debug) {           

        echo "=====post data======\r\n";

            var_dump($postfields);           

            echo "=====headers======\r\n";

            print_r($headers);           

            echo '=====request info====='."\r\n";

            print_r( curl_getinfo($ci) );           

            echo '=====response====='."\r\n";

            print_r( $response );

        }

        curl_close ($ci);       

        return $response;

    }

RPC框架

远程过程调用协议curl

RPC(Remote Procedure Call Protocol)——远程过程调用协议,它是一种经过网络从远程计算机程序上请求服务,而不须要了解底层网络技术的协议。RPC协议假定某些传输协议的存在,如TCP或UDP,为通讯程序之间携带信息数据。在OSI网络通讯模型中,RPC跨越了传输层和应用层。RPC使得开发包括网络分布式多程序在内的应用程序更加容易。编程语言

RPC采用客户机/服务器模式。请求程序就是一个客户机,而服务提供程序就是一个服务器。首先,客户机调用进程发送一个有进程参数的调用信息到服务进程,而后等待应答信息。在服务器端,进程保持睡眠状态直到调用信息到达为止。当一个调用信息到达,服务器得到进程参数,计算结果,发送答复信息,而后等待下一个调用信息,最后,客户端调用进程接收答复信息,得到进程结果,而后调用执行继续进行。

Yar

鸟哥出品的RPC框架,轻量级框架。

<?phpclass API {
    /**
     * the doc info will be generated automatically into service info page.
     * @params
     * @return
     */
    public function api($parameter, $option = "foo") {
    }    protected function client_can_not_see() {
    }
}$service = new Yar_Server(new API());$service->handle();?>

调用代码

<?php$client = new Yar_Client("http://host/api/");$result = $client->api("parameter);

?>

注意的是鸟哥出的东西文档比较少,须要多调试。

Thrift

thrift是一个软件框架,用来进行可扩展且跨语言的服务的开发。它结合了功能强大的软件堆栈和代码生成引擎,以构建在 C++, Java, Python, PHP, Ruby, Erlang, Perl, Haskell, C#, Cocoa, JavaScript, Node.js, Smalltalk, and OCaml 这些编程语言间无缝结合的、高效的服务。

远程调用的意义在于,不一样的子项目能够用更适合本身的语言来解决,更有效率的实现需求。

同时,对团队的开发来说,更能提升总体的技术水平。

SOAP

因为用的XML就很少描述了,毕竟仍是json用的多。

JSON-RPC

下面是返回值的标准

--> [

    {"jsonrpc": "2.0", "method": "sum", "params": [1,2,4], "id": "1"},

    {"jsonrpc": "2.0", "method": "notify_hello", "params": [7]},

    {"jsonrpc": "2.0", "method": "subtract", "params": [42,23], "id": "2"},

    {"foo": "boo"},

    {"jsonrpc": "2.0", "method": "foo.get", "params": {"name": "myself"}, "id": "5"},

    {"jsonrpc": "2.0", "method": "get_data", "id": "9"}

    ]

<-- [

    {"jsonrpc": "2.0", "result": 7, "id": "1"},

    {"jsonrpc": "2.0", "result": 19, "id": "2"},

    {"jsonrpc": "2.0", "error": {"code": -32600, "message": "Invalid Request"}, "id": null},

    {"jsonrpc": "2.0", "error": {"code": -32601, "message": "Method not found"}, "id": "5"},

    {"jsonrpc": "2.0", "result": ["hello", 5], "id": "9"}

    ]

实际上你会发现咱们在给客户端提供接口的返回值,就是按照这个标准来作的。

相应的,服务端对服务端的数据接收和返回,也要一样按照这个标准来作。

项目拆分带来的变化

项目细化

一个模块对应一个项目,项目之间经过基于REST的接口标准进行面向资源的数据访问。

人员需求

项目拆分的前提是一个项目不足以知足现有的业务发展要求,也就意味着拆分以后的开发人员数量的扩增。

游击队向正规军编制的跨越!

文档

更多的项目也就意味着更多的接口调用文档,适当的处理文档才能更好的提升团队协做效率。

后记

服务的远程调用在于怎么合理的把一个正在变得不可维护的项目从焦油坑中解救出来,并提升项目总体能承载的业务量,不过,世界上没有银弹。