溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

spring cloud中Hystrix斷路器如何開啟和關(guān)閉

發(fā)布時間:2021-12-24 10:24:58 來源:億速云 閱讀:516 作者:小新 欄目:云計算

小編給大家分享一下spring cloud中Hystrix斷路器如何開啟和關(guān)閉,希望大家閱讀完這篇文章之后都有所收獲,下面讓我們一起去探討吧!

18 斷路器的開啟和關(guān)閉

斷路器開啟

        斷路器一旦開啟,就會直接調(diào)用回退方法,不再執(zhí)行命令,而且也不會更新鏈路的健康狀況。斷路器的開啟要滿足兩個條件:

        1、整個鏈路達到一定的閥值,默認情況下,10秒內(nèi)產(chǎn)生超過20次請求,則符合第一個條件。

        2、滿足第一個條件的情況下,如果請求的錯誤百分比大于閥值,則會打開斷路器,默認為50%。

        Hystrix的邏輯,先判斷是否滿足第一個條件,再判斷第二個條件,如果兩個條件都滿足,則會開啟斷路器。斷路器開啟的測試代碼,請見代碼清單6-8。

        代碼清單6-8:

        codes\06\6.2\first-hnystrix-client\src\main\java\org\crazyit\cloud\breaker\OpenTest.java

public class OpenTest {

    public static void main(String[] args) throws Exception {
        // 10秒內(nèi)有10個請求,則符合第一個條件
        ConfigurationManager.getConfigInstance().setProperty(
                "hystrix.command.default.metrics.rollingStats.timeInMilliseconds", 10000);
        ConfigurationManager.getConfigInstance().setProperty(
                "hystrix.command.default.circuitBreaker.requestVolumeThreshold", 10);
        ConfigurationManager.getConfigInstance().setProperty(
                "hystrix.command.default.circuitBreaker.errorThresholdPercentage", 50);
        for(int i = 0; i < 15; i++) {
            // 執(zhí)行的命令全部都會超時
            MyCommand c = new MyCommand();
            c.execute();
            // 斷路器打開后輸出信息
            if(c.isCircuitBreakerOpen()) {
                System.out.println("斷路器被打開,執(zhí)行第 " + (i + 1) + " 個命令");
            }
        }
    }

    /**
     * 模擬超時的命令
     * @author 楊恩雄
     *
     */
    static class MyCommand extends HystrixCommand<String> {
        // 設(shè)置超時的時間為500毫秒
        public MyCommand() {
            super(Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey("ExampleGroup"))
                    .andCommandPropertiesDefaults(HystrixCommandProperties.Setter()
                            .withExecutionTimeoutInMilliseconds(500))
                    );
        }

        protected String run() throws Exception {
            // 模擬處理超時
            Thread.sleep(800);
            return "";
        }

        @Override
        protected String getFallback() {
            return "";
        }
    }
}

        注意代碼清單6-8中的三個配置,第一個配置了數(shù)據(jù)統(tǒng)計的時間,第二個配置了請求的閥值,第三個配置了錯誤百分比。如果在10秒內(nèi),有大于10個請求發(fā)生,并且請求的錯誤率超過50%,則開啟斷路器。

        命令類MyCommand中,設(shè)置了命令執(zhí)行的超時時間為500毫秒,命令執(zhí)行需要800毫秒,換言之,該命令總會超時,命令模擬了現(xiàn)實環(huán)境中所依賴的服務(wù)癱瘓(超時響應(yīng))的情況。

        在運行類中,循環(huán)15次執(zhí)行命令,調(diào)用isCircuitBreakerOpen方法,如果斷路器打開,則輸出信息。運行代碼清單6-8的OpenTest類,輸出如下:

斷路器被打開,執(zhí)行第 11 個命令
斷路器被打開,執(zhí)行第 12 個命令
斷路器被打開,執(zhí)行第 13 個命令
斷路器被打開,執(zhí)行第 14 個命令
斷路器被打開,執(zhí)行第 15 個命令

        根據(jù)結(jié)果可知,前面執(zhí)行的10個命令沒有開啟斷路器,而到了第11個命令,斷路器被打開,命令不再執(zhí)行。

斷路器關(guān)閉

        斷路器打開后,在一段時間內(nèi),命令不會再執(zhí)行(一直觸發(fā)回退),這段時間我們稱作“休眠期”。休眠期默認值為5秒,休眠期結(jié)束后,Hystrix會嘗試性的執(zhí)行一次命令,此時斷路器的狀態(tài)不是開啟,也不是關(guān)閉,而是一個半開的狀態(tài),如果這一次命令執(zhí)行成功,則會關(guān)閉斷路器并清空鏈路的健康信息,如果執(zhí)行失敗,斷路器會繼續(xù)保持打開的狀態(tài)。斷路器的打開與關(guān)閉測試,請見代碼清單6-9。

        代碼清單6-9:

        codes\06\6.2\first-hnystrix-client\src\main\java\org\crazyit\cloud\breaker\CloseTest.java

public class CloseTest {

    public static void main(String[] args) throws Exception {
        // 10秒內(nèi)有3個請求就滿足第一個開啟斷路器的條件
        ConfigurationManager.getConfigInstance().setProperty(
                "hystrix.command.default.metrics.rollingStats.timeInMilliseconds", 10000);
        ConfigurationManager.getConfigInstance().setProperty(
                "hystrix.command.default.circuitBreaker.requestVolumeThreshold", 3);
        // 請求的失敗率,默認值為50%
        ConfigurationManager.getConfigInstance().setProperty(
                "hystrix.command.default.circuitBreaker.errorThresholdPercentage", 50);
        // 設(shè)置休眠期,斷路器打開后,這段時間不會再執(zhí)行命令,默認值為5秒,此處設(shè)置為3秒
        ConfigurationManager.getConfigInstance().setProperty(
                "hystrix.command.default.circuitBreaker.sleepWindowInMilliseconds", 3000);
        // 該值決定是否執(zhí)行超時
        boolean isTimeout = true;        
        for(int i = 0; i < 10; i++) {
            // 執(zhí)行的命令全部都會超時
            MyCommand c = new MyCommand(isTimeout);
            c.execute();        
            // 輸出健康狀態(tài)等信息
            HealthCounts hc = c.getMetrics().getHealthCounts();
            System.out.println("斷路器狀態(tài):" + c.isCircuitBreakerOpen() + 
                    ", 請求總數(shù):" + hc.getTotalRequests());
            if(c.isCircuitBreakerOpen()) {
                // 斷路器打開,讓下一次循環(huán)成功執(zhí)行命令
                isTimeout = false;
                System.out.println("=====  斷路器打開了,等待休眠期結(jié)束   =====");
                // 休眠期會在3秒后結(jié)束,此處等待4秒,確保休眠期結(jié)束
                Thread.sleep(4000);
            }    
        }
    }

    /**
     * 模擬超時的命令
     * @author 楊恩雄
     *
     */
    static class MyCommand extends HystrixCommand<String> {
        
        private boolean isTimeout;
        
        // 設(shè)置超時的時間為500毫秒
        public MyCommand(boolean isTimeout) {
            super(
                    Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey("ExampleGroup"))
                    .andCommandPropertiesDefaults(HystrixCommandProperties.Setter()
                            .withExecutionTimeoutInMilliseconds(500))
                 );
            this.isTimeout = isTimeout;
        }

        protected String run() throws Exception {
            // 讓外部決定是否超時
            if(isTimeout) {
                // 模擬處理超時
                Thread.sleep(800);
            } else {
                Thread.sleep(200);
            }
            return "";
        }

        @Override
        protected String getFallback() {
            return "";
        }
    }
}

        代碼清單中,配置了休眠期為3秒,循環(huán)10次,創(chuàng)建10個命令并予執(zhí)行。在執(zhí)行完第4個命令后,斷路器會被打開,此時我們等待休眠期結(jié)束,讓下次循環(huán)的命令執(zhí)行成功。

        代碼清單中使用了一個布而值來決定是否執(zhí)行成功,第5次命令會執(zhí)行成功,此時斷路器將會被關(guān)閉,剩下的命令全部都可以正常執(zhí)行。在循環(huán)體中,使用了HealthCounts對象,該對象用于記錄鏈路的健康信息,如果斷路器關(guān)閉(鏈路恢復(fù)健康),HealthCounts里面的健康信息將會被重置。運行代碼清單6-9,效果如下:

斷路器狀態(tài):false, 請求總數(shù):0
斷路器狀態(tài):false, 請求總數(shù):1
斷路器狀態(tài):false, 請求總數(shù):2
斷路器狀態(tài):true, 請求總數(shù):3
=====  斷路器打開了,等待休眠期結(jié)束   =====
斷路器狀態(tài):false, 請求總數(shù):0
斷路器狀態(tài):false, 請求總數(shù):1
斷路器狀態(tài):false, 請求總數(shù):1
斷路器狀態(tài):false, 請求總數(shù):3
斷路器狀態(tài):false, 請求總數(shù):3
斷路器狀態(tài):false, 請求總數(shù):5

看完了這篇文章,相信你對“spring cloud中Hystrix斷路器如何開啟和關(guān)閉”有了一定的了解,如果想了解更多相關(guān)知識,歡迎關(guān)注億速云行業(yè)資訊頻道,感謝各位的閱讀!

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI