dubbo 过滤器


dubbo 过滤器

          

              

                                

过滤器

            

                 

说明:dubbo服务调用、服务暴露的过程中均会使用到过滤器,两端的过滤器独立运行,互不影响

             

Filter:过滤器接口

/**
 * Extension for intercepting the invocation for both service provider and consumer, furthermore, most of
 * functions in dubbo are implemented base on the same mechanism. Since every time when remote method is
 * invoked, the filter extensions will be executed too, the corresponding penalty should be considered before
 * more filters are added.
 * <pre>
 *  They way filter work from sequence point of view is
 *    <b>
 *    ...code before filter ...
 *          invoker.invoke(invocation) //filter work in a filter implementation class
 *          ...code after filter ...
 *    </b>
 *    Caching is implemented in dubbo using filter approach. If cache is configured for invocation then before
 *    remote call configured caching type's (e.g. Thread Local, JCache etc) implementation invoke method gets called.
      //缓存在dubbo里使用过滤器实现的
 * </pre>
 *
 * Starting from 3.0, Filter on consumer side has been refactored. There are two different kinds of Filters working at different stages
 * of an RPC request.
 * 1. Filter. Works at the instance level, each Filter is bond to one specific Provider instance(invoker).
 * 2. ClusterFilter. Newly introduced in 3.0, intercepts request before Loadbalancer picks one specific Filter(Invoker).
   //从3.0开始,消费端的过滤器重构了,有两种不同的过滤器在不同的阶段起作用
   //filter:对单个provier实例起作用
   //clusterFilter:集群过滤器,在负载均衡选择invoker前起作用
 *
 * Filter Chain in 3.x
 *
 *                                          -> Filter -> Invoker
 *
 * Proxy -> ClusterFilter -> ClusterInvoker -> Filter -> Invoker
 *
 *                                          -> Filter -> Invoker
 *
 *
 * Filter Chain in 2.x
 *
 *                            Filter -> Invoker
 *
 * Proxy -> ClusterInvoker -> Filter -> Invoker
 *
 *                            Filter -> Invoker
 *
 *
 * Filter. (SPI, Singleton, ThreadSafe)
 *
 * @see org.apache.dubbo.rpc.filter.GenericFilter
 * @see org.apache.dubbo.rpc.filter.EchoFilter
 * @see org.apache.dubbo.rpc.filter.TokenFilter
 * @see org.apache.dubbo.rpc.filter.TpsLimitFilter
 */
@SPI(scope = ExtensionScope.MODULE)
public interface Filter extends BaseFilter {
}

                 

                 

# META-INF/dubbo/internal/org.apache.dubbo.rpc.Filter文件
echo=org.apache.dubbo.rpc.filter.EchoFilter
generic=org.apache.dubbo.rpc.filter.GenericFilter
genericimpl=org.apache.dubbo.rpc.filter.GenericImplFilter
token=org.apache.dubbo.rpc.filter.TokenFilter
accesslog=org.apache.dubbo.rpc.filter.AccessLogFilter
classloader=org.apache.dubbo.rpc.filter.ClassLoaderFilter
classloader-callback=org.apache.dubbo.rpc.filter.ClassLoaderCallbackFilter
context=org.apache.dubbo.rpc.filter.ContextFilter
exception=org.apache.dubbo.rpc.filter.ExceptionFilter
executelimit=org.apache.dubbo.rpc.filter.ExecuteLimitFilter
deprecated=org.apache.dubbo.rpc.filter.DeprecatedFilter
compatible=org.apache.dubbo.rpc.filter.CompatibleFilter
timeout=org.apache.dubbo.rpc.filter.TimeoutFilter
tps=org.apache.dubbo.rpc.filter.TpsLimitFilter

trace=org.apache.dubbo.rpc.protocol.dubbo.filter.TraceFilter
monitor=org.apache.dubbo.monitor.support.MonitorFilter

metrics=org.apache.dubbo.monitor.dubbo.MetricsFilter

consumersign=org.apache.dubbo.auth.filter.ConsumerSignFilter
providerauth=org.apache.dubbo.auth.filter.ProviderAuthFilter
cache=org.apache.dubbo.cache.filter.CacheFilter
validation=org.apache.dubbo.validation.filter.ValidationFilter

             

dubbo 3.0.5中没有添加activeLimitFilter过滤器,需自行添加

                             

activeLimit=org.apache.dubbo.rpc.filter.ActiveLimitFilter

                  

ClusterFilter:消费端集群过滤器,在负载均衡之前调用

@SPI(scope = ExtensionScope.MODULE)
public interface ClusterFilter extends BaseFilter {
}

                 

# META-INF/dubbo/internal/org.apache.dubbo.rpc.cluster.filter.ClusterFilter文件
zone-aware=org.apache.dubbo.rpc.cluster.filter.support.ZoneAwareFilter
consumercontext=org.apache.dubbo.rpc.cluster.filter.support.ConsumerContextFilter
future=org.apache.dubbo.rpc.protocol.dubbo.filter.FutureFilter
monitor=org.apache.dubbo.monitor.support.MonitorClusterFilter

                               

服务端过滤器

@Activate(group = PROVIDER, value = ACCESS_LOG_KEY)  //服务端过滤器
public class AccessLogFilter implements Filter {

              

消费端过滤器

@Activate(group = CONSUMER, value = ACTIVES_KEY)     //消费端过滤器
public class ActiveLimitFilter implements Filter, Filter.Listener {

             

服务端过滤器说明

# accesslogFilter:日志过滤器,输出服务请求日志
输出到日志组件(如logback、log4j2等):true、default
输出到指定文件:access.log
  <dubbo:service interface="com.xxx.MenuService" accesslog="true | default" />
  <dubbo:service interface="com.xxx.MenuService" accesslog="access.log" />
日志文件输出样例:
  [2022-02-14 17:39:48] 172.25.12.168:56672 -> 172.25.12.168:20880 - com.example.demo.service.HelloService hello() 

# executeLimitFilter:限制服务中每个方法的最大并发数
  <dubbo:service interface="com.xxx.MenuService" executes="10" />
  <dubbo:service interface="com.xxx.MenuService" >
     <dubbo:method name="getMenuItems" executes="10" />
  <dubbo:service/>

# cacheFilter:缓存过滤器,可选值:lru, threadlocal, jcache
lru:最近最少使用原则删除多余缓存,保持最热的数据被缓存
threadlocal:当前线程缓存,比如一个页面渲染,用到很多portal,每个portal都要去查用户信息,通过线程缓存,可以减少这种多余访问。
jcache:与 JSR107 集成,可以桥接各种缓存实现

# classLoaderFilter:类加载器过滤器,切换当前线程的类加载器为接口的类加载器
# classLoaderCallbackFilter:在过滤器回调接口中切换类加载器(Switch thread context class loader on filter callback)

# contextFilter:记录当前线程的请求上下文
ContextFilter set the provider RpcContext with invoker, invocation, local port it is using and host for current execution thread.

# exceptionFilter:处理服务端自定义异常(用RuntimeException包装),防止消费端序列化失败
unexpected exception will be logged in ERROR level on provider side. 
Unexpected exception are unchecked exception not declared on the interface
Wrap the exception not introduced in API package into RuntimeException. 
Framework will serialize the outer exception but stringnize its cause in order to avoid of possible serialization problem on client side

# timeoutFilter:超时过滤器,超时打印日志,不会影响程序执行
Log any invocation timeout, but don't stop server from running

# tokenFilter:服务端对请求做令牌检验,验证通过后执行请求
Perform check whether given provider token is matching with remote token or not. 
If it does not match it will not allow invoking remote method.

# tpsLimitFilter:对服务端限流,使用令牌桶限流算法
TpsLimitFilter limit the TPS (transaction per second) for all method of a service or a particular method.
Service or method url can define tps or tps.interval to control this control. It use {@link DefaultTPSLimiter} as it limit checker. 
If a provider service method is configured with tps、tps.interval, then if invocation count exceed the configured tps value (default is -1 which means unlimited) then invocation will get RpcException.
服务或者方法使用tps或者tps.interval限流,如果超过设定的值,会抛出rpcException

                         

消费端过滤器说明

# activeLimitFilter:消费端并发限制,使用参数actives设置最大并发数
ActiveLimitFilter restrict the concurrent client invocation for a service or service's method from client side.
To use active limit filter, configured url with actives and provide valid >0 integer value

# cacheFilter:缓存过滤器,可选值:lru, threadlocal, jcache
lru:最近最少使用原则删除多余缓存,保持最热的数据被缓存
threadlocal:当前线程缓存,比如一个页面渲染,用到很多portal,每个portal都要去查用户信息,通过线程缓存,可以减少这种多余访问。
jcache:与 JSR107 集成,可以桥接各种缓存实现

# deprecatedFilter:如果有注解@Deprecated的方法被调用,会打印error日志
DeprecatedFilter logs error message if a invoked method has been marked as deprecated. 
To check whether a method is deprecated or not it looks for deprecated attribute value and consider it is deprecated it value is true

# futureFilter:调用异常时,触发onreturn、oninvoker、onthrow方法
<bean id ="demoCallback" class = "org.apache.dubbo.callback.implicit.NotifyImpl" />
<dubbo:reference id="demoService" interface="org.apache.dubbo.callback.implicit.IDemoService" version="1.0.0" group="cn" >
      <dubbo:method name="get" async="true" onreturn = "demoCallback.onreturn" onthrow="demoCallback.onthrow" />
</dubbo:reference>

           

                

                                

实现原理

    

过滤器链构造

@Activate(order = 100)
public class ProtocolFilterWrapper implements Protocol {

    @Override
    public <T> Exporter<T> export(Invoker<T> invoker) throws RpcException {
        if (UrlUtils.isRegistry(invoker.getUrl())) {
            return protocol.export(invoker);
        }
        FilterChainBuilder builder = getFilterChainBuilder(invoker.getUrl());
        return protocol.export(builder.buildInvokerChain(invoker, SERVICE_FILTER_KEY, CommonConstants.PROVIDER));
    }   //构建服务端过滤器链

    @Override
    public <T> Invoker<T> refer(Class<T> type, URL url) throws RpcException {
        if (UrlUtils.isRegistry(url)) {
            return protocol.refer(type, url);
        }
        FilterChainBuilder builder = getFilterChainBuilder(url);
        return builder.buildInvokerChain(protocol.refer(type, url), REFERENCE_FILTER_KEY, CommonConstants.CONSUMER);
    }   //构建消费端过滤器链

                  

DefaultFilterChainBuilder

@Activate
public class DefaultFilterChainBuilder implements FilterChainBuilder {

    /**
     * build consumer/provider filter chain
     */
    @Override
    public <T> Invoker<T> buildInvokerChain(final Invoker<T> originalInvoker, String key, String group) {
                          //构建服务端、消费端过滤器链
        Invoker<T> last = originalInvoker;
        URL url = originalInvoker.getUrl();
        List<ModuleModel> moduleModels = getModuleModelsFromUrl(url);
        List<Filter> filters;
        if (moduleModels != null && moduleModels.size() == 1) {
            filters = ScopeModelUtil.getExtensionLoader(Filter.class, moduleModels.get(0)).getActivateExtension(url, key, group);
        } else if (moduleModels != null && moduleModels.size() > 1) {
            filters = new ArrayList<>();
            List<ExtensionDirector> directors = new ArrayList<>();
            for (ModuleModel moduleModel : moduleModels) {
                List<Filter> tempFilters = ScopeModelUtil.getExtensionLoader(Filter.class, moduleModel).getActivateExtension(url, key, group);
                filters.addAll(tempFilters);
                directors.add(moduleModel.getExtensionDirector());
            }
            filters = sortingAndDeduplication(filters, directors);

        } else {
            filters = ScopeModelUtil.getExtensionLoader(Filter.class, null).getActivateExtension(url, key, group);
        }


        if (!CollectionUtils.isEmpty(filters)) {
            for (int i = filters.size() - 1; i >= 0; i--) {
                final Filter filter = filters.get(i);
                final Invoker<T> next = last;
                last = new CopyOfFilterChainNode<>(originalInvoker, next, filter);
            }
            return new CallbackRegistrationInvoker<>(last, filters);
        }

        return last;
    }

    /**
     * build consumer cluster filter chain
     */
    @Override
    public <T> ClusterInvoker<T> buildClusterInvokerChain(final ClusterInvoker<T> originalInvoker, String key, String group) {
                                 //构建消费端clusterFilter过滤器链
        ClusterInvoker<T> last = originalInvoker;
        URL url = originalInvoker.getUrl();
        List<ModuleModel> moduleModels = getModuleModelsFromUrl(url);
        List<ClusterFilter> filters;
        if (moduleModels != null && moduleModels.size() == 1) {
            filters = ScopeModelUtil.getExtensionLoader(ClusterFilter.class, moduleModels.get(0)).getActivateExtension(url, key, group);
        } else if (moduleModels != null && moduleModels.size() > 1) {
            filters = new ArrayList<>();
            List<ExtensionDirector> directors = new ArrayList<>();
            for (ModuleModel moduleModel : moduleModels) {
                List<ClusterFilter> tempFilters = ScopeModelUtil.getExtensionLoader(ClusterFilter.class, moduleModel).getActivateExtension(url, key, group);
                filters.addAll(tempFilters);
                directors.add(moduleModel.getExtensionDirector());
            }
            filters = sortingAndDeduplication(filters, directors);

        } else {
            filters = ScopeModelUtil.getExtensionLoader(ClusterFilter.class, null).getActivateExtension(url, key, group);
        }

        if (!CollectionUtils.isEmpty(filters)) {
            for (int i = filters.size() - 1; i >= 0; i--) {
                final ClusterFilter filter = filters.get(i);
                final Invoker<T> next = last;
                last = new CopyOfClusterFilterChainNode<>(originalInvoker, next, filter);
            }
            return new ClusterCallbackRegistrationInvoker<>(originalInvoker, last, filters);
        }

        return last;
    }

               

服务端应用启动时,过滤器链构造调用栈:

# ProtocolFilterWrapper.export:服务暴露过程中构造过滤器链
at org.apache.dubbo.rpc.cluster.filter.ProtocolFilterWrapper.export(ProtocolFilterWrapper.java:61)
at org.apache.dubbo.rpc.protocol.ProtocolSerializationWrapper.export(ProtocolSerializationWrapper.java:47)

# 自适应类Protocol$Adaptive
at org.apache.dubbo.rpc.Protocol$Adaptive.export(Protocol$Adaptive.java:-1)

# ServiceConfig类
at org.apache.dubbo.config.ServiceConfig.doExportUrl(ServiceConfig.java:638)
at org.apache.dubbo.config.ServiceConfig.exportLocal(ServiceConfig.java:654)
at org.apache.dubbo.config.ServiceConfig.exportUrl(ServiceConfig.java:567)
at org.apache.dubbo.config.ServiceConfig.doExportUrlsFor1Protocol(ServiceConfig.java:402)
at org.apache.dubbo.config.ServiceConfig.doExportUrls(ServiceConfig.java:388)
at org.apache.dubbo.config.ServiceConfig.doExport(ServiceConfig.java:363)
	  - locked <0x1bad> (a org.apache.dubbo.config.spring.ServiceBean)
at org.apache.dubbo.config.ServiceConfig.export(ServiceConfig.java:237)

# DefaultModuleDeployer类
at org.apache.dubbo.config.deploy.DefaultModuleDeployer.exportServiceInternal(DefaultModuleDeployer.java:338)
at org.apache.dubbo.config.deploy.DefaultModuleDeployer.exportServices(DefaultModuleDeployer.java:310)
at org.apache.dubbo.config.deploy.DefaultModuleDeployer.start(DefaultModuleDeployer.java:142)
	  - locked <0x1bae> (a org.apache.dubbo.config.deploy.DefaultModuleDeployer)

# DubboDeployApplicationListener类
at org.apache.dubbo.config.spring.context.DubboDeployApplicationListener.onContextRefreshedEvent(DubboDeployApplicationListener.java:108)
at org.apache.dubbo.config.spring.context.DubboDeployApplicationListener.onApplicationEvent(DubboDeployApplicationListener.java:98)
at org.apache.dubbo.config.spring.context.DubboDeployApplicationListener.onApplicationEvent(DubboDeployApplicationListener.java:44)

# SimpleApplicationEventMulticaster类
at org.springframework.context.event.SimpleApplicationEventMulticaster.doInvokeListener(SimpleApplicationEventMulticaster.java:176)
at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:169)
at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:143)

# AbstractApplicationContext类
at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:421)
at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:378)
at org.springframework.context.support.AbstractApplicationContext.finishRefresh(AbstractApplicationContext.java:938)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:586)
	  - locked <0x1baf> (a java.lang.Object)

# ServletWebServerApplicationContext类
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:145)

# SpringApplication类
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:730)
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:412)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:302)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1301)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1290)

# 项目启动入口
at com.example.demo.DemoApplication.main(DemoApplication.java:12)

            

消费端应用启动时,过滤器链构造调用栈:

# ProtocolFilterWrapper.refer执行过程中构造过滤器链
at org.apache.dubbo.rpc.cluster.filter.ProtocolFilterWrapper.refer(ProtocolFilterWrapper.java:74)
at org.apache.dubbo.rpc.protocol.ProtocolSerializationWrapper.refer(ProtocolSerializationWrapper.java:52)

# 自适应类:Protocol$Adaptive
at org.apache.dubbo.rpc.Protocol$Adaptive.refer(Protocol$Adaptive.java:-1)

# RegistryDirectory类
at org.apache.dubbo.registry.integration.RegistryDirectory.toInvokers(RegistryDirectory.java:377)
at org.apache.dubbo.registry.integration.RegistryDirectory.refreshInvoker(RegistryDirectory.java:237)
at org.apache.dubbo.registry.integration.RegistryDirectory.refreshOverrideAndInvoker(RegistryDirectory.java:184)
	  - locked <0x21d7> (a org.apache.dubbo.registry.integration.RegistryDirectory)

# notify操作
at org.apache.dubbo.registry.integration.RegistryDirectory.notify(RegistryDirectory.java:162)
at org.apache.dubbo.registry.support.AbstractRegistry.notify(AbstractRegistry.java:440)
at org.apache.dubbo.registry.support.FailbackRegistry.doNotify(FailbackRegistry.java:371)
at org.apache.dubbo.registry.support.FailbackRegistry.notify(FailbackRegistry.java:363)

# subscribe操作
at org.apache.dubbo.registry.zookeeper.ZookeeperRegistry.doSubscribe(ZookeeperRegistry.java:190)
at org.apache.dubbo.registry.support.FailbackRegistry.subscribe(FailbackRegistry.java:298)
at org.apache.dubbo.registry.ListenerRegistryWrapper.subscribe(ListenerRegistryWrapper.java:111)
at org.apache.dubbo.registry.integration.RegistryDirectory.subscribe(RegistryDirectory.java:117)

# 创建invoker
at org.apache.dubbo.registry.integration.RegistryProtocol.doCreateInvoker(RegistryProtocol.java:562)

# 获取invoker
at org.apache.dubbo.registry.integration.InterfaceCompatibleRegistryProtocol.getInvoker(InterfaceCompatibleRegistryProtocol.java:58)

# MigrationInvoker类
at org.apache.dubbo.registry.client.migration.MigrationInvoker.refreshInterfaceInvoker(MigrationInvoker.java:448)
at org.apache.dubbo.registry.client.migration.MigrationInvoker.migrateToApplicationFirstInvoker(MigrationInvoker.java:239)

# MigrationRuleHandler类
at org.apache.dubbo.registry.client.migration.MigrationRuleHandler.refreshInvoker(MigrationRuleHandler.java:73)
at org.apache.dubbo.registry.client.migration.MigrationRuleHandler.doMigrate(MigrationRuleHandler.java:57)
	  - locked <0x21d8> (a org.apache.dubbo.registry.client.migration.MigrationRuleHandler)
at org.apache.dubbo.registry.client.migration.MigrationRuleListener.onRefer(MigrationRuleListener.java:241)

# RegistryProtocol类
at org.apache.dubbo.registry.integration.RegistryProtocol.interceptInvoker(RegistryProtocol.java:531)
at org.apache.dubbo.registry.integration.RegistryProtocol.doRefer(RegistryProtocol.java:500)
at org.apache.dubbo.registry.integration.RegistryProtocol.refer(RegistryProtocol.java:485)

# refer操作
at org.apache.dubbo.rpc.protocol.ProtocolListenerWrapper.refer(ProtocolListenerWrapper.java:74)
at org.apache.dubbo.qos.protocol.QosProtocolWrapper.refer(QosProtocolWrapper.java:83)
at org.apache.dubbo.rpc.cluster.filter.ProtocolFilterWrapper.refer(ProtocolFilterWrapper.java:71)
at org.apache.dubbo.rpc.protocol.ProtocolSerializationWrapper.refer(ProtocolSerializationWrapper.java:52)

# 自适应类:Protocol$Adaptive
at org.apache.dubbo.rpc.Protocol$Adaptive.refer(Protocol$Adaptive.java:-1)

# ReferenceConfig类
at org.apache.dubbo.config.ReferenceConfig.createInvokerForRemote(ReferenceConfig.java:481)
at org.apache.dubbo.config.ReferenceConfig.createProxy(ReferenceConfig.java:386)
at org.apache.dubbo.config.ReferenceConfig.init(ReferenceConfig.java:275)
	  - locked <0x21d9> (a org.apache.dubbo.config.ReferenceConfig)
at org.apache.dubbo.config.ReferenceConfig.get(ReferenceConfig.java:216)

# SimpleReferenceCache类
at org.apache.dubbo.config.utils.SimpleReferenceCache.get(SimpleReferenceCache.java:110)

# DefaultModuleDeployer类
at org.apache.dubbo.config.deploy.DefaultModuleDeployer.lambda$referServices$6(DefaultModuleDeployer.java:384)
at org.apache.dubbo.config.deploy.DefaultModuleDeployer$$Lambda$880/0x000000080103a450.accept(Unknown Source:-1)
	  at java.util.concurrent.ConcurrentHashMap$ValuesView.forEach(ConcurrentHashMap.java:4780)
at org.apache.dubbo.config.deploy.DefaultModuleDeployer.referServices(DefaultModuleDeployer.java:364)
at org.apache.dubbo.config.deploy.DefaultModuleDeployer.start(DefaultModuleDeployer.java:151)
	  - locked <0x21da> (a org.apache.dubbo.config.deploy.DefaultModuleDeployer)

# DubboDeployApplicationListener类
at org.apache.dubbo.config.spring.context.DubboDeployApplicationListener.onContextRefreshedEvent(DubboDeployApplicationListener.java:108)
at org.apache.dubbo.config.spring.context.DubboDeployApplicationListener.onApplicationEvent(DubboDeployApplicationListener.java:98)
at org.apache.dubbo.config.spring.context.DubboDeployApplicationListener.onApplicationEvent(DubboDeployApplicationListener.java:44)

# SimpleApplicationEventMulticaster类
at org.springframework.context.event.SimpleApplicationEventMulticaster.doInvokeListener(SimpleApplicationEventMulticaster.java:176)
at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:169)
at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:143)

# AbstractApplicationContext类
at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:421)
at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:378)
at org.springframework.context.support.AbstractApplicationContext.finishRefresh(AbstractApplicationContext.java:938)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:586)
	  - locked <0x21db> (a java.lang.Object)

# ServletWebServerApplicationContext类
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:145)

# SpringApplication类
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:730)
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:412)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:302)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1301)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1290)

# 项目启动入口
at com.example.demo.DemoApplication.main(DemoApplication.java:14)

            

消费端应用启动时构建clusterFilter过滤器链,调用栈如下:

# DefaultFilterChainBuilder.buildClusterInvokerChain构造clusterFilter过滤器链
at org.apache.dubbo.rpc.cluster.filter.DefaultFilterChainBuilder.buildClusterInvokerChain(DefaultFilterChainBuilder.java:88)

# 自适应类:AbstractCluster$ClusterFilterInvoker初始化
at org.apache.dubbo.rpc.cluster.support.wrapper.AbstractCluster$ClusterFilterInvoker.<init>(AbstractCluster.java:84)

# AbstractCluster类
at org.apache.dubbo.rpc.cluster.support.wrapper.AbstractCluster.buildClusterInterceptors(AbstractCluster.java:47)
at org.apache.dubbo.rpc.cluster.support.wrapper.AbstractCluster.join(AbstractCluster.java:58)

# MockClusterWrapper类
at org.apache.dubbo.rpc.cluster.support.wrapper.MockClusterWrapper.join(MockClusterWrapper.java:39)

# 创建invoker
at org.apache.dubbo.registry.integration.RegistryProtocol.doCreateInvoker(RegistryProtocol.java:564)

# 获取invoker
at org.apache.dubbo.registry.integration.InterfaceCompatibleRegistryProtocol.getInvoker(InterfaceCompatibleRegistryProtocol.java:58)

# igrationInvoker类
at org.apache.dubbo.registry.client.migration.MigrationInvoker.refreshInterfaceInvoker(MigrationInvoker.java:448)
at org.apache.dubbo.registry.client.migration.MigrationInvoker.migrateToApplicationFirstInvoker(MigrationInvoker.java:239)

# MigrationRuleHandler类
at org.apache.dubbo.registry.client.migration.MigrationRuleHandler.refreshInvoker(MigrationRuleHandler.java:73)
at org.apache.dubbo.registry.client.migration.MigrationRuleHandler.doMigrate(MigrationRuleHandler.java:57)
	  - locked <0x225a> (a org.apache.dubbo.registry.client.migration.MigrationRuleHandler)

# MigrationRuleListener类
at org.apache.dubbo.registry.client.migration.MigrationRuleListener.onRefer(MigrationRuleListener.java:241)

# RegistryProtocol类
at org.apache.dubbo.registry.integration.RegistryProtocol.interceptInvoker(RegistryProtocol.java:531)
at org.apache.dubbo.registry.integration.RegistryProtocol.doRefer(RegistryProtocol.java:500)
at org.apache.dubbo.registry.integration.RegistryProtocol.refer(RegistryProtocol.java:485)

# refer操作
at org.apache.dubbo.qos.protocol.QosProtocolWrapper.refer(QosProtocolWrapper.java:83)
at org.apache.dubbo.rpc.protocol.ProtocolListenerWrapper.refer(ProtocolListenerWrapper.java:74)
at org.apache.dubbo.rpc.cluster.filter.ProtocolFilterWrapper.refer(ProtocolFilterWrapper.java:71)
at org.apache.dubbo.rpc.protocol.ProtocolSerializationWrapper.refer(ProtocolSerializationWrapper.java:52)

# 自适应类:Protocol$Adaptive
at org.apache.dubbo.rpc.Protocol$Adaptive.refer(Protocol$Adaptive.java:-1)

# ReferenceConfig类
at org.apache.dubbo.config.ReferenceConfig.createInvokerForRemote(ReferenceConfig.java:481)
at org.apache.dubbo.config.ReferenceConfig.createProxy(ReferenceConfig.java:386)
at org.apache.dubbo.config.ReferenceConfig.init(ReferenceConfig.java:275)
	  - locked <0x225b> (a org.apache.dubbo.config.ReferenceConfig)
at org.apache.dubbo.config.ReferenceConfig.get(ReferenceConfig.java:216)

# SimpleReferenceCache类
at org.apache.dubbo.config.utils.SimpleReferenceCache.get(SimpleReferenceCache.java:110)

# DefaultModuleDeployer类
at org.apache.dubbo.config.deploy.DefaultModuleDeployer.lambda$referServices$6(DefaultModuleDeployer.java:384)
at org.apache.dubbo.config.deploy.DefaultModuleDeployer$$Lambda$880/0x000000080103ed38.accept(Unknown Source:-1)
	  at java.util.concurrent.ConcurrentHashMap$ValuesView.forEach(ConcurrentHashMap.java:4780)
at org.apache.dubbo.config.deploy.DefaultModuleDeployer.referServices(DefaultModuleDeployer.java:364)
at org.apache.dubbo.config.deploy.DefaultModuleDeployer.start(DefaultModuleDeployer.java:151)
	  - locked <0x225c> (a org.apache.dubbo.config.deploy.DefaultModuleDeployer)

# DubboDeployApplicationListener类
at org.apache.dubbo.config.spring.context.DubboDeployApplicationListener.onContextRefreshedEvent(DubboDeployApplicationListener.java:108)
at org.apache.dubbo.config.spring.context.DubboDeployApplicationListener.onApplicationEvent(DubboDeployApplicationListener.java:98)
at org.apache.dubbo.config.spring.context.DubboDeployApplicationListener.onApplicationEvent(DubboDeployApplicationListener.java:44)

# SimpleApplicationEventMulticaster类
at org.springframework.context.event.SimpleApplicationEventMulticaster.doInvokeListener(SimpleApplicationEventMulticaster.java:176)
at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:169)
at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:143)

# AbstractApplicationContext类
at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:421)
at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:378)
at org.springframework.context.support.AbstractApplicationContext.finishRefresh(AbstractApplicationContext.java:938)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:586)
	  - locked <0x225d> (a java.lang.Object)

# 类
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:145)

# SpringApplication类
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:730)
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:412)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:302)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1301)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1290)

# 项目启动入口
at com.example.demo.DemoApplication.main(DemoApplication.java:14)

                         

消费端发起请求,过滤器执行过程:clusterFilter在clusterInvoker之前执行,filter之后执行

# Filter:ActiveLimitFilter过滤
	  at org.apache.dubbo.rpc.filter.ActiveLimitFilter.invoke(ActiveLimitFilter.java:53)
	  at org.apache.dubbo.rpc.cluster.filter.FilterChainBuilder$CopyOfFilterChainNode.invoke(FilterChainBuilder.java:313)
	  at org.apache.dubbo.rpc.cluster.filter.FilterChainBuilder$CallbackRegistrationInvoker.invoke(FilterChainBuilder.java:187)
	  at org.apache.dubbo.rpc.cluster.support.AbstractClusterInvoker.invokeWithContext(AbstractClusterInvoker.java:364)
	  at org.apache.dubbo.rpc.cluster.support.FailoverClusterInvoker.doInvoke(FailoverClusterInvoker.java:80)
	  at org.apache.dubbo.rpc.cluster.support.AbstractClusterInvoker.invoke(AbstractClusterInvoker.java:332)

# ClusterFilter:MonitorFilter过滤
	  at org.apache.dubbo.monitor.support.MonitorFilter.invoke(MonitorFilter.java:99)
	  at org.apache.dubbo.rpc.cluster.filter.FilterChainBuilder$CopyOfFilterChainNode.invoke(FilterChainBuilder.java:313)

# ClusterFilter:FutureFilter过滤
	  at org.apache.dubbo.rpc.protocol.dubbo.filter.FutureFilter.invoke(FutureFilter.java:51)
	  at org.apache.dubbo.rpc.cluster.filter.FilterChainBuilder$CopyOfFilterChainNode.invoke(FilterChainBuilder.java:313)

# ClusterFilter:ConsumerContextFilter过滤
	  at org.apache.dubbo.rpc.cluster.filter.support.ConsumerContextFilter.invoke(ConsumerContextFilter.java:108)
	  at org.apache.dubbo.rpc.cluster.filter.FilterChainBuilder$CopyOfFilterChainNode.invoke(FilterChainBuilder.java:313)
	  at org.apache.dubbo.rpc.cluster.filter.FilterChainBuilder$CallbackRegistrationInvoker.invoke(FilterChainBuilder.java:187)
	  at org.apache.dubbo.rpc.cluster.support.wrapper.AbstractCluster$ClusterFilterInvoker.invoke(AbstractCluster.java:92)
	  at org.apache.dubbo.rpc.cluster.support.wrapper.MockClusterInvoker.invoke(MockClusterInvoker.java:95)
	  at org.apache.dubbo.registry.client.migration.MigrationInvoker.invoke(MigrationInvoker.java:276)
	  at org.apache.dubbo.rpc.proxy.InvokerInvocationHandler.invoke(InvokerInvocationHandler.java:92)
	  at org.apache.dubbo.common.bytecode.proxy1.hello(proxy1.java:-1)
	  at jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(NativeMethodAccessorImpl.java:-1)
	  at jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
	  at jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	  at java.lang.reflect.Method.invoke(Method.java:568)
	  at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:344)
	  at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:208)
	  at jdk.proxy2.$Proxy64.hello(Unknown Source:-1)
	  at com.example.demo.controller.HelloController.hello(HelloController.java:28)
	  at jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(NativeMethodAccessorImpl.java:-1)
	  at jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
	  at jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	  at java.lang.reflect.Method.invoke(Method.java:568)
	  at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:205)
	  at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:150)
	  at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:117)
	  at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:895)
	  at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:808)
	  at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
	  at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1067)
	  at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:963)
	  at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006)
	  at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:898)
	  at javax.servlet.http.HttpServlet.service(HttpServlet.java:655)
	  at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883)
	  at javax.servlet.http.HttpServlet.service(HttpServlet.java:764)
	  at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:227)
	  at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
	  at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
	  at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
	  at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
	  at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100)
	  at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)
	  at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
	  at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
	  at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93)
	  at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)
	  at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
	  at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
	  at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)
	  at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)
	  at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
	  at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
	  at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:197)
	  at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97)
	  at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:540)
	  at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:135)
	  at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
	  at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78)
	  at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:357)
	  at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:382)
	  at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)
	  at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:895)
	  at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1732)
	  at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
	  - locked <0x2637> (a org.apache.tomcat.util.net.NioEndpoint$NioSocketWrapper)
	  at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191)
	  at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659)
	  at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
	  at java.lang.Thread.run(Thread.java:833)

                             

            

                                

注解配置

    

@DubboService:服务暴露注解

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE, ElementType.METHOD})
@Inherited
public @interface DubboService {
 
    /**
     * Interface class, default value is void.class
     */
    Class<?> interfaceClass() default void.class;
 
    /**
     * Interface class name, default value is empty string
     */
    String interfaceName() default "";
 
    String group() default "";    //服务分组
    String version() default "";  //服务版本
 
    /**
     * Service path, default value is empty string
     */
    String path() default "";
 
    boolean export() default true;       //是否暴露服务,默认true
    boolean dynamic() default true;      //服务是否动态注册,默认true
    boolean register() default true;     //是否向注册中心注册服务,默认true
    boolean deprecated() default false;  //服务是否禁用,默认false
 
    int delay() default -1;        //服务延时注册时间,默认为0
    int weight() default -1;       //服务权重,默认为0
    int executes() default -1;     //服务最大并发执行数,默认为0(不限制)
    int timeout() default -1;      //服务调用超时时间,默认为0

    /**
     * Specify cache implementation for service invocation, legal values include: lru, threadlocal, jcache
     */
    String cache() default "";     //缓存过滤器,可选值:lru, threadlocal, jcache
 
    /**
     * Service token, default value is false
     */
    String token() default "";     //token过滤器
 
    /**
     * Access log for the service, default value is ""
     */
    String accesslog() default ""; //acessLog过滤器
 
    /**
     * Filters for service invocation
     *
     * @see Filter
     */
    String[] filter() default {};      //过滤器,可自定义过滤器
 
    /**
     * Service doc, default value is ""
     */
    String document() default "";
 
 
    /**
     * @see DubboService#stub()
     * @deprecated
     */
    String local() default "";
 
    /**
     * Service stub name, use interface name + Local if not set
     */
    String stub() default "";
 
    /**
     * Cluster strategy, legal values include: failover, failfast, failsafe, failback, forking
     * you can use {@link org.apache.dubbo.common.constants.ClusterRules#FAIL_FAST} ……
     */
    String cluster() default ClusterRules.EMPTY;      //容错策略
 
    /**
     * Service invocation retry times
     *
     * @see org.apache.dubbo.common.constants.CommonConstants#DEFAULT_RETRIES
     */
    int retries() default -1;                         //重试次数
 
    /**
     * Service mock name, use interface name + Mock if not set
     */
    String mock() default "";                         //服务降级接口
 
    /**
     * Load balance strategy, legal values include: random, roundrobin, leastactive
     *
     * you can use {@link org.apache.dubbo.common.constants.LoadbalanceRules#RANDOM} ……
     */
    String loadbalance() default ClusterRules.EMPTY;  //负载均衡策略
 
    /**
     * How the proxy is generated, legal values include: jdk, javassist
     */
    String proxy() default "";
 
    /**
     * Maximum connections service provider can accept, default value is 0 - connection is shared
     */
    int connections() default -1;
 
    /**
     * The callback instance limit peer connection
     * <p>
     * see org.apache.dubbo.common.constants.CommonConstants.DEFAULT_CALLBACK_INSTANCES
     */
    int callbacks() default -1;
 
    /**
     * Callback method name when connected, default value is empty string
     */
    String onconnect() default "";
 
    /**
     * Callback method name when disconnected, default value is empty string
     */
    String ondisconnect() default "";
 
    /**
     * Service owner, default value is empty string
     */
    String owner() default "";
 
    /**
     * Service layer, default value is empty string
     */
    String layer() default "";
 
    /**
     * Whether to enable async invocation, default value is false
     */
    boolean async() default false;     //是否开启异步调用,默认false
 
    /**
     * Maximum active requests allowed, default value is 0
     */
    int actives() default -1;          //最大活跃请求数
 
    /**
     * Whether the async request has already been sent, the default value is false
     */
    boolean sent() default false;
 
    /**
     * Whether to use JSR303 validation, legal values are: true, false
     */
    String validation() default "";
  
    /**
     * Listeners for service exporting and unexporting
     *
     * @see ExporterListener
     */
    String[] listener() default {};
 
    /**
     * Customized parameter key-value pair, for example: {key1, value1, key2, value2}
     */
    String[] parameters() default {};  //自定义参数,如:{key1, value1, key2, value2}
 
    /**
     * Application spring bean name
     * @deprecated This attribute was deprecated, use bind application/module of spring ApplicationContext
     */
    @Deprecated
    String application() default "";   //已禁用
 
    /**
     * Module spring bean name
     */
    String module() default "";
 
    /**
     * Provider spring bean name
     */
    String provider() default "";
 
    /**
     * Protocol spring bean names
     */
    String[] protocol() default {};
 
    /**
     * Monitor spring bean name
     */
    String monitor() default "";
 
    /**
     * Registry spring bean name
     */
    String[] registry() default {};
 
    /**
     * Service tag name
     */
    String tag() default "";
 
    /**
     * methods support
     *
     * @return
     */
    Method[] methods() default {};
 
    /**
     * the scope for referring/exporting a service, if it's local, it means searching in current JVM only.
     * @see org.apache.dubbo.rpc.Constants#SCOPE_LOCAL
     * @see org.apache.dubbo.rpc.Constants#SCOPE_REMOTE
     */
    String scope() default "";            //服务暴露、调用类型,可选值:local、remote
 
    /**
     * Weather the service is export asynchronously
     */
    boolean exportAsync() default false;  //是否异步暴露,默认false
}

          

@Dubboreference:消费端服务调用注解

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD, ElementType.METHOD, ElementType.ANNOTATION_TYPE})
public @interface DubboReference {
 
    /**
     * Interface class, default value is void.class
     */
    Class<?> interfaceClass() default void.class;
 
    /**
     * Interface class name, default value is empty string
     */
    String interfaceName() default "";
 
    String group() default "";    //服务分组
    String version() default "";  //服务版本
 
    /**
     * Service target URL for direct invocation, if this is specified, then registry center takes no effect.
     */
    String url() default "";      //直连服务提供端(如果配置了,则不使用注册中心)
 
    /**
     * Client transport type, default value is "netty"
     */
    String client() default "";   //客户端传输方式,默认为netty
 
    /**
     * Whether to enable generic invocation, default value is false
     * @deprecated Do not need specify generic value, judge by injection type and interface class
     */
    @Deprecated
    boolean generic() default false;   //已禁用
 
    /**
     * When enable, prefer to call local service in the same JVM if it's present, default value is true
     * @deprecated using scope="local" or scope="remote" instead
     */
    @Deprecated
    boolean injvm() default true;      //已禁用
 
    /**
     * Check if service provider is available during boot up, default value is true
     */
    boolean check() default true;
 
    /**
     * Whether eager initialize the reference bean when all properties are set, default value is true ( null as true)
     * @see ReferenceConfigBase#shouldInit()
     */
    boolean init() default true;
 
    /**
     * Whether to make connection when the client is created, the default value is false
     */
    boolean lazy() default false;
 
    /**
     * Export an stub service for event dispatch, default value is false.
     * <p>
     * see org.apache.dubbo.rpc.Constants#STUB_EVENT_METHODS_KEY
     */
    boolean stubevent() default false;
 
    /**
     * Whether to reconnect if connection is lost, if not specify, reconnect is enabled by default, and the interval
     * for retry connecting is 2000 ms
     * <p>
     * see org.apache.dubbo.remoting.Constants#DEFAULT_RECONNECT_PERIOD
     */
    String reconnect() default "";
 
    /**
     * Whether to stick to the same node in the cluster, the default value is false
     * <p>
     * see Constants#DEFAULT_CLUSTER_STICKY
     */
    boolean sticky() default false;
 
    /**
     * How the proxy is generated, legal values include: jdk, javassist
     */
    String proxy() default "";
 
    /**
     * Service stub name, use interface name + Local if not set
     */
    String stub() default "";
 
    /**
     * Cluster strategy, legal values include: failover, failfast, failsafe, failback, forking
     * you can use {@link org.apache.dubbo.common.constants.ClusterRules#FAIL_FAST} ……
     */
    String cluster() default ClusterRules.EMPTY;
 
    /**
     * Maximum connections service provider can accept, default value is 0 - connection is shared
     */
    int connections() default -1;
 
    /**
     * The callback instance limit peer connection
     * <p>
     * see org.apache.dubbo.rpc.Constants#DEFAULT_CALLBACK_INSTANCES
     */
    int callbacks() default -1;
 
    /**
     * Callback method name when connected, default value is empty string
     */
    String onconnect() default "";
 
    /**
     * Callback method name when disconnected, default value is empty string
     */
    String ondisconnect() default "";
 
    /**
     * Service owner, default value is empty string
     */
    String owner() default "";
 
    /**
     * Service layer, default value is empty string
     */
    String layer() default "";
 
    /**
     * Service invocation retry times
     * <p>
     * see Constants#DEFAULT_RETRIES
     */
    int retries() default -1;
 
    /**
     * Load balance strategy, legal values include: random, roundrobin, leastactive
     * you can use {@link org.apache.dubbo.common.constants.LoadbalanceRules#RANDOM} ……
     */
    String loadbalance() default LoadbalanceRules.EMPTY;
 
    /**
     * Whether to enable async invocation, default value is false
     */
    boolean async() default false;
 
    /**
     * Maximum active requests allowed, default value is 0
     */
    int actives() default -1;      //客户端接口方法最大并发数
 
    /**
     * Whether the async request has already been sent, the default value is false
     */
    boolean sent() default false;
 
    /**
     * Service mock name, use interface name + Mock if not set
     */
    String mock() default "";
 
    /**
     * Whether to use JSR303 validation, legal values are: true, false
     */
    String validation() default "";
 
    /**
     * Timeout value for service invocation, default value is 0
     */
    int timeout() default -1;
 
    /**
     * Specify cache implementation for service invocation, legal values include: lru, threadlocal, jcache
     */
    String cache() default "";      //缓存过滤器,可选值:lru, threadlocal, jcache
 
    /**
     * Filters for service invocation
     * <p>
     * see Filter
     */
    String[] filter() default {};    //过滤器,可自定义过滤器
 
    /**
     * Listeners for service exporting and unexporting
     * <p>
     * see ExporterListener
     */
    String[] listener() default {};
 
    /**
     * Customized parameter key-value pair, for example: {key1, value1, key2, value2} or {"key1=value1", "key2=value2"}
     */
    String[] parameters() default {};
 
    /**
     * Application name
     * @deprecated This attribute was deprecated, use bind application/module of spring ApplicationContext
     */
    @Deprecated
    String application() default "";
 
    /**
     * Module associated name
     */
    String module() default "";
 
    /**
     * Consumer associated name
     */
    String consumer() default "";
 
    /**
     * Monitor associated name
     */
    String monitor() default "";
 
    /**
     * Registry associated name
     */
    String[] registry() default {};
 
    /**
     * The communication protocol of Dubbo Service
     *
     * @return the default value is ""
     * @since 2.6.6
     */
    String protocol() default "";
 
    /**
     * Service tag name
     */
    String tag() default "";
 
    /**
     * Service merger
     */
    String merger() default "";
 
    /**
     * methods support
     */
    Method[] methods() default {};
 
    /**
     * The id
     * NOTE: The id attribute is ignored when using @DubboReference on @Bean method
     * @return default value is empty
     * @since 2.7.3
     */
    String id() default "";
 
    /**
     * @return The service names that the Dubbo interface subscribed
     * @see RegistryConstants#SUBSCRIBED_SERVICE_NAMES_KEY
     * @since 2.7.8
     * @deprecated using {@link DubboReference#providedBy()}
     */
    @Deprecated
    String[] services() default {};
 
    /**
     * declares which app or service this interface belongs to
     * @see RegistryConstants#PROVIDED_BY
     */
    String[] providedBy() default {};
 
    /**
     * the scope for referring/exporting a service, if it's local, it means searching in current JVM only.
     * @see org.apache.dubbo.rpc.Constants#SCOPE_LOCAL
     * @see org.apache.dubbo.rpc.Constants#SCOPE_REMOTE
     */
    String scope() default "";
 
    /**
     * Weather the reference is refer asynchronously
     */
    boolean referAsync() default false;
}

            

           

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Dubbo服务过滤器可以用于在Dubbo服务调用的过程中对请求和响应进行预处理和后处理,例如权限控制、日志记录、统计信息等。在Dubbo中,可以通过配置<provider>或<consumer>标签下的<filter>元素来添加服务过滤器。具体的配置方法如下: 1. 创建一个服务过滤器类,实现org.apache.dubbo.common.extension.Activate接口,并重写filter方法。例如: ```java @Activate(group = "provider") public class MyFilter implements Filter { @Override public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException { // 在这里添加过滤器的逻辑 return invoker.invoke(invocation); } } ``` 2. 在服务提供者或服务消费者的配置文件中,添加<filter>元素来引用服务过滤器。例如: ```xml <!-- 服务提供者配置 --> <dubbo:service interface="com.example.SomeService" ref="someService"> <dubbo:method name="someMethod" timeout="5000"> <dubbo:filter ref="myFilter" /> </dubbo:method> </dubbo:service> <!-- 服务消费者配置 --> <dubbo:reference id="someService" interface="com.example.SomeService"> <dubbo:method name="someMethod" timeout="5000"> <dubbo:filter ref="myFilter" /> </dubbo:method> </dubbo:reference> ``` 注意,<filter>元素必须放在<method>元素内部,以便对每个方法都应用过滤器。如果想要对所有方法都应用过滤器,则可以将<filter>元素放在<service>或<reference>元素内部。另外,如果服务过滤器需要传递参数,则可以通过<parameter>元素来配置。例如: ```xml <dubbo:filter ref="myFilter"> <dubbo:parameter key="param1" value="value1" /> <dubbo:parameter key="param2" value="value2" /> </dubbo:filter> ``` 在服务过滤器中可以通过调用invocation.getAttachment(key)方法来获取这些参数。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值