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.ServiceListener | ServiceConfig回调扩展点,每个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.MigrationRuleListener | egistryProtocol 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.ApplicationDeployListener | Dubbo进程启动生命周期中的回调扩展,支持包括初始化、启动成功、停止等多个回调点。如果是多应用部署的场景,则是单应用粒度的生命周期回调 | org.apache.dubbo.security.cert.CertDeployerListener | 无需配置,自动激活 |
| org.apache.dubbo.common.deploy.ModuleDeployListener | Dubbo进程启动生命周期中的回调扩展,支持包括初始化、启动成功、停止等多个回调点。如果是多模块部署的场景,则是单模块粒度的生命周期回调 | 无 | 无需配置,自动激活 |
| org.apache.dubbo.qos.api.BaseCommand | QoS命令扩展点,实现扩展点增加新QoS命令 | org.apache.dubbo.qos.command.impl.Ls | 无需配置,自动激活 |
配置相关
| SPI扩展定义 | 功能说明 | 实例实现 | 激活条件 |
|---|---|---|---|
| org.apache.dubbo.common.extension.ExtensionInjector | IoC注入器扩展点,通过扩展可以实现多种类型的治理自动注入,用于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.Protocol | RPC协议实现扩展点。通过扩展该扩展点增加更多的协议实现 | org.apache.dubbo.rpc.protocol.dubbo.DubboProtocol | 通过配置dubbo.protocol.name=spi-name激活 |
| org.apache.dubbo.rpc.ProxyFactory | RPC代理实现的扩展点。可以提供多种不同的代理实现,如字节码增加、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.Cluster | Rpc请求容灾策略扩展点。比如设置请求失败时的动作,如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.Filter | RPC请求过滤器,用于在请求发起前、相应结果返回后,对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.ClusterFilter | RPC请求过滤器,与Filter作用相同,但ClusterFilter发生在选址之前,对于大部分用户可直接使用org.apache.dubbo.rpc.Filter | org.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相同作用,但具备更高性能。对大部分用户,简单起见使用RouterFactory | org.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.TracingContextProvider | MashRule路由规则处理扩展点,可用于从不同的第三方Tracing系统读取上下文 | 无 | 无需配置,自动激活 |
| org.apache.dubbo.rpc.cluster.router.mesh.route.MeshEnvListenerFactory | MashRule路由规则处理扩展点 | 无 | 无需配置,自动激活 |
| 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.MetricsReporterFactory | Metrics指标上报扩展点,可以通过扩展点实现适配到不同的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.CertProvider | TLS证书来源扩展,用于适配不同的证书来源实现 | 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.EchoFilterorg.apache.dubbo.rpc.filter.GenericFilterorg.apache.dubbo.rpc.filter.GenericImplFilterorg.apache.dubbo.rpc.filter.TokenFilterorg.apache.dubbo.rpc.filter.AccessLogFilterorg.apache.dubbo.rpc.filter.ActiveLimitFilterorg.apache.dubbo.rpc.filter.ClassLoaderFilterorg.apache.dubbo.rpc.filter.ContextFilterorg.apache.dubbo.rpc.filter.ExceptionFilterorg.apache.dubbo.rpc.filter.ExecuteLimitFilterorg.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插件扩展点使用
参考:SPI插件扩展点 Dubbo SPI概述 使用IoC容器帮助管理组件的生命周期、依赖关系注入等是很多开发框架的常用设计,Dubbo中内置了一个轻量版本的IoC容器,用来管理框架内部的插件,实现包括插件实例化、生命周期、依赖关系自动注入…...
青少年编程与数学 02-016 Python数据结构与算法 26课题、生物信息学算法
青少年编程与数学 02-016 Python数据结构与算法 26课题、生物信息学算法 一、序列比对算法二、基因表达分析算法三、蛋白质结构预测算法四、系统生物学模型构建算法五、单细胞分析算法六、遗传关联分析算法七、机器学习与数据挖掘算法八、数据可视化算法九、代谢组学分析算法十…...
【Rust 精进之路之第2篇-初体验】安装、配置与 Hello Cargo:踏出 Rust 开发第一步
系列: Rust 精进之路:构建可靠、高效软件的底层逻辑 **作者:**码觉客 发布日期: 2025-04-20 引言:磨刀不误砍柴工,装备先行! 在上一篇文章中,我们一起探索了 Rust 诞生的缘由&…...
洛谷题目:P7775 [COCI 2009/2010 #2] VUK 题解 (本题简)
题目传送门: P7775 [COCI 2009/2010 #2] VUK - 洛谷 (luogu.com.cn) 前言: 这道题的核心目标是找出狼从起点 V 到终点 J 的路径,使得狼在途中离它最近的树的距离的最小值最大。下面为大家详细讲解: #整体思路概述: 这道题我们可以采用“先计算距离,再来二分查找”的…...
腾讯旗下InstantCharacter框架正式开源 可高度个性化任何角色
目前基于学习的主题定制方法主要依赖于 U-Net 架构,但其泛化能力有限,图像质量也大打折扣。同时,基于优化的方法需要针对特定主题进行微调,这不可避免地会降低文本的可控性。为了应对这些挑战,我们提出了 “即时角色”…...
Python爬虫实战:获取fenbi网最新备考资讯
一、引言 1.1 研究背景 伴随互联网技术的迅猛发展,在线教育平台积累了海量备考数据。以粉某网为例,其备考数据涵盖考试资讯、备考资料、用户评价等,对备考者意义重大。然而,获取并分析这些数据颇具挑战,需借助先进的爬虫技术和数据分析方法。 1.2 研究目的 本研究旨在…...
详讲Linux下进程等待
3.进程等待 引言:什么是进程等待 想象有两个小伙伴,一个是 “大强”(父进程 ),一个是 “小强”(子进程 )。大强给小强安排了任务,比如去收集一些石头。 …...
JBoss + WildFly 本地开发环境完全指南
JBoss WildFly 本地开发环境完全指南 本篇笔记主要实现在本地通过 docker 创建 JBoss 和 WildFly 服务器这一功能,基于红帽的禁制 EAP 版本的重新分发,所以我这里没办法放 JBoss EAP 的 zip 文件。WildFly 是免费开源的版本,可以在红帽官网找…...
【网络原理】TCP协议如何实现可靠传输(确认应答和超时重传机制)
目录 一. TCP协议 二. 确定应答 三. 超时重传 一. TCP协议 1)端口号 源端口号:发送方端口号目的端口号:接收方端口号 16位(2字节)端口号,可以表示的范围(0~65535) 源端口和目的…...
【国家能源集团生态协作平台-注册/登录安全分析报告】
前言 由于网站注册入口容易被黑客攻击,存在如下安全问题: 暴力破解密码,造成用户信息泄露短信盗刷的安全问题,影响业务及导致用户投诉带来经济损失,尤其是后付费客户,风险巨大,造成亏损无底洞…...
Java表达式1.0
Java开发工具 在当今的Java开发领域,IntelliJ IDEA已然成为了众多开发者心目中的首选利器,它被广泛认为是目前Java开发效率最快的IDE工具。这款备受瞩目的开发工具是由JetBrains公司精心打造的,而JetBrains公司总部位于风景如画的捷克共和国首…...
idea中导入从GitHub上克隆下来的springboot项目解决找不到主类的问题
第一步:删除目录下的.idea和target,然后用idea打开 第二步:如果有需要,idea更换jdk版本 原文链接:https://blog.csdn.net/m0_74036731/article/details/146779040 解决方法(idea中解决)&#…...
Android音视频开发
Android Framework 与音视频技术深度解析 一、Android音视频架构全景 ▶ 四层架构协同┌──────────────┐│ 应用层 │ ▶ MediaPlayer/ExoPlayer/Camera2 API调用└──────┬───────┘┌──────▼───────┐│ 框架层 │…...
【AI论文】CLIMB:基于聚类的迭代数据混合自举语言模型预训练
摘要:预训练数据集通常是从网络内容中收集的,缺乏固有的领域划分。 例如,像 Common Crawl 这样广泛使用的数据集并不包含明确的领域标签,而手动整理标记数据集(如 The Pile)则是一项劳动密集型工作。 因此&…...
Linux操作系统--环境变量
目录 基本概念: 常见环境变量: 查看环境变量的方法: 测试PATH 测试HOME 和环境变量相关的命令 环境变量的组织方式:编辑 通过代码如何获取环境变量 通过系统调用获取或设置环境变量 环境变量通常具有全局属性 基本概念…...
Jenkins 多分支管道
如果您正在寻找一个基于拉取请求或分支的自动化 Jenkins 持续集成和交付 (CI/CD) 流水线,本指南将帮助您全面了解如何使用 Jenkins 多分支流水线实现它。 Jenkins 的多分支流水线是设计 CI/CD 工作流的最佳方式之一,因为它完全基于 git(源代…...
精益数据分析(9/126):如何筛选创业路上的关键数据指标
精益数据分析(9/126):如何筛选创业路上的关键数据指标 大家好!在创业的漫漫长路中,数据就像一盏明灯,指引着我们前行的方向。但要让这盏灯发挥作用,关键在于找到那些真正有价值的数据指标。今天…...
C语言之图像文件的属性
🌟 嗨,我是LucianaiB! 🌍 总有人间一两风,填我十万八千梦。 🚀 路漫漫其修远兮,吾将上下而求索。 图像文件属性提取系统设计与实现 目录 设计题目设计内容系统分析总体设计详细设计程序实现…...
LeetCode hot 100—分割等和子集
题目 给你一个 只包含正整数 的 非空 数组 nums 。请你判断是否可以将这个数组分割成两个子集,使得两个子集的元素和相等。 示例 示例 1: 输入:nums [1,5,11,5] 输出:true 解释:数组可以分割成 [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分,总计15分) 6. 7. 8. 9. 10. 三、求解下列各题(本大题共5小…...
【算法】快速排序、归并排序(非递归版)
目录 一、快速排序(非递归) 1.原理 2.实现 2.1 stack 2.2 partition(array,left,right) 2.3 pivot - 1 > left 二、归并排序(非递归) 1.原理 2.实现 2.1 gap 2.1.1 i 2*gap 2.1.2 gap * 2 2.1.3 gap < array.…...
python-将文本生成音频
将文本生成音频通常需要结合 文本转语音(TTS,Text-to-Speech) 工具或库来实现,比如 Google TTS (gtts)、Amazon Polly、Microsoft Azure TTS 等。 一、使用 Google TTS (gtts) 将文本生成音频 gtts 是一个简单易用的 Python 库&a…...
[王阳明代数讲义]语言模型核心代码调研
语言模型核心代码调研 基于Consciciteation的才气张量持续思考综述将文本生成建模为才气张量网络扩散过程,实现非自回归推理通过才气张量的群-拓扑流形交叉注意力实现多模态推理,将输入压缩到低维空间持续迭代提出「条件计算提前终止」机制,…...
4月19日记(补)算了和周日一块写了 4月20日日记
周六啊 昨天晚上又玩的太嗨了。睡觉的时候有点晚了,眼睛疼就没写日记。现在补上 实际上现在是20号晚上八点半了。理论上来说应该写今天的日记。 周六上午打比赛啦,和研究生,输了,我是替补没上场。没关系再练一练明天就可以变强…...
trivy开源安全漏洞扫描器——筑梦之路
开源地址:https://github.com/aquasecurity/trivy.git 可扫描的对象 容器镜像文件系统Git存储库(远程)虚拟机镜像Kubernetes 在容器镜像安全方面使用广泛,其他使用相对较少。 能够发现的问题 正在使用的操作系统包和软件依赖项…...
【实战中提升自己】内网安全部署之dot1x部署 本地与集成AD域的主流方式(附带MAC认证)
1 dot1x部署【用户名密码认证,也可以解决私接无线AP等功能】 说明:如果一个网络需要通过用户名认证才能访问内网,而认证失败只能访问外网与服务器,可以部署dot1x功能。它能实现的效果是,当内部用户输入正常的…...
[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
场景: win11家庭版,edge浏览器 , sqlin靶场 定义: SQL 注入(SQL Injection)是一种常见的网络安全攻击方式,攻击者通过在 Web 应用程序中输入恶意的 SQL 代码,绕过应用程序的安全机…...
大模型在胆管结石(无胆管炎或胆囊炎)预测及治疗方案制定中的应用研究
目录 一、引言 1.1 研究背景与意义 1.2 研究目的 1.3 国内外研究现状 二、胆管结石相关理论基础 2.1 胆管结石概述 2.2 临床表现与诊断方法 2.3 传统治疗方法 三、大模型技术原理与应用优势 3.1 大模型基本原理 3.2 在医疗领域的应用潜力 3.3 用于胆管结石预测的可…...
MIT6.S081-lab4
MIT6.S081-lab4 注:本篇lab的前置知识在《MIT6.S081-lab3前置》 1. RISC-V assembly 第一个问题 Which registers contain arguments to functions? For example, which register holds 13 in main’s call to printf? 我们先来看看main干了什么: …...
