微服務降級、熔斷與雪崩

本人博客網址:https://www.wzbjsz.cn

在微服務中,當持續的請求大量的失敗時,線程堆積導致服務器不堪重負,就會出現雪崩事件,這時候我們就要採取措施,進行熔斷與服務降級,下面先說這三者的概念
雪崩

假如有三個微服務A、B、C,一個請求的執行過程是A->B->C,當B請求C出現大量錯誤(即錯誤)到達一定的閾值,服務不堪重負C服務崩潰了,那麼B任然在不停地請求C,就會有大量的線程堆積,慢慢地B也崩了,隨後A也崩了,這就是雪崩效應

熔斷

當下遊的服務因爲某種原因突然變得不可用或響應過慢,上游服務爲了保證自己整體服務的可用性,不再繼續調用目標服務,直接返回,快速釋放資源。如果目標服務情況好轉則恢復調用(hytrix自動測試請求,請求在閾值內恢復調用)。

服務降級

當下遊的服務因爲某種原因響應過慢,下游服務主動停掉一些不太重要的業務,釋放出服務器資源,增加響應速度!
當下遊的服務因爲某種原因不可用,上游主動調用本地的一些降級邏輯,避免卡頓,迅速返回給用戶!

服務降級有很多種降級方式!如開關降級、限流降級、熔斷降級!
file
代碼:
添加依賴
添加Hystrix依賴,調用通過ribbon來負載均衡



org.springframework.boot
spring-boot-starter-web



org.springframework.boot
spring-boot-starter-test
test


org.springframework.cloud
spring-cloud-starter-config
1.4.5.RELEASE


org.springframework.cloud
spring-cloud-starter-eureka
1.4.6.RELEASE


org.apache.httpcomponents
httpclient
4.5.8


org.springframework.cloud
spring-cloud-starter-hystrix
1.3.2.RELEASE
 




org.springframework.cloud
spring-cloud-dependencies
Dalston.SR5
pom
import



修改配置
修改application.properties文件,設置名稱,端口和註冊中心的信息

spring.application.name=eureka-ribbon-consumer-hystrix
server.port=9091

#設置服務註冊中心地址,指向另一個註冊中心
eureka.client.serviceUrl.defaultZone=http://eureka1:8761/eureka/,http://eureka2:8761/eureka/
修改啓動類

  在啓動類中添加註解開啓熔斷。@EnableCircuitBreaker

@EnableCircuitBreaker // 開啓熔斷 斷路器
@EnableEurekaClient
@SpringBootApplication
public class SpringcloudEurekaConsumerApplication {

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

}
修改業務層

  業務層代碼中在getUsers方法中通過ribbon來獲取負載均衡的地址,通過RestTemplate來調用服務,在方法頭部添加@HystrixCommand註解,通過fallbackMethod 屬性指定當調用的provider方法異常的時候的fallback方法爲fallBack方法,然後在其方法中返回了託底數據。

@Service
public class UserService {

/**
 * ribbon 負載均衡
 *    LoadBalancerClient 通過服務名稱可以獲取對應的服務的相關信息 ip port等
 */
@Autowired

private LoadBalancerClient loadBalancerClient;

@HystrixCommand(fallbackMethod = "fallBack")
public List<User> getUsers(){
    // ServiceInstance 封裝的有服務的基本信息  IP和端口等
    ServiceInstance si = this.loadBalancerClient.choose("eureka-ribbon-provider");
    StringBuilder sb = new StringBuilder();
    sb.append("http://")
            .append(si.getHost())
            .append(":")
            .append(si.getPort())
            .append("/user");
    System.out.println("服務地址:"+sb.toString());
    // SpringMVC RestTemplate
    RestTemplate rt = new RestTemplate();
    ParameterizedTypeReference<List<User>> type = new ParameterizedTypeReference<List<User>>() {};
    // ResponseEntity:封裝了返回值的信息
    ResponseEntity<List<User>> response = rt.exchange(sb.toString(), HttpMethod.GET,null,type);
    List<User> list = response.getBody();
    return list;
}

/**
 * 服務降級
 *   返回託底數據的方法
 * @return
 */
public List<User> fallBack(){
    List<User> list = new ArrayList<>();
    list.add(new User(3,"我是託底數據",22));
    return list;
}

}

控制層代碼僅僅是調用了業務層的方法
file
測試

  啓動eureka註冊中心,然後啓動consumer服務,provider服務不用啓動,這樣我們訪問consumer中的服務的時候就會出現異常,當我們瀏覽器看到託底數據的話,表示降級成功.
file

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章