实验目的

掌握GOF设计模式的代理模式

了解掌握socket编程、java反射、动态代理

了解NIO、多线程

掌握hadoop的RPC框架使用API

实验原理

1.什么是RPC
  在hadoop出现以前,我们写的程序一般都是单机版本,只能在一台机器上处理,而一台机器的处理能力总是有限的,hadoop让我们可以写出分布式程序,将多台节点联合到一起进行处理。分布式程序的各节点之间通信需要依靠网络,一种简单的思路就是部署一个Web服务器,例如tomcat,但是这样会使得整个架构太庞大冗余。通俗地讲,我们需要自己实现一个更加轻量级的通信规则框架,这就是我们说的RPC通信框架。
  RPC(Remote Procedure Call)—远程过程调用协议,它是一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的协议。RPC协议假定某些传输协议的存在,如TCP或UDP,为通信程序之间携带信息数据。在OSI网络通信模型中,RPC跨越了传输层和应用层。RPC使得开发包括网络分布式多程序在内的应用程序更加容易。所以我们知道,一个RPC框架分为客户端和服务端,客户端发送一个请求给服务端,服务端调用对应的方法逻辑,将得到的结果返回给客户端,整个过程就是这么简单,但是实现起来需要考虑网络带宽,执行性能等多方面的因素。

2.如何实现一个RPC框架
  代理模式是面向切面编程常使用的设计模式,动态代理是jdk帮助我们提供的工具,我们可以利用InvocationHandle类和Proxy类来动态的调用代理类的方法。
  我们实现一个简单的RPC过程为:

1.Client端获取一个RPC代理对象proxy。

2.调用proxy上的方法,被InvocationHandler实现类 Invoker的invoke()方法捕获。

3.invoke()方法内将RPC请求封装成 Invocation实例,再向Server发送RPC请求。

4.Server端循环接收RPC请求,对每一个请求都创建一个Handler线程处理。

5.Handler线程从输入流中反序列化出Invocation实例,再调用Server端的实现方法。

6.调用结束,向Client端返回调用结果。

3.hadoop的RPC框架
  Hadoop中RPC机制建立在Java的DynamicProxy(动态代理)、NIO、socket编程的基础上, 我们可以在Client端调用Server端方法, 就像调用本地方法一样,而屏蔽了中间的复杂过程。

实验环境

1.操作系统
  操作机:Windows_7
  操作机默认用户名:hongya,密码:123456

2.实验工具
  IntelliJ IDEA

IDEA 全称IntelliJ IDEA,是java语言开发的集成环境,IntelliJ在业界被公认为最好的java开发工具之一,尤其在智能代码助手、代码自动提示、重构、J2EE支持、Ant、JUnit、CVS整合、代码审查、 创新的GUI设计等方面的功能可以说是超常的。IDEA是JetBrains公司的产品,这家公司总部位于捷克共和国的首都布拉格,开发人员以严谨著称的东欧程序员为主。

  优点:
  1.最突出的功能自然是调试(Debug),可以对Java代码,JavaScript,JQuery,Ajax等技术进行调试。
  2.其他编辑功能抛开不看,这点远胜Eclipse。
  3.首先查看Map类型的对象,如果实现类采用的是哈希映射,则会自动过滤空的Entry实例。 不像Eclipse,只能在默认的toString()方法中寻找你所要的key。
  4.其次,需要动态Evaluate一个表达式的值,比如我得到了一个类的实例,但是并不知晓它的API,可以通过Code Completion点出它所支持的方法,这点Eclipse无法比拟。
  5.最后,在多线程调试的情况下,Log on console的功能可以帮你检查多线程执行的情况。

  缺点:
  1.插件开发匮乏,比起Eclipse,IDEA只能算是个插件的矮子,目前官方公布的插件不足400个,并且许多插件实质性的东西并没有,可能是IDEA本身就太强大了。
  2.在同一页面中只支持单工程,这为开发带来一定的不便,特别是喜欢开发时建一个测试工程来测试部分方法的程序员带来心理上的不认同。
  3.匮乏的技术文章,目前网络中能找到的技术支持基本没有,技术文章也少之又少。
  4.资源消耗比较大,建个大中型的J2EE项目,启动后基本要200M以上的内存支持,包括安装软件在内,差不多要500M的硬盘空间支持。(由于很多智能功能是实时的,因此包括系统类在内的所有类都被IDEA存放到IDEA的工作路径中)。

  特色功能:
  智能选择
  丰富的导航模式
  历史记录功能
  JUnit的完美支持
  对重构的优越支持
   编码辅助
  灵活的排版功能
   XML的完美支持
  动态语法检测
  代码检查
  等等。

步骤1:修改映射,查看开发环境

  1.1首先进入操作机C:\Windows\System32\drivers\etc\hosts,修改映射(以实验IP为准)。见下图:

1.2打开电脑,双击我们的编辑器idea64的图标,进入找到本地课程所在的代码包,在hellohadoop|src|com.hongya|day009,里面的两个包分别是两个试验内容,代码已经实现好,大家可以自己新建代码包,自己重新实现一遍。

 2.1客户端定义我们要实现的操作的类:Login。大家打开代码"com.hongya|day009|myrpc|client|Login"可以看到,Login是一个接口,只有一个未实现的方法!

2.2服务端定义Login的实现类:LoginImpl。大家打开代码"com.hongya|day009|myrpc|server|LoginImpl"可以看到,实现了它的login方法!

2.3定义Invocation,此类是用来传递客户端和服务器端的联系参数的代码为:"com.hongya|day009|myrpc|server|Invocation",内容为class、方法名、参数、返回值。

 2.4定义MyInvocationHandler,实现java的InvocationHandler接口代码为:"com.hongya|day009|myrpc|server|MyInvocationHandler",我们主要看他的invoke方法实现,可以看出它将我们要调用的class、方法名、参数通过ObjectOutputStream写出到socket,然后得到socket的返回值。

2.5定义RPCServer,不断监听端口的请求代码为:"com.hongya|day009|myrpc|server|RPCServer"此部分代码比较复杂,主要是启动一个线程,对客户端写来的数据进行解析,然后调用对应的方法,将返回值写进socket流。

2.6定义ClientTest和ServerTest。都在"com.hongya|day009|myrpc"包下,每个都有main方法。其中server端是监听端口产生代理对象,client是调用RPC的的getProxy方法得到代理对象,调用login方法。

3.1理清代码逻辑。这部分比较复杂,需要大家思路清晰,整个代码如下:

我们的调用顺序是:ServerTest启动,new一个RPCServer,调用start方法,启动线程监听,Client启动,得到代理的Proxy类,调用login方法,将请求封装为Invocation向socket发送ObjectOutputStream,Server端线程监听到后,得到Invocation类,执行对应方法,返回结果给client。

  3.2启动Server端。点开ServerTest,点击右边绿色三角形,run,结果如图:

启动程序以后可能会报异常,这和本地环境有关系,只要程序还没停止,就可以继续实验。判断进程是否停止的方法可以看最后的步骤6:关闭进程。

3.3Client调用。点开ClientTest,点击右边绿色三角形,点击"run",客户端的并没有实现Login的方法,但是依然有输出,因为远程调用了Server端的方法。我们的服务器如果不在本地,也可以实现类似的功能

关闭进程。参考步骤6。

步骤4:使用hadoop自带的RPC框架的API

  4.1Client端自定义接口。接口的完全限定名为:com.hongya|day009|hadooprpc|LoginProtocol。注意这里和自定义的RPC框架有所不同,需要添加一个versionId的属性,这是hadoop框架规定的。

4.2Server端的实现类。实现类为:com.hongya|day009|hadooprpc|LoginProtocolImpl,和自定义一样,只需要实现具体方法

4.3Server端启动监听代码。实现类为:com.hongya|day009|hadooprpc|Server,方法内容和自定义的Server端类似。注意代码内容,需要按照hadoop的API实现,这部分的源代码全部在org.apache.hadoop.ipc.RPC中:

RPC.Server server = new RPC.Builder(new Configuration()).setBindAddress("localhost").setPort(8888)

.setProtocol(LoginProtocol.class).setInstance(new LoginProtocolImpl()).build();

server.start();

4.4Client端发送远程请求。注意这里的Client和Server端的Ip都是localhost,通过本地模拟远程通信,如果你可以和别人合作,也可以修改这里的IP地址,但是注意Client和Server要保持一致。

步骤5:测试基于Hadoop的PRC通信实例

  5.1理清思路逻辑。这时候我们只有这四各类,一个接口和他的实现类、一个客户端程序、一个服务端程序。因为我们利用hadoop自带的RPC框架,调用过程和上面自定义的框架是一样的,只是中间的动态代理和Socket通信以及多线程监听由hadoop实现了。

5.2启动服务端,点击Server类右边的绿色三角形,启动程序:

5.3启动客户端,点击LoginClient类右边的绿色三角形,启动客户端程序,启动服务端后,不停止的话,会一直运行这个进程。然后可以多次执行步骤5.2,每次都会输出我们在LoginProtocolImpl实现的逻辑。这里报的异常信息和本地环境有关系,可以忽略。

步骤6:关闭进程

  6.1注意每次运行程序控制台会有输出信息,如果左边还有一个红点,就没有停止,实验结束需要点一下这个红点,停止这个进程:

吴裕雄--天生自然HADOOP操作实验学习笔记:分布式及RPC通信简介的更多相关文章

  1. 吴裕雄--天生自然HADOOP操作实验学习笔记:使用hive操作hbase

    实验目的 熟悉hive和hbase的操作 熟悉hadoop.hbase.hive.zookeeper的关系 熟练大数据环境的搭建 学会分析日志排除问题 实验原理 1.hive整合hbase原理 前面大 ...

  2. 吴裕雄--天生自然HADOOP操作实验学习笔记:hbase学生选课案例

    实验目的 复习hbase的shell操作和javaAPI操作 了解javaWeb项目的MVC设计 学会dao(数据库访问对象)和service层的代码编写规范 学会设计hbase表格 实验原理 前面我 ...

  3. 吴裕雄--天生自然HADOOP操作实验学习笔记:hbase的javaAPI应用

    实验目的 进一步了解hbase的操作 熟悉使用IDEA进行java开发 熟悉hbase的javaAPI 实验原理 前面已经了解通过hbase的shell操作hbase,确实比较难以使用,另外通过hiv ...

  4. 吴裕雄--天生自然HADOOP操作实验学习笔记:hbase的shell应用v2.0

    HRegion 当表的大小超过设置值的时候,HBase会自动地将表划分为不同的区域,每个区域包含所有行的一个子集.对用户来说,每个表是一堆数据的集合,靠主键来区分.从物理上来说,一张表被拆分成了多块, ...

  5. 吴裕雄--天生自然HADOOP操作实验学习笔记:hbase微博案例

    实验目的 熟悉hbase表格设计的方法 熟悉hbase的javaAPI 通过API理解掌握hbase的数据的逻辑视图 了解MVC的服务端设计方式 实验原理 上次我们已经初步设计了学生选课案例的,具体功 ...

  6. 吴裕雄--天生自然HADOOP操作实验学习笔记:mapreduce代码编程

    实验目的 深入了解mapreduce的底层 了解IDEA的使用 学会通过本地和集群环境提交程序 实验原理 1.回忆mapreduce模型 前面进行了很多基础工作,本次实验是使用mapreduce的AP ...

  7. 吴裕雄--天生自然HADOOP操作实验学习笔记:hive DDL

    实验目的 了解hive DDL的基本格式 了解hive和hdfs的关系 学习hive在hdfs中的保存方式 学习一些典型常用的hiveDDL 实验原理 有关hive的安装和原理我们已经了解,这次实验我 ...

  8. 吴裕雄--天生自然HADOOP操作实验学习笔记:mapreduce和yarn命令

    实验目的 了解集群运行的原理 学习mapred和yarn脚本原理 学习使用Hadoop命令提交mapreduce程序 学习对mapred.yarn脚本进行基本操作 实验原理 1.hadoop的shel ...

  9. 吴裕雄--天生自然HADOOP操作实验学习笔记:hdfs简单的shell命令

    实验目的 了解bin/hadoop脚本的原理 学会使用fs shell脚本进行基本操作 学习使用hadoop shell进行简单的统计计算 实验原理 1.hadoop的shell脚本 当hadoop集 ...

随机推荐

  1. kubernetes容器端口设置的坑

    1.使用dockerhub上面的镜像的时候,先到dockerhub上看镜像的相关信息. 2.不能随便修改容器应用的镜像,会出问题.

  2. Codeforces 1156E Special Segments of Permutation(启发式合并)

    题意: 给一个n的排列,求满足a[l]+a[r]=max(l,r)的(l,r)对数,max(l,r)指的是l到r之间的最大a[p] n<=2e5 思路: 先用单调栈处理出每个点能扩展的l[i], ...

  3. mapreduce清洗数据

    继上篇 MapReduce清洗数据 package mapreduce; import java.io.IOException; import org.apache.hadoop.conf.Confi ...

  4. Thingsboard源码安装部署

    交流QQ群 如果安装有其他问题,可以到QQ群求助 环境安装 开发环境要求:Jdk 1.8版本Postgresql 9以上Node.jsNpmMaven 3.6以上Git工具Idea开发工具 JDK 下 ...

  5. [Effective Java 读书笔记] 第7章 方法

    第39条 必要时进行保护性拷贝 对于可变类,如果作为参数传入到自己的类里,并作为自己类的数据使用存储时,需要进行保护性拷贝,比如Date是可变的,如果传入一个Date类,最好做一个保护性拷贝,以免在调 ...

  6. EF core (code first) 通过自动迁移实现多租户数据分离 :按Schema分离数据

    前言 本文是多租户系列文章的附加操作文章,如果想查看系列中的其他文章请查看下列文章 主线文章 Asp.net core下利用EF core实现从数据实现多租户(1) Asp.net core下利用EF ...

  7. 20200220--python学习第13天

    今日内容 作业题(21题) 推导式 装饰器 模块[可选] 内容回顾 1.函数 a.参数 def func(a1,a2):pass def func(a1,a2=None):pass 默认参数推荐使用不 ...

  8. Java Stack使用

    1.Stack继承自Vector.遵从先进后出的规则. 2.Stack 是线程同步的.(map.List.Set是线程不同步的,需要在外部封装的时候来同步) 试例代码: public static v ...

  9. WebSocket协议分析

    WebSocket协议分析 1.什么是WebSocket协议 WebScoket协议是基于TCP协议建立的全双工通信,所谓的全双工通信就是双向同时通信. 2.WebSocket协议优点 WebSock ...

  10. 惊讶!缓存刚Put再Get居然获取不到?

    最近一直在老家远程办公,微信突然响了下,有同事说遇到了一个奇怪的问题,让我帮忙看下. 现象就是标题所说的缓存获取不到的问题,我一听感觉这个问题挺有意思的,决定一探究竟. 下面给出部分代码还原下案发现场 ...