1. 程式人生 > >【Spring Cloud】分散式必學springcloud(八)——配置Feign重試機制

【Spring Cloud】分散式必學springcloud(八)——配置Feign重試機制

一、前言

      在上一篇部落格中,小編向大家介紹了Feign的負載均衡和斷路器的使用。在這篇部落格中,小編向大家介紹一下Ribbon在Feign的配置以及Feign的重試機制。

二、Ribbon配置

      通過小編上一篇部落格介紹,Feign的底層是通過Ribbon實現的。所以我們可以通過配置Ribbon對Feign進行自定義配置。

2.1 全域性配置

      全域性配置很簡單,直接使用ribbon.屬性=值 ,的方式來設定ribbon的各項引數。

      如,修改預設客戶端呼叫超時時間:

ribbon:
    ConnectTimeout: 500
    ReadTimeout: 5000

2.2 指定服務配置

      多數情況下,我們需要根據具體情況具體分析,所以針對不同的服務需要具體的配置。根據指定的服務進行特殊的配置。

      指定服務配置跟前幾篇部落格中配置ribbon指定負載均衡策略一樣: 服務名.ribbon.屬性=值 .

      如:client1為服務名,屬性在下面介紹

client1:
  ribbon:
    MaxAutoRetries: 1
    MaxAutoRetriesNextServer: 2
    ConnectTimeout: 5000
    ReadTimeout: 2000
    OkToRetryOnAllOperations: true

三、相關配置介紹

配置 說明
hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds 斷路器的超時時間需要大於ribbon的超時時間,不然不會觸發重試。
hello-service.ribbon.ConnectTimeout 請求連線的超時時間
hello-service.ribbon.ReadTimeout 請求處理的超時時間
hello-service.ribbon.OkToRetryOnAllOperations 是否對所有操作請求都進行重試
hello-service.ribbon.MaxAutoRetriesNextServer 重試負載均衡其他的例項最大重試次數,不包括首次server
hello-service.ribbon.MaxAutoRetries 同一臺例項最大重試次數,不包括首次呼叫

四、Feign測試

4.1 新增重試配置檔案

      設定請求處理時間 readtimeout 為 2000,另外設定hystrix的超時時間要大於readtimeout時間。

eureka:
  client:
    serviceUrl:
      defaultZone: http://localhost:8761/eureka/
server:
  port: 7001
spring:
  application:
    name: feign-service

feign:
  hystrix:
    enabled: true


client1:
  ribbon:
    #配置首臺伺服器重試1次
    MaxAutoRetries: 1
    #配置其他伺服器重試兩次
    MaxAutoRetriesNextServer: 2
    #連結超時時間
    ConnectTimeout: 500
    #請求處理時間
    ReadTimeout: 2000
    #每個操作都開啟重試機制
    OkToRetryOnAllOperations: true

#配置斷路器超時時間,預設是1000(1秒)
hystrix:
  command:
    default:
      execution:
        isolation:
          thread:
            timeoutInMilliseconds: 2001

4.2 設定提供者隨機超時

      提供者1:設定隨機執行緒休眠0~3000毫秒。

package com.wl.client.controller;

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

import java.util.Random;

/**
 * Created by Ares on 2018/4/11.
 */
@RestController
public class User {

    @GetMapping("/user/findById")
    public String findById(@RequestParam("id")String id) throws InterruptedException {
        int i = new Random().nextInt(3000);
        System.out.println("client執行緒休眠時間:"+i);
        Thread.sleep(i);
        return "這個是springcloud的客戶端1----"+id;
    }


}

      提供者2:設定隨機執行緒休眠0~3000毫秒。

package com.wl.client.controller;

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

import java.util.Random;

/**
 * Created by Ares on 2018/4/11.
 */
@RestController
public class User {

    @GetMapping("/user/findById")
    public String findById(@RequestParam("id")String id) throws InterruptedException {
        int i = new Random().nextInt(3000);
        System.out.println("clientc執行緒休眠時間:"+i);
        Thread.sleep(i);
        return "這個是springcloud的客戶端3----"+id;
    }


}

4.3 執行

4.3.1 測試1 隨機0~3000延遲

      依次執行eureka,兩個提供者,feign。

這裡寫圖片描述

      檢視列印的日誌:

這裡寫圖片描述 這裡寫圖片描述

4.3.2 測試2 3000延遲

      3000延遲,執行緒絕對會直接重試。可以通過這個例子體會一下MaxAutoRetries和MaxAutoRetriesNextServer的區別。

這裡寫圖片描述

      執行結果說明:開始請求訪問的時候,clientapplication(1)經過負載均衡分配,開始執行,但是執行3000超時,所以重試了一次,重試依舊是超時。所以安排給其他的提供者clientapplication處理,他處理第一次,超時,處理第二次也超時,然後就給其他的提供者處理,clientapplication(1)處理兩次後依舊超時。這時候,所有的提供者都重試完畢,所以就返回失敗了。

      可以通過上面的體會MaxAutoRetries和MaxAutoRetriesNextServer的區別:

  • MaxAutoRetries:首個處理的提供者,重試的次數

  • MaxAutoRetriesNextServer:首個提供者無法處理給其他提供者處理,重試的次數,首個提供者也會作為其他提供者,所有的提供者都重試失敗,則返回失敗。

五、小結

      通過這次重試的學習,我們可以針對特殊的服務設定超時時間,然後對不同的服務進行處理,非常的方便。另外Feign的預設的重試次數是5次。在用dubbo的時候,重試3次。