日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 综合教程 >内容正文

综合教程

dubbo服务降级

發(fā)布時間:2024/8/26 综合教程 30 生活家
生活随笔 收集整理的這篇文章主要介紹了 dubbo服务降级 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

轉(zhuǎn):

dubbo服務(wù)降級

1. 在 dubbo 管理控制臺配置服務(wù)降級

上圖的配置含義是:consumer 調(diào)用 com.zhang.HelloService 的方法時,直接返回 null,不發(fā)起遠程調(diào)用。

實際操作是:在 zk 的 /dubbo/com.zhang.HelloService/configurators 節(jié)點中添加了 override。

override://0.0.0.0/com.zhang.HelloService?category=configurators&dynamic=false&group=a&mock=force:return+null

2. 也可以通過代碼,進行服務(wù)降級:(dubbo文檔中給出了代碼片段)

可以通過服務(wù)降級功能,臨時屏蔽某個出錯的非關(guān)鍵服務(wù),并定義降級后的返回策略。
向注冊中心寫入動態(tài)配置覆蓋規(guī)則:

RegistryFactory registryFactory = 
    ExtensionLoader.getExtensionLoader(RegistryFactory.class).getAdaptiveExtension();
Registry registry = registryFactory.getRegistry(URL.valueOf("zookeeper://10.20.153.10:2181"));
registry.register(URL.valueOf("override://0.0.0.0/com.foo.BarService?category=configurators&dynamic=false&application=consumer_app&mock=force:return+null"));

mock=force:return+null
表示消費方對該服務(wù)的方法調(diào)用都直接返回 null 值,不發(fā)起遠程調(diào)用。用來屏蔽不重要服務(wù)不可用時對調(diào)用方的影響。
mock=fail:return+null
表示消費方對該服務(wù)的方法調(diào)用在失敗后,再返回 null 值,不拋異常。用來容忍不重要服務(wù)不穩(wěn)定時對調(diào)用方的影響。

dubbo 服務(wù)降級的真實含義:并不是對 provider 進行操作,而是告訴 consumer,調(diào)用服務(wù)時要做哪些動作。

3. 現(xiàn)在分析consumer端靜態(tài)配置mock, consumer中如何調(diào)用mock服務(wù)

用戶可以在<dubbo:reference>中配置mock屬性。如何配置自定義的mock,還沒有搞懂。以mock="force:return+null"為例,我們先分析dubbo默認的MockInvoker。

MockClusterInvoker邏輯:

// MockClusterInvoker
public Result invoke(Invocation invocation) throws RpcException {
    Result result = null;
    
    // 獲取<dubbo:reference>的mock屬性。
    String value = directory.getUrl().getMethodParameter(invocation.getMethodName(), Constants.MOCK_KEY, Boolean.FALSE.toString()).trim(); 
    if (value.length() == 0 || value.equalsIgnoreCase("false")){
        //mock="" 或者 mock="false"
        result = this.invoker.invoke(invocation);
    } else if (value.startsWith("force")) {
        //強制使用mock,如mock="force:return+null"
        if (logger.isWarnEnabled()) {
            logger.info("force-mock: " + invocation.getMethodName() + " force-mock enabled , url : " +  directory.getUrl());
        }
        result = doMockInvoke(invocation, null);
    } else {
        //mock="fail:return+null" 或 mock="MyMock"
        try {
            result = this.invoker.invoke(invocation);
        }catch (RpcException e) {
            if (e.isBiz()) {
                throw e;
            } else {
                if (logger.isWarnEnabled()) {
                    logger.info("fail-mock: " + invocation.getMethodName() + " fail-mock enabled , url : " +  directory.getUrl(), e);
                }
                //出現(xiàn)超時異常
                result = doMockInvoke(invocation, e);
            }
        }
    }
    return result;
}

private Result doMockInvoke(Invocation invocation, RpcException e) {
    Result result = null;
    Invoker<T> minvoker;
    
    List<Invoker<T>> mockInvokers = selectMockInvoker(invocation);
    if (mockInvokers == null || mockInvokers.size() == 0){
        //如果沒有配置自定義Mock,則使用默認MockInvoker
        minvoker = (Invoker<T>) new MockInvoker(directory.getUrl());
    } else {
        minvoker = mockInvokers.get(0);
    }
    try {
        //調(diào)用
        result = minvoker.invoke(invocation);
    } catch (RpcException me) {
        if (me.isBiz()) {
            result = new RpcResult(me.getCause());
        } else {
            throw new RpcException(me.getCode(), getMockExceptionMessage(e, me), me.getCause());
        }    
    } catch (Throwable me) {
        throw new RpcException(getMockExceptionMessage(e, me), me.getCause());
    }
    return result;
}

默認的MockInvoker:

// MockInvoker
public Result invoke(Invocation invocation) throws RpcException {
    //獲取url中的sayHello.mock參數(shù)值
    String mock = getUrl().getParameter(invocation.getMethodName() + "." + Constants.MOCK_KEY);
    if (invocation instanceof RpcInvocation) {
        ((RpcInvocation) invocation).setInvoker(this);
    }
    if (StringUtils.isBlank(mock)){
        //獲取mock屬性值
        mock = getUrl().getParameter(Constants.MOCK_KEY);
    }
    
    if (StringUtils.isBlank(mock)){
        throw new RpcException(new IllegalAccessException("mock can not be null. url :" + url));
    }
    //假定mock="force:return+null",處理后mock="return+null"
    mock = normallizeMock(URL.decode(mock));
    if (Constants.RETURN_PREFIX.trim().equalsIgnoreCase(mock.trim())){
        RpcResult result = new RpcResult();
        result.setValue(null);
        return result;
    } else if (mock.startsWith(Constants.RETURN_PREFIX)) {
        //構(gòu)造返回值
        mock = mock.substring(Constants.RETURN_PREFIX.length()).trim();
        mock = mock.replace('`', '"');
        try {
            Type[] returnTypes = RpcUtils.getReturnTypes(invocation);
            Object value = parseMockValue(mock, returnTypes);
            return new RpcResult(value);
        } catch (Exception ew) {
            throw new RpcException("mock return invoke error. method:" + invocation.getMethodName() + ", mock:" + mock + ", url: "+ url , ew);
        }
    } else if (mock.startsWith(Constants.THROW_PREFIX)) {
        mock = mock.substring(Constants.THROW_PREFIX.length()).trim();
        mock = mock.replace('`', '"');
        if (StringUtils.isBlank(mock)){
            throw new RpcException(" mocked exception for Service degradation. ");
        } else { //用戶自定義類
            Throwable t = getThrowable(mock);
            throw new RpcException(RpcException.BIZ_EXCEPTION, t);
        }
    } else { //impl mock
         try {
             Invoker<T> invoker = getInvoker(mock);
             return invoker.invoke(invocation);
         } catch (Throwable t) {
             throw new RpcException("Failed to create mock implemention class " + mock , t);
         }
    }
}

//mock=fail:throw
//mock=fail:return
//mock=xx.Service
private String normallizeMock(String mock) {
    if (mock == null || mock.trim().length() ==0){
        return mock;
    } else if (ConfigUtils.isDefault(mock) || "fail".equalsIgnoreCase(mock.trim()) || "force".equalsIgnoreCase(mock.trim())){
        mock = url.getServiceInterface()+"Mock";
    }
    if (mock.startsWith(Constants.FAIL_PREFIX)) {
        mock = mock.substring(Constants.FAIL_PREFIX.length()).trim();
    } else if (mock.startsWith(Constants.FORCE_PREFIX)) {
        mock = mock.substring(Constants.FORCE_PREFIX.length()).trim();
    }
    return mock;
}

標簽: dubbo

總結(jié)

以上是生活随笔為你收集整理的dubbo服务降级的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 91久久久久 | a久久久久久 | 老牛影视少妇在线观看 | 亚洲一二三av | 国产美女永久免费 | 看特级黄色片 | 爱草在线| 成人在线视频在线观看 | 色爽爽爽爽爽爽爽爽 | 日韩色资源 | 国产污网站| 福利在线免费视频 | 久久精品无码人妻 | 亚洲卡一卡二 | 亚洲理伦电影 | 日韩精品久久一区二区 | 桃花久久 | 亚洲精品小说 | av黄色一级片 | av天天干 | 免费看裸体视频网站 | 一区二区三区欧美在线 | 国产精品第100页 | 欧美aaa级 | 国产视频精品久久 | 精品国产综合 | 女同性恋毛片 | 国产精品免费av一区二区三区 | 伊人久久成人网 | 伊人av在线播放 | 成人小视频在线免费观看 | 国产精品一区二区三区四区 | 成人小网站 | 亚洲免费av在线 | 欧美三级一区二区三区 | 国产视频1 | 波多野结衣中文字幕一区二区三区 | 国产区在线| 亚洲欧美综合一区 | 国产精品入口a级 | 国产欧美精品一区二区色综合朱莉 | 国精无码欧精品亚洲一区蜜桃 | av在线电影院 | 女人被狂躁60分钟视频 | 二三区视频 | 久久狠狠高潮亚洲精品 | 丝袜熟女一区二区三区 | 美女扒开腿让人桶爽原神 | 美女露出粉嫩尿囗让男人桶 | 五月伊人婷婷 | 久久偷拍免费视频 | 亚洲av最新在线网址 | 污片免费网站 | 日韩成人一区二区 | 亚洲毛片视频 | 北条麻妃一区二区三区 | 黄色片的网站 | 国产美女无遮挡免费 | 成人av动漫在线观看 | 麻豆网址 | 成人亚洲电影 | 国产日韩激情 | 天堂中文在线看 | 污视频网站在线 | 操操综合网 | 老司机午夜免费视频 | 色婷婷伊人 | 性户外野战hd| 一本色道久久亚洲综合精品蜜桃 | 亚洲女人天堂色在线7777 | 欧美福利视频一区二区 | 日本精品视频一区 | 亚洲激情影院 | 日韩久久成人 | av香港经典三级级 在线 | 与亲女洗澡时伦了毛片 | 国产视频一二三 | 黑人极品ⅴideos精品欧美棵 | 奇米影 | 国产成人精品视频在线 | 少妇一区二区视频 | 精品国产xxx| 天天综合影院 | 懂色av中文一区二区三区天美 | 免费成人美女在线观看. | 国内精品久久久 | 亚洲图片视频在线 | 中文字幕亚洲日本 | 日韩成人在线网站 | 欧美自拍色图 | 天干夜夜爽爽日日日日 | 在线免费观看黄 | 流白浆视频 | 亚洲精品乱码久久久久久不卡 | 精国产人伦一区二区三区 | 国产经典久久 | 久射久| 美日韩中文字幕 | 天堂影视av |