Dubbo最全面试题 dubbo和zookeeper面试题

新闻资讯2024-06-10 21:28小乐

Dubbo最全面试题 dubbo和zookeeper面试题

基础知识为什么要使用Dubbo?随着服务化的进一步发展,服务越来越多,服务之间的调用和依赖也越来越复杂。面向服务的架构(SOA)诞生了,并衍生了一系列相应的技术。例如,封装了服务提供、服务调用、连接处理、通信协议、序列化方法、服务发现、服务路由、日志输出等行为的服务框架。这样,分布式系统的服务治理框架就出现了,Dubbo也诞生了。达博是什么? Dubbo是一个高性能、轻量级的开源RPC框架,提供自动服务注册、自动发现等高效的服务治理解决方案,并且可以与Spring框架无缝集成。 Dubbo的使用场景有哪些?透明的远程方法调用:像调用本地方法一样调用远程方法,配置简单,无API侵入。软负载均衡和容错机制:可以替代内网F5等硬件负载均衡器,降低成本和单点。自动服务注册和发现:无需硬编码服务提供商地址。注册中心根据接口名称查询服务提供商的IP地址,可以平滑地添加或删除服务提供商。 Dubbo的核心功能有哪些? Remoting:网络通信框架,提供对各种NIO框架的抽象封装,包括“同步到异步”和“请求-响应”模式的信息交换方式。集群:基于接口方法提供透明远程过程调用的服务框架,包括多协议支持,以及软负载均衡、容错、地址路由、动态配置等集群支持。注册中心:服务注册,基于注册中心目录服务,使服务消费者能够动态搜索服务提供者,使地址透明,让服务提供者可以平滑地增减机器。 Dubbo的核心组件有哪些? Provider:暴露服务的服务提供者Consumer:调用远程服务消费者Registry:服务注册和发现注册中心Monitor:监控中心和访问调用统计Container:服务运行容器Dubbo 服务器注册和发现流程?服务容器Container负责启动、加载、运行服务提供者。当服务提供者启动时,它向注册中心注册其提供的服务。当服务消费者启动时,它会向注册中心订阅它所需要的服务。注册中心Registry将服务提供者地址列表返回给消费者。如果有变更,注册中心会基于长连接将变更数据推送给消费者。服务消费者Consumer根据软负载均衡算法从提供者地址列表中选择调用的提供者。如果呼叫失败,它会选择另一个提供商进行呼叫。服务消费者和服务提供者将呼叫次数和呼叫时间累积在内存中,并定期每分钟向监控中心Monitor发送一次统计数据。

架构设计Dubbo整体架构设计中有哪些层次化接口?服务层(Service):该层与业务逻辑相关。根据提供者和消费者的业务设计,对应的接口和实现配置层(Config):外部配置接口,以ServiceConfig和ReferenceConfig为中心服务代理层(Proxy):对服务接口的透明代理,生成服务接口服务的客户端Stub 和服务器骨架。以ServiceProxy为中心,扩展的接口是ProxyFactory服务注册层(Registry):封装了服务地址的注册和发现。以服务URL为中心,扩展的接口有RegistryFactory、Registry、RegistryService。路由层(Cluster):封装多个Provider的路由和负载均衡,桥接注册中心。以Invoker为中心,扩展接口有Cluster、Directory、Router、LoadBlancce监控层(Monitor):RPC调用次数和调用时间监控,以Statistics为中心,扩展接口有MonitorFactory、Monitor和MonitorService远程调用层(Protocal):对RPC 调用的封装,以Invocable 和Result 为中心,扩展接口为Protocol 、 Invoker 和Exporter 信息交换层(Exchange):封装请求响应模式,将同步转换为异步。以Request和Response为中心,扩展接口有Exchanger、ExchangeChannel、ExchangeClient和ExchangeServer 网络传输层(Transport):抽象mina和netty是统一接口,以Message为中心,扩展接口有Channel、Transporter、Client、Server和Codec数据序列化层(Serialize):一些可复用的工具,扩展接口有Serialization、ObjectInput、ObjectOutput和ThreadPoolDubbo Monitor。实现原理?消费者端在发起调用之前会先经过过滤器链; Provider端在收到请求时也会先经过过滤器链,然后进行实际的业务逻辑处理。默认情况下,消费者和提供者过滤器链中都有一个Monitorfilter。 MonitorFilter向DubboMonitor发送数据。 DubboMonitor将数据进行聚合(默认聚合1分钟内的统计数据)并临时存储在ConcurrentMap statsMap中,然后使用3个线程的线程池(线程名称:DubboMonitorSendTimer)每隔1分钟调用SimpleMonitorService来遍历发送统计数据统计地图。每次发送时,当前统计信息的AtomicReference 都会被重置。 SimpleMonitorService将这些聚合后的数据填充到BlockingQueue队列中(队列大写为100000)。 SimpleMonitorService 使用一个后台线程(线程名称:DubboMonitorAsyncWriteLogThread)将队列中的数据写入文件(线程以无限循环的形式写入)。 SimpleMonitorService还使用包含1个线程(线程名称:DubboMonitorTimer)的线程池,每5分钟将文件中的统计数据绘制成分布式图表。还有哪些类似于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有哪些注册中心?组播注册中心:组播注册中心不需要任何中心节点。只要使用广播地址,就可以在网络中基于组播传输进行服务注册和发现。 Zookeeper注册中心:基于分布式协调系统Zookeeper实现,利用Zookeeper的watch机制实现数据变更。 Redis注册中心:基于Redis实现,采用key/map存储。键存储服务名称和类型。映射中的键存储服务URL 和值服务过期时间。基于Redis发布/订阅模型通知数据变化。简单的注册表。推荐使用Zookeeper作为注册中心。 Dubbo的注册中心集群宕机了。发布者和订阅者还能通信吗?可以进行通信。 Dubbo启动时,消费者会从Zookeeper中拉取注册生产者的地址接口等数据并缓存在本地。每次调用时都是根据本地存储的地址进行调用。 Dubbo集群提供哪些负载均衡策略? Random LoadBalance:随机选择提供商策略,有助于动态调整提供商权重。截面碰撞率高,调用越多,分布越均匀。 RoundRobin LoadBalance:采用轮询提供者选择策略,分布均匀,但存在请求堆积的问题。 LeastActive LoadBalance: 最少活跃调用策略,解决缓慢提供者接收较少请求的问题。 ConstantHash LoadBalance: 一致性哈希策略确保具有相同参数的请求始终发送到相同的提供者。如果一台机器宕机了,可以基于虚拟节点分发给其他提供者,避免提供者发生剧烈变化。默认为随机。

Dubbo的集群容错方案有哪些?故障转移集群:发生故障时自动切换。出现故障时,重试其他服务器。通常用于读取操作,但重试会导致更长的延迟。 Failfast Cluster:快速失败,只发起调用,失败立即报错。通常用于非幂等写入操作,例如添加新记录。 Failsafe Cluster:故障安全,当发生异常时,被忽略。通常用于写入审计日志等操作。故障恢复集群:自动从故障中恢复,在后台记录失败的请求,并定期重新发送。通常用于消息通知操作。 Forking Cluster:并行调用多个服务器,一旦成功就返回。通常用于实时性要求较高的读操作,但需要消耗较多的服务资源。最大并行数可以通过forks="2" 设置。广播集群:广播一一调用所有提供者。谁报错,就报错。通常用于通知所有提供者更新本地资源信息,例如缓存或日志。默认的容错方案是故障转移集群。

Dubbo配置文件是如何加载到Spring中的? Spring容器启动时会读取一些Spring默认的schema和Dubbo自定义的schema。每个模式都对应于它自己的NamespaceHandler。 NamespaceHandler使用BeanDefinitionParser来解析配置信息,并将其转换为需要加载的bean对象!核心配置有哪些?标签

使用

解释

服务配置

用于公开服务并定义服务的元信息。一个服务可以使用多种协议来暴露,一个服务也可以注册到多个注册中心。

参考配置

用于创建远程服务代理,一个引用可以指向多个注册中心

协议配置

用于配置提供服务的协议信息。该协议由提供者指定并由消费者被动接受。

应用配置

用于配置当前应用程序信息,无论应用程序是提供者还是消费者

模块配置

用于配置当前模块信息,可选

注册中心配置

用于配置连接注册中心相关信息

监控中心配置

用于配置连接监控中心相关信息,可选

提供商配置

当ProtocolConfig和ServiceConfig的某个属性没有配置时,使用该默认值。选修的

消费者配置

当未配置ReferenceConfig属性时,使用此默认值,可选

方法配置

用于ServiceConfig和ReferenceConfig指定方法级别的配置信息

参数配置

用于指定方法参数配置

如果是SpringBoot项目,只需要注释或者打开Application配置文件即可!

设置Dubbo超时的方法有哪些?设置Dubbo超时有两种方式:

在服务提供商端设置超时。在Dubbo的用户文档中,建议在服务器端配置尽可能多的配置,因为服务提供者比消费者更了解其提供的服务的特性。超时时间是在服务消费者端设置的。如果超时设置在消费者侧,则消费者侧为主,即优先级较高。因为服务调用者可以更灵活地设置超时时间。如果消费者超时,服务器线程将不会被定制,并且会产生警告。如果服务调用超时会发生什么?当dubbo调用服务失败时,默认会重试两次。通信协议Dubbo使用什么通信框架?默认使用Netty作为通信框架。 Dubbo支持哪些协议,它们的优缺点是什么? Dubbo:单长连接、NIO异步通信,适合数据量较小的大并发服务调用,且消费者远大于提供者。传输协议TCP,异步Hessian序列化。 Dubbo推荐使用dubbo协议。 RMI:采用JDK标准RMI协议实现。传输参数和返回参数对象需要实现Serialized接口,使用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导出服务时,会调用ServiceConfig的export方法。 ServiceConfig中有一个字段: private static final Protocol protocol=ExtensionLoader.getExtensionLoader(Protocol.class).getAdaptiveExtension();复制代码工厂模式Provider在导出服务时会调用ServiceConfig的export方法。 ServiceConfig中有一个字段: private static final Protocol protocol=ExtensionLoader.getExtensionLoader(Protocol.class).getAdaptiveExtension();复制代码Dubbo 中这样的代码还有很多。这也是一种工厂模式,只不过是利用JDKSPI机制来获取实现类。这种实现的优点是它具有高度可扩展性。如果想扩展实现,只需要在类路径中添加一个文件即可,零代码侵入。另外,和上面的Adaptive实现一样,可以在调用时动态决定调用哪个实现。但是,由于这种实现使用了动态代理,因此会让代码调试比较麻烦,需要分析实际调用的实现类。

装饰器模式Dubbo 在启动阶段和调用阶段都大量使用了装饰器模式。以Provider提供的调用链为例,具体的调用链代码在ProtocolFilterWrapper的buildInvokerChain中完成。具体来说,实现了注解中包含group=provider的Filter,并按照顺序排序。最终的调用顺序是: EchoFilter - ClassLoaderFilter - GenericFilter - ContextFilter -ExecuteLimitFilter - TraceFilter - TimeoutFilter - MonitorFilter -ExceptionFilter 复制代码更准确地说,这里是装饰器和责任链模式的混合。比如EchoFilter的作用就是判断是否是echo测试请求,如果是则直接返回内容。这是责任链的体现。而ClassLoaderFilter则只是在main函数中添加一个函数,并改变当前线程的ClassLoader。这是一个典型的装饰器模式。

观察者模式Dubbo 的Provider 启动时,需要与注册中心进行交互,首先注册自己的服务,然后订阅自己的服务。订阅时,使用观察者模式开启监听。注册中心会定期每隔5秒检查是否有服务更新。如果有更新,它会向服务提供商发送通知消息。提供者收到notify消息后,会运行NotifyListener的notify方法,执行listener方法。动态代理模式Dubbo 扩展JDK SPI 的ExtensionLoader 类的Adaptive 实现就是典型的动态代理实现。 Dubbo需要灵活控制实现类,即在调用阶段根据参数动态决定调用哪个实现类。因此,利用老师成为代理类的方法可以实现灵活的调用。生成代理类的代码是ExtensionLoader的createAdaptiveExtensionClassCode方法。代理类的主要逻辑是获取URL参数中指定参数的值作为获取实现类的key。运维管理服务上线后如何兼容旧版本?版本号可用于过渡。注册中心注册了多个不同版本的服务。不同版本号的服务不互相引用。这有点类似于服务分组的概念。 Dubbo telnet 命令可以做什么? dubbo服务发布后,我们可以使用telnet命令进行调试和管理。 Dubbo 2.0.5及以上版本提供了telnet命令的端口支持。 Dubbo是否支持服务降级?在dubbo:reference中设置mock=“return null”。也可以将mock的值改为true,然后在与接口相同的路径下实现一个Mock类。命名规则为“接口名称+Mock”后缀。然后在Mock 类中实现自己的降级逻辑。 Dubbo如何优雅关闭? Dubbo使用JDK的ShutdownHook来完成优雅关闭。因此,如果使用kill -9 PID等强制关机指令,则不会执行优雅关机。只有当使用kill PID时才会执行。 SPIDubbo 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 提供了声明式缓存,以减少用户添加缓存的工作量。其实它只是比普通的配置文件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注解。您无法连接到注册中心。检查配置文件中对应的测试IP是否正确。为什么RPC有RPChttp接口?是因为接口不多,与系统交互很少,是解决信息孤岛初期经常使用的通信方式;优点是简单、直接、易于开发。利用现成的http协议进行传输。但如果是一个大型网站,内部子系统很多,接口也很多,那么RPC框架的好处就显现出来了。首先是长链接,每次通信不需要像http那样经过3次握手。减少网络开销;其次,RPC框架一般都有一个注册中心,具有丰富的监控和管理功能;发布、离线接口、动态扩展等对于调用者来说是不可感知的统一操作。第三个是安全。最后就是最近流行的面向服务的架构和面向服务的治理。 RPC框架是强有力的支撑。 Socket只是一种简单的网络通信方式。它只是在两方之间创建一个沟通渠道。要实现rpc的功能,需要对其进行封装,以实现更多的功能。 RPC一般配合netty框架和spring自定义注解来编写轻量级框架。事实上,netty内部封装了socket。较新的jdk的IO一般都是NIO,即非阻塞IO。在高并发网站中,RPC的优势RPCRPC(Remote procedure Call Protocol)远程过程调用协议是什么,就显而易见了。它是一种在不了解底层网络技术的情况下通过网络向远程计算机程序请求服务的协议。简而言之,RPC 使程序能够访问远程系统资源以及本地系统资源。一些比较关键的方面包括:通信协议、序列化、资源(接口)描述、服务框架、性能、语言支持等。简单来说,RPC就是调用一个函数或方法(可以统称为服务)在另一台机器(服务器)上从一台机器(客户端)通过传递参数并获取返回结果。

PRC架构组件一个基本的RPC架构至少应该包含以下四个组件: 1.客户端(Client):服务调用者(服务消费者) 2.客户端存根(Client Stub):存储服务器地址信息。将客户端的请求参数数据信息封装成网络消息,然后通过网络传输发送给服务器3、服务器存根(Server Stub):接收客户端发送的请求消息并解包,然后调用本地服务进行处理4、服务器(Server):服务的真正提供者的具体调用流程: 1、服务消费者(客户端)通过调用本地服务来调用需要消费的服务; 2. 客户端存根(clientstub)收到调用请求后,负责方将

法、入参等信息序列化(组装)成能够进行网络传输的消息体; 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等。 反序列化:把字节序列恢复为对象的过程称为对象的反序列化,也就是解码的过程。 目前比较高效的开源序列化框架:如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的实现原理架构图也就是说两台服务器A,B,一个应用部署在A服务器上,想要调用B服务器上应用提供的函数/方法,由于不在一个内存空间,不能直接调用,需要通过网络来表达调用的语义和传达调用的数据。比如说,A服务器想调用B服务器上的一个方法: 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调用算是完成了,另外可能因为网络抖动等原因需要重试等。

猜你喜欢