1. 程式人生 > >SpringCloud實戰六:Spring Cloud Feign 高階應用

SpringCloud實戰六:Spring Cloud Feign 高階應用

上篇簡單的介紹了Feign的使用,本篇將結合註冊中心,進行Feign的高階應用,案例中有三個角色:服務註冊中心、服務提供者、服務消費者,註冊中心為上篇的eureka單機版。

具體高階應用為如下幾條:

  • 1.使用feign進行服務間的呼叫
  • 2.feign開啟Gzip壓縮
  • 3.feign開啟日誌
  • 4.feign替換JDK預設的URLConnection為okhttp
  • 5.feign超時設定
  • 6.feign使用hystrix進行熔斷、降級處理
1.使用feign進行服務間的呼叫
服務提供者
  • 建立provider-service服務提供者,新增如下依賴:
<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
	<groupId>org.springframework.cloud</groupId>
	<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
  • application.properties配置檔案程式碼如下:
server.port=9600
spring.application.name=provider-service
eureka.instance.prefer-ip-address=true
#配置註冊中心地址
eureka.client.serviceUrl.defaultZone=http://zy:[email protected]:10025/eureka/
  • 啟動主類新增@EnableDiscoveryClient
@EnableDiscoveryClient
@SpringBootApplication
public class ProviderServiceApplication {

	public static void main(String[] args) {
		SpringApplication.run(ProviderServiceApplication.class, args);
	}
}
  • 建立HelloController,新增一個hello方法
@RestController
public class HelloController {

    @RequestMapping("/hello")
    public String hello(String name){
        return  "hello " + name;
    }
}
服務消費者
  • 建立consumer-service服務提供者,新增如下依賴:
<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
	<groupId>org.springframework.cloud</groupId>
	<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<!-- 因為要使用feign呼叫其他服務,所以需要新增此依賴 -->
<dependency>
	<groupId>org.springframework.cloud</groupId>
	<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
  • application.properties配置檔案程式碼如下:
server.port=9700
spring.application.name=consumer-service
eureka.instance.prefer-ip-address=true
# 配置註冊中心地址
eureka.client.serviceUrl.defaultZone=http://zy:[email protected]:10025/eureka/
  • 啟動主類新增@EnableDiscoveryClient、@EnableFeignClients2個註解
@EnableFeignClients
@EnableDiscoveryClient
@SpringBootApplication
public class ConsumerServiceApplication {

	public static void main(String[] args) {
		SpringApplication.run(ConsumerServiceApplication.class, args);
	}
}
  • 建立一個介面HelloFeignService,呼叫服務提供者
//name為服務提供者向註冊中心註冊的例項名
@FeignClient(name = "provider-service" )
public interface HelloFeignService {
    //地址為服務提供者對外暴露的地址
    @RequestMapping(value = "/hello" , method = RequestMethod.GET)
    String hello(@RequestParam("name") String name);
}
  • 建立IndexController控制器,注入feign,像本地方法一樣呼叫服務提供者的服務
@RestController
public class IndexController {
   
    @Autowired private HelloFeignService feignService;

    @RequestMapping(value = "/hello" , method = RequestMethod.GET)
    public String hello(String name){
        return feignService.hello(name);
    }
}

啟動2個專案,訪問服務消費者 http://localhost:9700/hello?name=zy ,效果如下說明feign呼叫成功
在這裡插入圖片描述

高階應用的第一點ok了

2.feign開啟Gzip壓縮

Spring Cloud Feign支援對請求與響應的壓縮,以提高通訊效率,在服務消費者配置檔案開啟壓縮支援和壓縮檔案的型別即可

#feign 請求與響應的壓縮
feign.compression.request.enabled=true
feign.compression.response.enabled=true
feign.compression.request.mime-types=text/xml,application/xml,application/json
feign.compression.request.min-request-size=2048
3.feign開啟日誌

feign開啟日誌有兩種方式,一種是使用配置檔案,一種是使用java程式碼,下面將介紹程式碼方式
建立FeignLogConfig類,新增一個LoggerBean

@Configuration
public class FeignLogConfig {

    /**
     * 日誌level有4個級別
     * 1.NONE,不記錄任何日誌
     * 2.BASIC,僅記錄請求方法、URL以及響應狀態碼和執行時間
     * 3.HEADRES,除了BASIC以外的還會記錄請求和響應的頭資訊
     * 4.FULL,所有
     * @return
     */
    @Bean
    Logger.Level feignLogger(){
        return Logger.Level.FULL;
    }
}
4.feign替換JDK預設的URLConnection為okhttp

使用okhttp,能提高qps,因為okhttp有連線池和超時時間進行調優

  • 在服務消費者中,新增feign-okhttp依賴
<dependency>
	<groupId>io.github.openfeign</groupId>
	<artifactId>feign-okhttp</artifactId>
</dependency>
  • 在配置檔案中,禁用預設的http,啟用okhttp
feign.httpclient.enabled=false
feign.okhttp.enabled=true
  • 建立OkHttpConfig類,新增okhttp的bean
/**
 * 配置okhttp與連線池
 * ConnectionPool預設建立5個執行緒,保持5分鐘長連線
 */
@Configuration
@ConditionalOnClass(Feign.class)
@AutoConfigureBefore(FeignAutoConfiguration.class)
public class OkHttpConfig {

    @Bean
    public okhttp3.OkHttpClient okHttpClient(){
        return new okhttp3.OkHttpClient.Builder()
                //設定連線超時
                .connectTimeout(10 , TimeUnit.SECONDS)
                //設定讀超時
                .readTimeout(10 , TimeUnit.SECONDS)
                //設定寫超時
                .writeTimeout(10 , TimeUnit.SECONDS)
                //是否自動重連
                .retryOnConnectionFailure(true)
                .connectionPool(new ConnectionPool(10 , 5L, TimeUnit.MINUTES))
                .build();
    }
}
5.feign超時設定
# feign啟用hystrix,才能熔斷、降級
feign.hystrix.enabled=true

# hystrix的超時時間
hystrix.command.default.execution.timeout.enabled=true
hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=10000

# ribbon的超時時間
ribbon.ReadTimeout=10000
ribbon.ConnectTimeout=10000
6.feign使用hystrix進行熔斷、降級處理

上面的超時時間設定為10秒,把服務提供者sleep睡眠時間大於10秒,服務消費者就會觸發hystrix,進行熔斷保護

  • 改造服務提供者,讓服務睡眠60秒
@RequestMapping("/hello")
    public String hello(String name){
        try {
            //睡眠60秒,測試feign的熔斷、降級
            Thread.sleep(60 * 1000);
        }catch (Exception e){
            e.printStackTrace();
        }
        return  "hello " + name;
    }
  • 改造服務消費者,新增feign的熔斷、降級方法,feign的hystrix熔斷降級很好實現,只要在FeignClient的fallback回滾方法中指定那個實現類即可
@FeignClient(name = "provider-service" , fallback = HelloFeignFallbackService.class)
public interface HelloFeignService {

    @RequestMapping(value = "/hello" , method = RequestMethod.GET)
    String hello(@RequestParam("name") String name);
}

HelloFeignFallbackService程式碼如下:

/**
 * hystrix服務降級處理,防止因超時、異常等導致的服務呼叫雪崩
 */
@Service
public class HelloFeignFallbackService implements HelloFeignService{
    @Override
    public String hello(String name) {
        return "未找到" + name ;
    }
}

然後啟動服務提供者與消費者,再訪問 http://localhost:9700/hello?name=zy ,發現頁面緩了10來秒,就直接返回了熔斷方法中的內容,說明hystrix熔斷降級成功
在這裡插入圖片描述

程式碼已上傳至碼雲,原始碼,專案使用的版本資訊如下:

  • SpringBoot 2.0.6.RELEASE
  • SpringCloud Finchley.SR2(非常新的版本)