SpringCloud-OpenFeign

烽火戲諸侯★發表於2020-12-13

OpenFeign

1.使用Feign訪問其他服務

1.依賴

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

2.在服務呼叫模組啟動類上加上@EnableFeignClients註解

@SpringBootApplication
@EnableDiscoveryClient
@EnableCircuitBreaker
@EnableFeignClients(basePackages = "com.fengke.feign")//指定feign介面所在的包。如果 feign結構和啟動類在同一個模組下可以不加,不過如果feign介面在另外一個依賴進來的模組中的話必須加上。建議都加上
public class UserConsumerApplication {

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

3.定義Feign介面

加上要訪問服務提供方的介面如下:

http://user-server/user/findList?id=3  //其中的user-server代表提供方的服務名

則需要定義如下介面和方法 。注意在介面上加FeignClient 並且指定服務名

//宣告當前類是一個Feign客戶端,指定服務名為user-server
@FeignClient("user-server")
public interface UserFeign {
    //要訪問這樣的介面  http://user-server/user/findList?id=3  
    @RequestMapping("/user/findList")
    public List<User> findList(@RequestParam("id") Integer id);
    
        @RequestMapping("/user/findById")  //http://user-server/user/findById?id=3  
    public List<User> findById(@RequestParam("id") Integer id);
}

注意如果是 http://user-server/user/3 一定要記得在方法引數上加上@PathVariable註解

    @GetMapping("/user/{id}")
    public User findById(@PathVariable(name = "id") Integer id);   //注意PathVariable的name屬性必須寫上

注意不要再介面上加@RequestMapping 加了會導致後期日誌輸出問題甚至甚至fallback啟動不了

4.使用Feign訪問介面

@RestController
public class UserController {
    @Autowired
    private UserFeign userFeign;

    @RequestMapping("/findList")
    public List<User> findList(Integer id){
        List<User> list = userFeign.findList(id);
        System.out.println(list);
        log.error("hhh");
        return list;
    }

}

2.Feign配置

1.負載均衡配置

Feign中本身已經整合了Ribbon依賴和自動配置所以不需要在額外引入Ribbon

Fegin內建的ribbon預設設定了請求超時時長,預設是1000,我們可以通過手動配置來修改這個超時時長:

ribbon:
  ReadTimeout: 2000 # 讀取超時時長
  ConnectTimeout: 1000 # 建立連結的超時時長

因為ribbon內部有重試機制,一旦超時,會自動重新發起請求。如果不希望重試,可以新增配置:

ribbon:
  ConnectTimeout: 1000 # 連線超時時長
  ReadTimeout: 2000 # 資料通訊超時時長
  MaxAutoRetries: 0 # 當前伺服器的重試次數
  MaxAutoRetriesNextServer: 0 # 重試多少次服務
  OkToRetryOnAllOperations: false # 是否對所有的請求方式都重試

2.Hystrix熔斷配置

#####0.開啟熔斷

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

啟動類開啟Hystrix 加@EnableCircuitBreaker

@EnableCircuitBreaker
public class ConsumerApplication {

#####1.開啟熔斷

feign:
  hystrix:
    enabled: true # 開啟Feign的熔斷功能
2.建立一個失敗處理類實現要進行降級處理的Feign介面

注意在類上加@Component註解

@Component
public class UserFeignFallback implements UserFeign {
    @Override
    public List<User> findList(@RequestParam("id") Integer id) {
        return Arrays.asList(new User(500,"服務降級了"));
    }
}

在FeignClient註解的fallback屬性上指定feign介面使用的降級處理類

@FeignClient(name = "user-server",fallback = UserFeignFallback.class)
public interface UserFeign {

    //User user = restTemplate.getForObject("http://user-server/user/"+id, User.class);

    @GetMapping("/user/{id}")   //http://user-server/user/1
    public User findById(@PathVariable(name = "id") Integer id);


    @GetMapping("/user/findAll")//   http://user-server/user/findAll
    public List<User> findAll();
}

####3.請求壓縮

Spring Cloud Feign 支援對請求和響應進行GZIP壓縮,以減少通訊過程中的效能損耗。通過下面的引數即可開啟請求 與響應的壓縮功能:

feign:
  compression:
    request:
      enabled: true # 開啟請求壓縮
    response:
      enabled: true # 開啟響應壓縮

同時,我們也可以對請求的資料型別,以及觸發壓縮的大小下限進行設定:

feign:
  compression:
    request:
      enabled: true # 開啟請求壓縮
      mime-types: text/html,application/xml,application/json # 設定壓縮的資料型別
      min-request-size: 2048 # 設定觸發壓縮的大小下限

4.配置開啟Feign日誌

1.開啟日誌配置
logging:
  level:
    com.fengke: debug

#####2. 編寫Feign配置類,定義日誌級別

@Configuration
public class FeignConfig {

    @Bean
    Logger.Level feignLoggerLever(){
        return Logger.Level.FULL;
    }
}

這裡指定的Level級別是

  • FULL,Feign支援4種級別:
  • NONE:不記錄任何日誌資訊,這是預設值。
  • BASIC:僅記錄請求的方法,URL以及響應狀態碼和執行時間
  • HEADERS:在BASIC的基礎上,額外記錄了請求和響應的頭資訊
  • FULL:記錄所有請求和響應的明細,包括頭資訊、請求體、後設資料。

#####3.在Feign客戶端中配置Feign配置類


@FeignClient(name = "user-server",fallback = UserFeignFallback.class,configuration = FeignConfig.class)
public interface UserFeign {
    @RequestMapping("/user/findList")
    public List<User> findList(@RequestParam("id") Integer id);
}

4.測試

在這裡插入圖片描述

3.Feign攔截器

可以對通過Feign發生的請求進行攔截,常用於微服務間呼叫時的認證。
####3.1定義攔截器

定義一個類實現RequestInterceptor

@Component
public class FeignInterceptor implements RequestInterceptor {
    @Override
    public void apply(RequestTemplate requestTemplate) {
        //獲取當前執行緒中的請求物件
        ServletRequestAttributes servletRequestAttributes=
                (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = servletRequestAttributes.getRequest();
        System.out.println(request);
        //判斷是否有token這個頭,如果有,就把這個頭新增到feign發起的請求頭上
        String token = request.getHeader("token");
        if(!StringUtils.isEmpty(token)){
            requestTemplate.header("token",token);
        }
    }
}

如果該類和使用Feign發生請求的程式碼在同一個模組中上面程式碼就可以進行攔截。如果不是在同一個模組需要在

呼叫Feign去訪問的模組中增加下面的程式碼

@Bean
public FeignInterceptor feignInterceptor(){
    return new FeignInterceptor();
}

3.2配置隔離策略為訊號量

#hystrix 配置
hystrix:
  command:
    default:
      execution:
        isolation:
          strategy: SEMAPHORE  #隔離策略,預設是Thread, 可選Thread|SEMAPHORE