openfeign + hystrix 實現遠程調用,配置熔斷、超時、多 name


1,前提條件

生產者和消費者兩個項目必須都注冊到同一個注冊中心

2,生產者

生產者無需特殊配置,只需要是一個正常的web項目並且提供可訪問的接口即可,接口示例如下

package com.hwq.data.base.client;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class HomeClient {
    @GetMapping("/client/home/index")
    public String index() {
        return "Open Feign";
    }
}

3,消費者

1,pom.xml
<!-- 遠程調用 -->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-openfeign</artifactId>
    <exclusions>
        <exclusion>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-archaius</artifactId>
        </exclusion>
        <exclusion>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-netflix-archaius</artifactId>
        </exclusion>
    </exclusions>
</dependency>
<!-- Hystrix 熔斷器 -->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
    <exclusions>
        <exclusion>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-archaius</artifactId>
        </exclusion>
        <exclusion>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-netflix-archaius</artifactId>
        </exclusion>
    </exclusions>
</dependency>
2,配置開啟熔斷功能
feign:
  hystrix:
    # 開啟熔斷器
    enabled: true
3,啟動類
package com.hwq.admin.back;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;

@SpringBootApplication  // 啟動 SpringBoot 項目
@EnableDiscoveryClient  // 啟動 服務發現客戶端 功能
@EnableFeignClients     // 啟動 遠程調用
public class AdminBackApp {

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

}
4,FeignClient 接口
package com.hwq.admin.back.feign;

import com.hwq.admin.back.feign.impl.HomeFeignImpl;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;

// 聲明為 feign 遠程調用,name:生產者項目名,fallback:發生錯誤或超時時的熔斷類
@FeignClient(name = "sc-web-data-base", fallback = HomeFeignImpl.class)
public interface HomeFeign {

    // 這里的方法簽名要和生產者保持一致
    @GetMapping("/client/home/index")
    String index();

}
5,熔斷類

該類需要實現 FeignClient 接口,並且配置在 fallback 參數中

package com.hwq.admin.back.feign.impl;

import com.hwq.admin.back.feign.HomeFeign;
import org.springframework.stereotype.Component;

@Component
public class HomeFeignImpl implements HomeFeign {

    @Override
    public String index() {
        return "觸發熔斷";
    }

}
5,調用的控制層
package com.hwq.admin.back.controller;

import com.hwq.admin.back.feign.HomeFeign;
import com.hwq.admin.back.vo.ResultVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class HomeController {

    // FeignClient 接口 可以直接注入使用
    @Autowired
    private HomeFeign homeFeign;

    @GetMapping("/home/feign")
    public ResultVO<String> fegin() {
        String index = homeFeign.index();
        return ResultVO.success("OK", index);
    }
    
}

4,測試

啟動項目后,訪問:http://localhost:2011/home/feign

image-20201224113016474

我們關閉生產者,再次訪問觸發熔斷

image-20201224113238752

5,超時配置

配置超時可有效防止因為程序性能問題導致的長時間無響應,並且造成線程池忙碌堵塞

feign:
  hystrix:
    # 開啟熔斷器,如果要采用
    enabled: true

ribbon:
  # 遠程請求調用的超時時間 5 秒
  ConnectTimeout: 5000
  # 連接后的等待處理的超時時間 30 分鍾
  ReadTimeout: 1800000
  # 最大重試次數,當注冊中心中可以找到服務,但是服務連不上時將會重試
  MaxAutoRetries: 0
  # 切換實例的重試次數
  MaxAutoRetriesNextServer: 0

hystrix:
  command:
    default:
      execution:
        isolation:
          thread:
            # 觸發熔斷的超時時間
            timeoutInMilliseconds: 1801000
  • openfeign 是依賴於 ribbon 的,所以超時配置配置 ribbon
  • ribbon 配置下的項必須使用駝峰,使用中橫線會失效,雖然這看起來怪怪的
  • 重生次數建議設置為 0,否則會出現冪等性的問題,當然查詢的無所謂
  • 熔斷觸發的超時時間應該大於 (ConnectTimeout + ReadTimeout)* (總重試次數 + 1)
  • 總重試次數 = MaxAutoRetries * MaxAutoRetriesNextServer + 1

6,相同 name 配置

1,場景

我們在開發中常常會配置多個 feignclient 指向同一個服務,這必然導致這些接口的 name 屬性是形同的,但是啟動之后卻會出現如下異常:

image-20201224132952126

2,原因

如果我們要創建多個具有相同名稱或URL的偽客戶端,以便它們指向同一台服務器,但每個客戶端具有不同的自定義配置,則必須使用的contextId屬性

3,解決辦法
package com.hwq.admin.back.feign;

import com.hwq.admin.back.feign.impl.HomeFeignImpl;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;

// 聲明為 feign 遠程調用,name:生產者項目名,contextId: 唯一標識,fallback:發生錯誤或超時時的熔斷類
@FeignClient(name = "sc-web-data-base", contextId = "home", fallback = HomeFeignImpl.class)
public interface HomeFeign {

    // 這里的簽名要和生產者保持一致
    @GetMapping("/client/home/index")
    String index();

}


免責聲明!

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



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