溫馨提示×

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

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

怎么在springcloud中使用Hystrix對(duì)微服務(wù)進(jìn)行降級(jí)管理

發(fā)布時(shí)間:2021-05-17 17:30:06 來(lái)源:億速云 閱讀:169 作者:Leah 欄目:編程語(yǔ)言

這期內(nèi)容當(dāng)中小編將會(huì)給大家?guī)?lái)有關(guān)怎么在springcloud中使用Hystrix對(duì)微服務(wù)進(jìn)行降級(jí)管理,文章內(nèi)容豐富且以專(zhuān)業(yè)的角度為大家分析和敘述,閱讀完這篇文章希望大家可以有所收獲。

一:Hystrix是什么?

1.1:基本解釋

Hystrix最開(kāi)始由Netflix(看過(guò)美劇的都知道,它是一個(gè)美劇影視制作的巨頭公司)開(kāi)源的,后來(lái)由Spring Cloud Hystrix基于這款框架實(shí)現(xiàn)了斷路器、線程隔離等一系列服務(wù)保護(hù)功能,該框架的目標(biāo)在于通過(guò)控制訪問(wèn)遠(yuǎn)程系統(tǒng)、服務(wù)和第三方庫(kù)的節(jié)點(diǎn),從而延遲和故障提供更強(qiáng)大的容錯(cuò)能力。hystrix具備服務(wù)降級(jí)、服務(wù)熔斷、線程和信號(hào)隔離、請(qǐng)求緩存、請(qǐng)求合并以及服務(wù)監(jiān)控等強(qiáng)大功能。起到了微服務(wù)的保護(hù)機(jī)制,防止某個(gè)單元出現(xiàn)故障.從而引起依賴(lài)關(guān)系引發(fā)故障的蔓延,最終導(dǎo)致整個(gè)系統(tǒng)的癱瘓。

1.2:斷路器的概念

斷路器本身是一個(gè)開(kāi)關(guān)裝置,用在電路上保護(hù)線路過(guò)載,當(dāng)線路中有電器發(fā)生短路的時(shí)候?!皵嗦菲鳌蹦軌蚣皶r(shí)切斷故障,防止發(fā)生過(guò)載、發(fā)熱甚至起火等嚴(yán)重后果。當(dāng)分布式架構(gòu)中,斷路器模式起到的作用也是類(lèi)似的。當(dāng)某個(gè)服務(wù)發(fā)生故障的時(shí)候,通過(guò)斷路器的故障監(jiān)控向調(diào)用方返回一個(gè)錯(cuò)誤響應(yīng),而不是長(zhǎng)時(shí)間的線程掛機(jī),無(wú)限等待。這樣就不會(huì)使線程因故障服務(wù)被長(zhǎng)時(shí)間占用不釋放,避免了故障在分布式系統(tǒng)中的蔓延。如下圖是現(xiàn)實(shí)中的斷路器,它是一個(gè)開(kāi)關(guān)裝置:

怎么在springcloud中使用Hystrix對(duì)微服務(wù)進(jìn)行降級(jí)管理

二:Hystrix解決超時(shí)問(wèn)題

2.1:?jiǎn)栴}

假設(shè)我們前端提供了用戶查詢(xún)訂單的功能,首先請(qǐng)求映射到OrderController,控制器通過(guò)調(diào)用服務(wù)orderService獲取訂單信息,前端傳過(guò)來(lái)兩個(gè)參數(shù):一個(gè)是訂單id,一個(gè)是用戶id,orderService需要通過(guò)用戶id調(diào)取用戶服務(wù)來(lái)獲取用戶的相關(guān)信息返回給訂單服務(wù)去組裝信息,假設(shè)這里是通過(guò)http請(qǐng)求的,我們有一個(gè)單獨(dú)的工程叫做:userService部署在其他的服務(wù)器上。但是這個(gè)服務(wù)器宕機(jī)了,這時(shí)候訂單服務(wù)調(diào)取用戶信息就失敗了,然后查詢(xún)訂單整個(gè)請(qǐng)求就失敗了!由一個(gè)服務(wù)的宕機(jī)就導(dǎo)致整個(gè)查詢(xún)都失敗了,牽一發(fā)而動(dòng)全身。流程見(jiàn)下圖:

怎么在springcloud中使用Hystrix對(duì)微服務(wù)進(jìn)行降級(jí)管理

2.2:使用Hystrix進(jìn)行服務(wù)降級(jí)

2.2.1:引入hystrix依賴(lài) 這里引入了spring-cloud-starter-netflix-hystrix,springboot的starter里面整合了hystrix

<properties>
    <java.version>1.8</java.version>
    <spring-cloud.version>Greenwich.SR1</spring-cloud.version>
  </properties>

  <dependencies>
    <dependency>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
    </dependency>
    <dependency>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId>
    </dependency>

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

    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-test</artifactId>
      <scope>test</scope>
    </dependency>
  </dependencies>

  <dependencyManagement>
    <dependencies>
      <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-dependencies</artifactId>
        <version>${spring-cloud.version}</version>
        <type>pom</type>
        <scope>import</scope>
      </dependency>
    </dependencies>
  </dependencyManagement>

2.2.2:模擬訂單請(qǐng)求

首先通過(guò)OrderController映射/order請(qǐng)求,獲取前端傳入的參數(shù)orderId和useId,然后調(diào)用orderDetailService方法,

@RestController
public class OrderController {

  @Resource
  private OrderService orderService;


  /**
   * 獲取訂單信息
   *
   * @param orderNo
   * @return
   */
  @PostMapping("/order")
  public ResultVo<OrderDetail> getOrderInfo(@RequestParam("orderId") Long orderNo, @RequestParam("userId") Long userId) {

    OrderDetail orderDetail = orderService.orderDetailService(orderNo, userId);
    ResultVo resultVo = new ResultVo<>();
    resultVo.setCode(100);
    resultVo.setMessage("請(qǐng)求成功");
    resultVo.setData(orderDetail);
    return resultVo;
  }
}

2.2.3:訂單服務(wù)調(diào)取其他服務(wù)

這里引入了RestTemplate,它是一個(gè)spring封裝的http映射請(qǐng)求工具類(lèi),然后通過(guò)http請(qǐng)求訪問(wèn)url = "http://192.168.80.153:8070/user/getUser"獲取用戶名,將值給訂單對(duì)象。不過(guò)假如在這其中發(fā)生了調(diào)用異常,請(qǐng)求用戶服務(wù)異常的話,那么返回給前端就是一串空的訂單信息,導(dǎo)致用戶看到的訂單為空。在使用hystrix之后,可以用@HystrixCommand(fallbackMethod = "orderFallBack")注解,在fallbackMethod中指定回退的方法,這里必須注意在@HystrixCommand上的方法其指定的回調(diào)方法必須和原方法的參數(shù)保持一致,這里包括參數(shù)類(lèi)型、參數(shù)個(gè)數(shù)、參數(shù)順序。我們?cè)诨卣{(diào)用法中模擬去查詢(xún)緩存數(shù)據(jù),返回給訂單。有人又要問(wèn)了,如果查詢(xún)緩存服務(wù)器再異常呢?不排除這種可能性。如果是這樣的話,依然可以使用@HystrixCommand注解在回調(diào)方法中,再指定其他的回調(diào)方法:

@Service
public class OrderService {
  @Autowired
  private RestTemplate restTemplate;
  /**
   * 根據(jù)訂單id獲取訂單詳情
   *
   * @param orderId
   * @param userId
   * @return
   */
  @HystrixCommand(fallbackMethod = "orderFallBack")
  public OrderDetail orderDetailService(Long orderId, Long userId) {

    if (Objects.isNull(orderId)) {
      return null;
    }

    OrderDetail orderDetail = OrderDBSource.getOrderDB().get(orderId);
    //調(diào)用user服務(wù)
    final String url = "http://192.168.80.153:8070/user/getUser";
    String userName = "";
    ResponseEntity<String> responseEntity = restTemplate.postForEntity(url, userId, String.class);
    String returnContent = responseEntity.getBody();
    if (Objects.nonNull(responseEntity) && StrUtil.isNotEmpty(returnContent)) {
      userName = returnContent;
    }
    if (ObjectUtil.isNotNull(orderDetail)){
      orderDetail.setUserName(userName);
    }
    return orderDetail;
  }
  /**
   * 異常調(diào)用的回調(diào)方法
   *
   * @return
   */
  public OrderDetail orderFallBack(Long orderId, Long userId) {
    OrderDetail orderDetail = OrderDBSource.getOrderCache().get(orderId);
    final String unknown = "未知用戶";
    orderDetail.setUserName(unknown);
    return orderDetail;
  }
}

2.3.4:模擬測(cè)試

為了方便測(cè)試,首先我們將請(qǐng)求服務(wù)暫時(shí)先注釋?zhuān)缓笥胮ostman測(cè)試看正常的返回應(yīng)該是這樣的,這里使用了備注為數(shù)據(jù)庫(kù)獲取的訂單,表明它沒(méi)有走回調(diào)方法,因?yàn)檫@里沒(méi)有訪問(wèn)用戶url獲取用戶信息,程序可以正常訪問(wèn)。我再放開(kāi)

怎么在springcloud中使用Hystrix對(duì)微服務(wù)進(jìn)行降級(jí)管理

加上獲取用戶服務(wù)的鏈接,實(shí)際上用戶服務(wù)是無(wú)法訪問(wèn)到的,訪問(wèn)的話就會(huì)超時(shí),超時(shí)會(huì)被hystrix捕捉到,然后走fallBack指定的方法,我們來(lái)測(cè)試一下,可以看到實(shí)際上走的是緩存中查詢(xún)到的訂單,可以看到用戶服務(wù)已經(jīng)成功的降級(jí)了,降級(jí)后的訂單信息雖然是緩存獲取到的,可能會(huì)存在延時(shí)等問(wèn)題(當(dāng)然只要維護(hù)好緩存就可以避免這個(gè)問(wèn)題)。但是比沒(méi)有任何數(shù)據(jù)帶來(lái)的用戶一點(diǎn)會(huì)更好!

怎么在springcloud中使用Hystrix對(duì)微服務(wù)進(jìn)行降級(jí)管理

三:Hystrix的流程

Hystrix實(shí)際上的工作原理是這樣的:通過(guò)command來(lái)解耦請(qǐng)求與返回操作,在具體的實(shí)例中就是,Hystrix會(huì)對(duì)依賴(lài)的服務(wù)進(jìn)行觀察,通過(guò)command.toObservable調(diào)用返回一個(gè)觀察的對(duì)象,同時(shí)發(fā)起一個(gè)事件,然后用Subscriber對(duì)接受到的事件進(jìn)行處理。在command命令發(fā)出請(qǐng)求后,它通過(guò)一系列的判斷,順序依次是緩存是否命中、斷路器是否打開(kāi)、線程池是否占滿,然后它才會(huì)開(kāi)始對(duì)我們編寫(xiě)的代碼進(jìn)行實(shí)際的請(qǐng)求依賴(lài)服務(wù)的處理,也就是Hystrix.run方法,如果在這其中任一節(jié)點(diǎn)出現(xiàn)錯(cuò)誤或者拋出異常,它都會(huì)返回到fallback方法進(jìn)行服務(wù)降級(jí)處理,當(dāng)降級(jí)處理完成之后,它會(huì)將結(jié)果返回給,際的調(diào)用者,經(jīng)過(guò)一系列流程處理的,它的具體工作流程如下:

怎么在springcloud中使用Hystrix對(duì)微服務(wù)進(jìn)行降級(jí)管理

上述就是小編為大家分享的怎么在springcloud中使用Hystrix對(duì)微服務(wù)進(jìn)行降級(jí)管理了,如果剛好有類(lèi)似的疑惑,不妨參照上述分析進(jìn)行理解。如果想知道更多相關(guān)知識(shí),歡迎關(guān)注億速云行業(yè)資訊頻道。

向AI問(wèn)一下細(xì)節(jié)

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

AI