什么是RPC,和HTTP有什么区别?
RPC 是Remote Procedure Call的缩与,译为远程过程调用。要想实现RPC通常需要包含传输协议和序列化协议的实现。而我们熟知的HTTP,他的中文名叫超文本传输协议,所以他就是一种传输协议。
所以,我们可以认力
RPC和HTTP并不是同一个维度的两个概念。只不过他们都是可以作为远程调用的,所以经常拿来对比。
RPC的具体实现上,,可以像HTTP一样,基于TCP协议来实现,也可以直接基于HTTP协议实现。
RPC主要用于公司内部服务之间的互相调用,所以他性能消耗低,传输效率高,服务治理方便。而HTTP主要用于
对外的异构环境,
•浏览器调用,APP接口调用,第三方接口调用等等。
什么场景只能用HTTP,不能用RPC?
1、在异构系统(跨语言和跨平台),HTTP具有更好的兼容性,因为HTTP是一种通用的协议,几乎所有的编程语言和操作系统都支持HTTP协议,而不是所有的编程语言和操作系统都支持相同的RPC协议。
2、RPC适合用在企业内部,要求使用同一套注册中心进行服务治理,如果是跨组织,或者跨公司,这种情况只能用更加通用的HTTP进行通信。
什么是泛化调用
泛化调用是指在调用方没有服务方提供的API(SDK)的情况下,对服务方进行调用,并且可以拿到调用结果。
什么是Dubbo的优雅停机,怎么实现的?
Dubbo是通过JDK的shutdown hook来完成优雅停机(下线)的。
对于服务提供方来说,应用下线时时,先标记为不接受新请求,请求过来时直接报错,让客户端重试。然后,检测线程池中的线程是否正在运行,如果有,那就等线程执行完。
对于服务消费方来说,应用下线时,不再发起新的调用请求,所有的新调用在客户端侧直接报错。然后,检测还有没有远程请求没有得到返回的,如果有,则等待返回结果。
Dubbo支持哪些调用协议
dubbo支持多种协议,主要由以下几个:
-
dubbo 协议 (默认)
默认就是走dubbo协议的,基于hessian作为序列化协议,单一长连接,TCP协议传输,NIO异步通信,适合大并发小数据量的服务调用,以及消费者远大于提供者,传输数据量很小(每次请求在100kb以内),但是并发量很高。 -
rmi 协议
采用JDK标准的rmi协议实现,传输参数和返回参数对象需要实现Serializable接口,使用java标准序列化机制,使用阻塞式短连接,传输数据包大小混合,消费者和提供者个数差不多,可传文件,传输协议TCP。 -
hessian 协议
集成Hessian服务,基于HTTP通讯,采用Servlet暴露服务,Dubbo内嵌Jetty作为服务器时默认实现,提供与Hession服务互操作。
hessian序列化协议,多个短连接,同步HTTP传输,传入参数较大,提供者大于消费者,提供者压力较大,适用于文件的传输,一般较少用; -
http 协议
基于Http表单提交的远程调用协议,使用Spring的HttpInvoke实现。 -
webservice 协议
基于WebService的远程调用协议,集成CXF实现,提供和原生WebService的互操作。 -
thrift 协议
当前 dubbo 支持的 thrift 协议是对 thrift 原生协议 的扩展,在原生协议的基础上添加了一些额外的头信息,比如 service name,magic number 等。 -
memcached 协议
基于 memcached实现的 RPC 协议。 -
redis 协议
基于 Redis实现的 RPC 协议。 -
restful
基于标准的Java REST API——JAX-RS 2.0(Java API for RESTful Web Services的简写)实现的REST调用支持
Dubbo服务发现与路由的概念有什么不同?
服务发现是指在Dubbo注册中心中查找提供某个服务的服务提供者,以便服务消费者可以调用它们。
Dubbo的注册中心可以是ZooKeeper、Redis等,服务提供者在启动时会将自己的地址信息注册到注册中心中,服务消费者在调用服务时会从注册中心中获取服务提供者的地址信息。
服务路由是指根据一定的规则将服务请求路由到指定的服务提供者上。Dubbo提供了多种路由策略,如随机路由、轮询路由、一致性哈希路由等。路由规则可以在Dubbo的配置文件中进行配置,也可以在运行时通过API进行动态修改。
因此,服务发现是获取服务提供者的地址信息,路由则是将服务请求路由到指定的服务提供者上。两者都是Dubbo中非常重要的概念,但是它们的作用是不同的。
Dubbo的缓存机制有了解吗?
Dubbo提供了缓存机制,其主要作用是缓存服务调用的响应结果,减少重复调用服务的次数,提高调用性能。
Dubbo支持了服务端结果缓存和客户端结果缓存。
服务端缓存是指将服务端方法的返回结果缓存到内存中,以便下次请求时可以直接从缓存中获取结果,而不必再调用服务方法。服务端缓存可以提高响应速度和系统吞吐量。Dubbo提供了三种服务端缓存的实现方式:
●
LRU Cache: 使用基于LRU(最近最少使用)算法的缓存,当缓存空间满时,会将最近最少使用的缓存清除掉。
●
Thread Local Cache: 使用线程本地缓存,即每个线程都拥有一个缓存实例,缓存结果只对当前线程可见。
●
Concurrent Map Cache: 使用基于ConcurrentMap的缓存,支持并发读写,相对LRU Cache和Thread Local Cache来说,缓存效率更高。
客户端缓存是指客户端将调用远程服务方法的返回结果缓存到内存中,以便下次请求时可以直接从缓存中获取结果,而不必再调用远程服务方法。消费端缓存可以提高系统的响应速度和降低系统的负载。Dubbo提供了两种消费端缓存的实现方式:
●
LRU Cache: 使用基于LRU算法的缓存,当缓存空间满时,会将最近最少使用的缓存清除掉。
●
Thread Local Cache: 使用线程本地缓存,即每个线程都拥有一个缓存实例,缓存结果只对当前线程可见。
需要注意的是,缓存虽好用,使用需谨慎,过度依赖缓存可能会出现数据不一致的问题。
Dubbo如何实现像本地方法一样调用远程方法的?
Dubbo 实现像本地方法一样调用远程方法的核心技术是动态代理。Dubbo 使用 JDK 动态代理或者字节码增强技术,生成一个代理类,该代理类实现了本地接口,具有本地接口的所有方法。在调用本地接口方法时,会通过代理类的 invoke 方法将请求转发到远程服务提供者上。
生成代理类,Dubbo 在启动时会扫描配置文件(注解)中指定的服务接口,并根据服务接口生成一个代理类。这个代理类实现了服务接口,并且在调用服务接口的方法时,会将参数封装成请求消息,然后通过网络传输给服务提供方。
网络通信,Dubbo 支持多种通信协议,包括 Dubbo 协议、HTTP 协议、Hessian 协议等。在配置文件中指定了要使用的通信协议后,Dubbo 会根据协议的不同,选择不同的序列化方式,将请求消息序列化成二进制流并发送给服务提供方。
负载均衡,Dubbo 支持多种负载均衡算法,包括轮询、随机、加权随机、最小活跃数等。在客户端发起调用时,Dubbo 会根据负载均衡算法选择一台服务提供方进行调用。
远程服务执行,当客户端发起远程调用后,服务提供方接收到请求后,会根据请求中的服务接口名和方法名,找到对应的实现类和方法,并将请求消息反序列化成参数列表,最终调用服务实现类的方法,并将执行结果序列化成响应消息返回给客户端。
Dubbo实现服务调用的过程是什么样的?
Dubbo的整体架构中,有多个角色,分别是服务提供者,服务调用者以及服务注册中心。一次完成的服务调用过程其实要分为服务注册、服务发现和服务调用三个过程。
1、服务注册:服务提供者在启动时,会向注册中心注册自己提供的服务,并将服务相关的信息(如服务名称、版本号、IP地址、端口号、协议、权重等)一并注册。Dubbo支持多种注册中心,包括ZooKeeper、Redis、Multicast、Simple等。一旦服务注册成功,服务提供者就可以等待服务调用请求的到来。
2、服务发现:服务调用者在启动时,需要向注册中心订阅自己所需的服务,注册中心会将服务提供者列表返回给服务调用者。当过程中,如果服务提供者列表发生变化,那么Dubbo会通知客户端进行变更。
3、服务调用:服务调用者需要根据负载均衡策略选择一个服务提供者,之后,就可以发送服务调用请求了。Dubbo支持多种通信协议和序列化方式。Dubbo客户端将调用请求序列化成二进制数据,并使用网络协议发送给服务提供者,服务提供者将调用请求反序列化后,调用目标方法并将结果序列化成二进制数据返回给服务调用者。在整个调用过程中
Dubbo会对服务调用进行监控,包括调用次数、调用时间、响应时间、异常次数、异常信息等,以便于服务提供者和服务调用者进行故障排查和性能调优。