谈谈RPC的演进史

     如果一台电脑需要用到的所有功能都在本台PC上实现,那是最方便的事情了,但除非这是台超级计算机,否则就难以容纳所有的功能。因而我们就有了这样一种需求——调用在其他电脑上实现的功能。

    因为我们通常关注的是结果,至于过程在哪个地方执行其实并不关心,因而就可以把我们的需求交给别的服务器并查看返回的结果就行了。就像我们下达了发射导弹的命令,千里之外的舰艇执行命令并将结果汇报给我们就行了。这就是远程程序调用——Remote procedure Call, 简称RPC


1.     调用另一台电脑上的Java程序,可以用这样常用的办法——

         把我们编译生成的.class文件或者将源文件打包成.jar包,放到另一台电脑上,就可以在另一台电脑上去调用了。

        看着挺简单,而且我们也经常这么做。 但是问题来了, 如果要是有成千上万台电脑需要使用这个功能,我们岂不是要拷上成千上万次?

        手动拷贝太麻烦,不如我们通过别的方法来发送,比如说,通过网络传输 

2.    通过网络来传输

     用什么方法来传呢? 简单啊,可以用我们常用的TCP/UDP通信,一个socket妥妥的。

     另外,网络只能传输二进制,因此,要对我们想传输的.class进行编码,变成二进制,这个过程我们叫它序列化。对面接受以后,看不懂发来的010101是啥玩意儿,还要把它们还原成原来的内容,这个过程叫反序列化

       真是不错!这就是Java语言里的RMI(Remote Method Invocation,远程方法调用)。

       可是,如果对面不是用Java语言来写的呢? 是用C/C++/Python/JS都有可能啊!一端用Java调用,在另一端是用C语言写的,这样跨语言的调用肯定是会有问题的啊!我们能不能改进一下,让它对所有语言通用? 

3.   想办法跨语言

     不管是用什么语言,我们都可以对其进行抽象,它无非就是一个什么样的类/对象, 有什么样的属性和方法/函数,调用什么样的参数。我们用一种统一的格式去描述这些代码:

     我们将这种格式定义为xml格式。

     然后将这种格式序列化后发送到调用端,调用端再将其反序列化。 这种格式是不是很眼熟啊? 可不是嘛,html啊。html也是和xml一样的标签对的格式,它使用http协议来传输。我们利用xml与html的相似性,也使用http协议来传输,应该可以提高效率。当需要使用跨语言调用时,我们就用

                                                                            xml 格式  + http协议

  我们将这种传输方式称为webservice

  这就是SOAP(Simple Object Access Protocol)协议,一种跨语言调用的协议。

  现在我们可以用 xml去序列化并传输了,但是xml里似乎有不少东西其实是可以简化的,如<method>其实用一个<m>就可以表示了嘛,或者再简单一点不要m只用一对方括号 [ ] 也可以嘛,把这些简化一下就可以少发送很多无用的东西,提高传输的效率了。

 

4. 再优化一下传输 

   Json格式是一种相当精简的格式,其语法规则很简单,尽可能地减少了格式上的数据量

  • 对象表示为键值对
  • 数据由逗号分隔
  • 花括号保存对象
  • 方括号保存数组

   我们用一段简单的代码例子来比较一下它们的数据体量 

<?xml version="1.0" encoding="utf-8"?>
<country>
    <name>中国</name>
    <province>
        <name>广东</name>
        <cities>
            <city>广州</city>
            <city>深圳</city>
            <city>珠海</city>
        </cities>
    </province>
    <province>
        <name>新疆</name>
        <cities>
            <city>乌鲁木齐</city>
        </cities>
    </province>
</country>
{
    "name": "中国",
    {
        "name": "广东",
        "cities": {
            "city": ["广州", "深圳", "珠海"]
        }
    }, {
        "name": "新疆",
        "cities": {
            "city": ["乌鲁木齐"]
        }
    }]
}

    可以看出Json格式很精简,用来传输数据很合适。 这种格式仍然是标签对的形式,与html相似,仍然适合用http传输。


    从上面的RMI、 webservice 到 Json + http 都是RPC的一种实现方式,RMI是java语言的,而其他两种则是跨语言的。

    到这里,RPC已经能够实现调用远程PC上面的服务了。 但还有些地方可以进行完善。

 

5.继续完善

    (1)某个服务器的状态是否可用?调用次数是多少?每次调用的round-trip time是多少?

             --> 我们可以给这个框架加上一个监控模块,用来监测这个系统的运行状态。

   (2)如果我们为了提升性能使用了多个服务器组成一个集群,那么每台服务器是否在线?每台服务器能够提供什么服务呢?

             --> 我们可以加入一个注册模块,每一台服务器上线后都在这上面注册自己的IP、端口以及能提供的服务,加入心跳机制监测服务器的上下线。

   (3)每台服务器运行的状态不一样,来了一个请求,我们该让哪一个服务器来运行能够发挥最好的效果呢?

            -->  我们可以加入一个负载均衡模块,让它决定该发送到哪一个上面。

   (4)如果某一台或几台服务器上已经满载,再发送更多的请求到上面可以会导致服务器被打挂,怎么办?

            --> 要加入一种过滤机制,当服务器已经满载时,更多的需求会被拒绝。

6. 开源的RPC框架

    RPC这么重要,一定会有大牛站出来为我们写出来优秀的RPC框架来。比较流行的有阿里的Dubbo、Facebook的Thrift,Google的gRPC,以及其他的如Hessian等。我将在后续的章节中详细分析Dubbo的原理框架与源码实现。

    下一章,我们先来手写实现一个简单的RPC。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值