要完成一个高可用、高性能的RPC框架,需要对其架构的设计进行梳理,这里参考xxl-rpc框架,对整个项目进行梳理。

以上就是项目的整个构架,分为四个部分;

第一个是服务发布与引入,基于JDK动态代理以及Spring实现;包括invoker和provider。

第二个部分是服务注册,基于zookeeper实现;

第三部分是远程调用,基于并发编程基础知识实现;这里最为复杂,使用了分层的模式。

第四部分是远程通信,基于Netty实现。



服务引入

服务引入的实质就是输入请求,然后得到请求回来的对象。

创建一个处理引入的Bean类,属性是请求时需要的数据,包括:

.网络传输的组件:Netty等,比如MiNA等

.序列化方式,HESSIAN等,比如JACKSON

.调用的方式,一共有四种,同步、异步、回调、单一长连接

.负载均衡的方式,一共5种,RANDOM、ROUND、LRU、LFU、CONSISTENT_HASH

.接口名称

.超时时间,若超时,则请求报错

.请求地址:ip+prot

.进入token

.是否使用回调

.调用工厂,如果没有,默认实例化工厂。

返回的数据当然就是客户端所需要的对象。

这里请求和返回的操作,是该类的getObject方法执行。

分析:getObject方法是一个动态代理的过程,即给定一个接口,将接口实现。因此,使用动态代理来获取代理的对象。

简单来说,当得到了接口的所有信息:接口名,方法名,方法类型以及方法属性值。那么就可以去对服务端发起请求了。

这里需要注意几点,客户端发起请求不一定会将那些属性都配置上,因此,需要考虑各种配置不同的情况,应该做的操作

动态代理的意义是:当我们在客户端调用哪个方法,哪个方法被代理,传入Proxy函数的就是哪个方法,而不是代理整个类。

步骤1:接口名是一定要配置的,否则根本不知道请求什么,   

若类名是一个通用的业务类,则转向得到这一接口中方法的特定请求(比如在通用业务类接口方法中定义了所要调用的业务的类名,方法和参数等),

若类名是一个Object类,则需要抛出异常,这种类不能当做业务类。

步骤2:有可能只配置了接口名,但没有配置请求地址,但不代表一定会出错,这里就是使用注册服务的好处,注册服务可以管理我们的各种请求地址,和请求的类;

若没有请求地址,则看看注册服务中有没有现在请求的类(一般会通过类名和版本号按照一定的规则形成一个key值存在注册服务中),若找到这个key,就能够得到所请求类的请求地址。

但请求地址可能没有,抛异常;可能有一个,就把这个当做请求地址;若有多个,就要调用负载均衡,让它来决定请求哪个。

步骤3:将请求封装起来,这里需要一个请求的封装类, 

需要封装的内容包括:请求的id(通过该id可以在返回响应时获得同步的响应)、请求创建时间、请求的进入token、请求的类名、方法名、方法属性类型、方法属性。

步骤4:可以发送请求了,可以选择四种不同的调用方式,同步、异步、回调、单一长连接

  同步方式

  由于netty的NIO是异步模型,在调用的同时,并不会阻塞获取调用结果;因此需要实现sync-over-async(在异步中同步),其过程如下:

  调用XxlRpcFutureResponse类的get方法

  该类继承了Future类,并实现了其方法,可以使用其get方法来实现同步,即,如果done不为true,一直使线程处于阻塞状态,然后当达到超时时间后,主动唤醒该线程,然后就可以得到响应对象了。

  具体来说,当客户端netty的nio线程组发送的请求后,netty的服务端会异步返回response,然后该响应会被传入一个调用工厂的唤醒调用的方法中,在该方法中,取出XxlRpcFutureResponse类,并将其设置response,然后唤醒线程,此时就可以通过get方法来得到response,这样通过唯一的resquesId就可以同步唯一的得到response对象了。

  为啥说实现了同步,即在发送请求以后,线程阻塞,无法接收到其他所有的响应,只有这个响应收到或抛异常后,才能收到其他的响应。如果是采用异步方式,则会出现请求得到的是同一个响应的情况。

  异步方式

  在发送了请求之后,不马上得到返回的结果,而是在需要的时候再取,这时候就需要用异步的方式,所谓异步,就是利用一个InvokerFuture对象,来包装已经得到响应的respnsefuture对象,然后将InvokerFuture放到ThreadLocal里面,等需要的时候,取出来使用。

  

  callback方式

  这种方式也是异步的,而且是需要等待请求返回,因此,会造成异步的请求返回有多个,请求不及时。

  过程是,设置一个ConcurrentMap集合,先将callback和request存入futureresponse中,然后将futureresponse放入ConcurrentMap集合中,这样,当我们发送了请求之后,请求会从handle类中,找到read方法,然后read方法会调用notify函数,将返回的response对象取到,同时,notify函数还会把futureresponse从ConcurrentMap集合中取出来,然后把callback从futureresponse中取出,最后调用callback中的方法。这样就会准确的执行callback函数了。

  

  oneway方式

  暂时不清楚

以上就是rpc的四种连接方式。

RPC之总体架构的更多相关文章

  1. [源码解析] TensorFlow 分布式环境(1) --- 总体架构

    [源码解析] TensorFlow 分布式环境(1) --- 总体架构 目录 [源码解析] TensorFlow 分布式环境(1) --- 总体架构 1. 总体架构 1.1 集群角度 1.1.1 概念 ...

  2. jQuery总体架构

    第一章  总体架构 1.设计理念 jQuery的理念就是“写更少的代码,做更多的事”,而且做到代码的高度兼容性. 2.总体架构 大致可以分为三个部分:构造模块,底层支持模块和功能模块. 3.使用自调用 ...

  3. [转]新型智慧城市总体架构 华为 新ICT 一云二网三平台

    本文转自:http://www.jpsycn.com/hangyexinwen/20160801142354.html “十三五”规划提出,充分运用现代信息技术和大数据,建设一批新型示范性智慧城市.日 ...

  4. Openvswitch原理与代码分析(1):总体架构

      一.Opevswitch总体架构   Openvswitch的架构网上有如下的图表示:       每个模块都有不同的功能 ovs-vswitchd 为主要模块,实现交换机的守护进程daemon ...

  5. jQuery源码分析-01总体架构

    1. 总体架构 1.1自调用匿名函数 self-invoking anonymous function 打开jQuery源码,首先你会看到这样的代码结构: (function( window, und ...

  6. Apache Mesos总体架构

    http://developer.51cto.com/art/201401/426507.htm 1. 前言 同其他大部分分布式系统一样,Apache Mesos为了简化设计,也是采用了master/ ...

  7. Android MediaScanner:(一)MediaScanner总体架构

    Android MediaScanner:(一)MediaScanner总体架构 分类: Android android.multimedia2012-05-19 18:29 5050人阅读 评论(5 ...

  8. Web Magic 总体架构

    1.2 总体架构 WebMagic的结构分为Downloader.PageProcessor.Scheduler.Pipeline四大组件,并由Spider将它们彼此组织起来.这四大组件对应爬虫生命周 ...

  9. 2019-1-24 Spark 学习 --总体架构

    2019-1-24 Spark 学习 --总体架构 新建 模板 小书匠 1548339392539.jpg 1548339357270.jpg 1548339372461.jpg 1548339345 ...

随机推荐

  1. IntelliJIDEA的安装、配置与使用

    引言: IDEA,全称 IntelliJ IDEA,是 Java 语言的集成开发环境,IDEA 在业界被公认为是 最好的 java 开发工具之一,尤其在智能代码助手.代码自动提示.重构.J2EE 支持 ...

  2. Azure DevOps+Docker+Asp.NET Core 实现CI/CD(一 .简介与创建自己的代理池)

    前言 本文主要是讲解如何使用Azure DevOps+Docker 来实现持续集成Asp.NET Core项目(当然 也可以是任意项目). 打算用三个篇幅来记录完整的全过程 觉得有帮助的朋友~可以左上 ...

  3. 前端面试 vue 部分 (5)——VUE组件之间通信的方式有哪些

    VUE组件之间通信的方式有哪些(SSS) 常见使用场景可以分为三类: 父子通信: null 父向子传递数据是通过 props ,子向父是通过 $emit / $on $emit / $bus Vuex ...

  4. C#LeetCode刷题-蓄水池抽样

    蓄水池抽样篇 # 题名 刷题 通过率 难度 382 链表随机节点   47.0% 中等 398 随机数索引   41.6% 中等

  5. JavaScript promise基础示例

    const { info } = console // cooking function cook() { info('[COOKING] start cooking.') const p = new ...

  6. 制作qq简易聊天框

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  7. DVWA-1.9之fileupload

    low级 对文件类型没有任何约束,可直接上传"一句话木马"hack.php,连接冰蝎. 一句话木马 : medium级 源代码 if( ( $uploaded_type == &q ...

  8. Android studio 运行程序出现两个apk的解决方案

    保留主项目中的 intent-filter,将其他module中 AndroidManifest.xml文件的intent-filter的内容删除掉即可. 感恩:https://blog.csdn.n ...

  9. 2.MongoDB 4.2副本集环境基于时间点的恢复

    (一)MongoDB恢复概述 对于任何数据库,如果要将数据库恢复到过去的任意时间点,否需要有过去某个时间点的全备+全备之后的重做日志. 接下来根据瑞丽航空的情况进行概述: 全备:每天晚上都会进行备份: ...

  10. andriod开发中遇到的错误

    1.java.net.UnknownServiceException: CLEARTEXT communication ** not permitted by network security pol ...