SpringCloud Hystrix使用和配置,SpringCloud Hystrix服務熔斷降級


SpringCloud Hystrix使用和配置,SpringCloud Hystrix服務熔斷降級

 

================================

©Copyright 蕃薯耀 2021-03-15

https://www.cnblogs.com/fanshuyao/

 

一、SpringCloud Hystrix概述
Hystrix不再處於積極開發中,並且目前處於維護模式.Hystrix(版本1.5.18)足夠穩定,可以滿足Netflix現有應用程序的需求。

Hystrix是一個延遲和容錯庫,旨在隔離對遠程系統,服務和第三方庫的訪問點,停止級聯故障,並在不可避免發生故障的復雜分布式系統中實現彈性。

在分布式環境中,不可避免地會有許多服務依賴項中的某些失敗。 Hystrix是一個庫,可通過添加等待時間容限和容錯邏輯來幫助您控制這些分布式服務之間的交互。 Hystrix通過隔離服務之間的訪問點,停止服務之間的級聯故障並提供后備選項來實現此目的,所有這些都可以提高系統的整體彈性。

Hystrix旨在執行以下操作:
1、提供保護並控制延遲和失敗,以及通過第三方客戶端庫(通常是通過網絡)訪問的依賴項的失敗。
2、停止復雜的分布式系統中的級聯故障。
3、快速失敗,迅速恢復。
4、回退並在可能的情況下正常降級。
5、啟用近乎實時的監視,警報和操作控制。

 

架構流程圖:

 

circuit-breaker:

 

 

二、SpringCloud Hystrix使用和配置,以及服務熔斷降級
服務提供者:springCloud-hystrix-provider-8651
服務消費者:springCloud-hystrix-web-8655
一般在服務消費者實現服務熔斷降級,當然服務提供者也同樣可以實現。
下面以服務消費者實現服務熔斷降級為例進行配置開發。

1、pom.xml引入依賴
引入openfeign、eureka-client、hystrix

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-openfeign</artifactId>
    <version>2.2.7.RELEASE</version>
</dependency>

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
    <version>2.2.7.RELEASE</version>
</dependency>

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
    <version>2.2.7.RELEASE</version>
</dependency>

<dependency>
    <groupId>cn.hutool</groupId>
    <artifactId>hutool-all</artifactId>
    <version>5.4.4</version>
</dependency>

 

2、application.properties配置文件修改
啟動hystrix:將feign.hystrix.enabled設置為true

server.port=8655

spring.application.name=SPRINGCLOUD-EUREKA-FEIGN-HYSTRIX

#eureka服務端的實例名稱
eureka.instance.hostname=HOSTNAME-EUREKA-FEIGN-HYSTRIX-8655

#eureka實例名稱
eureka.instance.instance-id=INSTANCEID-EUREKA-FEIGN-HYSTRIX-8655
#路徑顯示IP地址
eureka.instance.prefer-ip-address=true
#eureka客戶端向服務端發送心跳的時間間隔,單元為秒,默認為30秒
eureka.instance.lease-renewal-interval-in-seconds=2
#eureka服務端收到最后一次心跳等待的時間上限,超時將移除服務,單元為秒,默認為90秒
eureka.instance.lease-expiration-duration-in-seconds=5

#false表示向注冊中心注冊自己
eureka.client.register-with-eureka=false
#是否從Eureka抓取已有的注冊信息,默認為true。單節點不用設置,集群必須設置為true,才能配置ribbon使用負載均衡
eureka.client.fetch-registry=true
#設置與Eureka server交互的地址查詢服務和注冊服務都需要依賴這個地址
eureka.client.service-url.defaultZone=http://eureka8501.com:8501/eureka


#feign客戶端建立連接最大的時間
feign.client.config.default.read-timeout=3000
#建立連接后,從服務器獲取響應結果的最大時間
feign.client.config.default.connect-timeout=3000

#打印日志的4個級別:none、basic、headers、full
feign.client.config.default.logger-level=full
#設置要日志打印的接口類
logging.level.com.lqy.springCloud.hystrix.web.service.HystrixService: DEBUG

#啟動hystrix
feign.hystrix.enabled=true

 

3、啟動類
有三個注解:
EnableFeignClients:啟動FeignClients
EnableEurekaClient:啟動EurekaClient
EnableHystrix:啟動Hystrix

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.netflix.hystrix.EnableHystrix;
import org.springframework.cloud.openfeign.EnableFeignClients;

@SpringBootApplication
@EnableFeignClients
@EnableEurekaClient
@EnableHystrix
public class SpringCloudHystrixWeb8655Application {

    public static void main(String[] args) {
        SpringApplication.run(SpringCloudHystrixWeb8655Application.class, args);
    }

}

 

 

4、FeignClient接口定義及降級實現
使用@FeignClient注解定義,value:遠程服務名,fallback:服務降級的實現類

接口調用定義類:

import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;

import com.lqy.springCloud.hystrix.web.controller.Result;
import com.lqy.springCloud.hystrix.web.service.impl.HystrixServiceImpl;

/**
 *   使用OpenFeign調用遠程服務實現服務降級
 * value:遠程服務名
 * fallback:服務降級的實現類
 * 
 *
 */
@FeignClient(value="SPRINGCLOUD-EUREKA-SERVER-HYSTRIX", fallback = HystrixServiceImpl.class)
public interface HystrixService {

    @RequestMapping(value = "/test", produces = MediaType.APPLICATION_JSON_VALUE)
    public Result test();
    
    
    @RequestMapping(value = "/get/{text}", produces = MediaType.APPLICATION_JSON_VALUE)
    public Result get(@PathVariable(required = false, value = "text") String text);
    
    
    @RequestMapping(value = "/cal/{text}", produces = MediaType.APPLICATION_JSON_VALUE)
    public Result cal(@PathVariable(value = "text") int text) throws InterruptedException;
    
    
    @RequestMapping(value = "/timeout/{text}", produces = MediaType.APPLICATION_JSON_VALUE)
    public Result timeout(@PathVariable(required = false, value = "text") String text) throws InterruptedException;
    
}

 

降級實現類:
這里需要注意的是:必須要加上注解@Component

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import com.lqy.springCloud.hystrix.web.controller.Result;
import com.lqy.springCloud.hystrix.web.service.HystrixService;

/**
 * 必須要有注解:@Component,不然會報錯
 *
 */
@Component
public class HystrixServiceImpl implements HystrixService{

    @Value("${server.port}")
    private String serverPort;
    
    @Override
    public Result test() {
        return Result.fail(serverPort);
    }

    @Override
    public Result get(String text) {
        return Result.fail(serverPort);
    }

    @Override
    public Result cal(int text) throws InterruptedException {
        return Result.fail(serverPort);
    }

    @Override
    public Result timeout(String text) throws InterruptedException {
        return Result.fail(serverPort);
    }
    
}

 

缺少@Component,啟動報錯:

Caused by: java.lang.IllegalStateException: No fallback instance of type class com.lqy.springCloud.hystrix.web.service.impl.HystrixServiceImpl found for feign client SPRINGCLOUD-EUREKA-SERVER-HYSTRIX
    at org.springframework.cloud.openfeign.HystrixTargeter.getFromContext(HystrixTargeter.java:81) ~[spring-cloud-openfeign-core-2.2.7.RELEASE.jar:2.2.7.RELEASE]
    at org.springframework.cloud.openfeign.HystrixTargeter.targetWithFallback(HystrixTargeter.java:72) ~[spring-cloud-openfeign-core-2.2.7.RELEASE.jar:2.2.7.RELEASE]
    at org.springframework.cloud.openfeign.HystrixTargeter.target(HystrixTargeter.java:49) ~[spring-cloud-openfeign-core-2.2.7.RELEASE.jar:2.2.7.RELEASE]

 

5、、不使用FeignClient接口,自己實現服務降級

使用注解@HystrixCommand進行服務降級,通過fallbackMethod方法實現當服務降級時回調的方法;
commandProperties可以不配置,示例中配置了超時(3秒超時,調用服務降級)。
HystrixProperty的配置可以見:

https://github.com/Netflix/Hystrix/wiki/Configuration
import java.util.concurrent.TimeUnit;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import com.lqy.springCloud.hystrix.web.controller.Result;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty;

/**
 *   自帶服務實現,不使用OpenFeign,使用@HystrixCommand
 * @HystrixCommand:注解實現服務降級
 * 
 *
 */
@Service
public class HystrixCommandServiceImpl {

    @Value("${server.port}")
    private String serverPort;
    
    @HystrixCommand(fallbackMethod = "selfTimeoutFallBack", commandProperties = {
            @HystrixProperty(name="execution.isolation.thread.timeoutInMilliseconds", value = "3000")
    })
    public Result selfTimeout() throws InterruptedException {
        TimeUnit.SECONDS.sleep(5);
        return Result.ok(serverPort);
    }
    
    public Result selfTimeoutFallBack() throws InterruptedException {
        return Result.failMsg(serverPort + ":服務器請求超時,請重試");
    }
    
}

 

6、Controller調用
hystrixService是使用OpenFeign調用遠程服務
hystrixCommandServiceImpl是調用自己本身的服務

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.lqy.springCloud.hystrix.web.service.HystrixService;
import com.lqy.springCloud.hystrix.web.service.impl.HystrixCommandServiceImpl;


@RestController
public class WebController {

    @Value("${server.port}")
    private String serverPort;
    
    @Autowired
    private HystrixService hystrixService;
    @Autowired
    private HystrixCommandServiceImpl hystrixCommandServiceImpl;
    
    @RequestMapping("/self")
    public Result self() {
        return Result.ok("端口:" + serverPort);
    }
    
    @RequestMapping("/test")
    public Result test() {
        return hystrixService.test();
    }
    
    @RequestMapping(value = "/get/{text}", produces = MediaType.APPLICATION_JSON_VALUE)
    public Result get(@PathVariable(required = false, value = "text") String text) throws InterruptedException {
        return hystrixService.get(text);
    }
    
    @RequestMapping(value = "/cal/{text}", produces = MediaType.APPLICATION_JSON_VALUE)
    public Result cal(@PathVariable(value = "text") int text) throws InterruptedException {
        return hystrixService.cal(text);
    }
    
    @RequestMapping("/timeout/{text}")
    public Result timeout(@PathVariable(required = false, value = "text") String text) throws InterruptedException {
        return hystrixService.timeout(text);
    }
    
    
    @RequestMapping("/selfTimeout")
    public Result selfTimeout() throws InterruptedException {
        return hystrixCommandServiceImpl.selfTimeout();
    }
    
    
}

 

7、Hystrix服務降級測試


調用遠程服務獲取數據:

http://127.0.0.1:8655/get/ccbb

{
  "result": true,
  "timestamp": "2021-03-15 11:31:05",
  "msg": "操作成功。",
  "datas": "端口:8651,ccbb"
}

 


調用遠程服務超時:
http://127.0.0.1:8655/timeout/ccbb

{
"result": false,
"timestamp": "2021-03-15 11:31:29",
"msg": "操作失敗!",
"datas": "8655"
}

 

調用遠程服務發生錯誤(除0):

http://127.0.0.1:8655/cal/0
{
"result": false,
"timestamp": "2021-03-15 11:32:45",
"msg": "操作失敗!",
"datas": "8655"
}

 

調用本身服務降級:
http://127.0.0.1:8655/selfTimeout

{
"result": false,
"timestamp": "2021-03-15 11:32:10",
"msg": "8655:服務器請求超時,請重試",
"datas": null
}

 

8、@HystrixCommand 默認是1秒超時,超時報錯:

@HystrixCommand
public Result timeout(String text) throws InterruptedException {
    TimeUnit.SECONDS.sleep(5);
    return Result.ok(text);
}

There was an unexpected error (type=Internal Server Error, status=500).
timeout timed-out and fallback failed.
com.netflix.hystrix.exception.HystrixRuntimeException: timeout timed-out and fallback failed.
    at com.netflix.hystrix.AbstractCommand$22.call(AbstractCommand.java:832)
    at com.netflix.hystrix.AbstractCommand$22.call(AbstractCommand.java:807)
Caused by: java.util.concurrent.TimeoutException
    at com.netflix.hystrix.AbstractCommand.handleTimeoutViaFallback(AbstractCommand.java:997)
    at com.netflix.hystrix.AbstractCommand.access$500(AbstractCommand.java:60)
    at com.netflix.hystrix.AbstractCommand$12.call(AbstractCommand.java:609)
    at com.netflix.hystrix.AbstractCommand$12.call(AbstractCommand.java:601)
    at rx.internal.operators.OperatorOnErrorResumeNextViaFunction$4.onError(OperatorOnErrorResumeNextViaFunction.java:140)

 

三、@HystrixCommand屬性配置
官網地址:

https://github.com/Netflix/Hystrix/wiki/Configuration

 

1、Command Properties(命令屬性)(Command 注解相關的屬性配置)

Execution屬性

execution.isolation.strategy
execution.isolation.thread.timeoutInMilliseconds
execution.timeout.enabled
execution.isolation.thread.interruptOnTimeout
execution.isolation.thread.interruptOnCancel
execution.isolation.semaphore.maxConcurrentRequests

 

Fallback屬性

fallback.isolation.semaphore.maxConcurrentRequests
fallback.enabled

 

Circuit Breaker屬性

circuitBreaker.enabled
circuitBreaker.requestVolumeThreshold
circuitBreaker.sleepWindowInMilliseconds
circuitBreaker.errorThresholdPercentage
circuitBreaker.forceOpen
circuitBreaker.forceClosed

 

circuitBreaker.enabled

Default Value:true

此屬性確定斷路器是否將用於跟蹤運行狀況以及在跳閘時用於短路請求。

 

circuitBreaker.requestVolumeThreshold

Default Value :20

此屬性在滾動窗口中設置將使電路跳閘的最小請求數。

例如,如果值為20,則如果在滾動窗口(例如10秒的窗口)中僅收到19個請求,則即使所有19個失敗,電路也不會跳閘斷開。

 

circuitBreaker.sleepWindowInMilliseconds

Default Value :5000

此屬性設置在電路跳閘后拒絕請求的時間,然后允許再次嘗試確定是否應再次閉合電路。

 

circuitBreaker.errorThresholdPercentage

Default Value:50

該屬性設置錯誤百分比,電路應在該百分比或以上跳閘,並啟動對后備邏輯的短路請求。

 

Metrics屬性

metrics.rollingStats.timeInMilliseconds
metrics.rollingStats.numBuckets
metrics.rollingPercentile.enabled
metrics.rollingPercentile.timeInMilliseconds
metrics.rollingPercentile.numBuckets
metrics.rollingPercentile.bucketSize
metrics.healthSnapshot.intervalInMilliseconds

 

Request Context屬性

requestCache.enabled
requestLog.enabled

 

2、Collapser Properties(折疊器屬性

maxRequestsInBatch
timerDelayInMilliseconds
requestCache.enabled

 

3、Thread Pool Properties(線程池屬性

coreSize
maximumSize
maxQueueSize
queueSizeRejectionThreshold
keepAliveTimeMinutes
allowMaximumSizeToDivergeFromCoreSize
metrics.rollingStats.timeInMilliseconds
metrics.rollingStats.numBuckets

 

四、SpringCloud Hystrix dashboard2.2.7使用和配置,SpringCloud Hystrix dashboard服務監控

https://www.cnblogs.com/fanshuyao/p/14539320.html

 

 

 

(時間寶貴,分享不易,捐贈回饋,^_^)

================================

©Copyright 蕃薯耀 2021-03-15

https://www.cnblogs.com/fanshuyao/

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM