PHP遠程調用, 爲什麼需要使用RPC 轉

前言

 

一個項目,從開始到版本更新,一直到最後的版本維護。功能在不斷增多,對應的代碼量也在不斷增加,也就意味着項目變得更不可維護,這時候,我們需要用拆分的方式將一個項目打散,以便開發團隊更好的對項目進行維護。

分模塊

這個階段,一般也是項目的初級階段,由於人手不夠,一個服務端的接口項目只有一個開發進行維護,根據開發的習慣,會把項目分成若干個模塊進行開發,在一個項目下進行部署。

這樣做的缺點在於項目會隨着版本更新而變得不可維護。

分項目

隨着每個模塊功能的不斷完善,代碼變得更加臃腫。這時候需要對項目進行拆分,比如上面的圖,分成用戶體系項目、支付體系項目。

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

遠程過程調用協議

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的接口標準進行面向資源的數據訪問。

人員需求

項目拆分的前提是一個項目不足以滿足現有的業務發展要求,也就意味着拆分之後的開發人員數量的擴增。

游擊隊向正規軍編制的跨越!

文檔

更多的項目也就意味着更多的接口調用文檔,適當的處理文檔才能更好的提高團隊協作效率。

後記

服務的遠程調用在於怎麼合理的把一個正在變得不可維護的項目從焦油坑中解救出來,並提高項目整體能承載的業務量,不過,世界上沒有銀彈。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章