阿里限流框架sentinel详解

sentinel-adapter模块

2018-09-18  本文已影响0人  博恒NO1

sentinel-adapter模块,见名知意,这个模块的职能是适配,目前适配主流的框架有dubbo,grpc和web.

由于最了解的是dubbo,目前就先以dubbo为例子进行讲解。

由于dubbo框架的设计思想,具体不展开了,有兴趣可以去了解下,我后续也会写dubbo源码分析。

如下面三个配置的filter,在dubbo请求时会执行到:SentinelDubboProviderFilter,SentinelDubboConsumerFilter和DubboAppContextFilter 的invoke方法

sentinel.dubbo.provider.filter=com.alibaba.csp.sentinel.adapter.dubbo.SentinelDubboProviderFilter

sentinel.dubbo.consumer.filter=com.alibaba.csp.sentinel.adapter.dubbo.SentinelDubboConsumerFilter

dubbo.application.context.name.filter=com.alibaba.csp.sentinel.adapter.dubbo.DubboAppContextFilter

干货

源码分析SentinelDubboProviderFilter  dubbo调用方:

public Resultinvoke(Invoker invoker, Invocation invocation)throws RpcException {

    // Get origin caller.

//获取客户端 消费方是否包含dubboApplication数据,标明调用方身份

    String application = DubboUtils.getApplication(invocation, "");

    Entry interfaceEntry =null;

    Entry methodEntry =null;

    try {

        String resourceName = getResourceName(invoker, invocation);

        String interfaceName = invoker.getInterface().getName();

       //将数据加载到容器中保存

        ContextUtil.enter(resourceName, application);

        //设置资源保护,接口级别接口保护

        interfaceEntry = SphU.entry(interfaceName, EntryType.IN);

        //设置资源保护,方法级别接口保护

        methodEntry = SphU.entry(resourceName, EntryType.IN, 1, invocation.getArguments());

        //调用

        Result result = invoker.invoke(invocation);

        if (result.hasException()) {

//统计异常比例

Tracer.trace(result.getException());

        }

return result;

    }catch (BlockException e) {

//当出现拒绝后,进入fallback,可定制化fallback,默认DefaultDubboFallback,抛出SentinelRpcException异常

return DubboFallbackRegistry.getProviderFallback().handle(invoker, invocation, e);

    }catch (RpcException e) {

//统计异常比例

Tracer.trace(e);

        throw e;

    }finally {

if (methodEntry !=null) {

//清理方法级别资源

methodEntry.exit(1, invocation.getArguments());

        }

if (interfaceEntry !=null) {

//清理接口级别资源

interfaceEntry.exit();

        }

//清理

ContextUtil.exit();

    }

}

源码分析DubboAppContextFilter  dubbo被调用方:

@Override

public Resultinvoke(Invoker invoker, Invocation invocation)throws RpcException {

String application = invoker.getUrl().getParameter(Constants.APPLICATION_KEY);

    if (application !=null) {

RpcContext.getContext().setAttachment(DubboUtils.DUBBO_APPLICATION_KEY, application);

    }

return invoker.invoke(invocation);

}

写入自定义的dubboApplication命名

源码分析SentinelDubboConsumerFilter  dubbo被调用方:

@Override

public Resultinvoke(Invoker invoker, Invocation invocation)throws RpcException {

Entry interfaceEntry =null;

    Entry methodEntry =null;

    try {

//获取调用方接口名称

String resourceName = getResourceName(invoker, invocation);

        ContextUtil.enter(resourceName);

//设置资源保护,接口级别接口保护

        interfaceEntry = SphU.entry(invoker.getInterface().getName(), EntryType.OUT);

//设置资源保护,方法级别接口保护

        methodEntry = SphU.entry(resourceName, EntryType.OUT);

        Result result = invoker.invoke(invocation);

        if (result.hasException()) {

//统计异常比例

            Tracer.trace(result.getException());

        }

return result;

    }catch (BlockException e) {

//fallback

return DubboFallbackRegistry.getConsumerFallback().handle(invoker, invocation, e);

    }catch (RpcException e) {

//统计异常比例

Tracer.trace(e);

        throw e;

    }finally {

if (methodEntry !=null) {

//资源释放

methodEntry.exit();

        }

if (interfaceEntry !=null) {

//资源释放

interfaceEntry.exit();

        }

//资源释放

ContextUtil.exit();

    }

}

上一篇下一篇

猜你喜欢

热点阅读