dubbo SPI插件扩展点使用

news2025/4/21 16:54:55

参考:SPI插件扩展点

Dubbo SPI概述

使用IoC容器帮助管理组件的生命周期、依赖关系注入等是很多开发框架的常用设计,Dubbo中内置了一个轻量版本的IoC容器,用来管理框架内部的插件,实现包括插件实例化、生命周期、依赖关系自动注入等能力。

Dubbo插件体系与IoC容器具有以下特点:

  • 核心组件均被定义为插件,用户或二次开发者扩展非常简单。在无需改造框架内核的情况下,用户可以基于自身需求扩展如负载均衡、注册中心、通讯协议、路由等策略。
  • 平等对待第三方扩展实现。Dubbo中所有内部实现和第三方实现都是平等的,用户可以基于自身业务需求替换Dubbo提供的原生实现。
  • 插件依赖支持自动注入(IoC)。如果插件实现依赖其他插件属性,则Dubbo框架会完成该依赖对象的自动注入,支持属性、构造函数等方式。
  • 插件扩展实现支持AOP能力。框架可以自动发现扩展类的包装类,通过包装器模式对插件进行Aop增强。
  • 支持插件自动激活。通过为插件实现指定激活条件(通过注解参数等),框架可在运行时自动根据当前上下文决策是否激活该插件实现。
  • 支持插件扩展排序。

Dubbo SPI插件及详情

声明周期与事件回调

SPI扩展定义功能说明实例实现激活条件
org.apache.dubbo.common.lang.ShutdownHookCallback优雅下线回调逻辑扩展点,Dubbo进程销毁前会调用所有ShutdownHookCallback实现无需配置,自动激活
org.apache.dubbo.common.threadpool.event.ThreadPoolExhaustedListener当dubbo业务线程池满时,会调用这个扩展点发出事件通知org.apache.dubbo.metrics.collector.sample.MetricThreadPoolExhaustedListener通过dubbo.protocol.threadpool-exhausted-listeners=spi-name1,spi-name2设置激活哪些实现
org.apache.dubbo.rpc.ExporterListener每个Exporter成功export/unexport发布后,都会回调这个扩展点org.apache.dubbo.rpc.listener.InjvmExporterListener扩展实现必须增加@Activate注解激活,可按需配置激活条件。支持通过在URL中配置export.listener=spi-name1,spi-name2控制具体哪个实现
org.apache.dubbo.rpc.InvokerListener每个Invoker成功refer/destory发布后,都会回调这个扩展点org.apache.dubbo.rpc.listener.DeprecatedInvokerListener扩展实现必须增加@Activate注解激活。可按需配置激活条件。支持通过在URL中配置invoker.listener=pi-name1,spi-name2控制具体哪个实现
org.apache.dubbo.common.status.StatusChecker对外透出内部组件状态的扩展点,每个需要透出状态的组件均可实现次扩展点org.apache.dubbo.rpc.protocol.dubbo.status.ThreadPoolStatusChecker通过设置dubbo.protocol.status=spi-name1,spi-name2激活
org.apache.dubbo.config.ServiceListenerServiceConfig回调扩展点,每个ServiceConfig成功export/unexport后都会被回调。拦截点与ExporterListener略有不同无需配置,自动激活
org.apache.dubbo.registry.RegistryServiceListener服务URL向注册中心register/unregister之后的回调扩展点,所有扩展实现会被依次通知扩展实现必须增加@Activate注解激活,默认激活。支持通过在Registry URL中配置registry.listeners控制具体激活哪个实现,如dubbo.registry.parameters.registry.listeners=spi-name1,spi-name2
org.apache.dubbo.registry.integration.RegistryProtocolListener用于接口级服务发现org.apache.dubbo.registry.client.migration.MigrationRuleListeneregistryProtocol listener is introduced to provide a chance to user to customize or change export and refer behavior of RegistryProtocol. For example: re-export or re-refer on the fly when certain condition meets.
org.apache.dubbo.qos.probe.LivenessProbe生命周期检测扩展点。可通过qos live http接口配置为k8s liveness检测,qos live会检测所有LivenessProbe扩展点实现扩展实现必须增加@Activate注解激活,默认激活。支持通过在URL中配置dubbo.application.liveness-probe=spi-name2,spi-name2控制具体激活哪些实现
org.apache.dubbo.qos.probe.ReadinessProbe生命周期检测扩展点。可通过qos read http接口配置为k8s readiness检测,qos read会检查所有ReadinessProbe扩展点实现扩展实现必须增加@Activate注解激活,默认激活。支持通过在URL中配置dubbo.application.readiness-probe=spi-name2,spi-name2控制具体激活哪些实现
org.apache.dubbo.qos.probe.StartupProbe生命周期检测扩展点。可通过qos startup http接口配置为k8s startup,qos startup会检查所有StartupProbe扩展点实现扩展实现必须增加@Activate注解激活,默认激活。支持通过在URL中配置dubbo.application.startup-probe=spi-name2,spi-name2控制具体激活哪些实现
org.apache.dubbo.common.deploy.ApplicationDeployListenerDubbo进程启动生命周期中的回调扩展,支持包括初始化、启动成功、停止等多个回调点。如果是多应用部署的场景,则是单应用粒度的生命周期回调org.apache.dubbo.security.cert.CertDeployerListener无需配置,自动激活
org.apache.dubbo.common.deploy.ModuleDeployListenerDubbo进程启动生命周期中的回调扩展,支持包括初始化、启动成功、停止等多个回调点。如果是多模块部署的场景,则是单模块粒度的生命周期回调无需配置,自动激活
org.apache.dubbo.qos.api.BaseCommandQoS命令扩展点,实现扩展点增加新QoS命令org.apache.dubbo.qos.command.impl.Ls无需配置,自动激活

配置相关

SPI扩展定义功能说明实例实现激活条件
org.apache.dubbo.common.extension.ExtensionInjectorIoC注入器扩展点,通过扩展可以实现多种类型的治理自动注入,用于Dubbo框架SPI实例与不同IOC容器之间的结合,如支持Spring Bean注入SPI实例org.apache.dubbo.config.spring.extension.SpringExtensionInjector无需额外配置,自动激活
org.apache.dubbo.common.infra.InfraAdapter用于自定义加载环境变量的扩展实现,可以批量的通过编码的方式获取想要读取的环境变量,框架会自动将这些值附加到每个服务的URL参数中org.apache.dubbo.common.infra.support.EnvironmentAdapter无需额外配置,自动激活
org.apache.dubbo.common.logger.LoggerAdapter日志框架适配,如果要额外提供Dubbo不支持的日志框架适配,可以使用此扩展点org.apache.dubbo.common.logger.slf4j.Slf4jLoggerAdapter通过dubbo.application.logger=spi-name激活
org.apache.dubbo.config.ConfigInitializer在配置初始化之前,服务初始化之前定制ServiceConfig、ReferenceConfig参数扩展实现必须增加@Active注解激活,可按需增加激活条件
org.apache.dubbo.config.ConfigPostProcessor在配置初始化之后,服务初始化之前定制ServiceConfig、ReferenceConfig参数,在ConfigInitializer之后执行扩展实现必须增加@Active注解激活,可按需增加激活条件
org.apache.dubbo.config.spring.context.DubboSpringInitCustomizer无需额外配置,自动激活

服务发现


SPI扩展定义
功能说明实例实现激活条件
org.apache.dubbo.registry.AddressListener用于服务发现。URL地址通知发生时会调用此扩展点实现,可做一些地址预处理操作扩展实现修增加@Activate注解激活,可按需配置激活条件
org.apache.dubbo.registry.ProviderFirstParams用于服务发现。用于制定URL参数的优先级,改扩展点实现返回的参数列表(provider优先级高于consumer),多个扩展实现的参数列表会合并org.apache.dubbo.registry.support.DefaultProviderFirstParams无需配置,自动激活
org.apache.dubbo.registry.RegistryFactory用于接口级服务发现。通过扩展此SPI可实现不同注册中心适配org.apache.dubbo.registry.nacos.NacosRegistryFactory通过配置dubbo.registry.address=spi-name://ip:port激活
org.apache.dubbo.registry.client.RegistryClusterIdentifier用于应用级服务发现。dubbo框架支持为注册中心集群指定标识,通过此标识key可以对地址URL进行分类,从而根据不同集群做一些事情。此扩展点给用户机会指定那个key来作为注册中心集群分类org.apache.dubbo.registry.client.DefaultRegistryClusterIdentifier通过dubbo.provider.parameters.registry-cluster-tyoe=spi-name激活指定扩展实现
org.apache.dubbo.registry.client.ServiceDiscoveryFactory用于应用级服务发现。通过扩展此SPI实现不同注册中心适配org.apache.dubbo.registry.nacos.NacosServiceDiscoveryFactory通过配置dubbo.registry.address=spi-name://ip:port指定 ,同时指定dubbo.registry.register-mode=instance激活应用服务发现
org.apache.dubbo.registry.client.ServiceInstanceCustomizer用于应用级服务发现。在应用级地址实例URL注册到注册中心之前,通过此扩展点实现进行定制org.apache.dubbo.registry.client.metadata.ServiceInstanceMetadataCustomizer无需配置,自动激活
org.apache.dubbo.registry.client.migration.MigrationAddressComparator用于应用级服务发现。作为接口级地址向应用级地址迁移机制的一部分,在框架决策是否迁移之前,用于对两边的地址做比较,可自行定制决策逻辑org.apache.dubbo.registry.client.migration.DefaultMigrationAddressComparator无需配置,自动激活
org.apache.dubbo.metadata.MetadataParamsFilter用于应用级服务发现。通过该扩展点可以控制那些参数注册到注册中心,那些参数注册到服务元数据org.apache.dubbo.metadata.DefaultMetadataParamsFilter扩展实现必须增加@Active注解激活。支持通过在URL中配置params-filter控制具体激活哪个实现,如 dubbo.provider.parameters.params-filter=-default,spi-name1 表示关闭所有扩展实现仅启用 spi-name1 实现
org.apache.dubbo.registry.client.metadata.ServiceInstanceNotificationCustomizer用于应用级服务发现。识别特定类型的地址URL,实例扩展实现用于识别Spring Cloud Alibaba Dubbo地址类型org.apache.dubbo.registry.client.metadata.SpringCloudServiceInstanceNotificationCustomizer无需配置,自动激活
org.apache.dubbo.registry.integration.ServiceURLCustomizer用于接口级服务发现。在优化接口级地址列表并做URL精简时,可以通过该扩展点指定那些URL注册到注册中心、那些URL不注册。当有多个扩展实现时,效果叠加org.apache.dubbo.registry.integration.DefaultServiceURLCustomizer无需配置,自动激活
org.apache.dubbo.rpc.cluster.ProviderURLMergeProcessor用于接口级服务发现。该扩展点用于完成consumer url和provider url合并,可以使用不同的实现控制合并策略,以确保保留不同的key,使用不同的覆盖关系(仅对接口级服务发现有效)org.apache.dubbo.rpc.cluster.support.merger.DefaultProviderURLMergeProcessor可通过dubbo.consumer.url-merge-processor=spi-name启用指定扩展实现

RPC与流量管控

SPI扩展定义功能说明实例实现激活条件
org.apache.dubbo.rpc.ProtocolRPC协议实现扩展点。通过扩展该扩展点增加更多的协议实现org.apache.dubbo.rpc.protocol.dubbo.DubboProtocol通过配置dubbo.protocol.name=spi-name激活
org.apache.dubbo.rpc.ProxyFactoryRPC代理实现的扩展点。可以提供多种不同的代理实现,如字节码增加、JDK等org.apache.dubbo.rpc.proxy.javassist.JavassistProxyFactory通过配置dubbo.application.compiler=spi-name激活
org.apache.dubbo.rpc.ZoneDetector在多注册中心场景下,Dubbo提供了自动同区域有限的匹配策略。此扩展点可以让用户更方便的扩展zone读取策略,以更灵活的决策当前请求属于哪个zone。默认情况下框架会从RpcContext特点的Key读取只会有一个ZoneDetector实现会被激活。key为default的扩展实现被激活
org.apache.dubbo.rpc.cluster.ClusterRpc请求容灾策略扩展点。比如设置请求失败时的动作,如FailoverCluster、FailfastCluster等org.apache.dubbo.rpc.cluster.support.FailoverCluster通过配置dubbo.consumer.cluster=spi-name激活
org.apache.dubbo.rpc.cluster.LoadBalance负载均衡策略扩展点,通过扩展可以实现不同的负载均衡策略org.apache.dubbo.rpc.cluster.loadbalance.RandomLoadBalance通过配置dubbo.consumer.loadbalance=spi-name激活
org.apache.dubbo.rpc.HeaderFilter在rpc请求前,通过不同的扩展实现各种attachment/header校验策略org.apache.dubbo.rpc.filter.TokenHeaderFilter扩展实现必须通过@Activate注解激活。支持通过在URL中配置header.filter=spi-name1,spi-name2控制具体激活哪个实现
org.apache.dubbo.rpc.FilterRPC请求过滤器,用于在请求发起前、相应结果返回后,对RPC调用进行过滤org.apache.dubbo.rpc.filter.GenericFilter扩展实现必须增加 @Activate 注解激活,可按需配置激活条件如@Activate(group=“consumer”)。支持通过在 URL 中配置 service.filter=spi-name1,spi-name2 控制具体在provider侧激活哪些实现;支持通过在 URL 中配置 reference.filter=spi-name1,spi-name2 控制具体在consumer侧激活哪些实现
org.apache.dubbo.rpc.cluster.filter.ClusterFilterRPC请求过滤器,与Filter作用相同,但ClusterFilter发生在选址之前,对于大部分用户可直接使用org.apache.dubbo.rpc.Filterorg.apache.dubbo.rpc.cluster.filter.support.ConsumerContextFilter扩展实现必须增加 @Activate 注解激活,可按需配置激活条件。支持通过在 URL 中配置 filter=spi-name1,spi-name2 控制具体激活哪个实现
org.apache.dubbo.rpc.cluster.RouterFactory路由器扩展点,可以通过扩展增加不同的路由规则策略扩展实现必须增加 @Activate 注解激活,可按需配置激活条件。支持通过在 URL 中配置 router=spi-name1,spi-name2 控制具体激活哪个实现
org.apache.dubbo.rpc.cluster.router.state.StateRouterFactory与RouterFactory相同作用,但具备更高性能。对大部分用户,简单起见使用RouterFactoryorg.apache.dubbo.rpc.cluster.router.condition.ConditionStateRouterFactory扩展实现必须增加 @Activate 注解激活,可按需配置激活条件。支持通过在 URL 中配置 router=spi-name1,spi-name2 控制具体激活哪个实现
org.apache.dubbo.rpc.cluster.ConfiguratorFactory动态配置规则扩展点,通过增加扩展可以增加不同的动态配置规则策略org.apache.dubbo.rpc.cluster.configurator.override.OverrideConfiguratorFactory扩展实现必须增加 @Activate 注解激活,可按需配置激活条件。支持通过在 URL 中配置 router=spi-name1,spi-name2 控制具体激活哪个实现
org.apache.dubbo.rpc.cluster.router.condition.matcher.pattern.ValuePattern路由规则处理扩展点。条件路由规则内部的规则处理器,通过扩展可支持更丰富的规则和匹配条件org.apache.dubbo.rpc.cluster.router.condition.matcher.pattern.range.RangeValuePattern自动激活,通过规则控制激活哪个具体实现
org.apache.dubbo.rpc.cluster.router.condition.matcher.ConditionMatcherFactory路由规则处理扩展点。条件路由规则内部的规则处理器,通过扩展可支持更丰富的规则和匹配条件org.apache.dubbo.rpc.cluster.router.condition.matcher.argument.ArgumentConditionMatcherFactory扩展实现必须增加 @Activate 注解激活,可按需配置激活条件。
org.apache.dubbo.rpc.cluster.router.mesh.util.TracingContextProviderMashRule路由规则处理扩展点,可用于从不同的第三方Tracing系统读取上下文无需配置,自动激活
org.apache.dubbo.rpc.cluster.router.mesh.route.MeshEnvListenerFactoryMashRule路由规则处理扩展点无需配置,自动激活
org.apache.dubbo.cache.CacheFactory缓存实现扩展点,用于缓存RPC调用结果org.apache.dubbo.cache.support.expiring.ExpiringCacheFactory通过在 URL 中配置 cache=spi-name 控制具体激活哪个实现
org.apache.dubbo.common.serialize.Serialization序列化协议扩展点,如果要扩展新的序列化协议,可以使用此扩展点org.apache.dubbo.common.serialize.hessian2.Hessian2Serialization通过配置 dubbo.provider.serialization=spi-name 激活
org.apache.dubbo.common.threadpool.ThreadPool线程池策略扩展点。目前仅适用于dubbo协议实现,不适用于triple协议org.apache.dubbo.common.threadpool.support.fixed.FixedThreadPool通过配置 dubbo.provider.threadpool=spi-name 激活
org.apache.dubbo.rpc.executor.IsolationExecutorSupportFactory线程池隔离策略扩展点,如dubbo协议、triple协议都可以定义不同的隔离策略,每个协议可设置一个线程池隔离策略org.apache.dubbo.rpc.protocol.tri.transport.TripleIsolationExecutorSupportFactory跟随用户配置的 dubbo.protocol.name,因此必须确保配置的 key 值与 rpc 协议名相同
org.apache.dubbo.rpc.PenetrateAttachmentSelector通过此扩展点可以自定义参数全链路传递(dubbo链路),Dubbo 默认只会在 A->B 链路传递参数,通过此扩展点可以控制参数在 A->B->C一直传递下去。无需配置,自动激活

服务治理

SPI扩展定义功能说明实例实现激活条件
org.apache.dubbo.common.config.configcenter.DynamicConfigurationFactory配置中心核心扩展点。用于提供不同配置中心适配实现org.apache.dubbo.configcenter.support.nacos.NacosDynamicConfigurationFactory通过指定dubbo.config-center.address=spi-name://激活
org.apache.dubbo.metadata.report.MetadataReportFactory元数据中心扩展点,用于提供新的元数据中心存储实现org.apache.dubbo.metadata.store.nacos.NacosMetadataReportFactory通过指定dubbo.metadata-report.address=spi-name://激活
org.apache.dubbo.metrics.report.MetricsReporterFactoryMetrics指标上报扩展点,可以通过扩展点实现适配到不同的Metrics后端服务org.apache.dubbo.metrics.prometheus.PrometheusMetricsReporterFactory通过指定 dubbo.metrics.protocol=spi-name 激活
org.apache.dubbo.metrics.collector.MetricsCollector框架内部Metrics采集扩展点,可以通过扩展支持RPC、注册中心等不同组件的metrics埋点数据采集org.apache.dubbo.metrics.registry.collector.RegistryMetricsCollector扩展实现必须增加 @Activate 注解激活,可按需增加激活条件
org.apache.dubbo.auth.spi.AccessKeyStorage采用dubbo-auth模块,该扩展点可不同的AK来源读取方法org.apache.dubbo.auth.DefaultAccessKeyStorage通过指定 accessKey.storage URL 参数激活
org.apache.dubbo.auth.spi.Authenticator用于dubbo-auth模块,该扩展点用于实现具体的认证逻辑org.apache.dubbo.auth.AccessKeyAuthenticator通过指定 authenticator URL 参数激活
org.apache.dubbo.common.ssl.CertProviderTLS证书来源扩展,用于适配不同的证书来源实现org.apache.dubbo.common.ssl.impl.SSLConfigCertProvider扩展实现必须增加 @Activate 注解激活

协议与传输层实现

SPI扩展定义功能说明实例实现激活条件
org.apache.dubbo.remoting.ChannelHandler
org.apache.dubbo.remoting.Codec
org.apache.dubbo.remoting.Codec2
org.apache.dubbo.remoting.Dispatcher
org.apache.dubbo.remoting.Transporter
org.apache.dubbo.rpc.protocol.dubbo.ByteAccessor
org.apache.dubbo.remoting.api.pu.PortUnificationTransporter
org.apache.dubbo.remoting.api.WireProtocol
org.apache.dubbo.remoting.api.connection.ConnectionManager
org.apache.dubbo.remoting.exchange.Exchanger
org.apache.dubbo.remoting.http.HttpBinder
org.apache.dubbo.remoting.http12.message.HttpMessageEncoderFactory
org.apache.dubbo.remoting.http12.message.HttpMessageDecoderFactory
org.apache.dubbo.remoting.http12.h2.Http2ServerTransportListenerFactory
org.apache.dubbo.remoting.http12.h1.Http1ServerTransportListenerFactory
org.apache.dubbo.remoting.http12.message.HttpMessageAdapterFactory
org.apache.dubbo.metadata.annotation.processing.builder.TypeBuilder
org.apache.dubbo.metadata.annotation.processing.rest.AnnotatedMethodParameterProcessor
org.apache.dubbo.metadata.annotation.processing.rest.ServiceRestMetadataResolver
org.apache.dubbo.metadata.definition.builder.TypeBuilder
org.apache.dubbo.metadata.rest.AnnotatedMethodParameterProcessor
org.apache.dubbo.metadata.rest.ServiceRestMetadataReader
org.apache.dubbo.rpc.protocol.tri.compressor.Compressor
org.apache.dubbo.rpc.protocol.tri.compressor.DeCompressor
org.apache.dubbo.rpc.protocol.tri.rest.argument.ArgumentConverter
org.apache.dubbo.rpc.protocol.tri.rest.argument.ArgumentResolver
org.apache.dubbo.rpc.protocol.tri.rest.filter.RestExtension
org.apache.dubbo.rpc.protocol.tri.rest.filter.RestExtensionAdapter
org.apache.dubbo.rpc.protocol.tri.rest.mapping.RequestMappingResolver
org.apache.dubbo.rpc.protocol.tri.route.RequestHandlerMapping
org.apache.dubbo.rpc.protocol.rest.annotation.param.parse.provider.BaseProviderParamParser
org.apache.dubbo.metadata.rest.ServiceRestMetadataResolver
org.apache.dubbo.rpc.protocol.rest.filter.RestRequestFilter
org.apache.dubbo.rpc.protocol.rest.filter.RestResponseFilter
org.apache.dubbo.metadata.rest.NoAnnotatedParameterRequestTagProcessor
org.apache.dubbo.rpc.protocol.rest.message.HttpMessageCodec
org.apache.dubbo.rpc.protocol.rest.annotation.consumer.HttpConnectionPreBuildIntercept
org.apache.dubbo.rpc.protocol.rest.annotation.param.parse.consumer.BaseConsumerParamParser
org.apache.dubbo.remoting.http.factory.RestClientFactory
org.apache.dubbo.rpc.protocol.rest.filter.RestResponseInterceptor
org.apache.dubbo.remoting.zookeeper.ZookeeperTransporter

框架内部实现

SPI扩展定义功能说明实例实现激活条件
org.apache.dubbo.common.url.component.param.DynamicParamSource可通过扩展自定义动态参数列表,与 Dubbo3 中关于 URL 存储的优化相关。org.apache.dubbo.common.url.component.param.DefaultDynamicParamSource
org.apache.dubbo.common.compiler.Compiler用于设置 Dubbo IoC 容器的自适应扩展实现依赖的字节码工具。默认使用 javassist,可设置使用 jdk 或 bytebuddy 等实现。org.apache.dubbo.common.compiler.support.JavassistCompiler
org.apache.dubbo.common.serialize.MultipleSerialization
org.apache.dubbo.common.convert.Converter实现原类型到目标类型的转换,多限于框架内部集成使用org.apache.dubbo.common.convert.StringToFloatConverter
org.apache.dubbo.common.config.OrderedPropertiesProvider通过扩展可以为框架提供更多的 properties 来源,多限于框架内部集成使用
org.apache.dubbo.common.convert.multiple.MultiValueConverter实现原类型到目标类型的转换,多限于框架内部集成使用org.apache.dubbo.common.convert.multiple.StringToArrayConverter
org.apache.dubbo.common.store.DataStore
org.apache.dubbo.common.threadpool.manager.ExecutorRepository
org.apache.dubbo.spring.security.jackson.ObjectMapperCodecCustomer
org.apache.dubbo.validation.Validation
org.apache.dubbo.rpc.PathResolver
org.apache.dubbo.rpc.model.PackableMethodFactory
org.apache.dubbo.rpc.model.ApplicationInitListener
org.apache.dubbo.rpc.model.BuiltinServiceDetector
org.apache.dubbo.rpc.model.ScopeModelInitializer
org.apache.dubbo.aot.api.ReflectionTypeDescriberRegistrar
org.apache.dubbo.aot.api.ProxyDescriberRegistrar
org.apache.dubbo.common.json.JsonUtil
org.apache.dubbo.rpc.protocol.injvm.ParamDeepCopyUtil
org.apache.dubbo.aot.api.ResourceDescriberRegistrar
org.apache.dubbo.common.context.ApplicationExt
org.apache.dubbo.common.context.ModuleExt
org.apache.dubbo.metrics.service.MetricsService用于对外发布/透出 Metrics 指标的内部服务定义,以标准 Dubbo 服务形式发布。org.apache.dubbo.metrics.service.DefaultMetricsService
org.apache.dubbo.metrics.service.MetricsServiceExporter
org.apache.dubbo.rpc.cluster.filter.FilterChainBuilder
org.apache.dubbo.rpc.cluster.filter.InvocationInterceptorBuilder
org.apache.dubbo.rpc.cluster.Merger目前用于多 group 调用场景,对请求结果进行合并
org.apache.dubbo.rpc.cluster.governance.GovernanceRuleRepository
org.apache.dubbo.qos.permission.PermissionChecker用于检查扩展QoS执行权限检查逻辑,配合每个 QoS 命令配置的 @CMD 权限注解,结合上下文进行检查。org.apache.dubbo.qos.permission.DefaultAnonymousAccessPermissionChecker默认只支持 qosPermissionChecker
org.apache.dubbo.common.status.reporter.FrameworkStatusReporter用于上报 Dubbo 框架内部运行状态的扩展点,目前框架在服务发现模型自动迁移等位置做了统计埋点,所有迁移动作都会通过此扩展实现上报出去。未来可考虑用 metrics标准埋点取代。
org.apache.dubbo.registry.client.metadata.MetadataServiceURLBuilder用于应用级服务发现。在收到应用级地址 URL 推送后,生成 MetadataService URL 时的定制逻辑(仅对点对点应用级地址发现有效)org.apache.dubbo.registry.client.metadata.StandardMetadataServiceURLBuilder
org.apache.dubbo.metadata.ServiceNameMapping用于应用级服务发现org.apache.dubbo.registry.client.metadata.MetadataServiceNameMapping

Dubbo SPI插件定义以及使用

协议扩展

扩展说明

RPC协议扩展,封装远程调用细节。

契约:

  • 当用户调用refer()所返回的Invoker对象的invoke()方法时,协议需相应执行同URL远端export()传入的Invoker对象的invoker()方法。
  • 其中,refer()返回的Invoker由协议实现,协议通常需要在此Invoker中发送远程请求,export()传入的Invoker由框架实现并传入,协议不需要关心。

注意

  • 协议不关心业务接口的透明代理,

调用拦截扩展

扩展说明

服务提供方和服务消费方调用过程拦截,Dubbo本身的大多功能均基于此扩展点实现,每次远程方法执行,该拦截器都会被执行,请注意对性能的影响。

约定:

  • 用户自定义filter默认在内置filter之后。
  • 特殊值default,表示缺省扩展点插入的位置。比如:filter="xxx,default,yyy",表示xxx在缺省filter之前,yyy在缺省filter之后。
  • 特殊符合-,表示删除。比如:filter="-fool",删除添加缺省扩展点foo1。比如:filter="-default",剔除添加所有缺省扩展点。
  • provider和service同时配置filter时,累加所有filter,而不是覆盖。比如:<dubbo:provider filter="xxx,yyy" /><dubbo:service filte="aaa,bbb"/>,则xxx,yyy,aaa,bbb均会生效。如果需要覆盖,需配置:<dubbo:service filter="-xxx,-yyy,aaa,bbb"/>
扩展接口
org.apache.dubbo.rpc.Filter
扩展配置
<!-- 消费方调用过程拦截 -->
<dubbo:reference filter="xxx,yyy"/>
<!-- 消费方调用过程缺省拦截器,将拦截所有reference -->
<dubbo:consumer filter="xxx,yyy"/>
<!-- 提供方调用过程拦截 -->
<dubbo:service filter="xxx,yyy"/>
<!-- 提供方调用过程缺省拦截器,将拦截所有的service -->
<dubbo:provider filter="xxx,yyy"/>
已知扩展
  • org.apache.dubbo.rpc.filter.EchoFilter
  • org.apache.dubbo.rpc.filter.GenericFilter
  • org.apache.dubbo.rpc.filter.GenericImplFilter
  • org.apache.dubbo.rpc.filter.TokenFilter
  • org.apache.dubbo.rpc.filter.AccessLogFilter
  • org.apache.dubbo.rpc.filter.ActiveLimitFilter
  • org.apache.dubbo.rpc.filter.ClassLoaderFilter
  • org.apache.dubbo.rpc.filter.ContextFilter
  • org.apache.dubbo.rpc.filter.ExceptionFilter
  • org.apache.dubbo.rpc.filter.ExecuteLimitFilter
  • org.apache.dubbo.rpc.filter.DeprecatedFilter
扩展实例
src
 |-main
    |-java
        |-com
            |-doudou
                |- filter
                    |-LogFilter.java (实现Filter接口)
    |-resources
        |-META-INF
            |-dubbo
                |-org.apache.dubbo.rpc.Filter (纯文本文件,内容为:logFilter=com.doudou.filter.LogFilter)

XxxFilter.java

package com.doudou.filter;

import com.alibaba.fastjson2.JSON;
import org.apache.dubbo.rpc.Filter;
import org.apache.dubbo.rpc.Invocation;
import org.apache.dubbo.rpc.Invoker;
import org.apache.dubbo.rpc.Result;
import org.apache.dubbo.rpc.RpcException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class LogFilter implements Filter {

    private Logger logger = LoggerFactory.getLogger(LogFilter.class);

    @Override
    public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {
        logger.info("param {}", JSON.toJSONString(invocation.getArguments()));
        Result result = invoker.invoke(invocation);
        logger.info("result {}", JSON.toJSONString(result.getValue()));
        return result;
    }
}

META-INF/dubbo/org.apache.dubbo.rpc.Filter:

logFilter=com.doudou.filter.LogFilter

DemoServiceImpl.java

package com.doudou.demo.service;

import com.doudou.demo.api.DemoService;
import org.apache.dubbo.config.annotation.DubboService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@DubboService(filter = "logFilter")
public class DemoServiceImpl implements DemoService {
    private Logger logger = LoggerFactory.getLogger(DemoServiceImpl.class);

    @Override
    public String sayHello(String name) {
        logger.info("name:{}", name);
        return "DemoService "
                + "hello " + name;
    }
}
2025-04-14 11:15:31.809  INFO 20540 --- [:20880-thread-2] com.doudou.filter.LogFilter              : param ["world"]
2025-04-14 11:15:31.809  INFO 20540 --- [:20880-thread-2] com.doudou.demo.service.DemoServiceImpl  : name:world
2025-04-14 11:15:31.811  INFO 20540 --- [:20880-thread-2] com.doudou.filter.LogFilter              : result "DemoService hello world"

引用监听扩展

扩展说明

当有服务引用时,触发该事件。

扩展接口

org.apache.dubbo.rpc.InvokerListener

扩展配置
<!-- 引用服务监听 -->
<dubbo:reference listener="xxx,yyy"/>
<!-- 引用服务缺省监听器 -->
<dubbo:consumer listener="xxx,yyy"/>
已知扩展

org.apache.dubbo.rpc.listener.DeprecatedInvokerListener

扩展实例
src
 |-main
    |-java
        |-com
            |-doudou
                |-listener
                    |-DemoListener.java (实现InvokerListener接口)
    |-resources
        |-META-INF
            |-dubbo
                |-org.apache.dubbo.rpc.InvokerListener (纯文本文件,内容为:demoListener=com.doudou.listener.DemoListener)

DemoListener.java

package com.doudou.listener;


import org.apache.dubbo.rpc.Invoker;
import org.apache.dubbo.rpc.InvokerListener;
import org.apache.dubbo.rpc.RpcException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class DemoListener implements InvokerListener {
    private Logger logger = LoggerFactory.getLogger(DemoListener.class);

    @Override
    public void referred(Invoker<?> invoker) throws RpcException {
        String name = invoker.getInterface().getName();
        String methodName = invoker.getUrl().getParameter("method");
        String params = invoker.getUrl().getParameter("params");
        logger.info("referred interfaceName {}, methodName {}, params {}", name, methodName, params);
    }

    @Override
    public void destroyed(Invoker<?> invoker) {
        String name = invoker.getInterface().getName();
        String methodName = invoker.getUrl().getParameter("method");
        String params = invoker.getUrl().getParameter("params");
        logger.info("destroyed interfaceName {}, methodName {}, params {}", name, methodName, params);
    }
}

META-INF/dubbo/org.apache.dubbo.rpc.InvokerListener:
demoListener=com.doudou.listener.DemoListener
Task.java

package com.doudou.demo.Task;

import com.doudou.demo.api.DemoService;
import com.doudou.demo.api.HelloService;
import org.apache.dubbo.config.annotation.DubboReference;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;

@Component
public class Task implements CommandLineRunner {
    private static final Logger logger = LoggerFactory.getLogger(Task.class);

    @DubboReference(listener = {"demoListener"})
    private DemoService demoService;

    @DubboReference(listener = {"demoListener"})
    private HelloService helloService;

    @Override
    public void run(String... args) throws Exception {
        String result = demoService.sayHello("world");
        logger.info("demoService result:{}", result);

        String world = helloService.hello("world");
        logger.info("helloService result:{}", world);
    }
}
2025-04-14 11:52:38.613  INFO 23088 --- [egistryReceiver] com.doudou.listener.DemoListener         : referred interfaceName com.doudou.demo.api.HelloService, methodName null, params null

暴露监听扩展

扩展说明

当有服务暴露时,触发该事件。

扩展接口

org.apache.dubbo.rpc.ExporterListener

扩展配置
<!-- 暴露服务监听 -->
<dubbo:service listener="xxx,yyy"/>
<!-- 暴露服务缺省监听器 -->
<dubbo:provider listener="xxx,yyy"/>
已知扩展

org.apache.dubbo.rpc.listener.InjvmExporterListener

扩展实例
src
 |-main
    |-java
        |-com
            |-doudou
                |-listener
                    |-DemoExporterListener.java (实现ExporterListener接口)
    |-resources
        |-META-INF
            |-dubbo
                |-org.apache.dubbo.rpc.ExporterListener (纯文本文件,内容为:demo=com.doudou.listener.DemoExporterListener)

DemoExporterListener.java

package com.doudou.listener;

import com.alibaba.fastjson2.JSON;
import org.apache.dubbo.common.URL;
import org.apache.dubbo.rpc.Exporter;
import org.apache.dubbo.rpc.ExporterListener;
import org.apache.dubbo.rpc.RpcException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class DemoExporterListener implements ExporterListener {

    private Logger logger = LoggerFactory.getLogger(DemoExporterListener.class);

    @Override
    public void exported(Exporter<?> exporter) throws RpcException {
        String interfaceName = exporter.getInvoker().getInterface().getName();
        URL url = exporter.getInvoker().getUrl();
        String address = url.getAddress();
        String serviceKey = url.getServiceKey();
        logger.info("exported interfaceName:{},address:{},serviceKey:{}", interfaceName, address, serviceKey);
    }

    @Override
    public void unexported(Exporter<?> exporter) {
        String interfaceName = exporter.getInvoker().getInterface().getName();
        URL url = exporter.getInvoker().getUrl();
        String address = url.getAddress();
        String serviceKey = url.getServiceKey();
        logger.info("unexported interfaceName:{},address:{},serviceKey:{}", interfaceName, address, serviceKey);
    }
}

META-INF/dubbo/org.apache.dubbo.rpc.ExporterListener:
demoExporterListener=com.doudou.listener.DemoExporterListener

使用

package com.doudou.demo.service;

import com.doudou.demo.api.DemoService;
import org.apache.dubbo.config.annotation.DubboService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@DubboService(filter = {"logFilter"}, listener = {"demoExporterListener"})
public class DemoServiceImpl implements DemoService {
    private Logger logger = LoggerFactory.getLogger(DemoServiceImpl.class);

    @Override
    public String sayHello(String name) {
        logger.info("name:{}", name);
        return "DemoService "
                + "hello " + name;
    }
}
2025-04-14 13:58:11.131  INFO 26080 --- [           main] c.doudou.listener.DemoExporterListener   : exported interfaceName:com.doudou.demo.api.DemoService,address:10.1.6.137:50051,serviceKey:com.doudou.demo.api.DemoService

集群扩展

扩展说明

当有多个服务提供方时,将多个服务提供方组装成一个集群,并伪装成一个提供方。

扩展接口

org.apache.dubbo.rpc.cluster.Cluster

扩展配置
<dubbo:protocol cluster="xxx"/>
<!-- 缺省值配置,如果<dubbo:protocol>没有配置cluster时,使用此配置。-->
<dubbo:provider cluster="xxx"/>
已知扩展
  • org.apache.dubbo.rpc.cluster.support.wrapper.MockClusterWrapper
  • org.apache.dubbo.rpc.cluster.support.FailoverCluster
  • org.apache.dubbo.rpc.cluster.support.FailfastCluster
  • org.apache.dubbo.rpc.cluster.support.FailsafeCluster
  • org.apache.dubbo.rpc.cluster.support.FailbackCluster
  • org.apache.dubbo.rpc.cluster.support.ForkingCluster
  • org.apache.dubbo.rpc.cluster.support.AvailableCluster
  • org.apache.dubbo.rpc.cluster.support.MergeableCluster
  • org.apache.dubbo.rpc.cluster.support.BroadcastCluster
  • org.apache.dubbo.rpc.cluster.support.registry.ZoneAwareCluster
扩展实例
src
 |-main
    |-java
        |-com
            |-doudou
                |-invoker
                    |-MyClusterInvoker.java(必须集成AbstractClusterInvoker抽象类)
                |-cluster
                    |-MyCluster.java (实现org.apache.dubbo.rpc.cluster.Cluster接口)
    |-resources
        |-META-INF
            |-dubbo
                |-org.apache.dubbo.rpc.cluster.Cluster (纯文本文件,内容为:myCluster=com.doudou.cluster.MyCluster)
package com.doudou.invoker;

import java.util.List;
import java.util.Random;
import org.apache.dubbo.rpc.Invocation;
import org.apache.dubbo.rpc.Invoker;
import org.apache.dubbo.rpc.Result;
import org.apache.dubbo.rpc.RpcException;
import org.apache.dubbo.rpc.cluster.Directory;
import org.apache.dubbo.rpc.cluster.LoadBalance;
import org.apache.dubbo.rpc.cluster.support.AbstractClusterInvoker;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * @author admin
 */
public class MyClusterInvoker<T> extends AbstractClusterInvoker<T> {
    private Logger logger = LoggerFactory.getLogger(MyClusterInvoker.class);

    Random random = new Random();

    public MyClusterInvoker(Directory<T> directory) {
        super(directory);
    }

    @Override
    protected Result doInvoke(Invocation invocation, List<Invoker<T>> invokers,
            LoadBalance loadbalance) throws RpcException {
        int num = random.nextInt(invokers.size());
        logger.info("invoke num: {}", num);
        Invoker<T> invoker = invokers.get(num);
        return invoker.invoke(invocation);
    }
}
package com.doudou.cluster;

import com.doudou.invoker.MyClusterInvoker;
import org.apache.dubbo.rpc.Invoker;
import org.apache.dubbo.rpc.RpcException;
import org.apache.dubbo.rpc.cluster.Cluster;
import org.apache.dubbo.rpc.cluster.Directory;

/**
 * @author admin
 */
public class MyCluster implements Cluster {

    @Override
    public <T> Invoker<T> join(Directory<T> directory, boolean buildFilterChain)
            throws RpcException {
        return new MyClusterInvoker<>(directory);
    }
}

org.apache.dubbo.rpc.cluster.Cluster
myCluster=com.doudou.cluster.MyCluster

使用

dubbo:
  consumer:
    cluster: myCluster

package com.doudou.task;

import com.doudou.service.api.DemoService;
import org.apache.dubbo.config.annotation.DubboReference;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;

/**
 * @author admin
 */
@Component
public class Task01 implements CommandLineRunner {
    private Logger logger = LoggerFactory.getLogger(Task01.class);

    @DubboReference(cluster = "myCluster")
    private DemoService demoService;

    @Override
    public void run(String... args) throws Exception {
        for (int i = 0; i < 10; i++) {
            String result = demoService.sayHello("zhangsan");
            logger.info("result {}", result);
        }
    }
}

路由扩展

扩展说明

从多个服务提供方中选择一个进行调用

扩展接口
  • org.apache.dubbo.rpc.cluster.RouterFactory
  • org.apache.dubbo.rpc.cluster.Router
扩展实例
src
 |-main
    |-java
        |-com
            |-doudou
                |-route
                    |-GrayRouter.java(实现Router或继承AbstractRouter类)
                |-cluster
                    |-GrayRouterFactory.java (实现org.apache.dubbo.rpc.cluster.RouterFactory接口)
    |-resources
        |-META-INF
            |-dubbo
                |-org.apache.dubbo.rpc.cluster.RouterFactory (纯文本文件,内容为:gray=com.doudou.router.GrayRouterFactory)
package com.doudou.router;

import org.apache.dubbo.common.URL;
import org.apache.dubbo.rpc.Invocation;
import org.apache.dubbo.rpc.Invoker;
import org.apache.dubbo.rpc.RpcException;
import org.apache.dubbo.rpc.cluster.router.AbstractRouter;
import org.apache.dubbo.rpc.cluster.router.RouterResult;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @title CustomRouter
 * @description <TODO description class purpose>
 * author zzw
 * version 1.0.0
 * create 2025/4/15 22:21
 **/
public class GrayRouter extends AbstractRouter {
    private Logger logger = LoggerFactory.getLogger(GrayRouter.class);

    @Override
    public <T> List<Invoker<T>> route(List<Invoker<T>> invokers, URL url, Invocation invocation) throws RpcException {
        String grayFlag = invocation.getAttachments().get("env");
        return invokers.stream()
                .filter(invoker ->
                {
                    String envStr = invoker.getUrl().getParameter("env");
                    logger.info("envStr:{}", envStr);
                    return envStr.equals(Objects.isNull(grayFlag) ? "prod" : "gray");
                })
                .collect(Collectors.toList());
    }
}
package com.doudou.router;

import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.extension.Activate;
import org.apache.dubbo.rpc.cluster.Router;
import org.apache.dubbo.rpc.cluster.RouterFactory;

/**
 * @title CustomRouterFactory
 * @description <TODO description class purpose>
 * author zzw
 * version 1.0.0
 * create 2025/4/15 22:22
 **/
@Activate(order = 100, group = "consumer")
public class GrayRouterFactory implements RouterFactory {

    @Override
    public Router getRouter(URL url) {
        return new GrayRouter();
    }
}

org.apache.dubbo.rpc.cluster.RouterFactory
gray=com.doudou.router.GrayRouterFactory

使用

dubbo:
    provider:
        parameters:
            env: "gray"
conditions:
  - => env=gray

负载均衡扩展

扩展说明

从多个服务提供方中选择一个进行调用

扩展接口

org.apache.dubbo.rpc.cluster.LoadBalance

扩展配置
dubbo:
  # 服务提供者配置
  provider:
    loadbalance: xxx
  # 服务消费者配置
  consumer:
    loadbalance: xxx
已知配置
  • org.apache.dubbo.rpc.cluster.loadbalance.RandomLoadBalance
  • org.apache.dubbo.rpc.cluster.loadbalance.RoundRobinLoadBalance
  • org.apache.dubbo.rpc.cluster.loadbalance.LeastActiveLoadBalance
  • org.apache.dubbo.rpc.cluster.loadbalance.ConsistentHashLoadBalance
  • org.apache.dubbo.rpc.cluster.loadbalance.ShortestResponseLoadBalance
扩展实例
src
 |-main
    |-java
        |-com
            |-doudou
                |-loadbalance
                    |-WeightRandomLoadBalance.java(实现LoadBalance或继承AbstractLoadBalance类)
    |-resources
        |-META-INF
            |-dubbo
                |-org.apache.dubbo.rpc.cluster.LoadBalance (纯文本文件,内容为:weight-random=com.doudou.demo.loadbalance.WeightRandomLoadBalance)
package com.doudou.demo.loadbalance;

import org.apache.dubbo.common.URL;
import org.apache.dubbo.rpc.Invocation;
import org.apache.dubbo.rpc.Invoker;
import org.apache.dubbo.rpc.cluster.loadbalance.AbstractLoadBalance;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.List;
import java.util.concurrent.ThreadLocalRandom;

/**
 * @title WeightRandomLoadBalance
 * @description 实现基于权重的随机选择
 * author zzw
 * version 1.0.0
 * create 2025/4/15 23:29
 **/
public class WeightRandomLoadBalance extends AbstractLoadBalance {
    private Logger logger = LoggerFactory.getLogger(WeightRandomLoadBalance.class);

    @Override
    protected <T> Invoker<T> doSelect(List<Invoker<T>> invokers, URL url, Invocation invocation) {
        int totalWeight = invokers.stream().mapToInt(invoker -> invoker.getUrl().getParameter("weight", 100)).sum();
        logger.info("total weight:{}", totalWeight);
        int random = ThreadLocalRandom.current().nextInt(totalWeight);
        logger.info("random:{}", random);
        for (Invoker<T> invoker : invokers) {
            random -= invoker.getUrl().getParameter("weight", 100);
            logger.info("random:{}", random);
            if (random < 0) {
                return invoker;
            }
        }
        return invokers.get(0);
    }
}

org.apache.dubbo.rpc.cluster.LoadBalance
weight-random=com.doudou.demo.loadbalance.WeightRandomLoadBalance

package com.doudou.demo.task;

import com.doudou.demo.api.DemoService;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.dubbo.rpc.RpcContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;

/**
 * @title Task01
 * @description <TODO description class purpose>
 * author zzw
 * version 1.0.0
 * create 2025/4/15 21:32
 **/
@Component
public class Task01 implements CommandLineRunner {
    private Logger logger = LoggerFactory.getLogger(Task01.class);

    @DubboReference(loadbalance = "weight-random")
    private DemoService demoService;

    @Override
    public void run(String... args) throws Exception {
        for (int i = 0; i < 10; i++) {
            RpcContext.getClientAttachment().setAttachment("env", "gray1");
            String result = demoService.sayHello("provider " + i);
            logger.info("{} --->> {}", i, result);
        }
    }
}

dubbo:
  # 服务提供者配置
  provider:
    loadbalance: weight-random
  # 服务消费者配置 优先级高于服务提供者配置
  consumer:
    loadbalance: weight-random

合并结果扩展

扩展说明

合并返回的结果,用于分组聚合。

扩展接口

org.apache.dubbo.rpc.cluster.Merger

扩展配置

<dubbo:method merge="xxx"/>

@DubboReference(group = "*", merger = "true", methods = @Method(name = "sayHello", merger = "customListMerger"))
private DemoService demoService;
已知扩展
  • org.apache.dubbo.rpc.cluster.merger.ArrayMerger
  • org.apache.dubbo.rpc.cluster.merger.BooleanArrayMerger
  • org.apache.dubbo.rpc.cluster.merger.ByteArrayMerger
  • org.apache.dubbo.rpc.cluster.merger.CharArrayMerger
  • org.apache.dubbo.rpc.cluster.merger.DoubleArrayMerger
  • org.apache.dubbo.rpc.cluster.merger.FloatArrayMerger
  • org.apache.dubbo.rpc.cluster.merger.IntArrayMerger
  • org.apache.dubbo.rpc.cluster.merger.ListMerger
  • org.apache.dubbo.rpc.cluster.merger.LongArrayMerger
  • org.apache.dubbo.rpc.cluster.merger.MapMerger
  • org.apache.dubbo.rpc.cluster.merger.MergerFactory
  • org.apache.dubbo.rpc.cluster.merger.SetMerger
  • org.apache.dubbo.rpc.cluster.merger.ShortArrayMerger
扩展实例
src
 |-main
    |-java
        |-com
            |-demo
                |-CustomListMerger.java 实现Merger接口
    |-resources
        |-META-INF
            |-dubbo
                |-org.apache.dubbo.rpc.cluster.Merger (纯文本文件,内容为:customListMerger=com.doudou.demo.merger.CustomListMerger)

CustomListMerger.java

package com.doudou.demo.merger;

import com.alibaba.fastjson2.JSON;
import org.apache.dubbo.rpc.cluster.Merger;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * @title CustomListMerger
 * @description <TODO description class purpose>
 * author zzw
 * version 1.0.0
 * create 2025/4/16 20:37
 **/
public class CustomListMerger<T> implements Merger<T> {
    private Logger logger = LoggerFactory.getLogger(CustomListMerger.class);


    @Override
    public T merge(T... items) {
        logger.info(" -------------------------- items {}", JSON.toJSONString(items));
        return items[0];
    }
}

org.apache.dubbo.rpc.cluster.Merger

customListMerger=com.doudou.demo.merger.CustomListMerger
@DubboReference(group = "*", merger = "true", methods = @Method(name = "sayHello", merger = "customListMerger"))
private DemoService demoService;

注册中心扩展

扩展说明

负责服务的注册与发现

扩展接口
  • org.apache.dubbo.registry.RegistryFactory
  • org.apache.dubbo.registry.Registry
扩展配置
<!-- 定义注册中心 -->
<dubbo:registry id="xxx1" address="xxx://ip:port" />
<!-- 引用注册中心。如果没有配置registry属性,将在ApplicationContext中自动扫描registry配置 -->
<dubbo:service registry="xxx1" />
<!-- 引用注册中心缺省值,当<dubbo:service>没有配置registry时,使用此配置 -->
<dubbo:provider registry="xxx1" />
扩展

RegistryFactory.java:

import java.net.URL;

public interface RegistryFactory {
    /**
     * 连接注册中心
     *
     * 连接注册中心需处理契约:
     * 1. 当设置check=false时表示不检查连接,否则连接不上时抛出异常。
     * 2. 支持URL上的username:password权限认证。
     * 3. 支持backup=10.20.111.10备选注册中心集群地址。
     * 4. 支持file=registry.cache本地磁盘文件缓存。
     * 5. 支持timeout=1000请求超时设置。
     * 6. 支持session=60000会话超时或过期设置。
     *
     * @param url 注册中心地址,不允许为空
     * @return 注册中心引用,总不返回空
     */
    Registry getRegistry(URL url);
}

RegistryService.java:

ublic interface RegistryService { // Registry extends RegistryService 
    /**
     * 注册服务.
     * 
     * 注册需处理契约:<br>
     * 1. 当URL设置了check=false时,注册失败后不报错,在后台定时重试,否则抛出异常。<br>
     * 2. 当URL设置了dynamic=false参数,则需持久存储,否则,当注册者出现断电等情况异常退出时,需自动删除。<br>
     * 3. 当URL设置了category=overrides时,表示分类存储,缺省类别为providers,可按分类部分通知数据。<br>
     * 4. 当注册中心重启,网络抖动,不能丢失数据,包括断线自动删除数据。<br>
     * 5. 允许URI相同但参数不同的URL并存,不能覆盖。<br>
     * 
     * @param url 注册信息,不允许为空,如:dubbo://10.20.153.10/com.alibaba.foo.BarService?version=1.0.0&application=kylin
     */
    void register(URL url);
 
    /**
     * 取消注册服务.
     * 
     * 取消注册需处理契约:<br>
     * 1. 如果是dynamic=false的持久存储数据,找不到注册数据,则抛IllegalStateException,否则忽略。<br>
     * 2. 按全URL匹配取消注册。<br>
     * 
     * @param url 注册信息,不允许为空,如:dubbo://10.20.153.10/com.alibaba.foo.BarService?version=1.0.0&application=kylin
     */
    void unregister(URL url);
 
    /**
     * 订阅服务.
     * 
     * 订阅需处理契约:<br>
     * 1. 当URL设置了check=false时,订阅失败后不报错,在后台定时重试。<br>
     * 2. 当URL设置了category=overrides,只通知指定分类的数据,多个分类用逗号分隔,并允许星号通配,表示订阅所有分类数据。<br>
     * 3. 允许以interface,group,version,classifier作为条件查询,如:interface=com.alibaba.foo.BarService&version=1.0.0<br>
     * 4. 并且查询条件允许星号通配,订阅所有接口的所有分组的所有版本,或:interface=*&group=*&version=*&classifier=*<br>
     * 5. 当注册中心重启,网络抖动,需自动恢复订阅请求。<br>
     * 6. 允许URI相同但参数不同的URL并存,不能覆盖。<br>
     * 7. 必须阻塞订阅过程,等第一次通知完后再返回。<br>
     * 
     * @param url 订阅条件,不允许为空,如:consumer://10.20.153.10/com.alibaba.foo.BarService?version=1.0.0&application=kylin
     * @param listener 变更事件监听器,不允许为空
     */
    void subscribe(URL url, NotifyListener listener);
 
    /**
     * 取消订阅服务.
     * 
     * 取消订阅需处理契约:<br>
     * 1. 如果没有订阅,直接忽略。<br>
     * 2. 按全URL匹配取消订阅。<br>
     * 
     * @param url 订阅条件,不允许为空,如:consumer://10.20.153.10/com.alibaba.foo.BarService?version=1.0.0&application=kylin
     * @param listener 变更事件监听器,不允许为空
     */
    void unsubscribe(URL url, NotifyListener listener);
 
    /**
     * 查询注册列表,与订阅的推模式相对应,这里为拉模式,只返回一次结果。
     * 
     * @see org.apache.dubbo.registry.NotifyListener#notify(List)
     * @param url 查询条件,不允许为空,如:consumer://10.20.153.10/com.alibaba.foo.BarService?version=1.0.0&application=kylin
     * @return 已注册信息列表,可能为空,含义同{@link org.apache.dubbo.registry.NotifyListener#notify(List<URL>)}的参数。
     */
    List<URL> lookup(URL url);

NotifyListener.java:

public interface NotifyListener { 
    /**
     * 当收到服务变更通知时触发。
     * 
     * 通知需处理契约:<br>
     * 1. 总是以服务接口和数据类型为维度全量通知,即不会通知一个服务的同类型的部分数据,用户不需要对比上一次通知结果。<br>
     * 2. 订阅时的第一次通知,必须是一个服务的所有类型数据的全量通知。<br>
     * 3. 中途变更时,允许不同类型的数据分开通知,比如:providers, consumers, routes, overrides,允许只通知其中一种类型,但该类型的数据必须是全量的,不是增量的。<br>
     * 4. 如果一种类型的数据为空,需通知一个empty协议并带category参数的标识性URL数据。<br>
     * 5. 通知者(即注册中心实现)需保证通知的顺序,比如:单线程推送,队列串行化,带版本对比。<br>
     * 
     * @param urls 已注册信息列表,总不为空,含义同{@link org.apache.dubbo.registry.RegistryService#lookup(URL)}的返回值。
     */
    void notify(List<URL> urls);
 
}
已知扩展
  • org.apache.dubbo.registry.nacos.NacosRegistryFactory
  • org.apache.dubbo.registry.zookeeper.ZookeeperRegistryFactory
  • org.apache.dubbo.registry.multicast.MulticastRegistryFactory

监控中心扩展

扩展说明

负责服务调用次数和调用时间的监控

扩展接口
  • org.apache.dubbo.monitor.MonitorFactory
  • org.apache.dubbo.monitor.Monitor
扩展配置
<!-- 定义监控中心 -->
<dubbo:monitor address="xxx://ip:port" />
已知扩展

org.apache.dubbo.monitor.dubbo.DubboMonitorFactory

动态代理扩展

扩展说明

Invoker接口转换成业务接口。

扩展接口

org.apache.dubbo.rpc.ProxyFactory

扩展配置
<dubbo:protocol proxy="xxx"/>
<!-- 缺省值配置,当<dubbo:protocol>没有配置proxy属性时,使用此配置 -->
<dubbo:provider proxy="xxx"/>
已知扩展
  • org.apache.dubbo.rpc.proxy.jdk.JdkProxyFactory
    • 基于JDK原生动态代理,兼容性更强
  • org.apache.dubbo.rpc.proxy.javassist.JavassistProxyFactory
    • 基于字节码生成,性能更高
扩展实现
package com.doudou.demo.proxy;

import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.extension.Activate;
import org.apache.dubbo.rpc.*;
import org.apache.dubbo.rpc.model.ServiceModel;
import org.apache.dubbo.rpc.proxy.AbstractProxyFactory;
import org.apache.dubbo.rpc.proxy.AbstractProxyInvoker;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.MDC;

import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.UUID;

@Activate(order = -10000) // 高优先级激活扩展
public class TracingProxyFactory extends AbstractProxyFactory {

  private static final Logger logger = LoggerFactory.getLogger(TracingProxyFactory.class);
  private static final String TRACE_ID_KEY = "traceId";


  // 消费者端代理增强
  @SuppressWarnings("unchecked")
  @Override
  public <T> T getProxy(Invoker<T> invoker, Class<?>[] types) {
    Class<?> interfaceClass = invoker.getInterface();
    return (T) Proxy.newProxyInstance(
            interfaceClass.getClassLoader(),
            new Class[]{interfaceClass},
            (proxy, method, args) -> {
              RpcContext clientContext = RpcContext.getClientAttachment();
              String traceId = clientContext.getAttachment(TRACE_ID_KEY);

              // 生成或透传 traceId
              if (traceId == null) {
                traceId = generateTraceId(); // 自定义生成规则‌:ml-citation{ref="3,5" data="citationList"}
                clientContext.setAttachment(TRACE_ID_KEY, traceId);
              }
              logger.info("traceId : {}", traceId);
              MDC.put(TRACE_ID_KEY, traceId); // 绑定到日志上下文‌:ml-citation{ref="7,8" data="citationList"}

              logger.info("[Dubbo-Consumer] {}.{} args={}",
                      interfaceClass.getSimpleName(), method.getName(), args);

              long start = System.currentTimeMillis();
              try {
                URL invokerUrl = invoker.getUrl();
                ServiceModel serviceModel = invokerUrl.getServiceModel();
                String protocolServiceKey = invokerUrl.getProtocolServiceKey();
                RpcInvocation rpcInvocation = new RpcInvocation(serviceModel, method.getName(),
                        invoker.getInterface().getName(), protocolServiceKey, method.getParameterTypes(), args);

                Object result = invoker.invoke(rpcInvocation).recreate();
                logger.info("[Dubbo-Consumer] {}.{} return={}",
                        interfaceClass.getSimpleName(), method.getName(), result);
                return result;
              } catch (Exception e) {
                logger.error("[Dubbo-Consumer] {}.{} error={}",
                        interfaceClass.getSimpleName(), method.getName(), e.getMessage(), e);
                throw e;
              } finally {
                logger.debug("[Dubbo-Consumer] {}.{} cost={}ms",
                        interfaceClass.getSimpleName(), method.getName(),
                        System.currentTimeMillis() - start);
                MDC.remove(TRACE_ID_KEY); // 清理上下文‌:ml-citation{ref="7,8" data="citationList"}
              }
            }
    );
  }

  // 服务提供者端 Invoker 增强
  @Override
  public <T> Invoker<T> getInvoker(T proxy, Class<T> type, URL url) {
    return new AbstractProxyInvoker<T>(proxy, type, url) {
      @Override
      protected Object doInvoke(T proxy, String methodName,
                                Class<?>[] paramTypes, Object[] args) throws Throwable {
        Method method = proxy.getClass().getMethod(methodName, paramTypes);
        RpcContext serverContext = RpcContext.getServerAttachment();
        String traceId = serverContext.getAttachment(TRACE_ID_KEY);
        logger.info("traceId : {}", traceId);
        MDC.put(TRACE_ID_KEY, traceId); // 透传 traceId:ml-citation{ref="5,8" data="citationList"}

        logger.info("[Dubbo-Provider] {}.{} args={}",
                type.getSimpleName(), methodName, args);

        long start = System.currentTimeMillis();
        try {
          Object result = method.invoke(proxy, args);
          logger.info("[Dubbo-Provider] {}.{} return={}",
                  type.getSimpleName(), methodName, result);
          return result;
        } catch (Exception e) {
          logger.error("[Dubbo-Provider] {}.{} error={}",
                  type.getSimpleName(), methodName, e.getMessage(), e);
          throw e;
        } finally {
          logger.debug("[Dubbo-Provider] {}.{} cost={}ms",
                  type.getSimpleName(), methodName,
                  System.currentTimeMillis() - start);
          MDC.remove(TRACE_ID_KEY); // 清理上下文‌:ml-citation{ref="7,8" data="citationList"}
        }
      }
    };
  }

  // TraceId 生成规则(UUID 精简版)
  private String generateTraceId() {
    return UUID.randomUUID().toString().replace("-", "").substring(0, 16);
  }
}

META-INF/dubbo/org.apache.dubbo.rpc.ProxyFactory

tracing=com.doudou.demo.proxy.TracingProxyFactory
@DubboReference(proxy = "tracing")
private DemoService demoService;

@DubboService(proxy = "tracing")
public class DemoServiceImpl implements DemoService {}

或全局配置

dubbo:
  provider:
    proxy: tracing
---
dubbo:
  consumer:
    proxy: tracing

Readiness 就绪探针

扩展说明

扩展应用就绪的监测点。
Readiness 探针用于检测容器是否已准备好接收外部请求。
当探针检查失败时,Pod 的 IP 地址会从关联 Service 的 Endpoints 列表中移除,确保流量不会转发到未就绪的容器实例‌。
确保容器完成初始化(如依赖服务连接、配置加载、数据预热等)后才开放服务请求,避免因未就绪实例处理请求导致业务异常‌

扩展接口

org.apache.dubbo.qos.probe.ReadinessProbe

扩展配置

Dubbo QOS ready命令自动发现

已知扩展
  • org.apache.dubbo.qos.probe.impl.ProviderReadinessProbe
  • org.apache.dubbo.qos.probe.impl.DeployerReadinessProbe
扩展实例

DatabaseReadinessProbe.java

package com.doudou.demo.readiness;

import org.apache.dubbo.qos.probe.ReadinessProbe;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * @title DatabaseReadinessProbe
 * @description 验证数据库连接池是否可用,防止因连接泄漏或数据库宕机导致服务不可用。
 * author zzw
 * version 1.0.0
 * create 2025/4/20 18:08
 **/
public class DatabaseReadinessProbe implements ReadinessProbe {
    private Logger logger = LoggerFactory.getLogger(DatabaseReadinessProbe.class);
    @Override
    public boolean check() {
        logger.info("DatabaseReadinessProbe check");
        // 自定义实现
        return false;
    }
}

RedisHealthReadinessProbe.java

package com.doudou.demo.readiness;

import org.apache.dubbo.qos.probe.ReadinessProbe;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * @title RedisHealthProbe
 * @description 确保 Redis 集群连接正常,避免缓存服务不可用影响业务逻辑。
 * author zzw
 * version 1.0.0
 * create 2025/4/20 18:12
 **/
public class RedisHealthReadinessProbe implements ReadinessProbe {
    private Logger logger = LoggerFactory.getLogger(RedisHealthReadinessProbe.class);

    @Override
    public boolean check() {
        logger.info("Redis health check");
        // 自定义实现
        return false;
    }
}

/META-INF/dubbo/org.apache.dubbo.qos.probe.ReadinessProbe

dbCheck=com.doudou.demo.readiness.DatabaseReadinessProbe
redisCheck=com.doudou.demo.readiness.RedisHealthReadinessProbe

application.properties

dubbo.application.readiness-probe: dbCheck,redisCheck

Startup 启动探针

扩展说明

扩展应用启动的监测点

扩展接口

org.apache.dubbo.qos.probe.StartupProbe

扩展配置

Dubbo QOS startup命令自动发现

已知扩展

org.apache.dubbo.qos.probe.impl.DeployerStartupProbe

编译器扩展

扩展说明

Java代码编译器,用于动态生成字节码,加速调用

扩展接口

org.apache.dubbo.common.compiler.Compiler

扩展配置

自动加载

已知扩展
  • org.apache.dubbo.common.compiler.support.JavassistCompiler
  • org.apache.dubbo.common.compiler.support.JdkCompiler

配置中心扩展

设计目的

配置中心的核心功能是作为 Key-Value 存储,Dubbo 框架告知配置中心其关心的 key,配置中心返回该key对应的 value 值。

按照应用场景划分,配置中心在 Dubbo 框架中主要承担以下职责:

  • 作为外部化配置中心,即存储 dubbo.properties 配置文件,此时,key 值通常为文件名如 dubbo.properties,value 则为配置文件内容。
  • 存储单个配置项,如各种开关项、常量值等。
  • 存储服务治理规则,此时key通常按照 “服务名+规则类型” 的格式来组织,而 value 则为具体的治理规则。

为了进一步实现对 key-value 的分组管理,Dubbo 的配置中心还加入了 namespace、group 的概念,这些概念在很多专业的第三方配置中心中都有体现,通常情况下,namespace 用来隔离不同的租户,group 用来对同一租户的key集合做分组。

扩展接口
  • org.apache.dubbo.common.config.configcenter.DynamicConfigurationFactory
  • org.apache.dubbo.common.config.configcenter.DynamicConfiguration
已知扩展
  • org.apache.dubbo.configcenter.support.zookeeper.ZookeeperDynamicConfigurationFactory
  • org.apache.dubbo.configcenter.support.nacos.NacosDynamicConfigurationFactory
  • org.apache.dubbo.configcenter.support.apollo.ApolloDynamicConfigurationFactory
  • org.apache.dubbo.common.config.configcenter.file.FileSystemDynamicConfigurationFactory

元数据中心扩展

扩展接口
  • org.apache.dubbo.metadata.report.MetadataReportFactory
  • org.apache.dubbo.metadata.report.MetadataReport
已知扩展
  • org.apache.dubbo.metadata.store.nacos.NacosMetadataReportFactory
  • org.apache.dubbo.metadata.store.redis.RedisMetadataReportFactory
  • org.apache.dubbo.metadata.store.zookeeper.ZookeeperMetadataReportFactory

消息派发扩展

扩展说明

通道消息派发器,用于指定线程池模型

扩展接口

org.apache.dubbo.remoting.Dispatcher

扩展配置
<dubbo:protocol dispatcher="xxx" />
<!-- 缺省值设置,当<dubbo:protocol>没有配置dispatcher属性时,使用此配置 -->
<dubbo:provider dispatcher="xxx" />
已知扩展
  • org.apache.dubbo.remoting.transport.dispatcher.all.AllDispatcher
  • org.apache.dubbo.remoting.transport.dispatcher.direct.DirectDispatcher.dispatch
  • org.apache.dubbo.remoting.transport.dispatcher.message.MessageOnlyDispatcher.dispatch
  • org.apache.dubbo.remoting.transport.dispatcher.execution.ExecutionDispatcher
  • org.apache.dubbo.remoting.transport.dispatcher.connection.ConnectionOrderedDispatcher

线程池扩展

扩展说明

服务提供方线程池实现策略,当服务器收到一个请求时,需要在线程池中创建一个线程去执行服务提供方业务逻辑。

扩展接口

org.apache.dubbo.common.threadpool.ThreadPool

扩展配置
<dubbo:protocol threadpool="xxx" />
<!-- 缺省值设置,当<dubbo:protocol>没有配置threadpool时,使用此配置 -->
<dubbo:provider threadpool="xxx" />
已知扩展
  • org.apache.dubbo.common.threadpool.support.limited.LimitedThreadPool
  • org.apache.dubbo.common.threadpool.support.fixed.FixedThreadPool
  • org.apache.dubbo.common.threadpool.support.eager.EagerThreadPool
  • org.apache.dubbo.common.threadpool.support.cached.CachedThreadPool

序列化扩展

扩展说明

将对象转成字节流,用于网络传输,以及将字节流转为对象,用于在收到字节流数据后还原成对象。

扩展接口
  • org.apache.dubbo.common.serialize.Serialization
  • org.apache.dubbo.common.serialize.ObjectInput
  • org.apache.dubbo.common.serialize.ObjectOutput
扩展配置
<!-- 协议的序列化方式 -->
<dubbo:protocol serialization="xxx" />
<!-- 缺省值设置,当<dubbo:protocol>没有配置serialization时,使用此配置 -->
<dubbo:provider serialization="xxx" />
已知扩展
  • org.apache.dubbo.common.serialize.hessian2.Hessian2Serialization
  • org.apache.dubbo.common.serialize.java.JavaSerialization
  • org.apache.dubbo.common.serialize.nativejava.NativeJavaSerialization
  • org.apache.dubbo.common.serialize.fastjson2.FastJson2Serialization
  • org.apache.dubbo.common.serialize.java.CompactedJavaSerialization

网络传输扩展

扩展说明

远程通讯的服务器及客户端传输实现。

扩展接口
  • org.apache.dubbo.remoting.Transporter
  • org.apache.dubbo.remoting.RemotingServer
  • org.apache.dubbo.remoting.Client
扩展配置
<!-- 服务器和客户端使用相同的传输实现 -->
<dubbo:protocol transporter="xxx" /> 
<!-- 服务器和客户端使用不同的传输实现 -->
<dubbo:protocol server="xxx" client="xxx" /> 
<!-- 缺省值设置,当<dubbo:protocol>没有配置transporter/server/client属性时,使用此配置 -->
<dubbo:provider transporter="xxx" server="xxx" client="xxx" />
已知扩展
  • org.apache.dubbo.remoting.transport.netty4.NettyTransporter

信息交换扩展

扩展说明

基于传输层之上,实现Request-Response信息交换语义。

扩展接口
  • org.apache.dubbo.remoting.exchange.Exchanger
  • org.apache.dubbo.remoting.exchange.ExchangeServer
  • org.apache.dubbo.remoting.exchange.ExchangeClient
扩展配置
<dubbo:protocol exchanger="xxx" />
<!-- 缺省值设置,当<dubbo:protocol>没有配置exchanger属性时,使用此配置 -->
<dubbo:provider exchanger="xxx" />
已知扩展

org.apache.dubbo.remoting.exchange.support.header.HeaderExchanger

对等网络节点组网器扩展

扩展说明

对等网络节点组网器

扩展接口

com.alibaba.dubbo.container.page.PageHandler

扩展配置
<dubbo:protocol page="xxx,yyy" />
<!-- 缺省值设置,当<dubbo:protocol>没有配置page属性时,使用此配置 -->
<dubbo:provider page="xxx,yyy" />
已知扩展
  • com.alibaba.dubbo.container.page.pages.StatusPageHandler
  • com.alibaba.dubbo.container.page.pages.HomePageHandler
  • com.alibaba.dubbo.container.page.pages.LogPageHandler
  • com.alibaba.dubbo.container.page.pages.SystemPageHandler

Telnet 命令扩展

扩展说明

所有服务均支持telnet访问,用于人工干预

扩展接口

org.apache.dubbo.remoting.telnet.TelnetHandler

扩展配置
<dubbo:protocol telnet="xxx,yyy" />
<!-- 缺省值设置,当<dubbo:protocol>没有配置telnet属性时,使用此配置 -->
<dubbo:provider telnet="xxx,yyy" />
已知扩展
  • org.apache.dubbo.remoting.telnet.support.command.ClearTelnetHandler
  • org.apache.dubbo.remoting.telnet.support.command.ExitTelnetHandler
  • org.apache.dubbo.remoting.telnet.support.command.HelpTelnetHandler
  • org.apache.dubbo.remoting.telnet.support.command.StatusTelnetHandler
  • org.apache.dubbo.qos.legacy.ChangeTelnetHandler
  • org.apache.dubbo.qos.legacy.TraceTelnetHandler

状态检查扩展

扩展说明

检查服务依赖各种资源的状态,此状态检查可同时用于telnet的status命令和hosting的status页面。

扩展接口

org.apache.dubbo.common.status.StatusChecker

扩展配置
<dubbo:protocol status="xxx,yyy" />
<!-- 缺省值设置,当<dubbo:protocol>没有配置status属性时,使用此配置 -->
<dubbo:provider status="xxx,yyy" />
已知扩展
  • org.apache.dubbo.common.status.support.MemoryStatusChecker
  • org.apache.dubbo.common.status.support.LoadStatusChecker
  • org.apache.dubbo.rpc.protocol.dubbo.status.ServerStatusChecker
  • org.apache.dubbo.rpc.protocol.dubbo.status.ThreadPoolStatusChecker
  • org.apache.dubbo.registry.status.RegistryStatusChecker
  • org.apache.dubbo.config.spring.status.SpringStatusChecker
  • org.apache.dubbo.config.spring.status.DataSourceStatusChecker

缓存扩展

扩展说明

用请求参数作为key,缓存返回结果

扩展接口

org.apache.dubbo.cache.CacheFactory

扩展配置
<dubbo:service cache="lru" />
<!-- 方法级缓存 -->
<dubbo:service><dubbo:method cache="lru" /></dubbo:service> 
<!-- 缺省值设置,当<dubbo:service>没有配置cache属性时,使用此配置 -->
<dubbo:provider cache="xxx,yyy" /> 
已知扩展
  • org.apache.dubbo.cache.support.lfu.LfuCacheFactory
  • org.apache.dubbo.cache.support.lru.LruCacheFactory
  • org.apache.dubbo.cache.support.jcache.JCacheFactory
  • org.apache.dubbo.cache.support.threadlocal.ThreadLocalCacheFactory

验证扩展

扩展说明

参数验证扩展点。

扩展接口

org.apache.dubbo.validation.Validation

扩展配置
<dubbo:service validation="xxx,yyy" />
<!-- 缺省值设置,当<dubbo:service>没有配置validation属性时,使用此配置 -->
<dubbo:provider validation="xxx,yyy" />
已知扩展
  • org.apache.dubbo.validation.support.jvalidation.JValidation
  • org.apache.dubbo.validation.support.jvalidation.JValidationNew

日志适配扩展

扩展说明

日志输出适配扩展点

扩展接口

org.apache.dubbo.common.logger.LoggerAdapter

扩展配置
<dubbo:application logger="xxx" />

-Ddubbo:application.logger=xxx
已知实例
  • org.apache.dubbo.common.logger.slf4j.Slf4jLoggerAdapter
  • org.apache.dubbo.common.logger.log4j2.Log4j2LoggerAdapter
  • org.apache.dubbo.common.logger.jcl.JclLoggerAdapter
  • org.apache.dubbo.common.logger.jdk.JdkLoggerAdapter
  • org.apache.dubbo.common.logger.log4j.Log4jLoggerAdapter

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2339556.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【Rust 精进之路之第2篇-初体验】安装、配置与 Hello Cargo:踏出 Rust 开发第一步

系列&#xff1a; Rust 精进之路&#xff1a;构建可靠、高效软件的底层逻辑 **作者&#xff1a;**码觉客 发布日期&#xff1a; 2025-04-20 引言&#xff1a;磨刀不误砍柴工&#xff0c;装备先行&#xff01; 在上一篇文章中&#xff0c;我们一起探索了 Rust 诞生的缘由&…

腾讯旗下InstantCharacter框架正式开源 可高度个性化任何角色

目前基于学习的主题定制方法主要依赖于 U-Net 架构&#xff0c;但其泛化能力有限&#xff0c;图像质量也大打折扣。同时&#xff0c;基于优化的方法需要针对特定主题进行微调&#xff0c;这不可避免地会降低文本的可控性。为了应对这些挑战&#xff0c;我们提出了 “即时角色”…

详讲Linux下进程等待

3.进程等待 引言&#xff1a;什么是进程等待 想象有两个小伙伴&#xff0c;一个是 “大强”&#xff08;父进程 &#xff09;&#xff0c;一个是 “小强”&#xff08;子进程 &#xff09;。大强给小强安排了任务&#xff0c;比如去收集一些石头。 …

JBoss + WildFly 本地开发环境完全指南

JBoss WildFly 本地开发环境完全指南 本篇笔记主要实现在本地通过 docker 创建 JBoss 和 WildFly 服务器这一功能&#xff0c;基于红帽的禁制 EAP 版本的重新分发&#xff0c;所以我这里没办法放 JBoss EAP 的 zip 文件。WildFly 是免费开源的版本&#xff0c;可以在红帽官网找…

【网络原理】TCP协议如何实现可靠传输(确认应答和超时重传机制)

目录 一. TCP协议 二. 确定应答 三. 超时重传 一. TCP协议 1&#xff09;端口号 源端口号&#xff1a;发送方端口号目的端口号&#xff1a;接收方端口号 16位&#xff08;2字节&#xff09;端口号&#xff0c;可以表示的范围&#xff08;0~65535&#xff09; 源端口和目的…

【国家能源集团生态协作平台-注册/登录安全分析报告】

前言 由于网站注册入口容易被黑客攻击&#xff0c;存在如下安全问题&#xff1a; 暴力破解密码&#xff0c;造成用户信息泄露短信盗刷的安全问题&#xff0c;影响业务及导致用户投诉带来经济损失&#xff0c;尤其是后付费客户&#xff0c;风险巨大&#xff0c;造成亏损无底洞…

idea中导入从GitHub上克隆下来的springboot项目解决找不到主类的问题

第一步&#xff1a;删除目录下的.idea和target&#xff0c;然后用idea打开 第二步&#xff1a;如果有需要&#xff0c;idea更换jdk版本 原文链接&#xff1a;https://blog.csdn.net/m0_74036731/article/details/146779040 解决方法&#xff08;idea中解决&#xff09;&#…

【AI论文】CLIMB:基于聚类的迭代数据混合自举语言模型预训练

摘要&#xff1a;预训练数据集通常是从网络内容中收集的&#xff0c;缺乏固有的领域划分。 例如&#xff0c;像 Common Crawl 这样广泛使用的数据集并不包含明确的领域标签&#xff0c;而手动整理标记数据集&#xff08;如 The Pile&#xff09;则是一项劳动密集型工作。 因此&…

Linux操作系统--环境变量

目录 基本概念&#xff1a; 常见环境变量&#xff1a; 查看环境变量的方法&#xff1a; 测试PATH 测试HOME 和环境变量相关的命令 环境变量的组织方式&#xff1a;​编辑 通过代码如何获取环境变量 通过系统调用获取或设置环境变量 环境变量通常具有全局属性 基本概念…

Jenkins 多分支管道

如果您正在寻找一个基于拉取请求或分支的自动化 Jenkins 持续集成和交付 (CI/CD) 流水线&#xff0c;本指南将帮助您全面了解如何使用 Jenkins 多分支流水线实现它。 Jenkins 的多分支流水线是设计 CI/CD 工作流的最佳方式之一&#xff0c;因为它完全基于 git&#xff08;源代…

C语言之图像文件的属性

&#x1f31f; 嗨&#xff0c;我是LucianaiB&#xff01; &#x1f30d; 总有人间一两风&#xff0c;填我十万八千梦。 &#x1f680; 路漫漫其修远兮&#xff0c;吾将上下而求索。 图像文件属性提取系统设计与实现 目录 设计题目设计内容系统分析总体设计详细设计程序实现…

LeetCode hot 100—分割等和子集

题目 给你一个 只包含正整数 的 非空 数组 nums 。请你判断是否可以将这个数组分割成两个子集&#xff0c;使得两个子集的元素和相等。 示例 示例 1&#xff1a; 输入&#xff1a;nums [1,5,11,5] 输出&#xff1a;true 解释&#xff1a;数组可以分割成 [1, 5, 5] 和 [11] 。…

高等数学同步测试卷 同济7版 试卷部分 上 做题记录 上册期中同步测试卷 B卷

上册期中同步测试卷 B卷 一、单项选择题(本大题共5小题,每小题3分,总计15分) 1. 2. 3. 4. 5. 由f(2/n), n→∞可知 2/n→0, 即x→0. 二、填空题(本大题共5小题,每小题3分&#xff0c;总计15分) 6. 7. 8. 9. 10. 三、求解下列各题(本大题共5小…

【算法】快速排序、归并排序(非递归版)

目录 一、快速排序&#xff08;非递归&#xff09; 1.原理 2.实现 2.1 stack 2.2 partition(array,left,right) 2.3 pivot - 1 > left 二、归并排序&#xff08;非递归&#xff09; 1.原理 2.实现 2.1 gap 2.1.1 i 2*gap 2.1.2 gap * 2 2.1.3 gap < array.…

【实战中提升自己】内网安全部署之dot1x部署 本地与集成AD域的主流方式(附带MAC认证)

1 dot1x部署【用户名密码认证&#xff0c;也可以解决私接无线AP等功能】 说明&#xff1a;如果一个网络需要通过用户名认证才能访问内网&#xff0c;而认证失败只能访问外网与服务器&#xff0c;可以部署dot1x功能。它能实现的效果是&#xff0c;当内部用户输入正常的…

[matlab]南海地形眩晕图代码

[matlab]南海地形眩晕图代码 请ChatGPT帮写个南海地形眩晕图代码 图片 图片 代码 .rtcContent { padding: 30px; } .lineNode {font-size: 12pt; font-family: "Times New Roman", Menlo, Monaco, Consolas, "Courier New", monospace; font-style: n…

Web安全和渗透测试--day6--sql注入--part 1

场景&#xff1a; win11家庭版&#xff0c;edge浏览器 &#xff0c; sqlin靶场 定义&#xff1a; SQL 注入&#xff08;SQL Injection&#xff09;是一种常见的网络安全攻击方式&#xff0c;攻击者通过在 Web 应用程序中输入恶意的 SQL 代码&#xff0c;绕过应用程序的安全机…

[SpringBoot]快速入门搭建springboot

默认有spring基础&#xff0c;不会一行代码一行代码那么细致地讲。 SpringBoot的作用 Spring Boot是为了简化Spring应用的创建、运行、调试、部署等而出现的。就像我们整个SSM框架时&#xff0c;就常常会碰到版本导致包名对不上、Bean非法参数类型的一系列问题&#xff08;原出…

理解.NET Core中的配置Configuration

什么是配置 .NET中的配置&#xff0c;本质上就是key-value键值对&#xff0c;并且key和value都是字符串类型。 在.NET中提供了多种配置提供程序来对不同的配置进行读取、写入、重载等操作&#xff0c;这里我们以为.NET 的源码项目为例&#xff0c;来看下.NET中的配置主要是有…

MYSQL “Too Many Connections“ 错误解决

1.查询当前连接数 show status like "Threads_connected"; 2.查询数据库最大连接数 show variables like "max_connections" 3.查询所有活动连接 show processlist; 4.根据查询结果观察是否有长时间未被释放的连接 参数解释 : 字段说明id连接的唯一…