Hystrix結(jié)合Eureka+OpenFeign的使用

概述

Hystrix是一個(gè)用于處理分布式系統(tǒng)的延遲和容錯(cuò)的開(kāi)元庫(kù),在分布式系統(tǒng)里,許多以來(lái)不可避免的會(huì)調(diào)用失敗,比如超時(shí),異常等,Hystrix能夠保證在一個(gè)依賴出問(wèn)題的情況下,不會(huì)導(dǎo)致整體服務(wù)失敗,避免級(jí)聯(lián)鼓掌,以提高分布式系統(tǒng)的彈性


"斷路器"本身是一種開(kāi)關(guān)裝置,當(dāng)某個(gè)服務(wù)單元發(fā)生故障之后,通過(guò)斷路器的鼓掌監(jiān)控(類似熔斷保險(xiǎn)絲),想調(diào)用方返回一個(gè)符合預(yù)期的,可處理的備選響應(yīng)(FallBack),而不是長(zhǎng)時(shí)間的等待或者跑出調(diào)用方無(wú)法處理的異常,這樣就保證了服務(wù)調(diào)用方的線程不會(huì)被長(zhǎng)時(shí)間,不必要的占用,從而避免了故障在分布式系統(tǒng)中的蔓延,乃至雪崩.

主要做的是

  • 服務(wù)熔斷

類似保險(xiǎn)絲達(dá)到最大服務(wù)訪問(wèn)后,直接拒絕訪問(wèn),拉閘限電,然后調(diào)用服務(wù)降級(jí)的方法并返回友好提示

  • 服務(wù)降級(jí)

程序運(yùn)行異常,超時(shí),服務(wù)熔斷出發(fā)服務(wù)降級(jí),線程池/信號(hào)量打滿也會(huì)導(dǎo)致服務(wù)降級(jí).服務(wù)器忙,請(qǐng)稍后再試,不讓客戶端等待并立刻返回一個(gè)友好提示,fallback

  • 服務(wù)限流

秒殺高并發(fā)等操作,嚴(yán)禁一窩蜂的過(guò)來(lái)?yè)頂D,大家排隊(duì),一秒鐘N個(gè),有序進(jìn)行

  • 接近實(shí)時(shí)的監(jiān)控

實(shí)操

構(gòu)建

  • 引入jar包
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
        </dependency>

高并發(fā)測(cè)試

在使用我們的jmeter200線程,200輪次的2w次請(qǐng)求同一耗時(shí)比較慢的接口時(shí)

public String paymentInfo_error(Integer id) {
        try {
            TimeUnit.SECONDS.sleep(3);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return "線程池" + Thread.currentThread().getName() + "\t" + id + "\t" + "^_^" + "耗時(shí)3秒鐘";
    }

這個(gè)時(shí)候,即使訪問(wèn)比較快的方法,也會(huì)受到拖累,因?yàn)閠omcat默認(rèn)200個(gè)線程,因?yàn)樯鲜龇椒▓?zhí)行時(shí),多數(shù)線程都被調(diào)用去擁擠到那兒去執(zhí)行滿方法,導(dǎo)致我們?cè)菊5姆?wù)也會(huì)被變慢

public String paymentInfo_OK(Integer id) {
        return "線程池" + Thread.currentThread().getName() + "\t" + id + "\t" + "^_^";
    }

hyxtrix如何解決

降級(jí)處理緯度

  • 服務(wù)端down機(jī),不能讓客戶端一直等待,必須有服務(wù)降級(jí)(選擇較多)
  • 對(duì)方服務(wù)執(zhí)行成功,但時(shí)間大于我所期待的時(shí)間,自己做服務(wù)降級(jí)處理
  1. 服務(wù)端處理

在主啟動(dòng)類上加上開(kāi)啟配置注解

@EnableCircuitBreaker

在可能出錯(cuò)的業(yè)務(wù)類中添加服務(wù)降級(jí)fallback方法,并指定

 /**
     * @HystrixCommand 指定fallback降級(jí)方法
     * @HystrixProperty 指定峰值等待時(shí)間
     */
    @HystrixCommand(fallbackMethod = "paymentInfo_error_timeOutHandler", commandProperties = {
            @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "3000")})
    public String paymentInfo_error(Integer id) {
        try {
            TimeUnit.SECONDS.sleep(5);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return "線程池" + Thread.currentThread().getName() + "\t" + id + "\t" + "^_^" + "耗時(shí)5秒鐘";
    }
    public String paymentInfo_error_timeOutHandler(Integer id) {
        return "線程池" + Thread.currentThread().getName() + "\t" + id + "\t" + "┭┮﹏┭┮" + "8001服務(wù)超時(shí)";
    }
  1. 客戶端處理(openFeign+hyxtrix)

主啟動(dòng)類加載開(kāi)啟配置注解

@EnableHystrix

yml配置文件開(kāi)啟hyxtrix

feign:
  hystrix:
    enabled: true

控制層添加fallback方法并指定

/**
     * @HystrixCommand 指定fallback降級(jí)方法
     * @HystrixProperty 指定峰值等待時(shí)間
     */
    @GetMapping("error/{id}")
    @HystrixCommand(fallbackMethod = "paymentInfo_error_timeOutHandler", commandProperties = {
            @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "1000")})
    public String error(@PathVariable("id") Integer id) {
        return feignService.error(id);
    }
    public String paymentInfo_error_timeOutHandler(Integer id) {
        return "線程池" + Thread.currentThread().getName() + "\t" + id + "\t" + "┭┮﹏┭┮" + "80服務(wù)超時(shí)";
    }

全局服務(wù)降級(jí)配置

由于每個(gè)方法都要配置一個(gè)fallback,導(dǎo)致代碼膨脹和麻煩,所以我們可以定義一個(gè)全局通用的服務(wù)降級(jí)處理,和自定義分開(kāi)

  1. 再需要做服務(wù)降級(jí)的restControll上加上全局降級(jí)配置注解(defaultFallback參數(shù)為,類中的共享fallback方法名)

@DefaultProperties(defaultFallback = "payment_Global_FallbackMethod")

  1. 再需要做服務(wù)降級(jí)的方法上,加上服務(wù)降級(jí)處理,并不需要加參數(shù),默認(rèn)走我們的全局服務(wù)降級(jí)處理

@HystrixCommand

全局服務(wù)降級(jí)配置(二)

由于業(yè)務(wù)不同,需要考慮解耦性的情況下,對(duì)于一個(gè)服務(wù)調(diào)用接口,再不同的controller里都有用到,那么對(duì)每一個(gè)controller進(jìn)行配置,也會(huì)增加耦合性,所以也有另一種方式來(lái)實(shí)現(xiàn)這種情況

  1. 針對(duì)于服務(wù)發(fā)現(xiàn)接口類去實(shí)現(xiàn)一個(gè)專門去配置fallback的類,并實(shí)現(xiàn)他們的接口方法
  2. 并在接口上的Fileclent注解上,指定這個(gè)class為,服務(wù)調(diào)用失敗統(tǒng)一的fallback處理

@FeignClient(value = "CLOUD-PROVIDER-HYSTRIX-PAYMENT",fallback = FeignFallbackServiceImpl.class)

服務(wù)熔斷

服務(wù)熔斷類比保險(xiǎn)絲達(dá)到最大服務(wù)訪問(wèn)后,直接拒絕訪問(wèn),拉閘限電,然后調(diào)用服務(wù)降級(jí)的方法并返回友好提示

熔斷機(jī)制是應(yīng)對(duì)雪崩效應(yīng)的一種微服務(wù)鏈路保護(hù)機(jī)制,當(dāng)扇出鏈路的某個(gè)微服務(wù)出錯(cuò)不可用或者訪問(wèn)時(shí)間太長(zhǎng)時(shí)間,會(huì)進(jìn)行服務(wù)的降級(jí),勁兒熔斷該節(jié)點(diǎn)微服務(wù)的調(diào)用,快速返回錯(cuò)誤的響應(yīng)信息

在Spring Cloud框架里,熔斷機(jī)制通過(guò)Hystrix實(shí)現(xiàn),Hystrix會(huì)監(jiān)控微服務(wù)之間的調(diào)用狀況,當(dāng)失敗的調(diào)用到一定閾值,缺省是五秒內(nèi)20次調(diào)用失敗,就會(huì)啟動(dòng)熔斷機(jī)制,熔斷機(jī)制.當(dāng)檢測(cè)到該節(jié)點(diǎn)微服務(wù)調(diào)用響應(yīng)正常后,恢復(fù)調(diào)用鏈路

實(shí)現(xiàn)

在需要服務(wù)熔斷的接口上添加服務(wù)熔斷注解

// =============服務(wù)熔斷
    @HystrixCommand(fallbackMethod = "paymentCircuitBreaker_fallback",commandProperties = {
            @HystrixProperty(name = "circuitBreaker.enabled",value = "true"),//是否開(kāi)啟斷路器
            @HystrixProperty(name = "circuitBreaker.requestVolumeThreshold",value = "10"),//請(qǐng)求次數(shù)
            @HystrixProperty(name = "circuitBreaker.sleepWindowInMilliseconds",value = "10000"),//時(shí)間范圍
            @HystrixProperty(name = "circuitBreaker.errorThresholdPercentage",value = "60")//失敗率%達(dá)到多少后跳閘
    })
    public String paymentCircuitBreaker(Integer id) {
        if (id < 0) {
            throw new RuntimeException("id 不能負(fù)數(shù)");
        }
        return Thread.currentThread().getName() + "\t" + "調(diào)用成功,流水號(hào): " + IdUtil.fastSimpleUUID();
    }

其他配置可參考HystrixCommandProperties類,有詳細(xì)參數(shù)

總結(jié)

服務(wù)熔斷器是,當(dāng)我們?cè)O(shè)定好的閾值達(dá)到了,便進(jìn)行服務(wù)熔斷的機(jī)制,再次重復(fù)調(diào)用直接返回fallback服務(wù)降級(jí)處理,根據(jù)內(nèi)部算法慢慢的將服務(wù)進(jìn)行恢復(fù)正常可調(diào)用狀態(tài)

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

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

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