spring cloud 之 Feign 使用HTTP請求遠程服務


一、Feign 簡介

在spring Cloud Netflix棧中,各個微服務都是以HTTP接口的形式暴露自身服務的,因此在調用遠程服務時就必須使用HTTP客戶端。我們可以使用JDK原生的URLConnection、Apache的Http Client、Netty的異步HTTP Client, Spring的RestTemplate。但是,用起來最方便、最優雅的還是要屬Feign了。

Feign是一種聲明式、模板化的HTTP客戶端。在Spring Cloud中使用Feign, 我們可以做到使用HTTP請求遠程服務時能與調用本地方法一樣的編碼體驗,開發者完全感知不到這是遠程方法,更感知不到這是個HTTP請求。

二、feign的使用在spring cloud中的使用

1、添加依賴

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

2、創建FeignClient  

@FeignClient(name="SPRING-PRODUCER-SERVER/spring")
public interface FeignUserClient {
  @RequestMapping( value = "/findAll/{name}",method = RequestMethod.GET)
  public List<SpringUser> findAll(@PathVariable("name") String name);
  
  @RequestMapping( value = "/findUserPost",method = RequestMethod.POST)
  public SpringUser findUserPost(@RequestBody SpringUser springUser);//復合類型好像默認是POST請求
}
  • @FeignClient(name="SPRING-PRODUCER-SERVER/spring"):用於通知Feign組件對該接口進行代理(不需要編寫接口實現),name屬性指定我們要調用哪個服務。使用者可直接通過@Autowired注入。
  • @RequestMapping表示在調用該方法時需要向/group/{groupId}發送GET請求。
  • @PathVariable與SpringMVC中對應注解含義相同。

原理:Spring Cloud應用在啟動時,Feign會掃描標有@FeignClient注解的接口,生成代理,並注冊到Spring容器中。生成代理時Feign會為每個接口方法創建一個RequetTemplate對象,該對象封裝了HTTP請求需要的全部信息,請求參數名、請求方法等信息都是在這個過程中確定的,Feign的模板化就體現在這里。

3、啟動類上添加注解

@Configuration
@ComponentScan
@EnableAutoConfiguration
@EnableEurekaClient
@EnableFeignClients
public class SpringConsumerServerFeignApplication {
    public static void main(String[] args) {
        SpringApplication.run(SpringConsumerServerFeignApplication.class, args);
    }
}

4、配置文件 application.yml

spring:
 application:
  name: spring-consumer-server-feign
server: 
 port: 8084
 context-path: /spring
#服務注冊中心的配置內容,指定服務注冊中心的位置
eureka:
 client:
  serviceUrl:
   defaultZone: http://user:password@localhost:8761/eureka/

三、自定義Feign的 配置

1、自定義Configuration

@Configuration
public class FooConfiguration {
    @Bean
    public Contract feignContract() {
        //這將SpringMvc Contract 替換為feign.Contract.Default
        return new feign.Contract.Default();
    }
}

2、使用自定義的Configuration

@FeignClient(name="SPRING-PRODUCER-SERVER/spring",configuration=FooConfiguration.class)
public interface FeignUserClient {
    @RequestLine("GET /findAll/{name}")
    public List<SpringUser> findAll(@Param("name") String name);    
 /* @RequestMapping( value = "/findAll/{name}",method = RequestMethod.GET)
  public List<SpringUser> findAll(@PathVariable("name") String name);
  
  @RequestMapping( value = "/findUserPost",method = RequestMethod.POST)
  public SpringUser findUserPost(@RequestBody SpringUser springUser);*/
}
@RequestLine:是feign的注解

四、Feign日志的配置
為每個創建的Feign客戶端創建一個記錄器。默認情況下,記錄器的名稱是用於創建Feign客戶端的接口的完整類名。Feign日志記錄僅響應DEBUG級別。logging.level.project.user.UserClient: DEBUG
在配置文件application.yml 中加入:
logging:
 level:
  com.jalja.org.spring.simple.dao.FeignUserClient: DEBUG 

在自定義的Configuration的類中添加日志級別

@Configuration
public class FooConfiguration {
   /* @Bean
    public Contract feignContract() {
        //這將SpringMvc Contract 替換為feign.Contract.Default
        return new feign.Contract.Default();
    }*/
    @Bean
    Logger.Level feignLoggerLevel() {
        //設置日志
        return Logger.Level.FULL;
    }
}

PS:Feign請求超時問題

Hystrix默認的超時時間是1秒,如果超過這個時間尚未響應,將會進入fallback代碼。而首次請求往往會比較慢(因為Spring的懶加載機制,要實例化一些類),這個響應時間可能就大於1秒了
解決方案有三種,以feign為例。
方法一
hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds: 5000
該配置是讓Hystrix的超時時間改為5秒
方法二
hystrix.command.default.execution.timeout.enabled: false
該配置,用於禁用Hystrix的超時時間
方法三
feign.hystrix.enabled: false
該配置,用於索性禁用feign的hystrix。該做法除非一些特殊場景,不推薦使用。




免責聲明!

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



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