服务治理深入浅出(1)- 远程方法调用的实现

需求

在了解了前面我们关于服务治理出现的必要性之后。我们知道服务治理是建立在众多“服务”基础之上的,那么,第一步,打通这些服务是基础,也就是我们常说的 RPC 远程调用。要像调用本地方法一样调用远程服务器上的方法。

现在简单粗暴口语化的方式来介绍一个需求:

A 服务器上部署的项目中,有一个UserService里面有一个getUserInfo的方法。
B 服务器上想"直接"调用该方法,怎么办?

分析

我们以 PHP 为例来进行分析。
我们希望在 B 服务器上实现类似于 A 服务器上直接调用方式

$userService = new UserService();
$userService->getUserInfo($uid);

我们经常会使用 SDK 来调用第三方提供的 api 服务,我们的做法肯定类似于

$client  = new \SDK\Client();
$request = new \SDK\UserService\Request\GetStudentInfoRequest();
$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/zhoumengkang/yar-java-client

客户端代码,假设该服务设在局域网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 也是最强大的语言
由于 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/1500000011300619

时间: 2024-08-19 19:45:43

服务治理深入浅出(1)- 远程方法调用的实现的相关文章

建立服务治理组织

Service,物理上类似海运服务,或被软件代理商所实现的服务,总是被设计与提炼成被尽量多的消费者所重用.这是面向服务架构的本质:降低成本.风险以及通过分解和实现可重用的IT资产来减少构建解决方案的延迟,这些通常在设计阶段处于未知状态.同样的SOA治理与数据和IT治理没什么区别,数据和IT治理致力于设计信息模型或选择超越给定项目边界的可重用技术.服务必须被治理为可重用的:所有可预见的消费者必须能表达他们的需求,这些需求接下来被划分出优先级和阶段,同时服务拥有者被指派且投资模型被建立. 在前一篇文

浅谈服务治理与微服务

近期都在谈微服务,本人也正在做相关的工作,应领导要求做了一个微服务的分享,本篇文章主要来源于分享的PPT,所以有些简单,有问题可以在下面留言,大家 一起讨论. 本篇文章先简单介绍了互联网架构的演变,进而介绍了服务化,最后再介绍微服务,微服务是服务治理的升级也是互联网架构的进一步延伸. 互联网架构演变 一体架构 在计算机软件发展早期,一般桌面软件都是采用这种架构,不管是界面还是业务处理还是数据处理都放到一个包中.这种其实谈不上架构,但也可以说是很好的架构,因为它足够简单. mvc架构 但随着浏览器

【详解】为什么选择Kubernetes作为云平台的微服务治理框架

如何做开源技术选型? 本文讲的是[详解]为什么选择Kubernetes作为云平台的微服务治理框架,很多同学在做技术选型的时候,往往过于关注技术/功能上的比较,陷入技术细节和功能特性上的争论.比如A产品有个X功能,看起来很棒,B产品有个Y功能,也不错,选哪个,好纠结--或者A产品的当前版本看起来不错,B就很一般,可是B的Roadmap里写,下一个版本会有个很强大的功能出来,是不是要再等等看,好纠结-- 有时候勉强选了A,又看到B发展的也不错,心里不踏实. 其实在我们看来,技术/功能只是技术选型过程

王晔倞:在‘持续污染’与服务治理之间寻找平衡

好买财富是一家专注为个人(零售+高端)与机构提供专业理财服务的公司,腾讯和联 想旗下的君联资本都是好买的战略股东. 2012年,好买获得中国证监会颁发的第一批独立基金销售牌照 . 2015年成为首家在新三板成功挂牌的独立财富管理公司. 服务多.服务杂.服务乱,就需要服务治理,英国伦敦雾霾事件就可以很好的体现这一概念. 空气质量的污染源是二氧化碳.一氧化碳.二氧化硫.粉尘,那微服务(或服务化)的污染源是什么呢? 污染源-1:全产品 好买拥有线上所有金融类产品,但它们的业务逻辑不同. 污染源-2:复

微服务治理实战:服务流的自动化构建与应用

本文根据DBAplus社群第89期线上分享整理而成.   讲师介绍  张真 宜信技术研发中心高级架构师   目前负责金融基础服务.微服务架构演进/计算平台.DevOps平台等. 曾任IBM,负责云计算.应用服务器等,拥有多个国际专利.开源社区活跃贡献者.   主题简介: 服务流及微服务架构下服务流构建的挑战 自动化构建(微)服务流 自动化构建服务流的应用场景   先谈谈这个话题的早期背景,作为一个发展了十年的企业,我们公司内部存在大量的系统,这些系统可能包括多种架构,多种技术栈,它们互相关联,互

微服务架构下,如何打造别具一格的服务治理体验?(下)

作者介绍 张真,宜信技术研发中心高级架构师,负责基础系统架构演进与优化.服务治理.监控平台.微服务建设.DevOps平台.自动化测试框架及电子签约.短信.邮件等应用系统.早年就职于IBM中国研发中心,负责IBM WebSphere应用服务器的设计与开发.目前主要关注微服务架构实施,微智能设计思想应用,虚拟化技术应用,共识计算研究.   上文我们已经详细讲到了一些经典微服务架构的特点及问题,微服务计算平台的设计思想与抽象模型,今天就接着打造微服务计算的基础三件事这一话题,说说服务情景感知与监控和服

springcloud微服务二:Eureka服务治理之服务注册中心

当初步的学习了spring boot,了解了spring boot的基本实现过程后,我就正式开始学习spring cloud,首先就从Eureka服务治理开始. 服务治理包含三个核心的角色:服务注册中心.服务提供者和服务消费者,他们相对独立,新的服务要向服务注册中心注册,新的消费者会向服务注册中心索引服务列表. 一番了解之后,让我想到了人才招聘.在我看来,现在普遍存在的招聘形式也是分为了三个部分:招聘网站或者人才市场.发布招聘需求的企业.需要找工作的人.当然了,也可以把企业和人换一下位置,那就是

基于mysql的分布式服务治理

问题描述 基于mysql的分布式服务治理 公司之前的分布式协调服务用的是zookeeper,现在准备用mysql替换zookeeper,做一个轻量的服务框架,就是把注册的服务和节点信息持久化在数据库中,需要的时候再从数据库中查询出来.基本的新增和查询功能都好实现,问题是如何监控已注册服务的状态变化?求有经验的大神指教 解决方案 我觉得这种需求zk比db更擅长. 如果非要用db的话,可以单独启动一个服务,去做监控的事情.

可能是最详尽的证券服务治理框架思路 | 华泰证券企业服务化思考 | 中生代38期

1.开始之前,请先容许我介绍下华泰证券,华泰证券中全国领先的大型综合性证券集团,具有庞大的客户基础.领先的互联网平台及敏捷协同的全业务链体系,股票代码601688,主营业务主要有经纪及财富管理.投资银行.投资及交易.资产管理.海外业务,经济业务多年保持市场第一,去年系统交易总额35万亿元. 2.券商以往系统建设都依赖于服务厂商,所以也造成了各系统之间的多样异构化,各种类型的系统架构都长期存在,例如集中交易用的恒生系统,主要基于C语言的消息路由架构,自营系统则是恒生系统的tuxdeo架构,管理系统