02_RPC通信原理

RPC通信原理

remote procedure call,远程过程调用。分布式通信靠此实现。也是分布式通信底层要解决的问题。

整体流程

rpc方法名字,参数。参数一般需要打包。

从caller端的User到RPCRuntime,中间需要序列化的流程,即把参数打包的流程。序列化之后就可以通过网络传到远端另外的机器。网络可以选用muduo网络库。

caller端

  1. User - 用户可见
    1. local call - 用户可见
  2. User-stub
    1. pack argument
  3. RPCRuntime
    1. transmit
    2. wait

远端callee端接收到RPC请求之后,从网络底层上报上来,需要把打包的参数进行解析,即反序列化为具体的信息,比如方法的标识、参数。传递到进程中执行某个函数。

callee端

  1. RPCRuntime
    1. receive
  2. Server-stub
    1. unpack argument
  3. Server - 服务器可见
    1. call - 服务器可见
    2. work(执行函数) - 服务器可见
    3. return - 服务器可见

远端callee返回结果时,需要pack result,给结果内容打包,序列化。传送给caller。

  1. Server
    1. return
  2. Server-stub
    1. pack result
  3. RPCRuntime
    1. transmit

caller端收到返回包后,唤醒,反序列化,解析为unpack result,生成本地对象。

  1. RPCRuntime
    1. receive
  2. User-stub
    1. unpack result
  3. User - 用户可见
    1. local return - 用户可见

我们RPC框架要实现的东西,除了标识的用户可见、服务器可见的地方之外,都要实现并封装。

image-20220815205906401

黄色部分:设计rpc方法参数的打包和解析, 也就是数据的序列化和反序列化, 使用Protobuf。此部分称之为stub,意思是桩,是一个代理类的角色。

绿色部分:网络部分,包括寻找rpc服务主机,发起rpc调用请求和响应rpc调用结果,使用muduo网络库和zookeeper服务配置中心(专门做服务发现)。

mprpc框架主要包含以上两个部分的内容。

序列化、反序列化工具

用protobuf。

protobuf是二进制存储的。相比于xml、json的文本存储形式来说,

  1. 二进制存储有节省空间的优点。在同等网络环境下,性能更优。
  2. protobuf不需要存储额外的信息,而json存储的是key-value。protobuf只存储值数据。

可能的形式:
Json:

1
2
name: "zhang san",
pwd: "123456"

Protobuf:

1
"zhangsan""123456"

git_各种切换分支_回退

参考文章:一文讲透 Git 底层数据结构和原理 - 阿里开发者的文章 - 知乎 https://zhuanlan.zhihu.com/p/142289703

image-20220815154815483

简要说明

命令 描述
checkout Switch branches or restore working tree files
reset Reset current HEAD to the specified state
revert Revert some existing commits
rebase Reapply commits on top of another base tip
switch Switch branches
restore Restore working tree files

可以看出,checkout实际上是switch和restore的结合。

对应的场景

checkout

两个作用,一是切换分支,二是恢复工作区代码。如果checkout相同分支,则作用就是恢复工作区代码。因此,可以作用于,想要把未add的代码恢复到最新commit的状态。

reset

  1. git reset --mixed:此为默认方式,等同于不带任何参数的git reset。这种方式,只保留源码,回退commit和index信息
  2. git reset --soft:回退到某个版本,只回退了commit的信息,如果还要提交,直接commit即可(修改的内容变成未add的状态),索引(暂存区)和工作目录的内容是不变的,在三个命令中对现有版本库状态改动最小。
  3. git reset --hard:彻底回退到某个版本,本地的源码也会变为上一个版本的内容,所有修改的内容都会丢失, (修改的代码 不会变成未add的状态)。索引(暂存区)内容和工作目录内容都会变给定提交时的状态。

revert

revert我们commit了三个版本(版本一、版本二、 版本三),突然发现版本二不行(如:有bug),想要撤销版本二,但又不想影响撤销版本三的提交就可以用 git revert 命令来反做版本二,生成新的版本四,这个版本四里会保留版本三的东西,但撤销了版本二的东西

参考链接:https://www.jianshu.com/p/ef34fa4c8bf8

rebase

https://blog.csdn.net/weixin_42310154/article/details/119004977

git回退

只回退单个文件

https://zhuanlan.zhihu.com/p/267141048

Git在2.17中新增两个命令,restore和switch,分担checkout的职责;

1
2
# 放弃工作区的内容,使保持与暂存区一致
git restore src/index.js src/images/file.png

这里的默认参数是--worktree(工作区)

暂存区单个文件放弃修改:

1
2
# 放弃暂存区的内容,使与最近一次提交保持一致(HEAD)
git restore --stage src/index.js src/images/file.png

这里是暂存区的内容发生了变化,工作区的内容不会受影响

工作区单个文件恢复到某个提交版本

1
2
3
# 恢复工作区的某个文件到指定的某个版本,如果文件有修改也会被覆盖
git restore --source HEAD src/index.js src/images/file.png
git restore --source d68fsdf68s6df src/index.js src/images/file.png

恢复操作执行后需要add

暂存区单个文件恢复到某个提交版本

1
2
3
# 恢复暂存区的某个文件到指定的某个版本,如果暂存区文件有未提交也会被覆盖
git reset HEAD src/index.js src/images/file.png
git reset d68fsdf68s6df src/index.js src/images/file.png

如果需要将工作区与暂存区的某个文件都恢复到之前某个提交版本,则使用checkout来操作,简称co

1
2
3
# 同时将工作区与暂存区的某个文件恢复到指定版本
git co HEAD src/index.js src/images/file.png
git co d68fsdf68s6df src/index.js src/images/file.png