当前位置: 首页 > news >正文

dubbo SPI插件扩展点使用

参考: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);@Overridepublic 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);@Overridepublic 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);@Overridepublic 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);}@Overridepublic 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;@Overridepublic 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);@Overridepublic 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);}@Overridepublic 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);@Overridepublic 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);}@Overrideprotected 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 {@Overridepublic <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;@Overridepublic 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);@Overridepublic <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 {@Overridepublic 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);@Overrideprotected <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;@Overridepublic 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);@Overridepublic 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")@Overridepublic <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);// 生成或透传 traceIdif (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 增强@Overridepublic <T> Invoker<T> getInvoker(T proxy, Class<T> type, URL url) {return new AbstractProxyInvoker<T>(proxy, type, url) {@Overrideprotected 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);@Overridepublic 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);@Overridepublic 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

相关文章:

dubbo SPI插件扩展点使用

参考&#xff1a;SPI插件扩展点 Dubbo SPI概述 使用IoC容器帮助管理组件的生命周期、依赖关系注入等是很多开发框架的常用设计&#xff0c;Dubbo中内置了一个轻量版本的IoC容器&#xff0c;用来管理框架内部的插件&#xff0c;实现包括插件实例化、生命周期、依赖关系自动注入…...

P8512 [Ynoi Easy Round 2021] TEST_152 Solution

Description 有一序列 c ( c 1 , c 2 , ⋯ , c m ) c(c_1,c_2,\cdots,c_m) c(c1​,c2​,⋯,cm​) 和 n n n 个三元组 ( l i , r i , v i ) (l_i,r_i,v_i) (li​,ri​,vi​). 回答 q q q 次形如 ( L , R ) (L,R) (L,R) 的询问&#xff0c;具体如下&#xff1a; 将 c c …...

开源项目FastAPI-MCP:一键API转换MCP服务

在当今AI开发的世界中,应用程序与AI模型之间的无缝集成至关重要。 模型上下文协议(Model Context Protocol, MCP)通过允许AI模型访问外部工具和数据源,弥合了这一差距。 FastAPI MCP是一个强大的工具,它可以通过最少的配置将您现有的FastAPI端点转换为MCP兼容的工具。 本…...

8、constexpr if、inline、类模版参数推导、lambda的this捕获---c++17

一、constexpr if&#xff1a;编译时条件分支 作用&#xff1a;在模板编程中&#xff0c;根据条件在编译时选择不同的代码路径&#xff0c;无需特化版本或复杂SFINAE技巧[替代SFINAE]。[SFINAE将在模版元编程再讲。下个月了。]基本语法 if constexpr (condition) {// 如果 co…...

github新建一个远程仓库并添加了README.md,本地git仓库无法push

1.本地git仓库与远程仓库绑定 2.push时报错&#xff0c;本地的 main 分支落后于远程仓库的 main 分支&#xff08;即远程有更新&#xff0c;但你本地没有&#xff09;&#xff0c;需要拉取远程的仓库--->在merge合并&#xff08;解决冲突&#xff09;--->push 3.但是git …...

贝叶斯分类器:原理、算法与应用详解

内容摘要 本文聚焦贝叶斯分类器&#xff0c;介绍其在各类分类器中分类错误概率最小的特性。详细阐述贝叶斯分类器的基本原理、朴素贝叶斯和半朴素贝叶斯分类器的算法&#xff0c;结合西瓜数据集实例说明朴素贝叶斯的应用。此外&#xff0c;还深入探讨极大似然估计和贝叶斯估计…...

算法篇之单调栈

单调栈算法入门 单调栈是一种特殊的数据结构应用&#xff0c;它的核心在于维护一个栈&#xff0c;使得栈内元素保持单调递增或者单调递减的顺序。这种数据结构在解决很多算法问题时非常有效&#xff0c;例如求数组中每个元素的下一个更大元素、每日温度问题等。 一、单调栈的…...

用python + PIL 实现图片格式转换工具

用python PIL 实现图片格式转换工具 要运行该程序&#xff0c;需要使用第三方库PIL&#xff08;pillow&#xff09;&#xff0c;详情可见https://blog.csdn.net/cnds123/article/details/126141838 格式支持&#xff1a; 支持常见图片格式转换&#xff08;JPEG, PNG, BMP, GIF…...

【数据库】事务

目录 1. 什么是事务&#xff1f; 2. 事务的ACID特性 3. 为什么使用事务&#xff1f; 4. 如何使用事务 4.1 查看支持事务的存储引擎 4.2 语法 4.3 保存点 4.4 自动/手动提交事务 5. 事物的隔离性和隔离级别 5.1 什么是隔离性 5.2 隔离级别 5.3 查看和设置隔离级别 1…...

C++:详解命名空间

目录 前言 一、命名空间是什么&#xff1f; 1.1命名空间域的定义 二、为什么有命名空间&#xff1f; 三、命名空间的用法 总结 前言 主要讲解命名空间是什么&#xff1f;为什么有命名空间&#xff1f;以及它的用法 一、命名空间是什么&#xff1f; 命名空间域&#xff08;nam…...

ClickHouse核心架构设计

列式存储原理与数据压缩 列式存储原理 列式存储 vs 行式存储 特性行式存储&#xff08;如MySQL&#xff09;列式存储&#xff08;ClickHouse&#xff09;数据排列按行连续存储&#xff08;所有字段相邻&#xff09;按列连续存储&#xff08;单列数据紧密排列&#xff09;适用场…...

K8s-Pod详解

Pod介绍 Pod是Kubernetes中能够创建和部署的最小单元&#xff0c;是Kubernetes集群中的一个应用实例&#xff0c;总是部署在同一个节点Node上。&#xff08;程序运行部署在容器中&#xff0c;容器必须存在pod中。pod可以认为是容器的封装&#xff0c;一个pod中可以存在一个或者…...

SSM(SpringMVC+spring+mybatis)整合的步骤以及相关依赖

目录 &#xff08;一&#xff09;导入SSM框架相关的依赖 ①创建一个新的web工程&#xff08;idea2023版&#xff09; ②思考三者之间的联系&#xff0c;回忆依赖 ③在pom.xml文件中引入依赖坐标 &#xff08;二&#xff09;使用注解开发&#xff0c;编写Spring的配置类&am…...

【LeetCode】算法详解#5 ---轮转数组

1.题目介绍 给定一个整数数组 nums&#xff0c;将数组中的元素向右轮转 k 个位置&#xff0c;其中 k 是非负数。 1 < nums.length < 105-231 < nums[i] < 231 - 10 < k < 105 2.解决思路 这道题的解决方法有很多&#xff0c;我这里给大家介绍我使用的方法。…...

LeetCode 打家劫舍+删除并获得点数

题目描述 打家劫舍题目传送门1 删除并获得点数传送门2 思路 这两道题看似毫无关系&#xff0c;但竟然可以用桶数组联系起来&#xff01;&#xff01; 先说打家劫舍这道题 限制条件是不能走相邻的屋&#xff0c;再联想到跳台阶&#xff08;走一格或两格&#xff09;&#x…...

【计量地理学】实验四 主成分分析与莫兰指数

一、实验内容 &#xff08;一&#xff09; 某地区35个城市2004年的7项经济统计指标数据见&#xff08;数据中的“题目1”sheet&#xff09;。 &#xff08;1&#xff09;试用最短距离聚类法对35个城市综合实力进行系统聚类分析&#xff0c;并画出聚类谱系图: 在此次实验内容…...

TDengine 性能监控与调优实战指南(二)

四、TDengine 性能调优实战 4.1 硬件层面优化 硬件是 TDengine 运行的基础&#xff0c;其性能直接影响着 TDengine 的整体表现。在硬件层面进行优化&#xff0c;就如同为高楼大厦打下坚实的地基&#xff0c;能够为 TDengine 的高效运行提供有力支持。 CPU&#xff1a;CPU 作…...

Linux `init 5` 相关命令的完整使用指南

Linux init 5 相关命令的完整使用指南—目录 一、init 系统简介二、init 5 的含义与作用三、不同 Init 系统下的 init 5 行为1. SysVinit&#xff08;如 CentOS 6、Debian 7&#xff09;2. systemd&#xff08;如 CentOS 7、Ubuntu 16.04&#xff09;3. Upstart&#xff08;如 …...

uni-app中map的使用

uni-app中map的使用 一、基本使用步骤 1. 引入 map 组件 在 .vue 文件的 template 中直接使用 <map> 标签&#xff1a; <template><view><map :latitude"latitude" :longitude"longitude" :markers"markers" style&quo…...

备战2025年全国信息素养大赛图形化大赛——绘制雪花

以上题目点击下方地址&#xff0c;可查看答案或者在线编程&#xff5e; 绘制雪花_scratch_少儿编程题库学习中心-嗨信奥https://www.hixinao.com/tiku/scratch/show-5775.html?_shareid3 程序演示可点击下方地址&#xff0c;支持源码和素材获取&#xff0c;方便高效&#xff…...

1Panel - 基于Web的Linux服务器管理工具

本文翻译整理自&#xff1a;https://github.com/1Panel-dev/1Panel 文章目录 一、关于 1Panel相关链接资源关键功能特性 二、安装系统要求安装脚本 三、基本使用&#xff08;快速开始&#xff09;1、快速安装2、访问面板 四、界面展示五、专业版六、安全信息感谢 一、关于 1Pan…...

基于SpringAI Alibaba实现RAG架构的深度解析与实践指南

一、RAG技术概述 1.1 什么是RAG技术 RAG&#xff08;Retrieval-Augmented Generation&#xff09;检索增强生成是一种将信息检索技术与生成式AI相结合的创新架构。它通过以下方式实现智能化内容生成&#xff1a; 知识检索阶段&#xff1a;从结构化/非结构化数据源中检索相关…...

SpringBoot Actuator指标收集:Micrometer与Prometheus集成

文章目录 引言一、Spring Boot Actuator基础二、Micrometer简介与集成三、基本指标收集与配置四、自定义业务指标实现五、与Prometheus集成六、实战案例&#xff1a;API性能监控总结 引言 在现代微服务架构中&#xff0c;监控应用程序的健康状况和性能指标变得至关重要。Sprin…...

Spring Boot 集成 Kafka 及实战技巧总结

Spring Boot 集成 Kafka 及实战技巧总结 一、Spring Boot 集成 Kafka 添加依赖 <dependency><groupId>org.springframework.kafka</groupId><artifactId>spring-kafka</artifactId> </dependency>配置 Kafka 在 application.yml 中配置生产…...

LeetCode hot 100—分割等和子集

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

JUC复习及面试题学习

资源来自沉默王二、小林coding、竹子爱熊猫、代码随想录 一、JUC 1、进程与线程 进程是对运行程序的封装&#xff0c;是系统进行资源调度和分配的最小单位。 线程是进程的子任务&#xff0c;是CPU调度分配的基本单位 不同的进程之间很难数据共享&#xff0c;同进程下的不同线…...

The_Planets_Earth靶场笔记(VulnHub)

环境说明&#xff1a; kali地址&#xff1a;192.168.144.128 靶机地址&#xff1a;192.168.144.181 靶机网卡改为NAT模式。 靶机下载地址&#xff1a; https://download.vulnhub.com/theplanets/Earth.ova 一.信息收集&#xff1a; 1.主机探测&#xff1a; 使用如下命令…...

dawgctf 2025 writeup

dawgctf 2025 writeup 赛事信息pwnJust Parry Lol miscDont Touch My FoneThe BirdsMystery Signal IinternsProjectSuspicious scriptSpectral SecretsCaddyshack forensicsKeeping on ScheduleJust Packets CryptoCipher For Good osintEs ist alles in ButterLook Long and …...

机器学习(神经网络基础篇)——个人理解篇6(概念+代码)———参数优化篇

1 在声明一个类中&#xff0c;构建一个属于类的函数&#xff0c;前面为什要加上“self”&#xff1f; 就像下面这一串代码&#xff1a; class TwoLayerNet:def __init__(self, input_size, hidden_size, output_size,weight_init_std0.01):# 初始化权重self.params {}self.p…...

AI速读:解锁LLM下Game Agent的奇妙世界

在 AI 浪潮中&#xff0c;大语言模型&#xff08;LLMs&#xff09;正重塑游戏智能体格局。想知道基于 LLMs 的游戏智能体如何运作&#xff0c;在各类游戏中有何惊艳表现&#xff0c;未来又将走向何方&#xff1f; 大型语言模型&#xff08;LLMs&#xff09;的兴起为游戏智能体的…...

个人所得税

文章目录 一、名词解释二、个人所得税计算方法 (举例)1.累计预扣预缴应纳税所得额、本期应预扣预缴税额2.个人所得税预扣率表一3.个人所得税计算举例 三、专项附加扣除政策介绍四、年度汇算清缴政策介绍五、常见问答 一、名词解释 累计预扣法是指扣缴义务人在一个纳税年度内预…...

DEA-Net:基于细节增强卷积和内容引导注意力的单图像去雾

IEEE TIP 2024 | DEA-Net&#xff1a;基于细节增强卷积和内容引导注意力的单图像去雾 DEA-Net: Single image dehazing based on detail-enhanced convolution and content-guided attention paper name: DEA-Net: Single image dehazing based on detail-enhanced convolutio…...

StringEscapeUtils:给你的字符串穿上“防弹衣“——转义工具类深度解析

各位代码勇士们好&#xff01;今天我们要聊的是Apache Commons Lang3中的StringEscapeUtils工具类。如果说StringUtils是瑞士军刀&#xff0c;那StringEscapeUtils就是你的字符串保镖&#xff0c;专门负责在各种危险场合保护你的字符串安全&#xff01; 一、为什么需要字符串转…...

Sharding-JDBC 系列专题 - 第二篇:广播表(Broadcast Tables)

Sharding-JDBC 系列专题 - 第二篇:广播表(Broadcast Tables) 本系列专题旨在帮助开发者深入掌握 Sharding-JDBC,一个轻量级的分布式数据库中间件。本篇作为系列的第二篇文章,将详细讲解 广播表(Broadcast Tables) 的概念、配置、使用场景、工作原理以及实战案例。广播表…...

PySide6 GUI 学习笔记——常用类及控件使用方法(常用类矩阵QRect)

文章目录 一、构造与初始化方法二、坐标与尺寸获取三、坐标与尺寸设置四、几何运算方法五、移动与调整方法六、状态判断方法七、类型转换方法八、操作符重载九、静态方法十、特殊方法附录方法速查表注意的问题交集和并集图解 &#x1f4d8; PySide6.QtCore.QRect 使用整数精度定…...

常见的页面报错

目录 1、 405报错&#xff0c;方法不允许 2、 404报错&#xff0c;未找到资源 404报错的两种可能&#xff1a; 1、前端找不到后端的资源&#xff1a; 2、后端找不到返回的资源&#xff1a; 3、 400报错&#xff0c;错误的请求 后端返回的数据类型与前端不匹配 前端传递的参…...

人机共跑,马拉松人型机器人同跑

马拉松比赛对人形机器人来说&#xff0c;是一场对硬件极限的测试&#xff0c;涉及机械、传感器、能源管理等多个方面。用户问的是硬件方面的考察和改进&#xff0c;这意味着我的回答需要聚焦于硬件性能&#xff0c;而不是算法或软件的优化。 对人形机器人硬件的考研 机械结构与…...

ES6 第一讲 变量定义 堆与栈 字符串的扩展和数值型的扩展

文章目录 1.ES6变量定义2.ES6堆和栈3.字符串的扩展3.1 模板字符串3.2 判断是否以指定的字符串开头或结尾3.3 字符串重复输出3.4 填充方法3.5 去除前后字符串空格3.6 返回参数指定位置的字符 4. 数值型的扩展4.1 二进制0B 八进制0O4.2 判断是否是一个无穷大的数字 &#xff08;判…...

Linux 动、静态库的实现

前言&#xff1a;当我们写了一段代码实现了一个方法&#xff0c;如果我们不想把方法的实现过程暴露给别人看&#xff0c;可以把代码打包成一个库&#xff0c;其中形成后缀为.a的是静态库&#xff0c;后缀为.so的为动态库&#xff1b;当别人想使用你的方法时&#xff0c;把打包好…...

linux多线(进)程编程——(9)信号量(二)

前言 上一篇文章我们讲解了信号量的基础用法&#xff0c;这一篇文章我们承接上面的内容&#xff0c;给大家进一步提升对信号量的理解。如果没有看过上一篇文章&#xff0c;请大家移步linux多线(进)程编程——&#xff08;9&#xff09;信号量&#xff08;一&#xff09; 案例…...

编码器---正交编码器

一、正交编码器定义与核心作用 正交编码器&#xff08;Orthogonal Encoder&#xff09;&#xff0c;又称增量式编码器&#xff0c;是一种通过输出两路相位差90的脉冲信号&#xff08;A相、B相&#xff09;来测量旋转角度、速度和方向的传感器。其核心优势是通过A/B相的脉冲顺序…...

【HDFS入门】HDFS故障排查与案例分析:从日志分析到实战解决

目录 1 HDFS故障排查概述 2 三大常见故障类型解析 2.1 块丢失问题处理流程 2.2 副本不足问题架构 2.3 DataNode无法启动诊断 3 日志分析实战技巧 3.1 NameNode日志分析框架 3.2 DataNode日志分析流程 4.1 实战案例分析 4.2 集群性能突然下降 4.2 数据读写异常处理 …...

爆肝整理!Stable Diffusion的完全使用手册(二)

继续介绍Stable Diffusion的文生图界面功能。 往期文章详见: 爆肝整理&#xff01;Stable Diffusion的完全使用手册&#xff08;一&#xff09; 下面接着对SD的文生图界面的进行详细的介绍。本期介绍文生图界面的截图2&#xff0c;主要包含生成模块下的采用方法、调度类型、迭…...

经典算法 表达式求值

表达式求值 问题描述 给你一个只包含、-、*、/、0、1、2、3、4、5、6、7、8、9的字符串求出该字符串所代表的表达式的值。这里的除法&#xff0c;为了简便&#xff0c;为整数除法&#xff0c;所以答案一定也是一个整数。保证0不作被除数。 示例输入 (16*(141))((13)*(74))*…...

【Java】接口interface学习

参考资料:&#xff1a;黑马程序员入门到飞起上 1 概述 在学习完抽象类后&#xff0c;我们了解到抽象类中既可以包含抽象方法&#xff0c;也能有普通方法、构造方法以及成员变量等。而接口则是一种更为彻底的抽象形式。在JDK7及之前的版本中&#xff0c;接口内全部为抽象方法&…...

数据结构实验7.1:二叉树的遍历

文章目录 一,实验目的二,实验描述三,基本要求四,算法分析五,实验操作六,示例代码七,运行效果一,实验目的 深入理解树与二叉树的基本概念,包括节点、度、层次、深度等,清晰区分二叉树与一般树的结构特点,为后续学习和应用打下坚实基础。熟练掌握用递归方法实现二叉树…...

seata db模式,nacos注册中心,spring boot ,spring cloud ,jdk1.8 完成的配置步骤

1. 环境准备 确保以下环境已经安装并正常运行&#xff1a; JDK 1.8MySQL&#xff08;或其他支持的数据库&#xff09;Nacos Server&#xff08;用于注册中心和配置中心&#xff09;Seata Server 2. 配置 Seata Server (1) 下载并解压 Seata 从 Seata 官方 GitHub 下载最新版…...

C++进阶-多态

文章目录 C进阶--多态概念多态的定义及实现多态的构成条件实现多态的两个重要条件虚函数虚函数的重写及覆盖协变析构函数的重写&#xff08;面试被问及最好需要举例说明&#xff09;override和final关键字重载&#xff0c;重写&#xff08;覆盖&#xff09;&#xff0c;隐藏&am…...

Linux教程-常用命令系列三

文章目录 1. 网络安全常用命令1. su (Switch User)2. chmod (Change Mode)3. chown (Change Owner)4. ps (Process Status)5. who6. top7. free8. kill9. gedit10. find总结 2. 字符串显示命令2.1 基本语法2.2 常用选项2.3 核心功能与示例2.3.1 输出字符串2.3.2 输出变量2.3.3 …...

GIS开发笔记(9)结合osg及osgEarth实现三维球经纬网格绘制及显隐

一、实现效果 二、实现原理 按照5的间隔分别创建经纬线的节点&#xff0c;挂在到组合节点&#xff0c;组合节点挂接到根节点。可以根据需要设置间隔度数和线宽、线的颜色。 三、参考代码 //创建经纬线的节点 osg::Node *GlobeWidget::createGraticuleGeometry(float interv…...