天天看點

SpringCloud(七)OpenFeign負載均衡服務調用

1、概述

1. OpenFeign是什麼

官網解釋:

https://cloud.spring.io/spring-cloud-static/Hoxton.SR1/reference/htmlsingle/#spring-cloud-openfegin

Feign是一個聲明式WebService用戶端。使用Feign能讓編寫Web Service用戶端更加簡單。

它的使用方法是定義一個接口然後在上面添加注解。Feign也支援可拔插式的編碼器和解碼器。Spring Cloud對Feign進行了封裝,使其支援SpringMVC和HttpMessageConverters。Feign可以與Eureka和Ribbon組合使用以支援負載均衡。

SpringCloud(七)OpenFeign負載均衡服務調用

Github源碼位址:https://github.com/spring-cloud/spring-cloud-openfeign

2. 能幹嘛

Feign能幹什麼

Feign旨在使編寫Java Http用戶端變得更容易。

前面在使用Ribbon+RestTemplate時,利用RestTemplate對http請求的封裝處理,形成了一套模闆化的調用方法。但是在實際開發中,由于對服務依賴的調用可能不止一處,往往一個接口會被多處調用,是以通常都會針對每個微服務自行封裝一些用戶端類來包裝這些依賴服務的調用。是以,Feign在此基礎上做了進一步封裝,由他來幫助我們定義和實作依賴服務接口的定義。在Feign的實作下,我們隻需建立一個接口并使用注解的方式來配置它(以前是Dao接口上面标注Mapper注解,現在是一個微服務接口上面标注一個Feign注解即可),即可完成對服務提供方的接口綁定,簡化了使用Spring cloud Ribbon時,自動封裝服務調用用戶端的開發量。

Feign內建了Ribbon

利用Ribbon維護了Payment的服務清單資訊,并且通過輪詢實作了用戶端的負載均衡。而與Ribbon不同的是,通過feign隻需要定義服務綁定接口且以聲明式的方法,優雅而簡單的實作了服務調用。

3. Feign和OpenFeign兩者差別

SpringCloud(七)OpenFeign負載均衡服務調用

2、OpenFeign使用步驟

  • 接口+ 注解:微服務調用接口[email protected]
  • 建立cloud-consumer-feign-order80【Feign在消費端使用】
  • POM
<dependencies>
   <!--openFeign-->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-openfeign</artifactId>
    </dependency>
    <!-- eureka-client -->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
    </dependency>
    <!--引入自己定義的api通用包,可以使用payment 支付Entity-->
    <dependency>
        <groupId>com.kuang</groupId>
        <artifactId>cloud-api-commons</artifactId>
        <version>${project.version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-devtools</artifactId>
        <scope>runtime</scope>
        <optional>true</optional>
    </dependency>
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <optional>true</optional>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
</dependencies>
           
  • YML
server:
  port: 80

eureka:
  client:
    register-with-eureka: true
    service-url:
      defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/
           
  • 主啟動

    添加@EnableFeignClients注解

@SpringBootApplication
@EnableFeignClients
public class OrderFeignMain80 {
    public static void main(String[] args) {
        SpringApplication.run(OrderFeignMain80.class, args);
    }
}
           
  • 業務類

    業務邏輯接口+@FeignClient配置調用provider服務

    建立PaymentFeignService接口并新增注解@FeignClient

@Component
@FeignClient(value = "CLOUD-PAYMENT-SERVICE")
public interface PaymentFeignService {

    @GetMapping(value = "/payment/get/{id}")
    public CommonResult<Payment> getPaymentById(@PathVariable("id") Long id);
}
           

控制層Controller

@RestController
@Slf4j
public class OrderFeignController {

    @Resource
    private PaymentFeignService paymentFeignService;

    @GetMapping(value = "/consumer/payment/get/{id}")
    public CommonResult<Payment> getPaymentById(@PathVariable("id") Long id){
        return paymentFeignService.getPaymentById(id);
    }
}
           
  • 測試

    先啟動2個eureka叢集7001/7002

    在啟動2個微服務8001/8002

    啟動OpenFeign

    http://localhost/consumer/payment/get/1

    Fegin自帶負載均衡配置項

    SpringCloud(七)OpenFeign負載均衡服務調用
  • 小總結
    SpringCloud(七)OpenFeign負載均衡服務調用

3、OpenFeign逾時控制

逾時設定,故意設定逾時示範出錯情況

  • 服務提供方8001故意寫暫停程式
@GetMapping(value = "/payment/feign/timeout")
public String paymentFeignTimeout()
 {
     // 業務邏輯處理正确,但是需要耗費3秒鐘
     try { TimeUnit.SECONDS.sleep(3); } catch (InterruptedException e) { e.printStackTrace(); }
     return serverPort;
 }
           
  • 服務提供方80添加逾時方法PaymentFeignService
@GetMapping(value = "/payment/feign/timeout")
public String paymentFeignTimeout();
           
  • 服務消費方添加逾時方法OrderFeignController
@GetMapping(value = "/consumer/payment/feign/timeout")
public String paymentFeignTimeout(){
     // OpenFeign用戶端一般預設等待1秒鐘
     return paymentFeignService.paymentFeignTimeout();
 }
           
  • 測試
    • http://localhost/consumer/payment/feign/timeout
    • 錯誤頁面
      SpringCloud(七)OpenFeign負載均衡服務調用

OpenFeign預設等待1秒鐘,逾時後報錯

是什麼:預設Feign用戶端隻等待一秒鐘,但是服務端處理需要超過1秒鐘,導緻Feign用戶端不想等待了,直接傳回報錯。為了避免這樣的情況,有時候我們需要設定Feign用戶端的逾時控制。yml檔案中開啟配置

YML檔案裡需要開始OpenFeign用戶端逾時控制

#設定feign用戶端逾時時間(OpenFeign預設支援ribbon)
ribbon:
#指的是建立連接配接所用的時間,适用于網絡狀況正常的情況下,兩端連接配接所用的時間
  ReadTimeout: 5000
#指的是建立連接配接後從伺服器讀取到可用資源所用的時間
  ConnectTimeout: 5000
           

4、OpenFeign日志列印功能

  • 是什麼
  • 日志級别

    NONE:預設的,不顯示任何日志

    BASIC:僅記錄請求方法、URL、響應狀态碼及執行時間

    HEADERS:除了BASIC中定義的資訊之外,還有請求和響應的頭資訊

    FULL:除了HEADERS中定義的資訊之外,還有請求和響應的正文及中繼資料

  • 配置日志bean
@Configuration
public class FeignConfig {
    @Bean
    Logger.Level feignLoggerLevel()
    {
        return Logger.Level.FULL;
    }
}
           
  • YML檔案裡需要開啟日志的Feign用戶端
logging:
  level:
    # feign日志以什麼級别監控哪個接口
    com.kuang.springcloud.service.PaymentFeignService: debug
           
  • 背景日志檢視
    SpringCloud(七)OpenFeign負載均衡服務調用

如果有收獲!!! 希望老鐵們來個三連,點贊、收藏、轉發。

創作不易,别忘點個贊,可以讓更多的人看到這篇文章,順便鼓勵我寫出更好的部落格

繼續閱讀