基础知识
为什么要用 Dubbo?
随着服务化的进一步倒退,服务越来越多,服务之间的调用和依赖关系也越来越简单,诞生了面向服务的架构体系(SOA),也因而衍生出了一系列相应的技术,如对服务提供、服务调用、连贯解决、通信协议、序列化形式、服务发现、服务路由、日志输入等行为进行封装的服务框架。就这样为分布式系统的服务治理框架就呈现了,Dubbo 也就这样产生了。
Dubbo 是什么?
Dubbo 是一款高性能、轻量级的开源 RPC 框架,提供服务主动注册、主动发现等高效服务治理计划,能够和 Spring 框架无缝集成。
Dubbo 的应用场景有哪些?
- 透明化的近程办法调用:就像调用本地办法一样调用近程办法,只需简略配置,没有任何 API 侵入。
- 软负载平衡及容错机制:可在内网代替 F5 等硬件负载均衡器,降低成本,缩小单点。
- 服务主动注册与发现:不再须要写死服务提供方地址,注册核心基于接口名查问服务提供者的 IP 地址,并且可能平滑增加或删除服务提供者。
Dubbo 外围性能有哪些?
- Remoting:网络通信框架,提供对多种 NIO 框架形象封装,包含“同步转异步”和“申请 - 响应”模式的信息替换形式。
- Cluster:服务框架,提供基于接口办法的通明近程过程调用,包含多协定反对,以及软负载平衡,失败容错,地址路由,动静配置等集群反对。
- Registry:服务注册,基于注册核心目录服务,使服务生产方能动静的查找服务提供方,使地址通明,使服务提供方能够平滑减少或缩小机器。
架构设计
Dubbo 外围组件有哪些?
- Provider:裸露服务的服务提供方
- Consumer:调用近程服务生产方
- Registry:服务注册与发现注册核心
- Monitor:监控核心和拜访调用统计
- Container:服务运行容器
Dubbo 服务器注册与发现的流程?
服务容器 Container负责启动,加载,运行服务提供者。
服务提供者 Provider在启动时,向注册核心注册本人提供的服务。
服务消费者 Consumer在启动时,向注册核心订阅本人所需的服务。
注册核心 Registry返回服务提供者地址列表给消费者,如果有变更,注册核心将基于长连贯推送变更数据给消费者。
服务消费者 Consumer,从提供者地址列表中,基于软负载平衡算法,选一台提供者进行调用,如果调用失败,再选另一台调用。
服务消费者 Consumer 和提供者 Provider,在内存中累计调用次数和调用工夫,定时每分钟发送一次统计数据到监控核心 Monitor。
Dubbo 的整体架构设计有哪些分层?
接口服务层(Service):该层与业务逻辑相干,依据 provider 和 consumer 的业务设计对应的接口和实现
配置层(Config):对外配置接口,以 ServiceConfig 和 ReferenceConfig 为核心
服务代理层(Proxy):服务接口通明代理,生成服务的客户端 Stub 和 服务端的 Skeleton,以 ServiceProxy 为核心,扩大接口为 ProxyFactory
服务注册层(Registry):封装服务地址的注册和发现,以服务 URL 为核心,扩大接口为 RegistryFactory、Registry、RegistryService
路由层(Cluster):封装多个提供者的路由和负载平衡,并桥接注册核心,以 Invoker 为核心,扩大接口为 Cluster、Directory、Router 和 LoadBlancce
监控层(Monitor):RPC 调用次数和调用工夫监控,以 Statistics 为核心,扩大接口为 MonitorFactory、Monitor 和 MonitorService
近程调用层(Protocal):封装 RPC 调用,以 Invocation 和 Result 为核心,扩大接口为 Protocal、Invoker 和 Exporter
信息替换层(Exchange):封装申请响应模式,同步转异步。以 Request 和 Response 为核心,扩大接口为 Exchanger、ExchangeChannel、ExchangeClient 和 ExchangeServer
网络 传输 层(Transport):形象 mina 和 netty 为对立接口,以 Message 为核心,扩大接口为 Channel、Transporter、Client、Server 和 Codec
数据序列化层(Serialize):可复用的一些工具,扩大接口为 Serialization、ObjectInput、ObjectOutput 和 ThreadPool
Dubbo Monitor 实现原理?
Consumer 端在发动调用之前会先走 filter 链;provider 端在接管到申请时也是先走 filter 链,而后才进行真正的业务逻辑解决。默认状况下,在 consumer 和 provider 的 filter 链中都会有 Monitorfilter。
1、MonitorFilter 向 DubboMonitor 发送数据
2、DubboMonitor 将数据进行聚合后(默认聚合 1min 中的统计数据)暂存到 ConcurrentMap<Statistics, AtomicReference> statisticsMap,而后应用一个含有 3 个线程(线程名字:DubboMonitorSendTimer)的线程池每隔 1min 钟,调用 SimpleMonitorService 遍历发送 statisticsMap 中的统计数据,每发送结束一个,就重置以后的 Statistics 的 AtomicReference
3、SimpleMonitorService 将这些聚合数据塞入 BlockingQueue queue 中(队列大写为 100000)
4、SimpleMonitorService 应用一个后盾线程(线程名为:DubboMonitorAsyncWriteLogThread)将 queue 中的数据写入文件(该线程以死循环的模式来写)
5、SimpleMonitorService 还会应用一个含有 1 个线程(线程名字:DubboMonitorTimer)的线程池每隔 5min 钟,将文件中的统计数据画成图表
分布式框架
Dubbo 相似的分布式框架还有哪些?
比拟驰名的就是 Spring Cloud。
Dubbo 和 Spring Cloud 有什么关系?
Dubbo 是 SOA 时代的产物,它的关注点次要在于服务的调用,流量散发、流量监控和熔断。而 Spring Cloud 诞生于微服务架构时代,思考的是微服务治理的方方面面,另外因为依靠了 Spring、Spring Boot 的劣势之上,两个框架在开始指标就不统一,Dubbo 定位服务治理、Spring Cloud 是打造一个生态。
Dubbo 和 Spring Cloud 有什么哪些区别?
Dubbo 底层是应用 Netty 这样的 NIO 框架,是基于 TCP 协定传输的,配合以 Hession 序列化实现 RPC 通信。
Spring Cloud 是基于 Http 协定 Rest 接口调用近程过程的通信,相对来说 Http 申请会有更大的报文,占的带宽也会更多。然而 REST 相比 RPC 更为灵便,服务提供方和调用方的依赖只依附一纸契约,不存在代码级别的强依赖,这在强调疾速演变的微服务环境下,显得更为适合,至于重视通信速度还是不便灵活性,具体情况具体思考。
Dubbo 和 Dubbox 之间的区别?
Dubbox 是继 Dubbo 进行保护后,当当网基于 Dubbo 做的一个扩大我的项目,如加了服务可 Restful 调用,更新了开源组件等。
注册核心
Dubbo 有哪些注册核心?
- Multicast 注册核心:Multicast 注册核心不须要任何核心节点,只有播送地址,就能进行服务注册和发现, 基于网络中组播传输实现。
- Zookeeper 注册核心:基于分布式协调系统 Zookeeper 实现,采纳 Zookeeper 的 watch 机制实现数据变更。
- Redis 注册核心:基于 Redis 实现,采纳 key/map 存储,key 存储服务名和类型,map 中 key 存储服务 url,value 服务过期工夫。基于 Redis 的公布 / 订阅模式告诉数据变更。
- Simple 注册核心。
举荐应用 Zookeeper 作为注册核心
Dubbo 的注册核心集群挂掉,发布者和订阅者之间还能通信么?
能够通信。启动 Dubbo 时,消费者会从 Zookeeper 拉取注册的生产者的地址接口等数据,缓存在本地。每次调用时,依照本地存储的地址进行调用。
集群
Dubbo 集群提供了哪些负载平衡策略?
- Random LoadBalance: 随机选取提供者策略,有利于动静调整提供者权重。截面碰撞率高,调用次数越多,散布越平均。
- RoundRobin LoadBalance: 轮循选取提供者策略,均匀散布,然而存在申请累积的问题。
- LeastActive LoadBalance: 起码沉闷调用策略,解决慢提供者接管更少的申请。
- ConstantHash LoadBalance: 一致性 Hash 策略,使雷同参数申请总是发到同一提供者,一台机器宕机,能够基于虚构节点,摊派至其余提供者,防止引起提供者的激烈变动。
默认为 Random 随机调用。
Dubbo 的集群容错计划有哪些?
- Failover Cluster:失败主动切换,当呈现失败,重试其它服务器。通常用于读操作,但重试会带来更长提早。
- Failfast Cluster:疾速失败,只发动一次调用,失败立刻报错。通常用于非幂等性的写操作,比方新增记录。
- Failsafe Cluster:失败平安,出现异常时,间接疏忽。通常用于写入审计日志等操作。
- Failback Cluster:失败主动复原,后盾记录失败申请,定时重发。通常用于音讯告诉操作。
- Forking Cluster:并行调用多个服务器,只有一个胜利即返回。通常用于实时性要求较高的读操作,但须要节约更多服务资源。可通过 forks=”2″ 来设置最大并行数。
- Broadcast Cluster:播送调用所有提供者,一一调用,任意一台报错则报错。通常用于告诉所有提供者更新缓存或日志等本地资源信息。
默认的容错计划是 Failover Cluster。
配置
Dubbo 配置文件是如何加载到 Spring 中的?
Spring 容器在启动的时候,会读取到 Spring 默认的一些 schema 以及 Dubbo 自定义的 schema,每个 schema 都会对应一个本人的 NamespaceHandler,NamespaceHandler 外面通过 BeanDefinitionParser 来解析配置信息并转化为须要加载的 bean 对象!
说说外围的配置有哪些?
标签 | 用处 | 解释 |
---|---|---|
<dubbo:service/> | 服务配置 | 用于裸露一个服务,定义服务的元信息,一个服务能够用多个协定裸露,一个服务也能够注册到多个注册核心 |
<dubbo:reference/> | 援用配置 | 用于创立一个近程服务代理,一个援用能够指向多个注册核心 |
<dubbo:protocol/> | 协定配置 | 用于配置提供服务的协定信息,协定由提供方指定,生产方被动承受 |
<dubbo:application/> | 利用配置 | 用于配置以后利用信息,不论该利用是提供者还是消费者 |
<dubbo:module/> | 模块配置 | 用于配置以后模块信息,可选 |
<dubbo:registry/> | 注册核心配置 | 用于配置连贯注册核心相干信息 |
<dubbo:monitor/> | 监控核心配置 | 用于配置连贯监控核心相干信息,可选 |
<dubbo:provider/> | 提供方配置 | 当 ProtocolConfig 和 ServiceConfig 某属性没有配置时,采纳此缺省值,可选 |
<dubbo:consumer/> | 生产方配置 | 当 ReferenceConfig 某属性没有配置时,采纳此缺省值,可选 |
<dubbo:method/> | 办法配置 | 用于 ServiceConfig 和 ReferenceConfig 指定办法级的配置信息 |
<dubbo:argument/> | 参数配置 | 用于指定办法参数配置 |
Dubbo 超时设置有哪些形式?
Dubbo 超时设置有两种形式:
- 服务提供者端设置超时工夫,在 Dubbo 的用户文档中,举荐如果能在服务端多配置就尽量多配置,因为服务提供者比消费者更分明本人提供的服务个性。
- 服务消费者端设置超时工夫,如果在消费者端设置了超时工夫,以消费者端为主,即优先级更高。因为服务调用方设置超时工夫控制性更灵便。如果生产方超时,服务端线程不会定制,会产生正告。
服务调用超时会怎么样?
dubbo 在调用服务不胜利时,默认是会重试两次。
通信协议
Dubbo 应用的是什么通信框架?
默认应用 Netty 作为通信框架。
Dubbo 反对哪些协定,它们的优缺点有哪些?
- Dubbo:繁多长连贯和 NIO 异步通信,适宜大并发小数据量的服务调用,以及消费者远大于提供者。传输协定 TCP,异步 Hessian 序列化。Dubbo 举荐应用 dubbo 协定。
- RMI:采纳 JDK 规范的 RMI 协定实现,传输参数和返回参数对象须要实现 Serializable 接口,应用 Java 规范序列化机制,应用阻塞式短连贯,传输数据包大小混合,消费者和提供者个数差不多,可传文件,传输协定 TCP。多个短连贯 TCP 协定传输,同步传输,实用惯例的近程服务调用和 RMI 互操作。在依赖低版本的 Common-Collections 包,Java 序列化存在安全漏洞。
- WebService:基于 WebService 的近程调用协定,集成 CXF 实现,提供和原生 WebService 的互操作。多个短连贯,基于 HTTP 传输,同步传输,实用系统集成和跨语言调用。
- HTTP:基于 Http 表单提交的近程调用协定,应用 Spring 的 HttpInvoke 实现。多个短连贯,传输协定 HTTP,传入参数大小混合,提供者个数多于消费者,须要给应用程序和浏览器 JS 调用。
- Hessian:集成 Hessian 服务,基于 HTTP 通信,采纳 Servlet 裸露服务,Dubbo 内嵌 Jetty 作为服务器时默认实现,提供与 Hession 服务互操作。多个短连贯,同步 HTTP 传输,Hessian 序列化,传入参数较大,提供者大于消费者,提供者压力较大,可传文件。
- Memcache:基于 Memcache 实现的 RPC 协定。
- Redis:基于 Redis 实现的 RPC 协定。
设计模式
Dubbo 用到哪些设计模式?
Dubbo 框架在初始化和通信过程中应用了多种设计模式,可灵便管制类加载、权限管制等性能。
工厂模式
Provider 在 export 服务时,会调用 ServiceConfig 的 export 办法。ServiceConfig 中有个字段:
private static final Protocol protocol =
ExtensionLoader.getExtensionLoader(Protocol.class).getAdaptiveExtensi
on();
Dubbo 里有很多这种代码。这也是一种工厂模式,只是实现类的获取采纳了 JDKSPI 的机制。这么实现的长处是可扩展性强,想要扩大实现,只须要在 classpath 下减少个文件就能够了,代码零侵入。另外,像下面的 Adaptive 实现,能够做到调用时动静决定调用哪个实现,然而因为这种实现采纳了动静代理,会造成代码调试比拟麻烦,须要剖析出理论调用的实现类。
装璜器模式
Dubbo 在启动和调用阶段都大量应用了装璜器模式。以 Provider 提供的调用链为例,具体的调用链代码是在 ProtocolFilterWrapper 的 buildInvokerChain 实现的,具体是将注解中含有 group=provider 的 Filter 实现,依照 order 排序,最初的调用程序是:
EchoFilter -> ClassLoaderFilter -> GenericFilter -> ContextFilter ->
ExecuteLimitFilter -> TraceFilter -> TimeoutFilter -> MonitorFilter ->
ExceptionFilter
更确切地说,这里是装璜器和责任链模式的混合应用。例如,EchoFilter 的作用是判断是否是回声测试申请,是的话间接返回内容,这是一种责任链的体现。而像 ClassLoaderFilter 则只是在主性能上增加了性能,更改以后线程的 ClassLoader,这是典型的装璜器模式。
观察者模式
Dubbo 的 Provider 启动时,须要与注册核心交互,先注册本人的服务,再订阅本人的服务,订阅时,采纳了观察者模式,开启一个 listener。注册核心会每 5 秒定时查看是否有服务更新,如果有更新,向该服务的提供者发送一个 notify 音讯,provider 承受到 notify 音讯后,运行 NotifyListener 的 notify 办法,执行监听器办法。
动静代理模式
Dubbo 扩大 JDK SPI 的类 ExtensionLoader 的 Adaptive 实现是典型的动静代理实现。Dubbo 须要灵便地管制实现类,即在调用阶段动静地依据参数决定调用哪个实现类,所以采纳学生成代理类的办法,可能做到灵便的调用。生成代理类的代码是 ExtensionLoader 的 createAdaptiveExtensionClassCode 办法。代理类次要逻辑是,获取 URL 参数中指定参数的值作为获取实现类的 key。
运维治理
服务上线怎么兼容旧版本?
能够用版本号(version)过渡,多个不同版本的服务注册到注册核心,版本号不同的服务相互间不援用。这个和服务分组的概念有一点相似。
Dubbo telnet 命令能做什么?
dubbo 服务公布之后,咱们能够利用 telnet 命令进行调试、治理。Dubbo2.0.5 以上版本服务提供端口反对 telnet 命令
Dubbo 反对服务降级吗?
以通过 dubbo:reference 中设置 mock=“return null”。mock 的值也能够批改为 true,而后再跟接口同一个门路下实现一个 Mock 类,命名规定是“接口名称 +Mock”后缀。而后在 Mock 类里实现本人的降级逻辑
Dubbo 如何优雅停机?
Dubbo 是通过 JDK 的 ShutdownHook 来实现优雅停机的,所以如果应用 kill -9 PID 等强制敞开指令,是不会执行优雅停机的,只有通过 kill PID 时,才会执行。
SPI
Dubbo SPI 和 Java SPI 区别?
JDK SPI:
JDK 规范的 SPI 会一次性加载所有的扩大实现,如果有的扩大很耗时,但也没用上,很浪费资源。所以只心愿加载某个的实现,就不事实了
DUBBO SPI:
1、对 Dubbo 进行扩大,不须要改变 Dubbo 的源码
2、提早加载,能够一次只加载本人想要加载的扩大实现。
3、减少了对扩大点 IOC 和 AOP 的反对,一个扩大点能够间接 setter 注入其
它扩大点。
4、Dubbo 的扩大机制能很好的反对第三方 IoC 容器,默认反对 Spring Bean。
其余
Dubbo 反对分布式事务吗?
目前临时不反对,可与通过 tcc-transaction 框架实现
介绍:tcc-transaction 是开源的 TCC 补偿性分布式事务框架
TCC-Transaction 通过 Dubbo 隐式传参的性能,防止本人对业务代码的入侵。
Dubbo 能够对后果进行缓存吗?
为了进步数据拜访的速度。Dubbo 提供了申明式缓存,以缩小用户加缓存的工作量 <dubbo:reference cache=“true”/>
其实比一般的配置文件就多了一个标签 cache=“true”
Dubbo 必须依赖的包有哪些?
Dubbo 必须依赖 JDK,其余为可选。
Dubbo 反对哪些序列化形式?
默认应用 Hessian 序列化,还有 Duddo、FastJson、Java 自带序列化。
Dubbo 在平安方面有哪些措施?
- Dubbo 通过 Token 令牌避免用户绕过注册核心直连,而后在注册核心上治理受权。
- Dubbo 还提供服务黑白名单,来管制服务所容许的调用方。
服务调用是阻塞的吗?
默认是阻塞的,能够异步调用,没有返回值的能够这么做。Dubbo 是基于 NIO 的非阻塞实现并行调用,客户端不须要启动多线程即可实现并行调用多个近程服务,绝对多线程开销较小,异步调用会返回一个 Future 对象。
服务提供者能实现生效踢出是什么原理?
服务生效踢出基于 zookeeper 的长期节点原理。
同一个服务多个注册的状况下能够直连某一个服务吗?
能够点对点直连,批改配置即可,也能够通过 telnet 间接某个服务。
Dubbo 服务降级,失败重试怎么做?
能够通过 dubbo:reference 中设置 mock=“return null”。mock 的值也能够批改为 true,而后再跟接口同一个门路下实现一个 Mock 类,命名规定是“接口名称 +Mock”后缀。而后在 Mock 类里实现本人的降级逻辑
Dubbo 应用过程中都遇到了些什么问题?
在注册核心找不到对应的服务, 查看 service 实现类是否增加了 @service 注解无奈连贯到注册核心, 查看配置文件中的对应的测试 ip 是否正确
RPC
为什么要有 RPC
http 接口是在接口不多、零碎与零碎交互较少的状况下,解决信息孤岛初期常应用的一种通信伎俩;长处就是简略、间接、开发不便。利用现成的 http 协定进行传输。然而如果是一个大型的网站,外部子系统较多、接口十分多的状况下,RPC 框架的益处就显示进去了,首先就是长链接,不用每次通信都要像 http 一样去 3 次握手什么的,缩小了网络开销;其次就是 RPC 框架个别都有注册核心,有丰盛的监控治理;公布、下线接口、动静扩大等,对调用方来说是无感知、统一化的操作。第三个来说就是安全性。最初就是最近风行的服务化架构、服务化治理,RPC 框架是一个强力的撑持。
socket 只是一个简略的网络通信形式,只是创立通信单方的通信通道,而要实现 rpc 的性能,还须要对其进行封装,以实现更多的性能。
RPC 个别配合 netty 框架、spring 自定义注解来编写轻量级框架,其实 netty 外部是封装了 socket 的,较新的 jdk 的 IO 个别是 NIO,即非阻塞 IO,在高并发网站中,RPC 的劣势会很显著
什么是 RPC
RPC(Remote Procedure Call Protocol)近程过程调用协定,它是一种通过网络从近程计算机程序上申请服务,而不须要理解底层网络技术的协定。简言之,RPC 使得程序可能像拜访本地系统资源一样,去拜访远端系统资源。比拟要害的一些方面包含:通信协定、序列化、资源(接口)形容、服务框架、性能、语言反对等。
简略的说,RPC 就是从一台机器 (客户端) 上通过参数传递的形式调用另一台机器 (服务器) 上的一个函数或办法 (能够统称为服务) 并失去返回的后果。
PRC 架构组件
一个根本的 RPC 架构外面应该至多蕴含以下 4 个组件:
1、客户端(Client): 服务调用方(服务消费者)
2、客户端存根(Client Stub): 寄存服务端地址信息,将客户端的申请参数数据信息打包成网络音讯,再通过网络传输发送给服务端
3、服务端存根(Server Stub): 接管客户端发送过去的申请音讯并进行解包,而后再调用本地服务进行解决
4、服务端(Server): 服务的真正提供者
具体调用过程:
1、服务消费者(client 客户端)通过调用本地服务的形式调用须要生产的服务;
2、客户端存根(client stub)接管到调用申请后负责将办法、入参等信息序列化(组装)成可能进行网络传输的音讯体;
3、客户端存根(client stub)找到近程的服务地址,并且将音讯通过网络发送给服务端;
4、服务端存根(server stub)收到音讯后进行解码(反序列化操作);
5、服务端存根(server stub)依据解码后果调用本地的服务进行相干解决;
6、本地服务执行具体业务逻辑并将处理结果返回给服务端存根(server stub);
7、服务端存根(server stub)将返回后果从新打包成音讯(序列化)并通过网络发送至生产方;
8、客户端存根(client stub)接管到音讯,并进行解码(反序列化);
9、服务生产方失去最终后果;
而 RPC 框架的实现目标则是将下面的第 2 -10 步完整地封装起来,也就是把调用、编码 / 解码的过程给封装起来,让用户感觉上像调用本地服务一样的调用近程服务。
RPC 和 SOA、SOAP、REST 的区别
1、REST
能够看着是 HTTP 协定的一种间接利用,默认基于 JSON 作为传输格局, 应用简略, 学习老本低效率高, 然而安全性较低。
2、SOAP
SOAP 是一种数据交换协定标准, 是一种轻量的、简略的、基于 XML 的协定的标准。而 SOAP 能够看着是一个重量级的协定,基于 XML、SOAP 在平安方面是通过应用 XML-Security 和 XML-Signature 两个标准组成了 WS-Security 来实现安全控制的, 以后曾经失去了各个厂商的反对。
它有什么长处?简略总结为:易用、灵便、跨语言、跨平台。
3、SOA
面向服务架构,它能够依据需要通过网络对涣散耦合的粗粒度利用组件进行分布式部署、组合和应用。服务层是 SOA 的根底,能够间接被利用调用,从而无效控制系统中与软件代理交互的人为依赖性。
SOA 是一种粗粒度、松耦合服务架构,服务之间通过简略、准确定义接口进行通信,不波及底层编程接口和通信模型。SOA 能够看作是 B / S 模型、XML(规范通用标记语言的子集)/Web Service 技术之后的天然延长。
4、REST 和 SOAP、RPC 有何区别呢?
没什么太大区别,他们的实质都是提供可反对分布式的根底服务,最大的区别在于他们各自的的特点所带来的不同利用场景。
RPC 框架须要解决的问题?
1、如何确定客户端和服务端之间的通信协议?
2、如何更高效地进行网络通信?
3、服务端提供的服务如何裸露给客户端?
4、客户端如何发现这些裸露的服务?
5、如何更高效地对申请对象和响应后果进行序列化和反序列化操作?
RPC 的实现根底?
1、须要有十分高效的网络通信,比方个别抉择 Netty 作为网络通信框架;
2、须要有比拟高效的序列化框架,比方谷歌的 Protobuf 序列化框架;
3、牢靠的寻址形式(次要是提供服务的发现),比方能够应用 Zookeeper 来注册服务等等;
4、如果是带会话(状态)的 RPC 调用,还须要有会话和状态放弃的性能;
RPC 应用了哪些关键技术?
1、动静代理
生成 Client Stub(客户端存根)和 Server Stub(服务端存根)的时候须要用到 Java 动静代理技术,能够应用 JDK 提供的原生的动静代理机制,也能够应用开源的:CGLib 代理,Javassist 字节码生成技术。
2、序列化和反序列化
在网络中,所有的数据都将会被转化为字节进行传送,所以为了可能使参数对象在网络中进行传输,须要对这些参数进行序列化和反序列化操作。
- 序列化:把对象转换为字节序列的过程称为对象的序列化,也就是编码的过程。
- 反序列化:把字节序列复原为对象的过程称为对象的反序列化,也就是解码的过程。
目前比拟高效的开源序列化框架:如 Kryo、FastJson 和 Protobuf 等。
3、NIO 通信
出于并发性能的思考,传统的阻塞式 IO 显然不太适合,因而咱们须要异步的 IO,即 NIO。Java 提供了 NIO 的解决方案,Java 7 也提供了更优良的 NIO.2 反对。能够抉择 Netty 或者 MINA 来解决 NIO 数据传输的问题。
4、服务注册核心
可选:Redis、Zookeeper、Consul、Etcd。个别应用 ZooKeeper 提供服务注册与发现性能,解决单点故障以及分布式部署的问题(注册核心)。
支流 RPC 框架有哪些
1、RMI
利用 java.rmi 包实现,基于 Java 近程办法协定(Java Remote Method Protocol) 和 java 的原生序列化。
2、Hessian
是一个轻量级的 remoting onhttp 工具,应用简略的办法提供了 RMI 的性能。基于 HTTP 协定,采纳二进制编解码。
3、protobuf-rpc-pro
是一个 Java 类库,提供了基于 Google 的 Protocol Buffers 协定的近程办法调用的框架。基于 Netty 底层的 NIO 技术。反对 TCP 重用 / keep-alive、SSL 加密、RPC 调用勾销操作、嵌入式日志等性能。
4、Thrift
是一种可伸缩的跨语言服务的软件框架。它领有功能强大的代码生成引擎,无缝地反对 C + +,C#,Java,Python 和 PHP 和 Ruby。thrift 容许你定义一个形容文件,形容数据类型和服务接口。根据该文件,编译器不便地生成 RPC 客户端和服务器通信代码。
最后由 facebook 开发用做零碎内个语言之间的 RPC 通信,2007 年由 facebook 奉献到 apache 基金,当初是 apache 下的 opensource 之一。反对多种语言之间的 RPC 形式的通信:php 语言 client 能够结构一个对象,调用相应的服务办法来调用 java 语言的服务,逾越语言的 C /S RPC 调用。底层通信基于 SOCKET。
5、Avro
出自 Hadoop 之父 Doug Cutting, 在 Thrift 曾经相当风行的状况下推出 Avro 的指标不仅是提供一套相似 Thrift 的通信中间件, 更是要建设一个新的,规范性的云计算的数据交换和存储的 Protocol。反对 HTTP,TCP 两种协定。
6、Dubbo
Dubbo 是 阿里巴巴公司开源的一个高性能优良的服务框架,使得利用可通过高性能的 RPC 实现服务的输入和输出性能,能够和 Spring 框架无缝集成。
RPC 的实现原理架构图
PS:这张图十分重点,是 PRC 的基本原理,请大家肯定记住!
也就是说两台服务器 A,B,一个利用部署在 A 服务器上,想要调用 B 服务器上利用提供的函数 / 办法,因为不在一个内存空间,不能间接调用,须要通过网络来表白调用的语义和传播调用的数据。
比如说,A 服务器想调用 B 服务器上的一个办法:
User getUserByName(String userName)
1、建设通信
首先要解决通信的问题:即 A 机器想要调用 B 机器,首先得建设起通信连贯。
次要是通过在客户端和服务器之间建设 TCP 连贯,近程过程调用的所有替换的数据都在这个连贯里传输。连贯能够是按需连贯,调用完结后就断掉,也能够是长连贯,多个近程过程调用共享同一个连贯。
通常这个连贯能够是按需连贯(须要调用的时候就先建设连贯,调用完结后就立马断掉),也能够是长连贯(客户端和服务器建设起连贯之后放弃长期持有,不论此时有无数据包的发送,能够配合心跳检测机制定期检测建设的连贯是否存活无效),多个近程过程调用共享同一个连贯。
2、服务寻址
要解决寻址的问题,也就是说,A 服务器上的利用怎么通知底层的 RPC 框架,如何连贯到 B 服务器(如主机或 IP 地址)以及特定的端口,办法的名称名称是什么。
通常状况下咱们须要提供 B 机器(主机名或 IP 地址)以及特定的端口,而后指定调用的办法或者函数的名称以及入参出参等信息,这样能力实现服务的一个调用。
牢靠的寻址形式(次要是提供服务的发现)是 RPC 的实现基石,比方能够采纳 Redis 或者 Zookeeper 来注册服务等等。
2.1、从服务提供者的角度看:
当服务提供者启动的时候,须要将本人提供的服务注册到指定的注册核心,以便服务消费者可能通过服务注册核心进行查找;
当服务提供者因为各种起因以致提供的服务进行时,须要向注册核心登记进行的服务;
服务的提供者须要定期向服务注册核心发送心跳检测,服务注册核心如果一段时间未收到来自服务提供者的心跳后,认为该服务提供者曾经进行服务,则将该服务从注册核心上去掉。
2.2、从调用者的角度看:
服务的调用者启动的时候依据本人订阅的服务向服务注册核心查找服务提供者的地址等信息;
当服务调用者生产的服务上线或者下线的时候,注册核心会告知该服务的调用者;
服务调用者下线的时候,则勾销订阅。
3、网络传输
3.1、序列化
当 A 机器上的利用发动一个 RPC 调用时,调用办法和其入参等信息须要通过底层的网络协议如 TCP 传输到 B 机器,因为网络协议是基于二进制的,所有咱们传输的参数数据都须要先进行序列化(Serialize)或者编组(marshal)成二进制的模式能力在网络中进行传输。而后通过寻址操作和网络传输将序列化或者编组之后的二进制数据发送给 B 机器。
3.2、反序列化
当 B 机器接管到 A 机器的利用发来的申请之后,又须要对接管到的参数等信息进行反序列化操作(序列化的逆操作),行将二进制信息复原为内存中的表达方式,而后再找到对应的办法(寻址的一部分)进行本地调用(个别是通过生成代理 Proxy 去调用, 通常会有 JDK 动静代理、CGLIB 动静代理、Javassist 生成字节码技术等),之后失去调用的返回值。
4、服务调用
B 机器进行本地调用(通过代理 Proxy 和反射调用)之后失去了返回值,此时还须要再把返回值发送回 A 机器,同样也须要通过序列化操作,而后再通过网络传输将二进制数据发送回 A 机器,而当 A 机器接管到这些返回值之后,则再次进行反序列化操作,复原为内存中的表达方式,最初再交给 A 机器上的利用进行相干解决(个别是业务逻辑解决操作)。
通常,通过以上四个步骤之后,一次残缺的 RPC 调用算是实现了,另外可能因为网络抖动等起因须要重试等。
起源:https://thinkwon.blog.csdn.net/
作者:thinkwon
本文首发于公众号:Java 版 web 我的项目,欢送关注获取更多精彩内容