国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

Dubbo 源碼分析 - 集群容錯之 Router

jcc / 1178人閱讀

摘要:源碼分析條件路由規(guī)則有兩個條件組成,分別用于對服務(wù)消費者和提供者進(jìn)行匹配。如果服務(wù)提供者匹配條件為空,表示對某些服務(wù)消費者禁用服務(wù)。此時第六次循環(huán)分隔符,,。第二個和第三個參數(shù)來自方法的參數(shù)列表,這兩個參數(shù)分別為服務(wù)提供者和服務(wù)消費者。

1. 簡介

上一篇文章分析了集群容錯的第一部分 -- 服務(wù)目錄 Directory。服務(wù)目錄在刷新 Invoker 列表的過程中,會通過 Router 進(jìn)行服務(wù)路由。上一篇文章關(guān)于服務(wù)路由相關(guān)邏輯沒有細(xì)致分析,一筆帶過了,本篇文章將對此進(jìn)行詳細(xì)的分析。首先,先來介紹一下服務(wù)目錄是什么。服務(wù)路由包含一條路由規(guī)則,路由規(guī)則決定了服務(wù)消費者的調(diào)用目標(biāo),即規(guī)定了服務(wù)消費者可調(diào)用哪些服務(wù)提供者。Dubbo 目前提供了三種服務(wù)路由實現(xiàn),分別為條件路由 ConditionRouter、腳本路由 ScriptRouter 和標(biāo)簽路由 TagRouter。其中條件路由是我們最常使用的,標(biāo)簽路由暫未在我所分析的 2.6.4 版本中提供,該實現(xiàn)會在 2.7.0 版本中提供。本篇文章將分析條件路由相關(guān)源碼,腳本路由和標(biāo)簽路由這里就不分析了。下面進(jìn)入正題。

2. 源碼分析

條件路由規(guī)則有兩個條件組成,分別用于對服務(wù)消費者和提供者進(jìn)行匹配。比如有這樣一條規(guī)則:

host = 10.20.153.10 => host = 10.20.153.11

該條規(guī)則表示 IP 為 10.20.153.10 的服務(wù)消費者只可調(diào)用 IP 為 10.20.153.11 機器上的服務(wù),不可調(diào)用其他機器上的服務(wù)。條件路由規(guī)則的格式如下:

[服務(wù)消費者匹配條件] => [服務(wù)提供者匹配條件]

如果服務(wù)消費者匹配條件為空,表示不對服務(wù)消費者進(jìn)行限制。如果服務(wù)提供者匹配條件為空,表示對某些服務(wù)消費者禁用服務(wù)。Dubbo 官方文檔對條件路由進(jìn)行了比較詳細(xì)的介紹,大家可以參考下,這里就不過多說明了。

條件路由實現(xiàn)類 ConditionRouter 需要對用戶配置的路由規(guī)則進(jìn)行解析,得到一系列的條件。然后再根據(jù)這些條件對服務(wù)進(jìn)行路由。本章將分兩節(jié)進(jìn)行說明,2.1節(jié)介紹表達(dá)式解析過程。2.2 節(jié)介紹服務(wù)路由的過程。接下來,我們先從表達(dá)式解析過程看起。

2.1 表達(dá)式解析

條件路由規(guī)則是一條字符串,對于 Dubbo 來說,它并不能直接理解字符串的意思,需要將其解析成內(nèi)部格式才行。條件表達(dá)式的解析過程始于 ConditionRouter 的構(gòu)造方法,下面一起看一下:

public ConditionRouter(URL url) {
    this.url = url;
    // 獲取 priority 和 force 配置
    this.priority = url.getParameter(Constants.PRIORITY_KEY, 0);
    this.force = url.getParameter(Constants.FORCE_KEY, false);
    try {
        // 獲取路由規(guī)則
        String rule = url.getParameterAndDecoded(Constants.RULE_KEY);
        if (rule == null || rule.trim().length() == 0) {
            throw new IllegalArgumentException("Illegal route rule!");
        }
        rule = rule.replace("consumer.", "").replace("provider.", "");
        // 定位 => 分隔符
        int i = rule.indexOf("=>");
        // 分別獲取服務(wù)消費者和提供者匹配規(guī)則
        String whenRule = i < 0 ? null : rule.substring(0, i).trim();
        String thenRule = i < 0 ? rule.trim() : rule.substring(i + 2).trim();
        // 解析服務(wù)消費者匹配規(guī)則
        Map when = 
            StringUtils.isBlank(whenRule) || "true".equals(whenRule) 
                ? new HashMap() : parseRule(whenRule);
        // 解析服務(wù)提供者匹配規(guī)則
        Map then = 
            StringUtils.isBlank(thenRule) || "false".equals(thenRule) 
                ? null : parseRule(thenRule);
        this.whenCondition = when;
        this.thenCondition = then;
    } catch (ParseException e) {
        throw new IllegalStateException(e.getMessage(), e);
    }
}

如上,ConditionRouter 構(gòu)造方法先是對路由規(guī)則做預(yù)處理,然后調(diào)用 parseRule 方法分別對服務(wù)提供者和消費者規(guī)則進(jìn)行解析,最后將解析結(jié)果賦值給 whenCondition 和 thenCondition 成員變量。ConditionRouter 構(gòu)造方法不是很復(fù)雜,這里就不多說了。下面我們把重點放在 parseRule 方法上,在詳細(xì)介紹這個方法之前,我們先來看一個內(nèi)部類。

private static final class MatchPair {
    final Set matches = new HashSet();
    final Set mismatches = new HashSet();
}

MatchPair 內(nèi)部包含了兩個 Set 型的成員變量,分別用于存放匹配和不匹配的條件。這個類兩個成員變量會在 parseRule 方法中被用到,下面來看一下。

private static Map parseRule(String rule)
        throws ParseException {
    // 定義條件映射集合
    Map condition = new HashMap();
    if (StringUtils.isBlank(rule)) {
        return condition;
    }
    MatchPair pair = null;
    Set values = null;
    // 通過正則表達(dá)式匹配路由規(guī)則,ROUTE_PATTERN = ([&!=,]*)s*([^&!=,s]+)
    // 這個表達(dá)式看起來不是很好理解,第一個括號內(nèi)的表達(dá)式用于匹配"&", "!", "=" 和 "," 等符號。
    // 第二括號內(nèi)的用于匹配英文字母,數(shù)字等字符。舉個例子說明一下:
    //    host = 2.2.2.2 & host != 1.1.1.1 & method = hello
    // 匹配結(jié)果如下:
    //     括號一      括號二
    // 1.  null       host
    // 2.   =         2.2.2.2
    // 3.   &         host
    // 4.   !=        1.1.1.1 
    // 5.   &         method
    // 6.   =         hello
    final Matcher matcher = ROUTE_PATTERN.matcher(rule);
    while (matcher.find()) {
           // 獲取括號一內(nèi)的匹配結(jié)果
        String separator = matcher.group(1);
        // 獲取括號二內(nèi)的匹配結(jié)果
        String content = matcher.group(2);
        // 分隔符為空,表示匹配的是表達(dá)式的開始部分
        if (separator == null || separator.length() == 0) {
            // 創(chuàng)建 MatchPair 對象
            pair = new MatchPair();
            // 存儲 <匹配項, MatchPair> 鍵值對,比如 
            condition.put(content, pair); 
        } 
        
        // 如果分隔符為 &,表明接下來也是一個條件
        else if ("&".equals(separator)) {
            // 嘗試從 condition 獲取 MatchPair
            if (condition.get(content) == null) {
                // 未獲取到 MatchPair,重新創(chuàng)建一個,并放入 condition 中
                pair = new MatchPair();
                condition.put(content, pair);
            } else {
                pair = condition.get(content);
            }
        } 
        
        // 分隔符為 =
        else if ("=".equals(separator)) {
            if (pair == null)
                throw new ParseException("Illegal route rule ...");

            values = pair.matches;
            // 將 content 存入到 MatchPair 的 matches 集合中
            values.add(content);
        } 
        
        //  分隔符為 != 
        else if ("!=".equals(separator)) {
            if (pair == null)
                throw new ParseException("Illegal route rule ...");

            values = pair.mismatches;
            // 將 content 存入到 MatchPair 的 mismatches 集合中
            values.add(content);
        }
        
        // 分隔符為 ,
        else if (",".equals(separator)) {
            if (values == null || values.isEmpty())
                throw new ParseException("Illegal route rule ...");
            // 將 content 存入到上一步獲取到的 values 中,可能是 matches,也可能是 mismatches
            values.add(content);
        } else {
            throw new ParseException("Illegal route rule ...");
        }
    }
    return condition;
}

以上就是路由規(guī)則的解析邏輯,該邏輯由正則表達(dá)式 + 一個 while 循環(huán) + 數(shù)個條件分支組成。下面使用一個示例對解析邏輯進(jìn)行演繹。示例為 host = 2.2.2.2 & host != 1.1.1.1 & method = hello。正則解析結(jié)果如下:

    括號一      括號二
1.  null       host
2.   =         2.2.2.2
3.   &         host
4.   !=        1.1.1.1
5.   &         method
6.   =         hello

現(xiàn)在線程進(jìn)入 while 循環(huán):

第一次循環(huán):分隔符 separator = null,content = "host"。此時創(chuàng)建 MatchPair 對象,并存入到 condition 中,condition = {"host": MatchPair@123}

第二次循環(huán):分隔符 separator = "=",content = "2.2.2.2",pair = MatchPair@123。此時將 2.2.2.2 放入到 MatchPair@123 對象的 matches 集合中。

第三次循環(huán):分隔符 separator = "&",content = "host"。host 已存在于 condition 中,因此 pair = MatchPair@123。

第四次循環(huán):分隔符 separator = "!=",content = "1.1.1.1",pair = MatchPair@123。此時將 1.1.1.1 放入到 MatchPair@123 對象的 mismatches 集合中。

第五次循環(huán):分隔符 separator = "&",content = "method"。condition.get("method") = null,因此新建一個 MatchPair 對象,并放入到 condition 中。此時 condition = {"host": MatchPair@123, "method": MatchPair@ 456}

第六次循環(huán):分隔符 separator = "=",content = "2.2.2.2",pair = MatchPair@456。此時將 hello 放入到 MatchPair@456 對象的 matches 集合中。

循環(huán)結(jié)束,此時 condition 的內(nèi)容如下:

{
    "host": {
        "matches": ["2.2.2.2"],
        "mismatches": ["1.1.1.1"]
    },
    "method": {
        "matches": ["hello"],
        "mismatches": []
    }
}

路由規(guī)則的解析過程稍微有點復(fù)雜,大家可通過 ConditionRouter 的測試類對該邏輯進(jìn)行測試。并且找一個表達(dá)式,對照上面的代碼走一遍,加深理解。關(guān)于路由規(guī)則的解析過程就先到這,我們繼續(xù)往下看。

2.2 服務(wù)路由

服務(wù)路由的入口方法是 ConditionRouter 的 router 方法,該方法定義在 Router 接口中。實現(xiàn)代碼如下:

public  List> route(List> invokers, URL url, Invocation invocation)
        throws RpcException {
    if (invokers == null || invokers.isEmpty()) {
        return invokers;
    }
    try {
        // 先對服務(wù)消費者條件進(jìn)行匹配,如果匹配失敗,表明當(dāng)前消費者 url 不符合匹配規(guī)則,
        // 無需進(jìn)行后續(xù)匹配,直接返回 Invoker 列表即可。比如下面的規(guī)則:
        //     host = 10.20.153.10 => host = 10.0.0.10
        // 這條路由規(guī)則希望 IP 為 10.20.153.10 的服務(wù)消費者調(diào)用 IP 為 10.0.0.10 機器上的服務(wù)。
        // 當(dāng)消費者 ip 為 10.20.153.11 時,matchWhen 返回 false,表明當(dāng)前這條路由規(guī)則不適用于
        // 當(dāng)前的服務(wù)消費者,此時無需再進(jìn)行后續(xù)匹配,直接返回即可。
        if (!matchWhen(url, invocation)) {
            return invokers;
        }
        List> result = new ArrayList>();
        // 服務(wù)提供者匹配條件未配置,表明對指定的服務(wù)消費者禁用服務(wù),也就是服務(wù)消費者在黑名單中
        if (thenCondition == null) {
            logger.warn("The current consumer in the service blacklist...");
            return result;
        }
        // 這里可以簡單的把 Invoker 理解為服務(wù)提供者,現(xiàn)在使用服務(wù)消費者匹配規(guī)則對 
        // Invoker 列表進(jìn)行匹配
        for (Invoker invoker : invokers) {
            // 匹配成功,表明當(dāng)前 Invoker 符合服務(wù)提供者匹配規(guī)則。
            // 此時將 Invoker 添加到 result 列表中
            if (matchThen(invoker.getUrl(), url)) {
                result.add(invoker);
            }
        }
        
        // 返回匹配結(jié)果,如果 result 為空列表,且 force = true,表示強制返回空列表,
        // 否則路由結(jié)果為空的路由規(guī)則將自動失效
        if (!result.isEmpty()) {
            return result;
        } else if (force) {
            logger.warn("The route result is empty and force execute ...");
            return result;
        }
    } catch (Throwable t) {
        logger.error("Failed to execute condition router rule: ...");
    }
    
    // 原樣返回,此時 force = false,表示該條路由規(guī)則失效
    return invokers;
}

router 方法先是調(diào)用 matchWhen 對服務(wù)消費者進(jìn)行匹配,如果匹配失敗,直接返回 Invoker 列表。如果匹配成功,再對服務(wù)提供者進(jìn)行匹配,匹配邏輯封裝在了 matchThen 方法中。下面來看一下這兩個方法的邏輯:

boolean matchWhen(URL url, Invocation invocation) {
    // 服務(wù)消費者條件為 null 或空,均返回 true,比如:
    //     => host != 172.22.3.91
    // 表示所有的服務(wù)消費者都不得調(diào)用 IP 為 172.22.3.91 的機器上的服務(wù)
    return whenCondition == null || whenCondition.isEmpty() 
        || matchCondition(whenCondition, url, null, invocation);  // 進(jìn)行條件匹配
}

private boolean matchThen(URL url, URL param) {
    // 服務(wù)提供者條件為 null 或空,表示禁用服務(wù)
    return !(thenCondition == null || thenCondition.isEmpty()) 
        && matchCondition(thenCondition, url, param, null);  // 進(jìn)行條件匹配
}

這兩個方法長的有點像,不過邏輯上還是有差別的,大家注意看。這兩個方法均調(diào)用了 matchCondition 方法,不過它們所傳入的參數(shù)是不同的,這個需要特別注意。不然后面的邏輯不好弄懂。下面我們對這幾個參數(shù)進(jìn)行溯源。matchWhen 方法向 matchCondition 方法傳入的參數(shù)為 [whenCondition, url, null, invocation],第一個參數(shù) whenCondition 為服務(wù)消費者匹配條件,這個前面分析過。第二個參數(shù) url 源自 route 方法的參數(shù)列表,該參數(shù)由外部類調(diào)用 route 方法時傳入。有代碼為證,如下:

private List> route(List> invokers, String method) {
    Invocation invocation = new RpcInvocation(method, new Class[0], new Object[0]);
    List routers = getRouters();
    if (routers != null) {
        for (Router router : routers) {
            if (router.getUrl() != null) {
                // 注意第二個參數(shù)
                invokers = router.route(invokers, getConsumerUrl(), invocation);
            }
        }
    }
    return invokers;
}

上面這段代碼來自 RegistryDirectory,第二個參數(shù)表示的是服務(wù)消費者 url。matchCondition 的 invocation 參數(shù)也是從這里傳入的。

接下來再來看看 matchThen 向 matchCondition 方法傳入的參數(shù) [thenCondition, url, param, null]。第一個參數(shù)不用解釋了。第二個和第三個參數(shù)來自 matchThen 方法的參數(shù)列表,這兩個參數(shù)分別為服務(wù)提供者 url 和服務(wù)消費者 url。搞清楚這些參數(shù)來源后,接下倆就可以分析 matchCondition 了。

private boolean matchCondition(Map condition, URL url, URL param, Invocation invocation) {
    // 將服務(wù)提供者或消費者 url 轉(zhuǎn)成 Map
    Map sample = url.toMap();
    boolean result = false;
    // 遍歷 condition 列表
    for (Map.Entry matchPair : condition.entrySet()) {
        // 獲取匹配項名稱,比如 host、method 等
        String key = matchPair.getKey();
        String sampleValue;
        // 如果 invocation 不為空,且 key 為 mehtod(s),表示進(jìn)行方法匹配
        if (invocation != null && (Constants.METHOD_KEY.equals(key) || Constants.METHODS_KEY.equals(key))) {
            // 從 invocation 獲取調(diào)用方法名稱
            sampleValue = invocation.getMethodName();
        } else {
            // 從服務(wù)提供者或消費者 url 中獲取指定字段值,比如 host、application 等
            sampleValue = sample.get(key);
            if (sampleValue == null) {
                // 嘗試通過 default.xxx 獲取相應(yīng)的值
                sampleValue = sample.get(Constants.DEFAULT_KEY_PREFIX + key);
            }
        }
        
        // --------------------? 分割線 ?-------------------- //
        
        if (sampleValue != null) {
            // 調(diào)用 MatchPair 的 isMatch 方法進(jìn)行匹配
            if (!matchPair.getValue().isMatch(sampleValue, param)) {
                // 只要有一個規(guī)則匹配失敗,立即返回 false 結(jié)束方法邏輯
                return false;
            } else {
                result = true;
            }
        } else {
            // sampleValue 為空,表明服務(wù)提供者或消費者 url 中不包含相關(guān)字段。此時如果 
            // MatchPair 的 matches 不為空,表示匹配失敗,返回 false。比如我們有這樣
            // 一條匹配條件 loadbalance = random,假設(shè) url 中并不包含 loadbalance 參數(shù),
            // 此時 sampleValue = null。既然路由規(guī)則里限制了 loadbalance = random,
            // 但 sampleValue = null,明顯不符合規(guī)則,因此返回 false
            if (!matchPair.getValue().matches.isEmpty()) {
                return false;
            } else {
                result = true;
            }
        }
    }
    return result;
}

如上,matchCondition 方法看起來有點復(fù)雜,這里簡單縷縷。分割線以上的代碼實際上主要是用于獲取 sampleValue 的值,分割線以下才是進(jìn)行條件匹配。條件匹配調(diào)用的邏輯封裝在 isMatch 中,代碼如下:

private boolean isMatch(String value, URL param) {
    // 情況一:matches 非空,mismatches 為空
    if (!matches.isEmpty() && mismatches.isEmpty()) {
        // 遍歷 matches 集合,檢測入?yún)?value 是否能被 matches 集合元素匹配到。
        // 舉個例子,如果 value = 10.20.153.11,matches = [10.20.153.*],
        // 此時 isMatchGlobPattern 方法返回 true
        for (String match : matches) {
            if (UrlUtils.isMatchGlobPattern(match, value, param)) {
                return true;
            }
        }
        
        // 如果所有匹配項都無法匹配到入?yún)?,則返回 false
        return false;
    }

    // 情況二:matches 為空,mismatches 非空
    if (!mismatches.isEmpty() && matches.isEmpty()) {
        for (String mismatch : mismatches) {
            // 只要入?yún)⒈?mismatches 集合中的任意一個元素匹配到,就返回 false
            if (UrlUtils.isMatchGlobPattern(mismatch, value, param)) {
                return false;
            }
        }
        // mismatches 集合中所有元素都無法匹配到入?yún)ⅲ藭r返回 true
        return true;
    }

    // 情況三:matches 非空,mismatches 非空
    if (!matches.isEmpty() && !mismatches.isEmpty()) {
        // matches 和 mismatches 均為非空,此時優(yōu)先使用 mismatches 集合元素對入?yún)⑦M(jìn)行匹配。
        // 只要 mismatches 集合中任意一個元素與入?yún)⑵ヅ涑晒Γ土⒓捶祷?false,結(jié)束方法邏輯
        for (String mismatch : mismatches) {
            if (UrlUtils.isMatchGlobPattern(mismatch, value, param)) {
                return false;
            }
        }
        // mismatches 集合元素?zé)o法匹配到入?yún)?,此時使用 matches 繼續(xù)匹配
        for (String match : matches) {
            // 只要 matches 集合中任意一個元素與入?yún)⑵ヅ涑晒?,就立即返?true
            if (UrlUtils.isMatchGlobPattern(match, value, param)) {
                return true;
            }
        }
        return false;
    }
    
    // 情況四:matches 和 mismatches 均為空,此時返回 false
    return false;
}

isMatch 方法邏輯比較清晰,由三個條件分支組成,用于處理四種情況。這里對四種情況下的匹配邏輯進(jìn)行簡單的總結(jié),如下:

條件 動作
情況一 matches 非空,mismatches 為空 遍歷 matches 集合元素,并與入?yún)⑦M(jìn)行匹配。只要有一個元素成功匹配入?yún)ⅲ纯煞祷?true。若全部失配,則返回 false。
情況二 matches 為空,mismatches 非空 遍歷 mismatches 集合元素,并與入?yún)⑦M(jìn)行匹配。只要有一個元素成功匹配入?yún)?,立?false。若全部失配,則返回 true。
情況三 matches 非空,mismatches 非空 優(yōu)先使用 mismatches 集合元素對入?yún)⑦M(jìn)行匹配,只要任一元素與入?yún)⑵ヅ涑晒?,就立即返?false,結(jié)束方法邏輯。否則再使用 matches 中的集合元素進(jìn)行匹配,只要有任意一個元素匹配成功,即可返回 true。若全部失配,則返回 false
情況四 matches 為空,mismatches 為空 直接返回 false

isMatch 方法邏輯不是很難理解,大家自己再看看。下面繼續(xù)分析 isMatchGlobPattern 方法。

public static boolean isMatchGlobPattern(String pattern, String value, URL param) {
    if (param != null && pattern.startsWith("$")) {
        // 引用服務(wù)消費者參數(shù),param 參數(shù)為服務(wù)消費者 url
        pattern = param.getRawParameter(pattern.substring(1));
    }
    // 調(diào)用重載方法繼續(xù)比較
    return isMatchGlobPattern(pattern, value);
}

public static boolean isMatchGlobPattern(String pattern, String value) {
    // 對 * 通配符提供支持
    if ("*".equals(pattern))
        // 匹配規(guī)則為通配符 *,直接返回 true 即可
        return true;
    if ((pattern == null || pattern.length() == 0)
            && (value == null || value.length() == 0))
        // pattern 和 value 均為空,此時可認(rèn)為兩者相等,返回 true
        return true;
    if ((pattern == null || pattern.length() == 0)
            || (value == null || value.length() == 0))
        // pattern 和 value 其中有一個為空,兩者不相等,返回 false
        return false;

    // 查找 * 通配符位置
    int i = pattern.lastIndexOf("*");
    if (i == -1) {
        // 匹配規(guī)則中不包含通配符,此時直接比較 value 和 pattern 是否相等即可,并返回比較結(jié)果
        return value.equals(pattern);
    }
    // 通配符 "*" 在匹配規(guī)則尾部,比如 10.0.21.*
    else if (i == pattern.length() - 1) {
        // 檢測 value 是否以不含通配符的匹配規(guī)則開頭,并返回結(jié)果。比如:
        // pattern = 10.0.21.*,value = 10.0.21.12,此時返回 true
        return value.startsWith(pattern.substring(0, i));
    }
    // 通配符 "*" 在匹配規(guī)則頭部
    else if (i == 0) {
        // 檢測 value 是否以不含通配符的匹配規(guī)則結(jié)尾,并返回結(jié)果
        return value.endsWith(pattern.substring(i + 1));
    }
    // 通配符 "*" 在匹配規(guī)則中間位置
    else {
        // 通過通配符將 pattern 分成兩半,得到 prefix 和 suffix
        String prefix = pattern.substring(0, i);
        String suffix = pattern.substring(i + 1);
        // 檢測 value 是否以 prefix 變量開頭,且以 suffix 變量結(jié)尾,并返回結(jié)果
        return value.startsWith(prefix) && value.endsWith(suffix);
    }
}

以上就是 isMatchGlobPattern 兩個重載方法的全部邏輯,這兩個方法分別對普通的匹配,以及”引用消費者參數(shù)“和通配符匹配做了支持。這兩個方法的邏輯并不是很復(fù)雜,而且我也在代碼上進(jìn)行了比較詳細(xì)的注釋,大家自己看看吧,就不多說了。

3. 總結(jié)

本篇文章對條件路由的表達(dá)式解析和服務(wù)路由過程進(jìn)行了較為細(xì)致的分析。總的來說,條件路由的代碼還是有一些復(fù)雜的,需要耐下心來看。在閱讀條件路由代碼的過程中,要多調(diào)試。一般的框架都會有單元測試,Dubbo 也不例外,因此大家可以直接通過 ConditionRouterTest 對條件路由進(jìn)行調(diào)試,無需自己手寫測試用例。

好了,關(guān)于條件路由就先分析到這,謝謝閱讀。

附錄:Dubbo 源碼分析系列文章
時間 文章
2018-10-01 Dubbo 源碼分析 - SPI 機制
2018-10-13 Dubbo 源碼分析 - 自適應(yīng)拓展原理
2018-10-31 Dubbo 源碼分析 - 服務(wù)導(dǎo)出
2018-11-12 Dubbo 源碼分析 - 服務(wù)引用
2018-11-17 Dubbo 源碼分析 - 集群容錯之 Directory
2018-11-20 Dubbo 源碼分析 - 集群容錯之 Router
本文在知識共享許可協(xié)議 4.0 下發(fā)布,轉(zhuǎn)載需在明顯位置處注明出處
作者:田小波
本文同步發(fā)布在我的個人博客:http://www.tianxiaobo.com


本作品采用知識共享署名-非商業(yè)性使用-禁止演繹 4.0 國際許可協(xié)議進(jìn)行許可。

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/72289.html

相關(guān)文章

  • Dubbo 源碼分析 - 集群容錯 Cluster

    摘要:集群用途是將多個服務(wù)提供者合并為一個,并將這個暴露給服務(wù)消費者。比如發(fā)請求,接受服務(wù)提供者返回的數(shù)據(jù)等。如果包含,表明對應(yīng)的服務(wù)提供者可能因網(wǎng)絡(luò)原因未能成功提供服務(wù)。如果不包含,此時還需要進(jìn)行可用性檢測,比如檢測服務(wù)提供者網(wǎng)絡(luò)連通性等。 1.簡介 為了避免單點故障,現(xiàn)在的應(yīng)用至少會部署在兩臺服務(wù)器上。對于一些負(fù)載比較高的服務(wù),會部署更多臺服務(wù)器。這樣,同一環(huán)境下的服務(wù)提供者數(shù)量會大于1...

    denson 評論0 收藏0
  • Dubbo 源碼分析 - 集群容錯 Directory

    摘要:在一個服務(wù)集群中,服務(wù)提供者數(shù)量并不是一成不變的,如果集群中新增了一臺機器,相應(yīng)地在服務(wù)目錄中就要新增一條服務(wù)提供者記錄。 1. 簡介 前面文章分析了服務(wù)的導(dǎo)出與引用過程,從本篇文章開始,我將開始分析 Dubbo 集群容錯方面的源碼。這部分源碼包含四個部分,分別是服務(wù)目錄 Directory、服務(wù)路由 Router、集群 Cluster 和負(fù)載均衡 LoadBalance。這幾個部分的...

    suemi 評論0 收藏0
  • Dubbo 源碼分析 - 集群容錯 LoadBalance

    摘要:即服務(wù)提供者目前正在處理的請求數(shù)一個請求對應(yīng)一條連接最少,表明該服務(wù)提供者效率高,單位時間內(nèi)可處理更多的請求。此時應(yīng)優(yōu)先將請求分配給該服務(wù)提供者。初始情況下,所有服務(wù)提供者活躍數(shù)均為。 1.簡介 LoadBalance 中文意思為負(fù)載均衡,它的職責(zé)是將網(wǎng)絡(luò)請求,或者其他形式的負(fù)載均攤到不同的機器上。避免集群中部分服務(wù)器壓力過大,而另一些服務(wù)器比較空閑的情況。通過負(fù)載均衡,可以讓每臺服務(wù)...

    ybak 評論0 收藏0
  • dubbo源碼解析——消費過程

    摘要:上一篇源碼解析概要篇中我們了解到中的一些概念及消費端總體調(diào)用過程。由于在生成代理實例的時候,在構(gòu)造函數(shù)中賦值了,因此可以只用該進(jìn)行方法的調(diào)用。 上一篇 dubbo源碼解析——概要篇中我們了解到dubbo中的一些概念及消費端總體調(diào)用過程。本文中,將進(jìn)入消費端源碼解析(具體邏輯會放到代碼的注釋中)。本文先是對消費過程的總體代碼邏輯理一遍,個別需要細(xì)講的點,后面會專門的文章進(jìn)行解析。...

    darkbug 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<