simple-rpc
RPC的实现原理
正如上一讲所说,RPC主要是为了解决的两个问题:
- 解决分布式系统中,服务之间的调用问题。
- 远程调用时,要能够像本地调用一样方便,让调用者感知不到远程调用的逻辑。
还是以计算器Calculator为例,如果实现类CalculatorImpl是放在本地的,那么直接调用即可:
现在系统变成分布式了,CalculatorImpl和调用方不在同一个地址空间,那么就必须要进行远程过程调用:
那么如何实现远程过程调用,也就是RPC呢,一个完整的RPC流程,可以用下面这张图来描述:
其中左边的Client,对应的就是前面的Service A,而右边的Server,对应的则是Service B。
下面一步一步详细解释一下。
- Service A的应用层代码中,调用了Calculator的一个实现类的add方法,希望执行一个加法运算;
- 这个Calculator实现类,内部并不是直接实现计算器的加减乘除逻辑,而是通过远程调用Service B的RPC接口,来获取运算结果,因此称之为Stub;
- Stub怎么和Service B建立远程通讯呢?这时候就要用到远程通讯工具了,也就是图中的Run-time Library,这个工具将帮你实现远程通讯的功能,比如Java的Socket,就是这样一个库,当然,你也可以用基于Http协议的HttpClient,或者其他通讯工具类,都可以,RPC并没有规定说你要用何种协议进行通讯;
- Stub通过调用通讯工具提供的方法,和Service B建立起了通讯,然后将请求数据发给Service B。需要注意的是,由于底层的网络通讯是基于二进制格式的,因此这里Stub传给通讯工具类的数据也必须是二进制,比如calculator.add(1,2),你必须把参数值1和2放到一个Request对象里头(这个Request对象当然不只这些信息,还包括要调用哪个服务的哪个RPC接口等其他信息),然后序列化为二进制,再传给通讯工具类,这一点也将在下面的代码实现中体现;
- 二进制的数据传到Service B这一边了,Service B当然也有自己的通讯工具,通过这个通讯工具接收二进制的请求;
- 既然数据是二进制的,那么自然要进行反序列化了,将二进制的数据反序列化为请求对象,然后将这个请求对象交给Service B的Stub处理;
- 和之前的Service A的Stub一样,这里的Stub也同样是个“假玩意”,它所负责的,只是去解析请求对象,知道调用方要调的是哪个RPC接口,传进来的参数又是什么,然后再把这些参数传给对应的RPC接口,也就是Calculator的实际实现类去执行。很明显,如果是Java,那这里肯定用到了反射。
- RPC接口执行完毕,返回执行结果,现在轮到Service B要把数据发给Service A了,怎么发?一样的道理,一样的流程,只是现在Service B变成了Client,Service A变成了Server而已:Service B反序列化执行结果->传输给Service A->Service A反序列化执行结果 -> 将结果返回给Application,完毕。
理论的讲完了,是时候把理论变成实践了。
把理论变成实践
本文的示例代码,可到Github下载。
本文参考网址:https://www.jianshu.com/p/5b90a4e70783
simple-rpc的更多相关文章
- 基于开源Dubbo分布式RPC服务框架的部署整合
一.前言 Dubbo 作为SOA服务化治理方案的核心框架,用于提高业务逻辑的复用.整合.集中管理,具有极高的可靠性(HA)和伸缩性,被应用于阿里巴巴各成员站点,同时在包括JD.当当在内的众多互联网项目 ...
- 踏着前人的脚印学Hadoop——RPC源码
A simple RPC mechanism.A protocol is a Java interface. All parameters and return types must be one ...
- 【Rpc】基于开源Dubbo分布式RPC服务框架的部署整合
一.前言 Dubbo 作为SOA服务化治理方案的核心框架,用于提高业务逻辑的复用.整合.集中管理,具有极高的可靠性(HA)和伸缩性,被应用于阿里巴巴各成员站点,同时在包括JD.当当在内的众多互联网项目 ...
- 应答流式RPC 请求流式RPC 向流式RPC 流式RPC的三种具体形式
https://mp.weixin.qq.com/s/pWwSfXl71GQZ3KPmAHE_dA 用Python进行gRPC接口测试(二) 大帆船 搜狗测试 2020-02-07 上期回顾:用P ...
- NoSQL数据库笔谈(转)
NoSQL数据库笔谈 databases , appdir , node , paper颜开 , v0.2 , 2010.2 序 思想篇 CAP 最终一致性 变体 BASE 其他 I/O的五分钟法则 ...
- Awesome C/C++
Awesome C/C++ A curated list of awesome C/C++ frameworks, libraries, resources, and shiny things. In ...
- A javascript library providing cross-browser, cross-site messaging/method invocation. http://easyxdm.net
easyXDM - easy Cross-Domain Messaging easyXDM is a Javascript library that enables you as a develope ...
- libevent入门教程
首先给出官方文档吧: http://libevent.org ,首页有个Programming with Libevent,里面是一节一节的介绍libevent,但是感觉信息量太大了,而且还是英文的- ...
- awesome cpp
https://github.com/fffaraz/awesome-cpp Awesome C/C++ A curated list of awesome C/C++ frameworks, lib ...
- 轻量级网络库libevent概况
Libevent is a library for writing fast portable nonblocking IO. libevent是一个为编写快速可移植的非阻塞IO程序而设计的. lib ...
随机推荐
- 发布MeteoInfo Java 1.2.2
主要更新了MeteoInfoLab至0.2版,已经有一些实用功能了,这里做些简单的介绍. 下载地址1,MeteoInfo网站:http://www.meteothinker.com/下载地址2,百度云 ...
- elasticsearch要点及常用查询
目录 elasticsearch要点及常用查询 查询与过滤 明确查询和过滤各自的优缺点,以及适用场景. 性能上的差异 适用场景 1.kibana 中操作es-查询 Mapping映射基础 mappin ...
- 为什么C语言是最适合单片机编程的高级语言!
为什么还在用C语言编程?答案是:C语言是最适合单片机编程的高级语言. 这个问题的意思应该是:现在有很多很好用的高级语言,如java,python等等,为什么这些语言不能用来编写单片机程序呢?那么这个问 ...
- 【循环矩阵乘优化DP】BZOJ 2510 弱题
题目大意 有 \(M\) 个球,一开始每个球均有一个初始标号,标号范围为 \(1\) - \(N\) 且为整数,标号为 \(i\) 的球有 \(a_i\) 个,并保证 \(\sum a_i = M\) ...
- openresty使用redis作本地缓存
一,为什么要使用redis作本地缓存? 1,使用缓存通常会有三层 当使用openresty作为web服务器时,我们更看重是的它可以通过lua编程的扩展能力,就openresty而言,它可以实现的功能非 ...
- scrapy 管道里面使用mysql插入数据库 python操作mysql
# -*- coding: utf-8 -*- # Define your item pipelines here # # Don't forget to add your pipeline to t ...
- CSS实现鼠标移入弹出下拉框
前言 最近比较沉迷CSS,所以我现在来做个鼠标的交互效果 HTML <ul> <li>测试</li> <li>测试</li> <li ...
- Luban图片压缩
导入依赖: implementation 'top.zibin:Luban:1.1.3' public class MainActivity extends AppCompatActivity { p ...
- 如何分析、排查、解决Redis变慢问题?
关于如何分析.排查.解决Redis变慢问题,根据实践总结了一些清单如下: 1.使用复杂度过高的命令(例如SORT/SUION/ZUNIONSTORE/KEYS),或一次查询全量数据(例如LRANGE ...
- PLC模拟量采集模块分辨率是什么意思?
14位分辨率的模块(mo kuai)和16位分辨率的模块有什么不同的地方? 14位的模块最高位是符号位,我们用S表示符号位,那么这个模块的数值范围(fàn wéi)就是S111 1111 1111 1 ...