远程过程调用失败_Java开发大型互联网RPC远程调用服务实现之问题处理方案

引言

RPC(Remote Procedure Call Protocol)——远程过程调用协议,它是一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的协议。RPC协议假定某些传输协议的存在,如TCP或UDP,为通信程序之间携带信息数据。在OSI网络通信模型中,RPC跨越了传输层和应用层。RPC使得开发包括网络分布式多程序在内的应用程序更加容易。

RPC采用客户机/服务器模式。请求程序就是一个客户机,而服务提供程序就是一个服务器。首先,客户机调用进程发送一个有进程参数的调用信息到服务进程,然后等待应答信息。在服务器端,进程保持睡眠状态直到调用信息到达为止。当一个调用信息到达,服务器获得进程参数,计算结果,发送答复信息,然后等待下一个调用信息,最后,客户端调用进程接收答复信息,获得进程结果,然后调用执行继续进行。有多种 RPC模式和执行。

RPC 结构

实现 RPC 的程序包括 5 个部分:

1. User

2. User-stub

3. RPCRuntime

4. Server-stub

5. Server

RPC 调用分类

RPC 调用的分类方式有很多种。

从通信协议层面可以分为:

基于 HTTP 协议的 RPC;

基于二进制协议的 RPC;

基于 TCP 协议的 RPC。

从是否跨平台可分为:

单语言 RPC,如 RMI, Remoting;

跨平台 RPC,如 google protobuffer, restful json,http XML。

从调用过程来看,可以分为同步通信RPC和异步通信RPC:

同步 RPC:指的是客户端发起调用后,必须等待调用执行完成并返回结果;

异步 RPC:指客户方调用后不关心执行结果返回,如果客户端需要结果,可用通过提供异步 callback 回调获取返回信息。大部分 RPC 框架都同时支持这两种方式的调用。

RPC 功能目标

RPC 的主要功能目标是让构建分布式计算(应用)更容易,在提供强大的远程调用能力时不损失本地调用的语义简洁性。为实现该目标,RPC 框架需提供一种透明调用机制让使用者不必显式的区分本地调用和远程调用,在前文《浅出篇》中给出了一种实现结构,基于 stub 的结构来实现。下面我们将具体细化 stub 结构的实现。

Java RPC 实现

在进一步拆解了组件并划分了职责之后,这里以一个最简单 Java RPC 框架实现为例,对 RPC 具体逻辑进行分析。

RPC 框架服务发布代码:

e96bacff77a88f3b7a2cb9ea85333372.png
57b15fb492a8b904f3c5c193c2e877c2.png
158e492a6ffec2eecc171b15981bdc21.png
e7d2585585054a9694e51b77a67db8b7.png
18ddd4d33c8f7646a15d363b4bfa67a5.png

服务端发布服务的代码如上,首先校验传入的端口和服务是否合法,然后开启一个 socket 监听,这儿为了简便,没有采用 NIO 方式,同时直接采用 java 的序列化方式,将传入的数据通过反射取出调用的方法和参数,本地执行后将运行结果通过 socket 套接字返回给客户端。RPC 框架服务调用代码:框架中客户端调用的代码中,首先校验对应的端口和主机是否合法,然后通过动态代理生成一个代理对象,在代理对象的方法中,拦截调用,通过建立 socket 连接,将方法和参数传递到远端执行并获取远程执行返回结果。

RPC 调用测试:如上图所示,服务器端发布一个接口服务 HelloService,客户端成功通过 RPC 调用。

怎么做到远程服务调用?

怎么封装通信细节才能让用户像以本地调用方式调用远程服务呢?对java来说就是使用代理!java代理有两种方式:1) jdk 动态代理;2)字节码生成。尽管字节码生成方式实现的代理更为强大和高效,但代码不易维护,大部分公司实现RPC框架时还是选择动态代理方式。

下面简单介绍下动态代理怎么实现我们的需求。我们需要实现RPCProxyClient代理类,代理类的invoke方法中封装了与远端服务通信的细节,消费方首先从RPCProxyClient获得服务提供方的接口,当执行helloWorldService.sayHello(“test”)方法时就会调用invoke方法。

Java

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

publicclassRPCProxyClient implementsjava.lang.reflect.InvocationHandler{

privateObjectobj;

publicRPCProxyClient(Objectobj){

this.obj=obj;

}

/**

* 得到被代理对象;

*/

publicstaticObjectgetProxy(Objectobj){

returnjava.lang.reflect.Proxy.newProxyInstance(obj.getClass().getClassLoader(),

obj.getClass().getInterfaces(),newRPCProxyClient(obj));

}

/**

* 调用此方法执行

*/

publicObjectinvoke(Objectproxy,Method method,Object[]args)

throwsThrowable{

//结果参数;

Objectresult=newObject();

// ...执行通信相关逻辑

// ...

returnresult;

}

}

Java

1

2

3

4

5

6

publicclassTest{

publicstaticvoidmain(String[]args){

HelloWorldService helloWorldService=(HelloWorldService)RPCProxyClient.getProxy(HelloWorldService.class);

helloWorldService.sayHello("test");

}

}

异常处理

无论 RPC 怎样努力把远程调用伪装的像本地调用,但它们依然有很大的不同点,而且有一些异常情况是在本地调用时绝对不会碰到的。在说异常处理之前,我们先比较下本地调用和 RPC调用的一些差异:

  1. 本地调用一定会执行,而远程调用则不一定,调用消息可能因为网络原因并未发送到服务方。
  2. 本地调用只会抛出接口声明的异常,而远程调用还会抛出 RPC 框架运行时的其他异常。
  3. 本地调用和远程调用的性能可能差距很大,这取决于 RPC 固有消耗所占的比重。

正是这些区别决定了使用 RPC 时需要更多考量。

当调用远程接口抛出异常时,异常可能是一个业务异常, 也可能是 RPC 框架抛出的运行时异常(如:网络中断等)。

业务异常表明服务方已经执行了调用,可能因为某些原因导致未能正常执行, 而 RPC 运行时异常则有可能服务方根本没有执行,对调用方而言的异常处理策略自然需要区分。

由于 RPC 固有的消耗相对本地调用高出几个数量级,

本地调用的固有消耗是纳秒级,而 RPC 的固有消耗是在毫秒级。

那么对于过于轻量的计算任务就并不合适导出远程接口由独立的进程提供服务,

只有花在计算任务上时间远远高于 RPC 的固有消耗才值得导出为远程接口提供服务。

总结

以 上就是我对Java开发大型互联网RPC远程调用服务实现之问题处理方案 问题及其优化总结,分享给大家,觉得收获的话可以点个关注收藏转发一波喔,谢谢大佬们支持!

最后,每一位读到这里的网友,感谢你们能耐心地看完。希望在成为一名更优秀的Java程序员的道路上,我们可以一起学习、一起进步!都能赢取白富美,走向架构师的人生巅峰!

想了解学习Java方面的技术内容以及Java技术视频的内容可加群:722040762 验证码:头条(06 必过)欢迎大家的加入哟!

38ac8831f8f0c61083b2b484c3d28d75.png

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/533985.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

chrome 新的session 设置_为什么还是由这么多人搞不懂Cookie、Session、Token?

作者:不学无数的程序员链接:https://urlify.cn/Yfm6Vr# Cookie洛:大爷,楼上322住的是马冬梅家吧? 大爷:马都什么? 夏洛:马冬梅。 7大爷:什么都没啊? 夏洛…

eview面板数据之混合回归模型_【视频教程】Eviews系列25|面板数据回归分析之Hausman检验及本章常见问题解答...

点击上方关注我们!本期我们学习Eviews统计建模最后一部分--面板数据回归分析Hausman检验及本章常见问题解答。实操:Hausman检验判断是固定效应模型还是随机效应模型上期我们讲到模型判断若选择模型2,需进一步通过Hausman检验判断固定效应还是随机效应,接…

mybatis mysql selectkey_Mybatis示例之SelectKey的应用

SelectKey在Mybatis中是为了解决Insert数据时不支持主键自动生成的问题,他可以很随意的设置生成主键的方式。不管SelectKey有多好,尽量不要遇到这种情况吧,毕竟很麻烦。SelectKey需要注意order属性,像Mysql一类支持自动增长类型的…

java treetable_在Swing中创建TreeTable | 学步园

TreeTable是Tree和Table的一个结合-就是一个即能够展开和收起行,同时也能够显示多个列的组件。在Swing的标准包里没有一个叫做JtreeTable的组件,但是我们很容易通过把Jtree做成Jtable的渲染器来创建一个这样的组件。这篇文章就是关于如何使用…

python期末大作业_大一期末考试很重要,考得好不仅有机会有钱拿,还有机会换专业...

现阶段很多高校放寒假的时间已经公布,这也就意味着,大学期末考试即将到来。对于大一新生来说,大学的期末考试是比较新鲜的,因为大家都没有经历过。经历过大学考试的学生,都知道大学的大概学习模式,一般情况…

java http 302重定向_Java 纯HTTP请求 禁止302自动重定向

Java 纯HTTP Get请求获取响应内容,如果发生302重定向,继而模拟请求域获取重定向后的响应内容。关键点:设置conn.setInstanceFollowRedirects为false即可示例代码public static void main(String[] args) {try {StringBuffer buffer new Stri…

python 且_Pyface库:一个基于pyqt、pyside、wx且简化的python的GUI

1 说明:1.1 Pyface库由大名鼎鼎的enthought出品。1.2 介绍:1.2.1 英文:traits-capable windowing framework.The pyface project contains a toolkit-independent GUI abstraction layer, which is used to support the "visualization&…

java方法的参数类型_Java 基础 14 方法的重载 与 方法参数类型详解

1.1 方法重载的概述和特点方法重载概述在同一个类中,允许存在一个以上的同名方法,只要它们的参数个数或者参数类型不同即可。方法重载特点与返回值类型无关,只看方法名和参数列表在调用时,虚拟机通过参数列表的不同来区分同名方法…

crv仪表上的i是什么指示灯_汽车打不着火是怎么回事,仪表盘汽车发动机故障灯亮是什么情况故障指示灯图解大全集...

如果打不着火,那有可能是起动机坏了,有可能是电池没电了,有可能是电路出现了问题,还有可能是点火系统出现了问题。汽车发动机的点火系统主要部件是火花塞和点火线圈,火花塞是一个需要定期更换的易损件。如果火花塞长时…

restful风格_什么是RESTful风格的API设计?

随着移动互联网的兴起,RESTful风格的API设计也随之流行起来,但我们说了那么多RESTful设计,它到底是什么?本篇文章带大家来了解一下它的真实面目。RESTful概念首先,我们需要明确的是RESTful,它是一个理念&am…

zookeeper 分布式锁_关于redis分布式锁,zookeeper分布式锁原理的一些学习与思考

编辑:业余草来源:https://www.xttblog.com/?p4946首先分布式锁和我们平常讲到的锁原理基本一样,目的就是确保,在多个线程并发时,只有一个线程在同一刻操作这个业务或者说方法、变量。在一个进程中,也就是一…

网页无法调用java9_JAVA 9 (内部类,异常,包)

内部类:将一个类定义在另一个类里面,称里面那个类为内部类。举例:class Zx{public static void main(String []arr){Outer o new Outer();o.method();}}class Outer{class Inner //内部类,可以定义多个内部类{void function(){S…

spark算子_Spark篇之持久化算子

一、前述Spark中控制算子也是懒执行的,需要Action算子触发才能执行,主要是为了对数据进行缓存。控制算子有三种,cache,persist,checkpoint,以上算子都可以将RDD持久化,持久化的单位是partition。cache和persist都是懒执…

java g1 gc ref proc_深入理解垃圾收集器的G1及日志分析

尽管Hotspot 最新的垃圾回收器G1是在2006年推出的。但是G1从推行至今的市场反响来看,但现在足以证明这款垃圾收集器是经得起考验的,从java9开始,就默认为G1垃圾收集器。G1是一款面向服务端应用的垃圾收集器。HotSpot开发团队赋予它的使命是(在…

gif透明背景动画_【超实用干货! 】iPad上的动画App大推荐

作者/立夏编辑/彼方大家好,我是立夏。大概在两年前吧我为大家写过几款动画APP的评测,这一次我也想给大家推荐一些我的新宠,供大家参考。我在这里就不过多提及如Animation Desk、Procreate或是Callipeg之类知名度相对更高一些的动画App了&…

iphone如何信任软件_【手机软件】千禾影院:全新观影神器,支持安卓+iOS,最新、最全、高清、免费!...

Hello,大家好,我是春哥!每天记得打卡哦!感谢每一位小伙伴们的关注和支持!免责声明大部分资源来源于网络,仅供学习和交流使用,如有侵权请联系我们删除。每期文章末尾都会有关键词,在公众号发消息…

Java小魔女芭芭拉_沉迷蘑菇不可自拔,黏土人《小魔女学园》苏西·曼芭芭拉 图赏...

GOOD SMILE出品的黏土人系列手办新作——《小魔女学园》苏西曼芭芭拉,已经开始接受预定了。这款黏土人的原型师是来自中国上海的陈天,售价4167日元,预计2018年4月发售。苏西是主人公亚可的室友,她是从东南亚来的身份不明的魔女。热…

java int相除向上取整_java实战项目常用类,Date、Calendar、BigDecimal、Math、UUID

Java开发中经常用到的类和方法,以下主要就日期是时间处理、金融数字处理、数学计算、随机数、MD5加密等。java.util.Date类java.util 包提供了 Date 类来封装当前的日期和时间。 Date 类提供两个构造函数来实例化 Date 对象。日期时间的本质是一个long,它…

R语言中dim函数_R语言--向量化计算(apply族函数)

R语言最优秀的是它的向量化编程,这其中apply族函数扮演了非常重要的角色。apply族函数是由apply、sapply、lapply、mapply、tapply等函数组成的。熟练使用apply族函数,能够简化程序,提高代码的运算速度。软件&环境win10 64bitR 3.6.1appl…

谷歌浏览器中文版_中国科学家设计超薄指尖传感器,厚度不到A4纸五分之一 / 谷歌发布地图时光机:百年前,你家街道啥样?/ AI看图说话首超人类...

关注我们了解计算机视觉最新动态 !动态先览1中国科学家设计超薄指尖传感器,厚度不到A4纸五分之一2谷歌发布地图「时光机」:100年前,你家街道长啥样?3仿真环境跟车2分钟,就让自动驾驶系统撞上马路牙子&#…