text: (window.webpackJsonp=window.webpackJsonp||[]).push([[108],{323:function(t,a,r){"use strict";r.r(a);var s=r(2),v=Object(s.a)({},(function(){var t=this,a=t.$createElement,r=t._self._c||a;return r("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[r("h1",{attrs:{id:"什么是-rpc-框架"}},[r("a",{staticClass:"header-anchor",attrs:{href:"#什么是-rpc-框架"}},[t._v("#")]),t._v(" 什么是 RPC 框架")]),t._v(" "),r("h2",{attrs:{id:"概述"}},[r("a",{staticClass:"header-anchor",attrs:{href:"#概述"}},[t._v("#")]),t._v(" 概述")]),t._v(" "),r("p",[t._v("RPC 是指远程过程调用，也就是说两台服务器 A，B 一个应用部署在 A 服务器上，想要调用 B 服务器上应用提供的函数或方法，由于不在一个内存空间，不能直接调用，需要通过网络来表达调用的语义和传达调用的数据。")]),t._v(" "),r("h2",{attrs:{id:"rpc-是如何通讯的？"}},[r("a",{staticClass:"header-anchor",attrs:{href:"#rpc-是如何通讯的？"}},[t._v("#")]),t._v(" RPC 是如何通讯的？")]),t._v(" "),r("p",[r("img",{attrs:{src:"http://114.116.184.67:81/images/service/service_45366c44f775abfd0ac3b43.jpg",alt:""}})]),t._v(" "),r("ol",[r("li",[t._v("要解决通讯的问题，主要是通过在客户端和服务器之间建立 TCP 连接，远程过程调用的所有交换的数据都在这个连接里传输。连接可以是按需连接，调用结束后就断掉，也可以是长连接，多个远程过程调用共享同一个连接。")]),t._v(" "),r("li",[t._v("要解决寻址的问题，也就是说，A 服务器上的应用怎么告诉底层的 RPC 框架，如何连接到 B 服务器（如主机或 IP 地址）以及特定的端口，方法的名称是什么，这样才能完成调用。比如基于 Web 服务协议栈的 RPC，就要提供一个 endpoint URI，或者是从 UDDI 服务上查找。如果是 RMI 调用的话，还需要一个 RMI Registry 来注册服务的地址。")]),t._v(" "),r("li",[t._v("当 A 服务器上的应用发起远程过程调用时，方法的参数需要通过底层的网络协议如 TCP 传递到 B 服务器，由于网络协议是基于二进制的，内存中的参数的值要序列化成二进制的形式，也就是序列化（Serialize）或编组（marshal），通过寻址和传输将序列化的二进制发送给 B 服务器。")]),t._v(" "),r("li",[t._v("B 服务器收到请求后，需要对参数进行反序列化（序列化的逆操作），恢复为内存中的表达方式，然后找到对应的方法（寻址的一部分）进行本地调用，然后得到返回值。")]),t._v(" "),r("li",[t._v("返回值还要发送回服务器 A 上的应用，也要经过序列化的方式发送，服务器 A 接到后，再反序列化，恢复为内存中的表达方式，交给 A 服务器上的应用。")])]),t._v(" "),r("h2",{attrs:{id:"为什么要用-rpc？"}},[r("a",{staticClass:"header-anchor",attrs:{href:"#为什么要用-rpc？"}},[t._v("#")]),t._v(" 为什么要用 RPC？")]),t._v(" "),r("p",[t._v("就是无法在一个进程内，甚至一个计算机内通过本地调用的方式完成的需求，比如比如不同的系统间的通讯，甚至不同的组织间的通讯。由于计算能力需要横向扩展，需要在多台机器组成的集群上部署应用，")]),t._v(" "),r("h2",{attrs:{id:"rpc-的实现原理"}},[r("a",{staticClass:"header-anchor",attrs:{href:"#rpc-的实现原理"}},[t._v("#")]),t._v(" RPC 的实现原理")]),t._v(" "),r("p",[t._v("首先需要有处理网络连接通讯的模块，负责连接建立、管理和消息的传输。其次需要有编解码的模块，因为网络通讯都是传输的字节码，需要将我们使用的对象序列化和反序列化。剩下的就是客户端和服务器端的部分，服务器端暴露要开放的服务接口，客户调用服务接口的一个代理实现，这个代理实现负责收集数据、编码并传输给服务器然后等待结果返回。")]),t._v(" "),r("h2",{attrs:{id:"dubbo-的实现原理"}},[r("a",{staticClass:"header-anchor",attrs:{href:"#dubbo-的实现原理"}},[t._v("#")]),t._v(" Dubbo 的实现原理")]),t._v(" "),r("p",[t._v("Dubbo 作为 RPC 框架，实现的效果就是调用远程的方法就像在本地调用一样。如何做到呢？")]),t._v(" "),r("ol",[r("li",[t._v("本地有对远程方法的描述，包括方法名、参数、返回值，在 Dubbo 中是远程和本地使用同样的接口")]),t._v(" "),r("li",[t._v("要有对网络通信的封装，要对调用方来说通信细节是完全不可见的，网络通信要做的就是将调用方法的属性通过一定的协议（简单来说就是消息格式）传递到服务端")]),t._v(" "),r("li",[t._v("服务端按照协议解析出调用的信息；执行相应的方法；在将方法的返回值通过协议传递给客户端；客户端再解析；在调用方式上又可以分为同步调用和异步调用；")])])])}),[],!1,null,null,null);a.default=v.exports}}]);