zoukankan      html  css  js  c++  java
  • RPC原理

    今天开始聊一些微服务的实践,第一块,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字节的字节流:

     

    即处理结果。

    调用方的代码可能变为:

    1. request = MakePacket(“add”, 1, 2);  
    2. SendRequest_ToService_B(request); 
    3. response = RecieveRespnse_FromService_B(); 
    4. int result = unMakePacket(respnse); 

    简单解释一下:

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

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

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

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

    服务方的代码可能变为:

    1. request = RecieveRequest(); 
    2. args/function = unMakePacket(request); 
    3. result = Add(1, 2); 
    4. response = MakePacket(result); 
    5. 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框架的职责是:让调用方感觉就像调用本地函数一样调用远端函数、让服务提供方感觉就像实现一个本地函数一样来实现服务

  • 相关阅读:
    我所理解的权限管理系统,纯粹个人规划
    小公司大公司
    找工作神器,提取各大网站有效的招聘信息(前程无忧、智联招聘、猎聘网)
    权限管理系统系列之WCF通信
    权限管理系统系列之序言
    用C#开发的双色球走势图(原创)值得园友拥有(二)接上一篇
    用C#开发的双色球走势图(原创)值得园友拥有
    实例甜点 Unreal Engine 4迷你教程(5)之函数中的静态变量
    实例甜点 Unreal Engine 4迷你教程(4)之用C++实现添加子Widget到VerticalBox中以及ClearChildren
    实例甜点 Unreal Engine 4迷你教程(3)之用C++改变Image小部件的其它属性
  • 原文地址:https://www.cnblogs.com/zourui4271/p/9690300.html
Copyright © 2011-2022 走看看