摘要:需求在了解了前面我們關于服務治理出現的必要性之后。我們知道服務治理是建立在眾多服務基礎之上的,那么,第一步,打通這些服務是基礎,也就是我們常說的遠程調用。上面執行遠程調用也類似。
需求
在了解了前面我們關于服務治理出現的必要性之后。我們知道服務治理是建立在眾多“服務”基礎之上的,那么,第一步,打通這些服務是基礎,也就是我們常說的 RPC 遠程調用。要像調用本地方法一樣調用遠程服務器上的方法。
現在簡單粗暴口語化的方式來介紹一個需求:
分析A 服務器上部署的項目中,有一個UserService里面有一個getUserInfo的方法。
B 服務器上想"直接"調用該方法,怎么辦?
我們以 PHP 為例來進行分析。
我們希望在 B 服務器上實現類似于 A 服務器上直接調用方式
$userService = new UserService(); $userService->getUserInfo($uid);
我們經常會使用 SDK 來調用第三方提供的 api 服務,我們的做法肯定類似于
$client = new SDKClient(); $request = new SDKUserServiceRequestGetStudentInfoRequest(); $request->setUid($uid); $request->setMethod("GET"); $response = $client->doAction($request);
sdk 里面的 GetStudentInfoRequest 通過http映射 A 服務器上的UserService::getUserInfo。
sdk 的改造我們只需要在原來的基礎上稍作修改即可,下面的代碼僅做簡單的演示
服務端該服務部署在localhost:8081
class UserService { public static function getUserInfo($uid) { // 假設以下內容從數據庫取出 return [ "id" => $uid, "username" => "mengkang", ]; } } $service = $_GET["service"]; $action = $_GET["action"]; $argv = file_get_contents("php://input"); if (!$service || !$action) { die(); } if ($argv) { $argv = json_decode($argv, true); } $res = call_user_func_array([$service, $action], $argv); echo json_encode($res);客戶端
class Client { private $url; private $service; private $rpcConfig = [ "UserService" => "http://127.0.0.1:8081", ]; /** * Client constructor. * @param $service */ public function __construct($service) { if (array_key_exists($service, $this->rpcConfig)) { $this->url = $this->rpcConfig[$service]; $this->service = $service; } } public function __call($action, $arguments) { $content = json_encode($arguments); $options["http"] = [ "timeout" => 5, "method" => "POST", "header" => "Content-type:application/x-www-form-urlencoded", "content" => $content, ]; $context = stream_context_create($options); $get = [ "service" => $this->service, "action" => $action, ]; $url = $this->url . "?" . http_build_query($get); $res = file_get_contents($url, false, $context); return json_decode($res, true); } } $userService = new Client("UserService"); var_export($userService->getUserInfo(103));
這樣是不是就非常方便的在客戶端實現了像在本地一樣調用遠程的方法呢?這也是鳥哥 @Laruence yar 的操作原理。下面對比下 Yar 的 demo:
Yar 演示yar https://github.com/laruence/yar
yar 的 java 客戶端 https://github.com/zhoumengka...
客戶端代碼,假設該服務設在局域網10.211.55.4上
class RpcClient { // RPC 服務地址映射表 public static $rpcConfig = array( "RewardScoreService" => "http://10.211.55.4/yar/server/RewardScoreService.class.php", ); public static function init($server){ if (array_key_exists($server, self::$rpcConfig)) { $uri = self::$rpcConfig[$server]; return new Yar_Client($uri); } } } $RewardScoreService = RpcClient::init("RewardScoreService"); var_dump($RewardScoreService->support(1, 2));
服務器端代碼
class RewardScoreService { /** * $uid 給 $feedId 點贊 * @param $feedId interge * @param $uid interge * @return void */ public function support($uid,$feedId){ return "uid = ".$uid.", feedId = ".$feedId; } } $yar_server = new Yar_server(new RewardScoreService()); $yar_server->handle();
yar 背后的故事就是我前面那段 sdk 改造的代碼演示。想必看到這里,rpc 框架不再那么神秘了吧。
當然這只是實現了 rpc 的一小部分,簡單的遠程調用。畢竟 php 是世界上最好的語言。
java 上面執行遠程調用也類似。
如果換成 java 可稍微麻煩點,java 實現起來之后會讓你覺得更加的本地化,所以 java 也是最強大的語言。
由于 java 是靜態編譯的,不存在類似于 php 里的__call方法的方式來實現遠程調用,一般通過動態代理來實現
import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; /** * Created by zhoumengkang on 5/12/15. */ /** * 點贊的積分服務接口 */ interface RewardScoreService{ String support(int uid,int feedId); } public class SupportService { public static void main(String[] args) { add(1,2); } /** * uid 給 feedId 點贊 * @param uid * @param feedId * @return */ public static String add(int uid, int feedId){ YarClient yarClient = new YarClient(); RewardScoreService rewardScoreService = (RewardScoreService) yarClient.proxy(RewardScoreService.class); return rewardScoreService.support(uid, feedId); } } class YarClient { public final Object proxy(Class type) { YarClientInvocationHandler handler = new YarClientInvocationHandler(); return Proxy.newProxyInstance(type.getClassLoader(), new Class[]{type}, handler); } } final class YarClientInvocationHandler implements InvocationHandler { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("這里的動態調用實現了 php 的 __call 方法"); System.out.println("method : " + method.getName()); for (int i = 0; i < args.length; i++) { System.out.println("args["+ i +"] : " + args[i]); } return null; } }了解更多
看完本篇,是不是頓時覺得 rpc 框架不再那么神秘,有一點點感覺了呢?
老鐵周末的直播:揭開她的神秘面紗 - 零基礎構建自己的服務治理框架 趕快上車
https://segmentfault.com/l/15...
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/31974.html
摘要:服務化的出現假想一個京東的發展路程都是我虛構的。更多的服務的提取抽離,更多的團隊出現業務繼續發展,出現了京東大藥房,專門賣藥,需要調用京東目前的財務系統。 以下內容都是自己的理解,不保證正確,可能是對的,也可能把你帶溝里,自己甄別。 更多詳情請看直播 揭開她的神秘面紗 - 零基礎構建自己的服務治理框架 https://segmentfault.com/l/15... 很久之前聽別人分...
摘要:在服務治理方面,相較于而言,并不成熟。遺憾的是,往往被部分開發者片面地視作服務治理的框架,而非微服務基礎設施。因此,建議開發人員將或者遷移為服務。因此,下一步需要將其配置服務遠程。當服務提供方啟動后,下一步實現一個服務消費方。 原文鏈接:Dubbo Spring Cloud 重塑微服務治理,來自于微信公眾號:次靈均閣 摘要 在 Java 微服務生態中,Spring Cloud1 成為...
摘要:大揭秘目標了解的新特性,以及版本升級的引導。四元數據改造我們知道以前的版本只有注冊中心,注冊中心的有數十個的鍵值對,包含了一個服務所有的元數據。 DUBBO——2.7大揭秘 目標:了解2.7的新特性,以及版本升級的引導。 前言 我們知道Dubbo在2011年開源,停止更新了一段時間。在2017 年 9 月 7 日,Dubbo 悄悄的在 GitHub 發布了 2.5.4 版本。隨后,版本...
摘要:管理這些服務方案則叫服務治理。協議假定某些傳輸協議的存在,如或,為通信程序之間攜帶信息數據。請求程序就是一個客戶機,而服務提供程序就是一個服務器。在服務器端,進程保持睡眠狀態直到調用信息到達為止。 不涉及其他的語言及工具,我們從PHP本身來談如何實現服務治理 本猿人已經寫好的服務治理 https://github.com/CrazyCodes... 治理什么? 這個專業名詞很容易發現...
閱讀 3020·2021-11-24 10:32
閱讀 676·2021-11-24 10:19
閱讀 5068·2021-08-11 11:17
閱讀 1455·2019-08-26 13:31
閱讀 1258·2019-08-23 15:15
閱讀 2286·2019-08-23 14:46
閱讀 2264·2019-08-23 14:07
閱讀 1073·2019-08-23 14:03