sentinel-adapter模塊

sentinel-adapter模塊,見名知意,這個模塊的職能是適配,目前適配主流的框架有dubbo,grpc和web.

由于最了解的是dubbo,目前就先以dubbo為例子進行講解。

由于dubbo框架的設計思想,具體不展開了,有興趣可以去了解下,我后續(xù)也會寫dubbo源碼分析。

如下面三個配置的filter,在dubbo請求時會執(zhí)行到: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數(shù)據(jù),標明調用方身份

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

? ? Entry interfaceEntry =null;

? ? Entry methodEntry =null;

? ? try {

? ? ? ? String resourceName = getResourceName(invoker, invocation);

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

? ? ? ?//將數(shù)據(jù)加載到容器中保存

? ? ? ? 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()) {

//統(tǒng)計異常比例

Tracer.trace(result.getException());

? ? ? ? }

return result;

? ? }catch (BlockException e) {

//當出現(xiàn)拒絕后,進入fallback,可定制化fallback,默認DefaultDubboFallback,拋出SentinelRpcException異常

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

? ? }catch (RpcException e) {

//統(tǒng)計異常比例

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()) {

//統(tǒng)計異常比例

? ? ? ? ? ? Tracer.trace(result.getException());

? ? ? ? }

return result;

? ? }catch (BlockException e) {

//fallback

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

? ? }catch (RpcException e) {

//統(tǒng)計異常比例

Tracer.trace(e);

? ? ? ? throw e;

? ? }finally {

if (methodEntry !=null) {

//資源釋放

methodEntry.exit();

? ? ? ? }

if (interfaceEntry !=null) {

//資源釋放

interfaceEntry.exit();

? ? ? ? }

//資源釋放

ContextUtil.exit();

? ? }

}

最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容