RPC框架的原理及实践 ,为什么说要搞定微服务架构,先搞定RPC框架呢

    xiaoxiao2021-03-25  154

    RPC 框架的原理及实践 ,为什么说要搞定微服务架构,先搞定RPC框架呢

    转自:http://www.open-open.com/lib/view/open1472132466172.html

    今天开始聊一些 微服务的实践 ,第一块, RPC 框架的原理及实践 ,为什么说要搞定微服务架构,先搞定RPC框架呢?

    一、需求缘起

    服务化的一个好处就是,不限定服务的提供方使用什么技术选型,能够实现大公司跨团队的技术解耦 ,如下图:

    服务 A 是欧洲团队提供服务,欧洲团队的技术背景是 Java ,可以用 Java 实现服务;

    服务 B 是美洲团队提供服务,可以用 C++ 实现服务;

    服务 C 是中国团队提供服务,可以用 Go 实现服务;

    服务的上游调用方,按照接口、协议即可完成对远端服务的调用。

    但实际上, 99.9% 的公司的团队规模有限,技术团队人数也有限,基本是使用同一套技术体系来调用和提供服务 的:

    这样的话, 如果没有统一的服务框架, RPC 框架 , 各个团队的服务提供方就需要各自实现一套序列化、反序列化、网络框架、连接池、收发线程、超时处理、状态机等“业务之外”的重复技术劳动 ,造成整体的低效。所以, 统一 RPC 框架 把上述“业务之外”的技术劳动统一处理, 是服务化首要解决的问题 。

    在达成【“使用统一的 RPC 框架”是正确的道路】这个一致的前提下,本文期望用简单通俗的言语简述一下一个通用 RPC 框架的技术点与实现。

    二、 RPC 背景与过程

    什么是 RPC ( Remote Procedure Call Protocol ),远程过程调用?

    先来看下什么是本地函数调用,当我们写下:

    int result = Add(1, 2);

    这段代码的时候,我们知道,我们传入了 1 , 2 两个入参数,调用了本地代码段中的一个 Add 函数,得到了 result 出参。此时, 传入数据,传出数据,代码段在同一个进程空间里,这是本地函数调用 。

    那有没有办法,我们能够调用一个跨进程(所以叫 “ 远程 ” ,典型的,这个进程部署在另一台服务器上)的函数呢 ?

      

    最容易想到的, 两个进程约定一个协议格式,使用 Socket 通信,来传输【入参】【调用哪个函数】【出参】 。

    假设请求报文协议是一个 11 字节的字节流:

    ( 1 )前 3 个字节填入函数名

    ( 2 )中间 4 个字节填入第一个参数

    ( 3 )末尾 4 个字节填入第二个参数

    同时可以设计响应报文协议是一个 4 字节的字节流:

    即处理结果。

    调用方的代码可能变为:

    request = MakePacket(“add”, 1, 2);

    SendRequest_ToService_B(request);

    response = RecieveRespnse_FromService_B();

    int result = unMakePacket(respnse);

    简单解释一下:

    ( 1 )讲传入参数变为字节流

    ( 2 )将字节流发给服务 B

    ( 3 )从服务 B 接受返回字节流

    ( 4 )将返回字节流变为传出参数

    服务方的代码可能变为:

    request = RecieveRequest();

    args/function = unMakePacket(request);

    result = Add(1, 2);

    response = MakePacket(result);

    SendResponse(response);

    这个过程也很好理解:

    ( 1 )服务端收到字节流

    ( 2 )将字节流转为函数名与参数

    ( 3 )本地调用函数得到结果

    ( 4 )将结果转变为字节流

    ( 5 )将字节流发送给调用方

    这个过程用一张图描述如上,调用方与服务方的处理步骤都是非常清晰的。 这个过程存在最大的问题是什么呢?

    回答:调用方太麻烦了,每次都要关注很多底层细节

    ( 1 )入参到字节流的转化,即序列化应用层协议细节

    ( 2 ) socket 发送,即网络传输协议细节

    ( 3 ) socket 接受

    ( 4 )字节流到出参的转化,即反序列化应用层协议细节

    能不能调用层不关注这个细节呢?

    回答:可以, RPC 框架就是解决这个问题的,它能够让调用方“像调用本地函数一样调用远端的函数(服务)” 。

    三、 RPC 框架职责

    通过上面的讨论, RPC 框架要向调用方屏蔽各种复杂性,要向服务提供方也屏蔽各类复杂性 :

    ( 1 )调用方感觉就像调用本地函数一样

    ( 2 )服务提供方感觉就像实现一个本地函数一样来实现服务

    所以整个 RPC 框架又分为 client 部分与 server 部分,负责把整个非( 1 )( 2 )的各类复杂性屏蔽,这些复杂性就是 RPC 框架的职责。

     再细化一些, client 端又包含:序列化、反序列化、连接池管理、负载均衡、故障转移、队列管理,超时管理、异步管理等等等等职责。

    server 端包含:服务端组件、服务端收发包队列、 io 线程、工作线程、序列化反序列化、上下文管理器、超时管理、异步回调等等等等职责。

    however ,因为篇幅有限,这些细节不做深入展开。

     

    四、结论

    ( 1 ) RPC 框架是架构微服务化的首要基础组件 ,它能大大降低架构微服务化的成本,提高调用方与服务提供方的研发效率,屏蔽跨进程调用函数(服务)的各类复杂细节

    ( 2 ) RPC 框架的 职责 是: 让调用方感觉就像调用本地函数一样调用远端函数、让服务提供方感觉就像实现一个本地函数一样来实现服务

    转载请注明原文地址: https://ju.6miu.com/read-1488.html

    最新回复(0)