一、Feign 簡(jiǎn)介
在上一章介紹Ribbon時(shí),我們使用RestTemplate調(diào)用服務(wù),如果是http://user-service/users/id 只有一個(gè)參數(shù)的URL還好,如果有多個(gè)參數(shù)的URl,例http://user-service/users?id=1&username="xxx",我們就要采取restTemplate封裝的另一種方式。
Map<String,Object> map = new HashMap(); map.put("id",id); map.put("username",username) this.restTemplate.getForEntity("http://user-service/users/",User.class,map)
這兩種方式都可以達(dá)到功能,程序猿天生就喜歡偷懶,就誕生了聲明式的客戶端Feign。
二、Feign 入門
- 加入Feign依賴
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
<version>2.1.2.RELEASE</version>
</dependency>
在Maven倉(cāng)庫(kù)feign的依賴也推薦使用此依賴替代spring-cloud-starter-feign
2.新建Feign接口
@FeignClient(name="user-service")
public interface UserService {
@GetMapping("/users/{id}") User findById(@PathVariable("id") Long id);
}
@FeignClient中的name即為服務(wù)提供方的名稱。使用Spring MVC的注解來發(fā)起http請(qǐng)求,對(duì)熟悉Spring MVC的開發(fā)者簡(jiǎn)直是個(gè)福音
3.Controller中調(diào)用
@Autowired
public UserController(UserService userService) {
this.userService = userService;
}
@GetMapping("user/{id}")
public User findUserById(@PathVariable("id") Long id){
return userService.findById(id);
}
- 主應(yīng)用程序中加入@EnableFeignClients開啟Feign的支持功能
@SpringBootApplication(exclude= {DataSourceAutoConfiguration.class})
@EnableFeignClients
public class FeginConsumerApplication {
public static void main(String[] args) { SpringApplication.run(FeginConsumerApplication.class, args);
}
}
-
開啟Eureka注冊(cè)中心,兩個(gè)服務(wù)提供者,瀏覽器中訪問/user/2,訪問兩次此地址,分別看服務(wù)1和服務(wù)2的控制臺(tái):
image.png
image.png
從圖片中看出Feign集成了負(fù)載均衡的功能,我們也許會(huì)想到它是基于Ribbon做的負(fù)載均衡的功能,畢竟他是Spring Cloud全家桶中的一員嘛,讓我們打開它的POM一探究竟;

我們發(fā)現(xiàn)在eureka-client中引入了Ribbon,所以這里就有負(fù)載均衡的功能;
三、Feign 配置
Feign中默認(rèn)的配置類為FeignClientsConfiguration,細(xì)細(xì)閱讀我們發(fā)現(xiàn)以下幾大類配置:
- Decoder:ResponseEntityDecoder
- Encoder:SpringEncoder
- Contract:SpringMvcContract(這里就解釋了為什么可以使用SpringMVC的注解)
- Retryer:Retryer.NEVER_RETRY(失敗也不重試,等會(huì)我們改寫此項(xiàng)配置)
我們先在客戶端加入Ribbon超時(shí)時(shí)間和3000毫秒內(nèi)的隨機(jī)超時(shí);
ribbon:
ConnectTimeout: 1000
ReadTimeout: 1000
MaxAutoRetries: 0
起先沒有重新重試配置時(shí),只要超過1000就會(huì)訪問就會(huì)報(bào)500的錯(cuò)誤;
我們加入Feign重試機(jī)制
@Bean
public Retryer feignRetryer(){
return new Retryer.Default(100,100000,5);
}

此時(shí)重試機(jī)制就起作用了只要訪問時(shí)間超過1000毫秒就重試,重試最大次數(shù)為5次;
四、其他配置
- 日志配置
Feign客戶端日志級(jí)別:
- none:不記錄日志(默認(rèn)的記錄方式)
- basic:記錄請(qǐng)求方式、狀態(tài)碼和請(qǐng)求時(shí)間
- headers:除basic之外,還會(huì)記錄響應(yīng)頭和請(qǐng)求頭信息
- full:除headers外,還會(huì)記錄請(qǐng)求和響應(yīng)的詳細(xì)內(nèi)容,以及元數(shù)據(jù)
1.1 配置Feign日志
添加日志級(jí)別
logging:
level:
com:
ybb:
feginconsumer:
service: DEBUG
配置Feign的日志級(jí)別
@Bean
public Logger.Level feignLoggerLevel(){
return Logger.Level.FULL;
}
為FeignClient裝載配置
@FeignClient(name="user-service",configuration = FeignConfiguration.class)
public interface UserService {
@GetMapping("/users/{id}")
User findById(@PathVariable("id") Long id);
}
實(shí)現(xiàn)截圖:


