Stub学习
RPC
RPC(Remote Procedure Call)就是某台主机A(一般为client)像调用本地的过程一样去调用另一台主机B(一般为server)上的某个过程。RPC代码可能长成这个样子:
//client
void SampleFunc() {
Request req;
req.set_key("client");
vector<string> values = {"v1", "v2"};
req.set_values(values);
Response response = remoteHost.RemoteFunc(req);
cout << response.status() << endl;
}
//server
Response RemoteFunc(Request req) {
//...
}
在client调用remoteHost.RemoteFunc()时,其实已经发生了一次网络传输。参数被封包后传递给了server,传递方式可能是HTTP请求,也可能直接用TCP。server接收到参数后调用相应的RemoteFunc函数,并在离开函数时再将结果封包后传回给client。整个过程被称为一次RPC调用。
RPC调用可能像上面代码一样是同步的,但也可以是异步的,client在发起请求后需要主动去查询response。
由此我们可以看出RPC需要做的事有:
- 在client和server端各自准备好用于网络通信的函数,也就是上面代码中的RemoteFunc;
- 在client和server端各自准备好用于网络通信的数据类型,也就是上面代码中的Request和Response;
- 把请求分发给相应的函数。
这里面有两个问题:
- 如何保证client调用的函数和server端准备的函数是一致的(也就是可调用的);
- 如何保证Request和Response类型在client和server端是一致的(也就是可被正确解析的)。
stub就是用于解决这两个问题的代码。
Stub
wiki里的解释是:分布式计算中的stub是在RPC调用中用于转换参数的代码。进行RPC调用的两端都要装相应的RPC函数库,而stub就是RPC函数库里用于保证数据在两端一致的代码。
数据在两端为什么会不一致呢?可能有以下原因:
- 编程语言不同,那么使用的数据类型肯定不同;
- 位宽不同,一边是32位,一边是64位,整数长度不一致;
- 大小端不同,一边是大端,一边是小端;
- 结构体的内存布局不同,这个和整个编译环境有关;
- 字符串编码不同,一边是GBK,一边是UTF-8。
stub就是要选取一种中间形式,让两端的数据都可以正确可逆的与中间数据进行转换。常用的中间数据类型包括:纯字符串、XML、JSON、protobuf。
stub的代码可以手动去写,优点是可以处理非常复杂的数据类型,缺点是比较繁琐,如果数据类型需要修改,工作量很大。
一般来说stub都是通过现成的函数库自动生成的。这种方法需要用指定的语言(interface description language, IDL)完成一个描述文档,这个文档同时应用于client和server端。在使用时两端的stub编译器会将IDL文档翻译成指定的编程语言供两端的程序使用。如前面程序中使用的两种数据类型可以这样描述:
message Request{
required bytes key = ;
repeated bytes values = ;
}
message Response {
required int32 status = ;
optional bytes error_code = ;
}
当数据类型要进行修改的时候,只要改一下IDL文档,再用stub编译器进行编译就OK了。
除了数据,RPC过程也可以通过IDL进行定义:
service DefaultService {
rpc RemoteFunc(Request) returns(Response)
}
Stub学习的更多相关文章
- TDD学习笔记【六】一Unit Test - Stub, Mock, Fake 简介
这篇文章简介一下,如何通过 mock framework,来辅助我们更便利地模拟目标对象的依赖对象,而不必手工敲堆只为了这次测试而存在的辅助类型. 而模拟目标对象的部分,常见的有 stub objec ...
- RhinoMock学习-Stub方法
// Arrange var stub = MockRepository.GenerateStub<IDemo>(); stub.Stub(x => x.StringArgStrin ...
- springMVC学习笔记--知识点总结1
以下是学习springmvc框架时的笔记整理: 结果跳转方式 1.设置ModelAndView,根据view的名称,和视图渲染器跳转到指定的页面. 比如jsp的视图渲染器是如下配置的: <!-- ...
- 学习SpringMVC——你们要的REST风格的CRUD来了
来来来,让一下,客官,您要的REST清蒸CRUD来了,火候刚刚好,不油不腻,请慢用~~~ 如果说前面是准备调料,洗菜,切菜,摆盘,那么今天就来完整的上道菜,主要说的是基于REST风格实现数据的增删改查 ...
- Spring学习系列(一) Spring简介
Spring简介 之前一直想写点东西,可一直没有开始实施,各种原因都有,最大原因可能还是自己太懒了,嘿嘿.最近在看Spring in action这本书,为了能让自己坚持下去把书看完,这次决定同步的在 ...
- SpringMVC学习记录2
废话 最近在看SpringMVC...里面东西好多...反正东看一点西看一点吧... 分享一下最近的一些心得..是关于DispatcherServlet的 DispatcherServlet与Cont ...
- TDD学习笔记【五】一隔绝相依性的方式与特性
前言 在上一篇文章中,提到了如何通过 IoC 的设计,以及 Stub Object 的方式,来独立测试目标对象. 这一篇文章,则要说明有哪些设计对象的方式,可以让测试或需求变更时,更容易转换. 并说明 ...
- TDD学习笔记【四】--- 如何隔离相依性 - 基本的可测试性
前言 相信许多读者都听过「可测试性」,甚至被它搞的要死要活的,还觉得根本是莫名其妙,徒劳无功.今天这篇文章,主要要讲的是对象的相依性,以及对象之间直接相依,会带来什么问题.为了避免发生因相依性而导致设 ...
- TDD学习笔记【三】---是否需针对非public方法进行测试?
前言 在Visual Studio 2012 中,针对Unit Test 的部分,有一个重要的变动: 原本针对「测试对象非public 的部分」,开发人员可通过Visual Studio 2010 自 ...
随机推荐
- Google浏览器提示用户要允许网站允许flash!
开发的flash播放器,在谷歌浏览器上播放不了,需要提示用户手动开启允许网站运行flash: <script type="text/javascript"> if (w ...
- 百度地图API开发----手机地图做导航功能
第一种方式:手机网页点击打开直接进百度地图APP <a href="baidumap://map/direction?mode=[transit:公交,driving:驾车]& ...
- 170713、springboot编程之多数据源切换
我们在开发过程中可能需要用到多个数据源,我们有一个项目(MySQL)就是和别的项目(SQL Server)混合使用了.其中SQL Server是别的公司开发的,有些基本数据需要从他们平台进行调取,那么 ...
- java 新手入门课程03
2017.7.6 java 课堂笔记 1.关于分支; if/else 是基于boolean 值的双分支 Switch 基于数字(包括整数 char byte 枚举, 字符串)类型的多分支 方法 ...
- php5.6 的curl开启和之前的不太一样了,搞了半天,记录下
设置电脑环境变量中的->系统变量(注:不是用户变量) 新建 PHP_HOME 值 D:\php /PHP 根目录 Path 增加 ;%PHP_HOME%;%PHP_HOME%\ext ...
- 内核通信之Netlink源码分析-用户内核通信原理3
2017-07-06 上节主讲了用户层通过netlink和内核交互的详细过程,本节分析下用户层接收数据的过程…… 有了之前基础知识的介绍,用户层接收数据只涉及到一个核心调用readmsg(), 其他的 ...
- andorid ListView和GirdView 与ScrollView 冲突
1.listview解决方法 public static void setListViewHeightBasedOnChildren(ListView listView) { if(listView ...
- centos LB负载均衡集群 三种模式区别 LVS/NAT 配置 LVS/DR 配置 LVS/DR + keepalived配置 nginx ip_hash 实现长连接 LVS是四层LB 注意down掉网卡的方法 nginx效率没有LVS高 ipvsadm命令集 测试LVS方法 第三十三节课
centos LB负载均衡集群 三种模式区别 LVS/NAT 配置 LVS/DR 配置 LVS/DR + keepalived配置 nginx ip_hash 实现长连接 LVS是四层LB ...
- java-mybaits-00201-DAO-SqlSession使用范围
1.SqlSession的使用范围 SqlSession中封装了对数据库的操作,如:查询.插入.更新.删除等. 通过SqlSessionFactory创建SqlSession,而SqlSessionF ...
- A Basic Example of Threads Synchronization in Python, python中的线程同步示例
http://zulko.github.io/blog/2013/09/19/a-basic-example-of-threads-synchronization-in-python/ We will ...