前言
上一章使用Ribbon實現了商品和多個用戶微服務之間的負載均衡效果,到現在我們的微服務架構已經“初具規模”啦。接下來會繼續完善我們的微服務架構,本章將會引入全新的組件——Feign。
看過前面的文章就知道我們採用的是RestTemplate來實現商品和用戶微服務間的通信。
如下圖所示:
代碼示例:
@GetMapping("/goods/{id}")
public User findById(@PathVariable Long id){
// 這裏用到了RestTemplate調用用戶微服務,獲取用戶信息
User user = this.restTemplate.getForObject("http://127.0.0.1:8080/users/"+id,User.class);
// 執行商品微服務業務......
return user;
}
上述利用RestTemplate實現了商品和用戶微服務的簡單調用,其實RestTemplate已經實現了對HTTP請求的封裝處理,形成了一套模版化的調用方法。但是在實際開發中,由於對服務依賴對調用可能不止於一處,往往一個接口會被多處調用,所以我們通常都會針對各個微服務自行封裝一些客戶端累來包裝這些依賴服務的調用。這個時候我們會發現,由於RestTemplate的封裝,幾乎每一個調用都是簡單的模版化內容。
this.restTemplate.getForObject("http://127.0.0.1:8080/simple/"+id,User.class);
這段代碼隨着業務的複雜和開發人員的頻繁變更,新人將會有一連串的問題冒出來,這時就得討好老員工,如果還在職的話就恭喜你,如果…[捂臉]。
記得之前有看到一位SpringCloud大佬在講解Feign的時候列舉了某度的一個連接,這裏小編專門找出來給大家秀一下:
https://www.baidu.com/s?wd=asf&rsv_spt=1&rsv_iqid=0xa25bbeba000047fd&issp=1&f=8&rsv_bp=0&rsv_idx=2&ie=utf-8&tn=baiduhome_pg&rsv_enter=1&rsv_sug3=3&rsv_sug1=2&rsv_sug7=100&rsv_sug2=0&inputT=328&rsv_sug4=328
如果需求在持續變更,所需參數越來越多…
好了,言歸正傳。基於上面那麼多的不足,就需要使用Feign來解決以上問題了!
Ribbon簡介及使用場景
Feign是Netflix開發的聲明式、模板化的HTTP客戶端,其靈感來自Retrofit、JAXRS-2.0以及WebSocket。Feign可幫助我們更加便捷、優雅地調用HTTP API。
那在SpringCloud中,集成Feign組件非常簡單,只需2步:
1、創建一個接口
2、在接口添加Feign註解
TIPS
Feign的GitHub:https://github.com/OpenFeign/feign
Coding Start
第一步:複製商品和用戶微服務項目
複製項目microservice-consumer-goods,將pom.xml文件中ArtifactId內容修改爲 microservice-consumer-goods-feign 。如下圖所示:
複製項目microservice-provider-user,將pom.xml文件中ArtifactId 內容修改爲microservice-provider-user-feign。如下圖所示:
設置端口
備註:記得修改端口,不然啓動會出現端口衝突問題
microservice-consumer-goods-feign:8095
microservice-provider-user-feign:8094
第二步:添加Feign依賴
商品微服務作爲調用方需要引入feign依賴:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
第三步:加註解
商品微服務啓動類上添加 @EnableFeignClients ;
@SpringBootApplication
@EnableFeignClients
public class MicroserviceConsumerFeignGoodsApplication {
public static void main(String[] args) {
SpringApplication.run(MicroserviceConsumerFeignGoodsApplication.class, args);
}
}
第四步:編寫Feign Client
@FeignClient(name = "microservice-provider-user-feign",url = "http://127.0.0.1:8094/")
public interface UserFeignClient {
@GetMapping("/users/{id}")
User findUserById(@PathVariable("id") Long id);
}
寫到這裏就結束了,@FeignClient 註解中的name值是請求用戶微服務的服務名稱(命名可以隨意,但是不能省略,否則不能正常啓動)。URL屬性是制定請求的用戶微服務的服務連接。
第五步:編寫商品業務Controller
@RequestMapping("/goods")
@RestController
public class GoodsController {
@Autowired
private UserFeignClient userFeignClient;
@GetMapping("/users/{id}")
public User findUserById(@PathVariable Long id){
return this.userFeignClient.findUserById(id);
}
}
只需使用@Autowire註解,即可注入上面編寫的Feign Client。
第六步:啓動測試
- 啓動microservice-discovery-eureka
- 啓動microservice-provider-user-feign
- 啓動microservice-provider-goods-feign
查看Eureka 控制檯可以看出商品和用戶微服務都已經註冊成功!
執行:http://127.0.0.1:8095/goods/users/2
查詢用戶ID爲2的用戶信息如下:
第七步:RestTemplate與FeignClient如何選擇?
先看一下兩種的優勢與劣勢對比:
正常情況下小編會建議大家使用Feign,一個項目裏面只保留一種編碼風格。但是查過資料的同學會吐槽Feign的性能問題,這點是沒辦法優化的,Spring Cloud官方成人,物流Feign如何改進,其靈活性也無法超越RestTemplate!
不過大家放心啦,大部分的業務場景下都是OK的——項目中的性能瓶頸一般不都出現在HTTP客戶端上,自身的業務也需要做相應處理!
原則:儘量使用Feign,避免使用RestTemplate
(因爲如果作爲架構師,做決定很重要,要讓大家編碼風格統一,代碼可維護性、可讀性高)
合理選擇即可。。。
配套代碼
關於Spring Cloud(Greenwich版) 系列完整的教程,可以點擊下方主代碼庫鏈接查看哦~~~ 。
主代碼庫:https://github.com/yundianzixun/spring-cloud-study
Eureka Server:https://github.com/yundianzixun/spring-cloud-study/tree/master/microservice-discovery-eureka
商品微服務:https://github.com/yundianzixun/spring-cloud-study/tree/master/microservice-consumer-goods-feign
用戶微服務:https://github.com/yundianzixun/spring-cloud-study/tree/master/microservice-consumer-user-feign