Spring - Dubbo 扩展点详解

扩展点整体架构

在这里插入图片描述

 

1. RPC层扩展点

按照完整的Dubbo结构分层,RPC层可以分为四层:Config、Proxy、Registry、Cluster。由于Config属于API范畴,因此只关注Proxy、Registry、Cluster三层的扩展点。

1.1 Proxy层扩展点

Proxy层主要的扩展接口是ProxyFactory。Dubbo中的ProxyFactory有两种默认实现:Javassist和JDK,用户可以自行扩展自己的实现,如CGLIB。Dubbo默认选择Javassist作为默认字节码生成工具,主要是基于性能和使用的简易性考虑,Javassist的字节码生成效率相对于其他库更快。

在这里插入图片描述

ProxyFactory接口有两个方法,每个方法上都有@Adaptive注解,并且方法会根据URL中的proxy参数决定使用哪种字节码工具。

已有的扩展点实现:

扩展key名扩展类名
jdkorg.apache.dubbo.rpc.proxy.jdk.JdkProxyFactory
javassistorg.apache.dubbo.rpc.proxy.javassist.JavassistProxyFactory

1.2 Registry层扩展点

Registry层可以理解为注册层,这一层中最重要的扩展点就是org.apache.dubbo.registry.RegistryFactory。整个框架的注册与服务发现客户端都是由这个扩展点负责创建的。该座站点有@Adaptive({"protocol"})注解,可以根据URL中的protocol参数创建不同的注册中心客户端。

例如:protocol=redis,该工厂会创建基于Redis的注册中心客户端。因此,如果我么扩展了自定义的注册中心,那么只需要配置不同的Protocol即可。

在这里插入图片描述

 

使用这个扩展点,还一些需要遵循的"潜规则":

  • 如果URL中设置了check=false,则连接不会被检查。否则,需要在断开连接时抛出异常;
  • 需要支持通过username:password格式在URL中传递鉴权;
  • 需要支持设置backup参数来指定备选注册集群的地址;
  • 需要自持设置file参数来指定本地文件缓存;
  • 需要支持设置timeout参数来指定请求的超时时间;
  • 需要支持设置session参数来指定连接的超时或过期时间;

在Dubbo,有AbstractRegistryFactory已经抽象了一些通用的逻辑,用户可以直接继承该抽象类实现自定义的注册中心工厂。

已有的RegistryFactory实现:

扩展key名扩展类名
zookeeperorg.apache.dubbo.registry.zookeeper.ZookeeperRegistryFactory
redisorg.apache.dubbo.registry.redis.RedisRegistryFactory
multicastorg.apache.dubbo.registry.multicast.MulticastRegistryFactory
dubboorg.apache.dubbo.registry.multicast.MulticastRegistryFactory

 

1.3 Cluster层扩展点

Cluster层负责了整个Dubbo框架的集群容错,涉及的扩展点较多,包括容错(Cluster)、路由(Router)、负载均衡(LoadBalnce)、配置管理工厂(ConfiguratorFactory)和合并器(Merger)。

1.3.1 Cluster扩展点:

Cluster需要与Cluster层区分开,Cluster主要负责一些容错的策略,也是整个集群容错的入口。当远程调用失败后,由Cluster负责重试、快速失败等,整个过程对上层透明。

在这里插入图片描述

 

Cluster接口只有一个join方法,并且有@Adaptice注解,说明会根据配置动态调用不同的容错机制。

扩展key名扩展类名
mockorg.apache.dubb.rpc.cluster.support.wrapper.MockClusterWrapper
failoverorg.apache.dubb.rpc.cluster.support.FailoverCluster
failfastorg.apache.dubb.rpc.cluster.support.FailfastCluster
failsafeorg.apache.dubb.rpc.cluster.support.FailsafeCluster
failbackorg.apache.dubb.rpc.cluster.support.FailbackCluster
forkingorg.apache.dubb.rpc.cluster.support.ForkingCluster
availableorg.apache.dubb.rpc.cluster.support.AvailableCluster
mergeableorg.apache.dubb.rpc.cluster.support.MergeableCluster
broadcastorg.apache.dubb.rpc.cluster.support.BroadcastCluster
registrywareorg.apache.dubb.rpc.cluster.support.RegistryAwareCluster

1.3.2 RouterFactory扩展点:

RouterFactory是一个工厂类,就是用于创建不同的Router。假设接口A有多个服务提供者提供服务,如果配置了路由规则(某个消费者只能调用某几个服务提供者),则Router会过滤其他服务提供者,只留下符合路由规则的服务提供者列表。

现有的路由规则支持文件、脚本和自定义表达式等方式。接口上有@Adaptive("protocol")注解,会根据不同的protocol自动匹配路由规则。

在这里插入图片描述

 

在2.7版本之后,路由模块会做出较大的更新,每个服务中每种类型的路由只会存在一个,它们会成为路由器链。

扩展key名扩展类名
fieorg.apache.dubbo.rpc.cluster.router.file.FileRouterFacttory
scriptorg.apache.dubbo.rpc.cluster.router.script.ScriptRouterFactory
conditionorg.apache.dubbo.rpc.cluster.router.condition.CnditionRouterFactory
serviceorg.apache.dubbo.rpc.cluster.router.condition.config.ServiceRouterFactory
apporg.apache.dubbo.rpc.cluster.router.condition.config.AppRouterFactory
tagorg.apache.dubbo.rpc.cluster.router.tag.TagRouterFactory
mockorg.apache.dubbo.rpc.cluster.router.mock.MockRouterFactory

1.3.3 LoadBalance扩展点:

LoadBalance是Dubbo框架中的负载均衡策略扩展点,框架中已经内置随机(Random)、轮询(RoundRobin)、最小连接数(LeastActive)、一致性Hash(ConsistenHash)这几种负载均衡策略,默认使用随机负载均衡。

LoadBalance主要负责在多个节点中,根据不同的负载均衡策略选择一个合适的节点来调用。

在这里插入图片描述

 

扩展key名扩展类名
randomorg.apache.dubbo.rpc.cluster.loadbalane.RandomLoadBalance
roundrobinorg.apache.dubbo.rpc.cluster.loadbalane.RoundRobinLoadBalance
leastactiveorg.apache.dubbo.rpc.cluster.loadbalane.LeastActiveLoadBalance
consistenthashorg.apache.dubbo.rpc.cluster.loadbalane.ConsistentHashLoadBalance

 

1.3.4 ConfiguratorFactory:

ConfiguratorFactory是创建配置实例的工厂类,现有override和absent两种工厂实现,分别会创建爱你OverrideConfigurator和AbsentConfigurator两种配置对象。默认的两种实现,OverrideConfigurator会直接把配置心中的参数覆盖本地的参数;AbsentConfigurator会先看本地是否存在该配置,没有则新增本地配置,如果已经存在则不会覆盖。

在这里插入图片描述

 

该扩展点的方法也有@Adaptive("protocol")注解,会根据URL中的protocol配置值使用不同的扩展点实现。

扩展key名扩展类名
overrideorg.apache.dubbo.rpc.cluster.configurator.override.OverrideConfiguratorFactory
sbsentorg.apache.dubbo.rpc.cluster.configurator.absent.AbsentConfiguratorFactory

1.3.5 Merger扩展点:

Merger是合并器,可以对并行调用的结果集进行合并,例如:并行调用A、B两个服务器都会返回一个List结果集,Merger可以把两个List合并为一个并返回给应用。默认已经支持map、set、list、byte等11中类型的返回值。用户可以基于该扩展点,添加自定义类型的合并器。

在这里插入图片描述

扩展key名扩展类名
maporg.apache.dubbo.rpc.cluster.merger.MapMerger
setorg.apache.dubbo.rpc.cluster.merger.SetMerger
listorg.apache.dubbo.rpc.cluster.merger.ListMerger
byteorg.apache.dubbo.rpc.cluster.merger.ByteArrayMerger
charorg.apache.dubbo.rpc.cluster.merger.CharArrayMerger
shortorg.apache.dubbo.rpc.cluster.merger.ShortArrayMerger
intorg.apache.dubbo.rpc.cluster.merger.IntArrayMger
longorg.apache.dubbo.rpc.cluster.merger.LongArrayMerger
floatorg.apache.dubbo.rpc.cluster.merger.FloatArrayMerger
duoubleorg.apache.dubbo.rpc.cluster.merger.DoubleArrayMerger
booleanorg.apache.dubbo.rpc.cluster.merger.BooleanArrayMerger}

 

2. Remte层扩展点

Remote处于整个Dubbo框架的底层,设计协议、数据的交换、网络的传输、序列化、线程池等,涵盖了一个远程调用的所有要素。

Remote层是对Dubbo传输协议的封装,内部再划分Transport传输层和Exchange信息叫魂层其中Transport层只负责单向消息传输,是对Mina、Netty等传输工具库的抽象。而Exchange层在传输层之上实现了Request-Response语义,这样就可以在不同传输方式之上都能做到统一的请求/响应处理。Serialize层是RPC的一部分,决定了在消费者和服务提供者之间的二进制数据传输格式。不同的序列化库的选择会对RPC调用的性能产生重要影响,目前默认选择是Hessian2序列化。

 

2.1 Protocol层扩展点

Protocol层主要包含四大扩展点,分别是Protocol、Filte、ExporterListener和InvokerListener。

2.1.1 Protocol扩展点:

Protocol是Dubbo RPC的核心调用层,具体的RPC协议都可以由Protocol点扩展。如果想增加一种新的RPC协议,则只需要扩展一个新的Protocol扩展点 即可。

@SPI("dubbo")
public interface Protocol {
	//当用户没有设置端口的时候,返回默认的端口
    int getDefaultPort();
    
    //把一个服务暴露成远程invocation
    @Adaptive
    <T> Exporter<T> export(Invoker<T> invoker) throws RpcException;

	//易用一个远程服务
    @Adaptive
    <T> Invoker<T> refer(Class<T> type, URL url) throws RpcException;

	//销毁
    void destroy();

}

Protocol的每个接口都会有一些"显规则",在实现自定义的时候需要注意:

export方法:

  1. 协议收到请求后硬记录请求源IP地址。通过RpcContext.getContext().setRemoteAddress()方法存入RPC上下文
  2. export方法必须实现幂等,即无论调用多少次,返回的URL都是相同的。
  3. Invoker实例由框架传入,无须关心协议层。

refer方法:

  1. 当我们调用refer()方法返回Invoker对象的invoke()方法时,协议也需要相应地执行invoker()方法。这一点在设计自定义协议的Invoker时需要注意。
  2. 正常来说refer()方法返回的自定义Invoker需要继承Invoker接口。
  3. 当URL的参数有check=false时,自定义的协议实现必须不能抛出异常,而是在出现连接失败异常时尝试恢复连接。

destroy方法:

  1. 调用destroy方法的时候,需要销毁所有本协议暴露和引用的方法。
  2. 需要释放所有占用的资源,如连接、端口等。
  3. 自定义的协议可以在被销毁后继续导出好引用新服务。

 

整个Protocol的逻辑由Protocol、Exporter、Invoker三个接口穿起来:

  • com.alibaba.dubbo.rpc.Protocol;
  • com.alibaba.dubbo.rpc.Exporter;
  • com.alibaba.dubbo.rpc.Invoker;

其中Protocol接口是入口,其实现封装了用来处理Exporter和Invoker的方法:

Exporter代表要暴露的远程服务引用, Protocol#export方法是将服务暴露的处理过程,Invoker代表要调用的远程服务代理对象,Protocol#refer 方法通过服务类型和URL获得要调用的服务代理。

由于Protocol可以实现Invoker和Exporter对象的创建,因此除了作为远程调用对象的构造,还能用于其他用途,例如:可以在创建Invoker的时候对原对象进行包装增强,添加其他File进去,Polorraper实现就是把Fiter链加入Invoker。如果对这一段并不是十分了解则可以先了解设计模式中的装饰器模式,对最原始的Invoker进行增强。

扩展key名扩展类名
injvmorg.apache.dubbo.rpc.protocol.injvm.InjvmProtocol
dubboorg.apache.dubbo.rpc.protocol.dubbo.DubboProtocol
rmiorg.apache.dubbo.rpc.protocol.rmi.RmProtocol
httporg.apache.dubbo.rpc.protocol.http.HttpProtocol
hessianorg.apache.dubbo.rpc.protocol.hessian.HessianProtocol
restorg.apache.dubbo.rpc.protocol.rest.RestProtocol
thriftorg.apache.dubbo.rpc.protocol.ThriftProtocol
-org.apache.dubbo.rpc.protocol.webservice.WebServiceProtocol
redisorg.apache.dubbo.rpc.protocol.redis.RedisProtocol
memcachedorg.apache.dubbo.rpc.protocol.memcached.MemcachedProtocol

 

2.1.2 Filter扩展点:

Filter是Dubbo的过滤器扩展点,可以自定义过滤器,在Invoekr调用前后执行自定义的逻辑。在Filter的实现中,必须要调用传入的Invoker的invoke方法,否则整个链路就断了。

在这里插入图片描述

 

2.1.3 ExprterListener / InvokerListener 扩展点:

ExprterListener和InvokerListener这两个扩展点非常相似,ExporterListener是在暴露和取消暴露服务时提供回调;InvokerListener则是在服务的引用于销毁时提供回调。

在这里插入图片描述

在这里插入图片描述

 

2.2 Exchange层扩展点

Echange层只有一个扩展点接口Exchanger,这个接口主要是为了封装请求/响应模式,例如:把同步请求转换为异步请求。默认的扩展点实现是org.apache.dubbo.remoting.exchange.support.header.HeaderExchanger。每个方法上都有@Adaptive注解,会根据URL中的Exchanger参数决定实现类。

 

在这里插入图片描述

既然已经有了Transport层来传输数据了,为什么还要有Exchange层呢?因为上层业务关注的并不是诸如Netty这样的底层Channel。上层一个Request只关注对应的Response,对于是同步还是异步请求,或者使用什么传输技术根本不关心。Transport层是无法满足这项需求的,Exchange层因此实现了Request-Response模型,可以理解为做了更高层次的封装。

 

2.3 Transport层扩展点

tranport层为了屏蔽不同通信框架的异同,封装了统一的对外接口。主要的扩展点有Transporter、Dispatcher、codec2和ChanelHandler。

其中,Channelhandler主要处理连接相关的时间,例如:连接上、断开、发送消息、收到消息、出现异常等。虽然接口上有SPI注解,但是在框架中实现类的使用却是直接"new"的方式。

2.3.1 Transporter扩展接口:

Transporter屏蔽了通信框架接口、实现的不同,使用同一的通信接口。

在这里插入图片描述

 

bind方法会生成一个服务,监听来自客户端的请求;connect方法则会连接到一个服务。两个方法上都有@Adaptive注解,首先会根据URL中server的参数值去匹配实现类,如果匹配不到则根据transporter参数去匹配实现类。默认的实现是netty4.

扩展key名扩展类名
minaorg.apache.dubbo.remoting.transport.mina.MinaTransporter
netty3org.apache.dubbo.remoting.transport.netty.NettyTransporter
netty4org.apache.dubbo.remoting.transport.netty4.NettyTransporter
nettyorg.apache.dubbo.remoting.transport.netty4.NettyTransporter
grizzlyorg.apache.dubbo.remoting.transport.grizzly.GrizzlyTransporter

2.3.2 Dispatcher扩展接口:

如果有些逻辑的处理比较慢,例如:发起I/O请求查询数据库、请求远程数据等,则需要使用线程池。因为I/O速度相对CPU是很慢的,如果不适用线程池,则线程会因为I/O导致同步阻塞等待。Dispatcher扩展接口通过不同的派发策略,把工作派发到不同的线程池,以此来应对不用的业务场景。

在这里插入图片描述

 

扩展key名扩展类名
allorg.apache.dubbo.remoting.transport.dispatcher.all.AllDispatcher
directorg.apache.dubbo.remoting.transport.dispatcher.direct.DirectDispatcher
messageorg.apache.dubbo.remoting.transport.dispatcher.message.MessageOnlyDispatcher
executionorg.apache.dubbo.remoting.transport.dispatcher.execution.ExecutionDispatch
connectionorg.apache.dubbo.remoting.transport.dispatcher.connection.ConnectionOrderedDispatcher

 

2.3.3 Codec2扩展接口:

Codec2主要实现对数据的编码和解码,但这个接口只是需要实现编码/解码过程中的通用逻辑流程,如解决半包、粘包等问题。该接口属于在序列化上封装的一层。

 

在这里插入图片描述

扩展key名扩展类名
transportorg.apache.dubbo.remoting.trnsport.codec.TranspotCodec
telnetorg.apache.dubbo.remoting.elnet.codec.TelnetCodec
exchangeorg.apache.dubbo.remoting.exchange.codec.ExchangeCodec

 

2.3.4 TreadPool扩展接口:

Transport层由Dispatcher实现不同的派发策略,最终会派发到不同的ThreadPool中执行。

在这里插入图片描述

 

现阶段,框架中默认含有四种线程池扩展的实现,以下内容摘自官方文档:

  • fixed,固定大小线程池,启动时建立线程,不关闭,一直持有;
  • cached,缓存线程池,空闲一分钟自动删除,需要时重建;
  • limited,可伸缩线程池,但池中的线程数只会增长不会收缩。只增长不收缩的目的是为了避免收缩时突然来了大流量引起的性能问题。
  • eager,优先创建爱你Worker线程池。在任务数量大于corePoolSize小于maximumPoolSize时,优先创建爱你Worker来处理任务。当任务数量大于maximumPoolSize时,将任务放入阻塞队列。阻塞队列充满时抛出RejectedExecutionException(cached在任务数量超过maximumPoolSize时直接抛出异常而不是将任务放入阻塞队列)。

其接口的实现类如下:

  • org.apache.dubbo.common.threadpool.support.fixed.FixedThreadPool;
  • org.apache.dubbo.common.threadpool.support.cached.CachedThreadPool;
  • org.apache.dubbo.common.threadpool.support.limited.LimiteThreadPool;
  • org.apache.dubbo.common.threadpool.support.eager.EagerThreadPool;

 

2.4 Serialize层扩展点

Serialize层主要实现具体的对象序列化,只有Serialization一个扩展接口。Serialization是具体的对象序列化扩展接口,即把对象序列化成可以通过网络进行传输的二进制流。

2.4.1 Serialization扩展接口:

在这里插入图片描述

 

Serialization默认使用Hessian2做序列化,已有的实现如下表:

扩展key名扩展类名
fastjsonorg.apache.dubbo.common.serialize.fastjson.FastJsonSerialization
fstorg.apache.dubbo.common.serialize.fst.FstSerialization
hessian2org.apache.dubbo.common.serialize.hessian2.Hessian2Serialization
javaorg.apache.dubbo.common.serialize.java.JavaSerialization
compactedjavaorg.apache.dubbo.common.serialize.java.CompactedJavaSerialization
nativejavaorg.apache.dubbo.common.serialize.nativejava.NativeJavaSerialization
kryoorg.apache.dubbo.common.serialize.kryo.KryoSerialization
protostufforg.apache.dubbo.common.serialize.protostuff.ProtostuffSerialization

其中compactedjava是在Java原生序列化的基础上做了压缩,实现了自定义的类描写叙述符合写入和读取。在序列化的时候仅写入类名,而不是完整的类信息,这样在对象数量很多的情况下,可以有效压缩体积。

NativeJavaSerialization是Java原生的序列化方式。
JavaSerializaiton是原生Java序列化及压缩的封装。

 

3. 其他扩展点

还有其他额一些扩展点接口:TelnetHandler、StatusChecker、Container、CacheFactory、Validation、LoggerAdapter和Compiler。

3.1 Telnethandler扩展点

Dubbo框架支持Telnet命令连接,TelnetHandler接口就是用于扩展新的Telnet命令的接口。

扩展key名扩展类名
clearorg.apache.dubbo.remoting.telnet.support.command.ClearTelnetHandler
exitorg.apache.dubbo.remoting.telnet.support.command.ExitTelnetHandler
helporg.apache.dubbo.remoting.telnet.support.command.HelpTelnetHandler
statusorg.apache.dubbo.remoting.telnet.support.command.StatusTelnetHandler
logorg.apache.dubbo.remoting.telnet.support.command.LogTelnetHandler

3.2 StatusChecker扩展点:

通过这个扩展点,可以让Dubbo框架支持各种状态的检查,默认已经实现了内存和load的检查。用户可以自定义扩展,如硬盘、CPU等的状态检查。

扩展key名扩展类名
memoryorg.apache.dubbo.common.status.support.MemoryStatusChecker
loadorg.apache.dubbo.common.status.support.LoadStatusChecker

3.3 Container扩展点:

服务容器就是为了不需要使用外部的Tomcat、JBoss等web容器来运行服务,因为有可能服务根本用不到它们的功能,只是简单地Main方法中暴露一个服务即可。此时就可以使用服务容器。Dubbo默认使用Spring作为服务容器。

 

3.4 CacheFactory扩展点:

可以通过dubbo:method配置每个方法的调用返回值是否进行缓存,用于加速数据访问速度。

扩展key名扩展类名
threadlocalorg.apache.dubbo.cache.support.threadlocal.ThreadLocalCacheFactory
lruorg.apache.dubbo.cache.support.lru.LruCacheFactory
jcacheorg.apache.dubbo.cache.support.jcache.JCacheFactory
expiringorg.apache.dubbo.cache.support.expiring.ExpiringCacheFactory

其中:

  • lru,基于最近最少使用原则删除多余缓存,保持最热的数据被缓存;
  • threadlocal,当前线程缓存,比如一个页面渲染,用到很多portal,每个portal都要去查用户信息,通过线程缓存可以减少这种多余访问;
  • jcache,与JSR107集成,可以桥接各种缓存实现;
  • expiring,实现了会过期的缓存,有一个守护线程会一直检查是否过期;

3.5 Validation扩展点:

该扩展点主要实现参数点校验,我们可以在配置中使用<dubbo:service validation="校验实现名" />实现参数的校验。已知的扩展实现有:

扩展key名扩展类名
jvalidationorg.apache.dubbo.validation.spport.jvalidation.JValidation

 

3.6 LoggerAdapter扩展点:

日志适配器主要用于适配各种不同的日志框架,使其有统一的使用接口。已知的扩展点实现如下:

扩展key名扩展类名
slf4jorg.apache.dbbo.common.logger.slf4j.Slf4jLoggerAdapter
jclorg.apache.dbbo.common.logger.jcl.JclLoggerAdapter
log4jorg.apache.dbbo.common.logger.log4j.Log4jLoggerAdapter
jdkorg.apache.dbbo.common.logger.jdk.JdkLoggerAdapter
log4j2org.apache.dbbo.common.logger.log4j2.Log4j2LoggAdapter

 

3.7 Compiler扩展点:

@Adaptive注解会生成Java代码,然后使用编译器动态编译出新的Class。Compiler接口就是可可扩展的编译器,现有两个uti的实现(adaptive不算在内):

在这里插入图片描述

 

扩展key名扩展类名
jdkorg.apache.dubbo.common.compiler.suppot.JdkCompiler
javassistorg.apache.dubbo.common.compiler.suppot.JavassistCompiler

 

 

 

 

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值