響應式網(wǎng)站設計稿百度知道下載
一.由來
1.在傳統(tǒng)的架構里面,我們是通過使用RestTemplate來訪問其他的服務,但是這種方式就存在了一個很大的缺陷,也就是被調(diào)用方如果發(fā)生了服務的遷移(IP和端口發(fā)生了變化),那么調(diào)用方也需要同步的在代碼里面進行修改,然后重啟服務;
2.這種方法在微服務新起以后,它的弊端就被無線放大,因此這個方式就逐漸的演變,然后形成了注冊中心和配置中心,雖然我們使用注冊中心解決服務發(fā)送遷移等等其他的一系列問題,但是最根本的服務之間的Http訪問問題還是沒有解決;
3.在兩個服務之間,需要發(fā)生調(diào)用,它首先需要來到注冊中心,在注冊中心拿到相應的服務以后,再在本地進行負載,負載之后再發(fā)起遠程調(diào)用,但是在微服務里面,服務的調(diào)用是非常的頻繁,比如在一個方法里面可能出現(xiàn)多個服務的調(diào)用,那么同一個服務之間的調(diào)用就出現(xiàn)了代碼的冗余。(我們以為最簡單的為例:比如我們通過一個代碼來都注冊中心里面,拉取這個注冊配置,然后再本地進行負載,負載之后再通過RestTemplate進行訪問,也就是說一次簡單的調(diào)用就需要寫三行代碼,如果是多個服務,就要編寫更多的代碼,這樣就出現(xiàn)了代碼的冗余)
因此,基于這種場景就引入了Fegin。
二.基本概念
1.Fegin是一個聲明式的Web服務客戶端,它簡化了使用基于HTTP的遠程服務開發(fā);(相當于把我們上面說的三行代碼進行了一個封裝,當我們使用遠程調(diào)用的時候,直接使用Fegin,然后Fegin的底層來幫我們實現(xiàn)這個調(diào)用的過程)
2.Fegin是在RestTemplate和Ribbon的基礎上進一步封裝,使用RestTemplate實現(xiàn)Http調(diào)用,使用Ribbon實現(xiàn)負載均衡,關系如圖所示:
Feign的主要特點和功能包括:
1.聲明式API:Feign允許開發(fā)者使用簡單的注解來定義和描述對遠程服務的訪問,通過使用注解,開發(fā)者可以輕松地指定URL、HTTP方法、請求參數(shù)、請求頭等信息,使得遠程調(diào)用變得非常直觀和易于理解。
@FeignClient(name = "example", url = "https://api.example.com")public interface ExampleService {@GetMapping("/endpoint")String getEndpointData();}
2.集成負載均衡:Feign集成了Ribbon負載均衡器,可以自動實現(xiàn)客戶端的負載均衡,它可以根據(jù)服務名和可用實例進行動態(tài)路由,并分發(fā)請求到不同的服務實例上,提高系統(tǒng)的可用性和可伸縮性;(我們不需要來處理負載均衡了,由Fegin來幫我們集成了)
3.容錯機制:Feign支持集成Hystrix容錯框架,可以在調(diào)用遠程服務時提供容錯和斷路器功能(防止雪崩),當遠程服務不可用或響應時間過長時,Feign可以快速失敗并返回預設的響應結果,避免對整個系統(tǒng)造成級聯(lián)故障。
3.自定義錯誤處理:允許你配置自定義的錯誤處理策略,當遠程服務返回錯誤時,能夠進行定制化的處理:
@FeignClient(name = "user-service", configuration = CustomFeignConfiguration.class)
public interface UserClient {// 方法定義
}@Configuration
public class CustomFeignConfiguration {@Beanpublic ErrorDecoder errorDecoder() {return new MyCustomErrorDecoder(); // 自定義錯誤解碼器}
}
注意:
在2019年,Netflix宣布停止對Feign的維護,為了替代 Feign ,Spring Cloud 社區(qū)推出了 OpenFeign,它繼承了Feign的所有功能,并增加了對Spring MVC注解的支持?,OpenFeign目前仍在維護中,特別是在Spring Cloud Finchley及以上版本中廣泛使用?。
其實,OpenFeign 和 Feign 在使用方式上非常相似,因為 OpenFeign 是 Feign 的社區(qū)版,并且在設計上保持了與 Feign 一致的 API 和功能,換句話說,OpenFeign 基本上是對 Feign 的延續(xù)和改進,尤其是在與 Spring Cloud 集成方面,所以,二者的使用方式差異并不大。
三.為什么Fegin第一次調(diào)用耗時很長?
主要原因是由于Ribbon的懶加載機制,當第一次調(diào)用發(fā)生時,Fegin會觸發(fā)Ribbon的加載過程,包括從服務注冊中心獲取服務列表、建立連接池等操作,這個加載過程會增加首次調(diào)用的耗時。
解決方案:
ribbon:eager-load:enabled: true // 開啟饑餓加載clients: service-1 // 服務名,多個以逗號隔開
可以在應用啟動時預熱Fegin客戶端,自動觸發(fā)一次無關緊要的調(diào)用,來提前加載Ribbon和其他相關組件,這個,就相當于提前進行了一次調(diào)用。
四.Fegin是怎么做負載均衡?
在Feign中,負載均衡是通過集成Ribbon來實現(xiàn)的。
Ribbon是Netfix開源的一個客戶端負載均衡器,可以與Feign無縫集成,為Feign提供負載均衡的能力。
Ribbon在發(fā)起請求前,會從“服務中心”獲取服務列表(清單),然后按照一定的負載均衡策略去發(fā)起請求,從而實現(xiàn)客戶端的負載均衡。
Ribbon本身也維護著“服務提供者”清單的有效性,相當于是緩存了服務清單,只有當它發(fā)現(xiàn)“服務提供者”不可用,才會重新從“服務中心”獲取有效的“服務提供者”清單來及時更新,并不是每一次調(diào)用都會進行拉取,這種方式也提高了整個系統(tǒng)的性能。
五.Fegin怎么實現(xiàn)認證傳遞?
首先先我們需要知道,為什么Fegin需要實現(xiàn)認證傳遞?先了解一下微服務的完調(diào)用鏈路:
1.通常用戶在前端進行請求,請求就就會到達Nginx,然后Nginx就會進行轉發(fā),到達我們的Api網(wǎng)關層,在Api網(wǎng)關層就會通過一個過濾器來實現(xiàn)一個認證服務,然后校驗通過的請求就會將相應的認證信息或者是用戶信息存到請求頭里面;
2.網(wǎng)關完成認證之后,就會將請求轉發(fā)到一個具體的微服務,微服務中使用HandlenInterceptor攔截器來獲取Api層傳遞過來的認證信息,使用過濾器和攔截器就打通了Api層和微服務層的一個認證信息的傳遞;
3.但是,其實大量的請求并不是直接通過網(wǎng)關層到達服務層,而是直接由微服務之間的調(diào)用產(chǎn)生,微服務都是通過了HandlenInterceptor攔截器來獲取請求頭里面的信息,而微服務之間的調(diào)用是通過了openFegin來進行處理的,而使用openFegin時并沒有在請求頭中添加相應的一個請求信息,所以被調(diào)用的微服務就沒有辦法直接使用攔截器獲取到一個相應的認證信息,所以為了解決這個問題,就需要在openfegin調(diào)用的時候?qū)⑾鄳挠脩粜畔⒒蛘J證信息存儲到請求頭里面,這樣才能完成微服務之間的一個認證問題。
解決方案:
比較常見的一種做法就是使用攔截器傳遞認證信息,可以通過實現(xiàn)RequestInterceptor接口來定義攔截器,在攔截器里,把認證信息添加到請求頭中,然后將其注冊到Fegin的配置中。
@Configuration
public class FeignclientConfig {@Beanpublic RequestInterceptor requestInterceptor() {return new RequestInterceptor() {@Overridepublic void apply(RequestTemplate template) {// 添加認證信息到請求頭中template.header("Authorization", "Bearer " + getToken());}};}private String getToken() {return "token";}
}