RPC学习笔记【一】:概述

2023-11-12

一、简介

1.1 引言

RPC 是远程过程调用 (Remote Procedure Call)的缩写形式,是一种跨进程的方法调用形式,是目前在 Java 分布式,微服务体系过程之中,重要的一种通信方式。

在 JVM 中,启动一个项目,就意味着开启了一个线程,这里的跨进程可以理解为:有两个项目在两个虚拟机之中去跑,或者在一个虚拟机之中同时运行。

究竟是那些问题的存在,导致了这种方式的出现呢?下面我们首先来看一下系统架构的演变过程

1.2 架构的演变过程

在软件开发的时候,最早出现的就是单体架构,就是将系统中所有的功能代码耦合在一起,生成一个 jar(war),部署在一个tomcat之中,是一个JVM进程,就比如下面这个系统一样

在这里插入图片描述

那么这个架构到底存在什么问题呢?下面来进行列举

1)存在热点问题:这两部分资源都是放在一个jar包里面,跑在一个虚拟机之中,就会出现一个系统的访问量过大,占用了服务器的资源,进而就会影响到另一个系统的访问

2)扩展性比较差:新资源的分配粒度不精确

3)模块的耦合性较高:两个模块都是在一个大项目之中去写的,可能会出现,两个模块都依赖于一个Service,如果有一天门户提出了一个新的需求,需要去修改AService,但是后台管理系统不需要或者说不想要这个需求,就会产生影响

4)维护和部署的成本较高:某一次发布,只更新一部分代码,但是由于是单体架构,所以会发布整个系统

5)技术栈受限,必须要使用相同的编程语言

接下来出现的架构就是:单体式架构的水平扩展,将一个相同的项目,部署到个多个机器之上

image-20230516093753818

但是这种架构只解决了热点问题,也就是说可以解决单体架构在单台服务器之上,内存,CPU,网络连接数遇到瓶颈时的问题,但是其余的问题还是没有解决掉,

垂直结构,把一个单体架构的应用,按照子系统进行划分,每个子系统都部署在自己的 tomcat 之中,多个子系统共享数据库等存储资源,有限的解决了单体架构的问题。当我们的系统通过垂直架构来进行划分之后,比如说现在已经拆分出来两个模块,模块A 和 模块B,如果说现在模块A要实现一个功能点C,但是这个功能在模块B之中已经存在了,所以现在就有两种策略:

  • 方式一:在模块A之中,再实现一波功能C
  • 方式二:调用模块B的这个功能

对于这两种方式,使用方式二能够使得系统的内聚性更高。

模块内部的各个元素之间的关联更加紧密,即所谓的高内聚性,模块的内聚性越高,其模块化的效果就会越好,软件的可维护性、可扩展性和可重用性也会更加优秀。

而方式二,由一个模块调用另一个模块的功能,也就是所说的 RPC

到这里为止,我们就看了一下整体架构的演变过程,那么我们该如何去设计一个 RPC 框架呢?

二、RPC 的设计

2.1 设计目标

对于一个RPC框架,它的设计目标就是:让调用者像调用本地方法一样调用远端的服务方法。

为了实现这个目标,究竟需要解决那些问题?

2.2 核心问题

RPC 是 两个模块之间进行跨进程调用,首先需要解决的就是通信方式

01 通信方式

两个模块在不同的虚拟机上,就会涉及到了跨进程的调用,跨进程调用可以走网络,进行网络编程,这里就会涉及到了协议的选择,使用 Http 协议? 还是使用 TCP协议 ?

Http 底层虽然也是 TCP,但是走Http协议,会在消息头加上Http相关信息

Http 是短连接协议 (即时到后面也是有限的长连接),需要频繁的建立 和关闭连接

那么走两种协议究竟会带来哪些优点,哪些缺点?

1)如果走 HTTP 协议

  • 使用HTTP协议,最为方便的是不用开发服务器,有现成的,如Tomcat,Resin。
  • 服务器端,不能够直接通过网络进行调用Service,需要通过控制器进行暴露。
  • 客户端发起 Http 请求,可以使用HttpClient,RestTemplate,WebClient,OKHttp
  • 优势:文本类型 字符串协议,跨语言平台好
  • 问题:传输数据量大
  • 典型的技术实现方案:Spring Clout Feign ;Hessian RPC

2)如果走 TCP 协议

  • 服务器端需要自己开发 Socket 编程,接受客户端传递过来的参数,不过可以直接调用 Service 进行使用,
  • 优势:效率高,连接的复用性较好。自己定义应用协议。自己定义序列化的方式
  • 问题:开发难度增大,对使用者不友好
  • 典型的技术实现方案:Dubbo
02 协议

如果使用 TCP ,需要自定义协议。如果说我们自定义协议,将会包含两大部分:

  • 协议头
  • 协议体
03 序列化

在网络通信之中,序列化是必不可少的一环。他相当于通信双方定义的一种标准,对数据进行处理。

发送方在发送的时候,将数据通过序列化操作转换为一种格式,接受方在接受之中,在将这种格式的数据通过反序列化转为原来的样子。

根据序列化之后的数据格式,可以分为以下两种:

  • 文本格式的序列化实现方案:数据通过某种格式通过文本的格式呈现;目前最为广泛使用是JSON格式和XML格式
  • 二进制格式的序列化实现方案:数据通过某种编排规则通过二进制格式呈现;但是这种方式对于异构性语言并不友好

由于序列化的最终目的是为了进行网络传输,所以选择一种比较好的序列化方式,让内容转换之后尽可能的小,就显得尤为重要了。

04 远程代理类

RPC 的设计目标就是让调用者像调用本地方法那样调用远端方法。在设计的时候,要尽可能屏蔽细节,让适用方只关注业务接口,所以在调用者这方,需要创建远程服务类的代理类。

2.3 衍生方案 - 注册中心

当服务端有多个实例的时候,这种情况之下就需要考虑注册中心了,在注册中心之中,有所有服务的注册的信息。

image-20230527003122309

那个这个注册中心究竟有哪些功能呢?

1)进行负载均衡,基于轮训或者加权的一些策略,将请求达到对应的服务上

2)进行服务的管理:定期的发送心跳,看那些服务是可以使用的

3)解耦合:客户端不需要写死服务端的地址,而是从注册中心去获取服务

4)熔断:如果服务端的这个实例挂了,断开这个连接

5)限流:限制某一个实例的访问量

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

RPC学习笔记【一】:概述 的相关文章

随机推荐

  • HTML在工作中的使用

    本文是在学习HTML的时候 心血来潮尝试的做法 纯属瞎玩 不可当真 示例 工作中编辑邮件 在管理系统上进行任务编辑 描述时 都可能会使用到HTML的简单知识 有一些简单的标签可以帮助我们更好的完成工作 比如字体加粗 换行等 比如我在办公系统
  • python使用装饰器记录方法耗时

    思路 python使用修饰器记录方法耗时 目的是每当方法执行完后 可以记录该方法耗时 而不需要在每个方法的执行前后 去创建一个临时变量 来记录耗时 方式一 不推荐 在每个方法的执行前后 去创建一个临时变量 来记录耗时 代码如下 缺点在于 如
  • 爱好高科技之人脸识别模块

    前段时间看到一款性价比很不错的人脸识别模组 2个关键指标引起了我极大的兴趣 1 99 的识别通过率 误识率低于百万分之一 2 双目摄像头 活体检测 于是买了几个 结合离线语音模块 两者通过串口进行一问一答通信 人机交互部分通过语音和OLED
  • 运行vue-admin-template和vue-element-admin及可能问题点解决

    系统 windows10 64位 需求 安装node js git客户端 ssh公钥设定好 安装node sass 前提 安装好node js 配置好环境 安装好的nodejs文件夹下如下图所示 其中node global和node cac
  • Java21天打卡Day8-break

    break和continue break 表示跳出当前层循环 continue 表示跳出本次循环 进入下一次循环 import com sun org apache xerces internal util SynchronizedSymb
  • vue 项目放弃“tui-editor“ “1.3.3“,

    从官网https github com PanJiaChen vue element admin下载的版本带有 tui editor 版本1 3 3 在编译时会遇到如下问题 error An unexpected error occurre
  • 使用 X2MindSpore 迁移 Pytorch 训练脚本mobileNet支持分布式训练

    简介 MindSpore是华为昇腾开发的深度学习框架 旨在提供端边云全场景的AI框架 Pytorch是由Facebook推出的AI框架 本教程使用MindStudio中的X2MindSpore功能自动将Pytorch脚本转换为MindSpo
  • 整数的逆序数

    本题要求实现一个求整数的逆序数的简单函数 函数接口定义 int reverse int number 其中函数reverse须返回用户传入的整型number的逆序数 include
  • 解决warning: this statement may fall through [-Wimplicit-fallthrough=]

    使用switch如果缺少break gcc编译的时候会报相关的warnning信息 如果是忘记写 这样肯定是有问题的 警告信息可以帮助我们排除隐藏的bug 要消除警告很简单 把break加上就行 但是有时候 我们的需求就是需要继续向下执行
  • 计算曲线与坐标轴的面积

    根据坐标点 计算曲线与坐标轴的面积 import numpy as np import matplotlib pyplot as plt x np arange 0 1 0 001 y np sqrt 1 x 2 plt close all
  • STM32F4通过U盘升级程序

    昨天的文章中介绍F4系列单片机的内部Flash读写 包括之前文章中介绍了FatFS文件系统读写U盘的操作 本篇文章就是将两者结合 实现F4系列单片机程序的U盘升级 首先对内部Flash空间进行划分 前128K用于存储BootLoader程序
  • chatgpt login进不去的原因和解决办法!

    chatgpt官网在国内是打不开的 可以说是双向封闭 1 由于国内实施了网络审查和防火墙措施 访问特定的网站会受到限制主要是针对服务器设置到境外的网站 为了确保网络安全和政策合规性防火墙会屏蔽包含敏感内容或违反相关规定的网站或服务 以确保网
  • Cadence OrCAD原理图如何统计元件管脚总数量

    Cadence OrCAD原理图如何统计元件管脚总数量 本章节教大家如何在Cadence OrCAD原理图如何统计元件管脚总数量 操作方法 1 打开原理图文件 File Open Design 2 鼠标单击选中根目录下DSN文件夹 右键选择
  • ajax 用户验证js,js ajax验证用户名

    回答 jQuery的ajax 验证用户名的例子 验证用户名 js 方法 uname 输入的用户名 function ajax check uname uname var url check uname php 这里是你的php post u
  • Vue3 框架使用报错以及解决办法

    1 TypeError Failed to fetch dynamically imported module 引入组件时 没有添加 vue后缀 或者引入的组建没有被使用 2 SyntaxError The requested module
  • IntelliJ IDEA更新Maven远程仓库索引index(pom文件终于有快速的自动提示了)

    IntelliJ IDEA更新Maven远程仓库索引 因为某些原因 在 IDEA 下载 Maven 索引总是特别慢 有时候等待它下载好几个小时 然后突然抽风下载失败 再下载又要重新下了 所以这里介绍从远程下载索引到本地更新的方法 本文默认你
  • 遍历实体包含的List

    for ShopGoodSpec s shopgood getSpecs s setGoods id shopgood getGoods id
  • springboot 注解实现AOP记录日志

    AOP AOP为Aspect Oriented Programming的缩写 意为 面向切面编程 通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术 在日常开发当中经常用来记录日志 方法跟踪 事务 权限等 切面方法说明 Aspe
  • 疯壳AI语音及人脸识别教程2-5中断

    目录 1 1寄存器 1 1 2实验现象 4 视频地址 https fengke club GeekMart su f9cTSxNsp jsp 官方QQ群 457586268 中断 接口数据传送控制方式有查询 中断和DMA等 中断是重要的接口
  • RPC学习笔记【一】:概述

    文章目录 一 简介 1 1 引言 1 2 架构的演变过程 二 RPC 的设计 2 1 设计目标 2 2 核心问题 01 通信方式 02 协议 03 序列化 04 远程代理类 2 3 衍生方案 注册中心 一 简介 1 1 引言 RPC 是远程