魅族 18s 新一代小屏滿血旗艦亮相:依舊 162g,輕得很
Ribbon
Spring Cloud Ribbon是一個基於HTTP和TCP的客戶端負載均衡工具,它基於Netflix Ribbon實現。通過Spring Cloud的封裝,可以讓我們輕鬆地將面向服務的REST模版請求自動轉換成客戶端負載均衡的服務呼叫。它不像服務註冊中心、配置中心、API閘道器那樣需要獨立部署,但是它幾乎存在於每一個spring could構建的微服務和基礎設施中。因為微服務間的呼叫,API閘道器的請求轉發等內容,實際上都是通過Ribbon來實現的。
Ribbon是什麼?
ribbon是一個http客戶端,它具備了負載均衡、失敗重試、ping等功能。比如httpclient就是一個http客戶端,它就是用來發送http請求的,但是Ribbon在httpclient上做了更多的封裝,滿足更好的使用,當然,也可以使用其他的http客戶端。所以,Ribbon並不是很多人說的負載均衡工具,而是一個具有負載均衡等功能的http客戶端。
Ribbon基本須知配置
(1)IClientConfig clientConfig:用於配置負載均衡客戶端,預設實現類是DefaultClientConfigImpl。
(2)IRule rule:用於配置負載均衡的策略,預設使用的是RoundRobinRule策略,也就是輪詢策略。
(3)IPing ping:用於檢查當前服務是否有響應,從而判斷當前服務是否可用,預設實現類是DummyPing,該實現類的isAlive()方法返回值是true,預設所有服務例項都是可用的。
(4)ServerList serverList: 用於獲取所有Server註冊列表資訊。通過跟蹤原始碼會發現,ServerList的實現類是DiscoveryEnabledNIWSServerList,該類定義的obtainServersViaDiscovery()方法是根據eurekaClientProvider.get()方法獲取EurekaClient,再根據EurekaClient獲取服務註冊列表資訊。EurekaClient的實現類是DiscoveryClient,DiscoveryClient具有服務註冊、獲取服務註冊列表等功能。
(5)ServerListFilter filter:定義了根據配置過濾或者動態獲取符合條件的服務列表,預設實現類是ZonePreferenceServerListFilter,該策略能夠優先過濾出與請求呼叫方處於同區域的服務例項。
ribbon基本配置
1. 禁用 Eureka
當我們在 RestTemplate 上新增 @LoadBalanced 註解後,就可以用服務名稱來呼叫介面了,當有多個服務的時候,還能做負載均衡。
這是因為 Eureka 中的服務資訊已經被拉取到了客戶端本地,如果我們不想和 Eureka 整合,可以通過下面的配置方法將其禁用。
# 禁用 Eureka ribbon.eureka.enabled=false
當我們禁用了 Eureka 之後,就不能使用服務名稱去呼叫介面了,必須指定服務地址。
2. 配置介面地址列表
上面我們講了可以禁用 Eureka,禁用之後就需要手動配置呼叫的服務地址了,配置如下:
# 禁用 Eureka 後手動配置服務地址
ribbon-config-demo.ribbon.listOfServers=localhost:8081,localhost:8083
這個配置是針對具體服務的,字首就是服務名稱,配置完之後就可以和之前一樣使用服務名稱來呼叫介面了。
3. 配置負載均衡策略
Ribbon 預設的策略是輪詢,從我們前面講解的例子輸出的結果就可以看出來,Ribbon 中提供了很多的策略,這個在後面會進行講解。我們通過配置可以指定服務使用哪種策略來進行負載操作。
4. 超時時間
Ribbon 中有兩種和時間相關的設定,分別是請求連線的超時時間和請求處理的超時時間,設定規則如下:
# 請求連線的超時時間
ribbon.ConnectTimeout=2000
# 請求處理的超時時間
ribbon.ReadTimeout=5000
#也可以為每個Ribbon客戶端設定不同的超時時間, 通過服務名稱進行指定:
ribbon-config-demo.ribbon.ConnectTimeout=2000
ribbon-config-demo.ribbon.ReadTimeout=5000
5. 併發引數
# 最大連線數
ribbon.MaxTotalConnections=500
# 每個host最大連線數
ribbon.MaxConnectionsPerHost=500
程式碼配置 Ribbon
配置 Ribbon 最簡單的方式就是通過配置檔案實現。當然我們也可以通過程式碼的方式來配置。
通過程式碼方式來配置之前自定義的負載策略,首先需要建立一個配置類,初始化自定義的策略,程式碼如下所示。
@Configurationpublic class BeanConfiguration { @Bean public MyRule rule() { return new MyRule(); }}
建立一個 Ribbon 客戶端的配置類,關聯 BeanConfiguration,用 name 來指定呼叫的服務名稱,程式碼如下所示。
純文字複製
@RibbonClient(name = "ribbon-config-demo", configuration = BeanConfiguration.class)public class RibbonClientConfig {}
重試機制
在叢集環境中,用多個節點來提供服務,難免會有某個節點出現故障。用 Nginx 做負載均衡的時候,如果你的應用是無狀態的、可以滾動釋出的,也就是需要一臺臺去重啟應用,這樣對使用者的影響其實是比較小的,因為 Nginx 在轉發請求失敗後會重新將該請求轉發到別的例項上去。
由於 Eureka 是基於 AP 原則構建的,犧牲了資料的一致性,每個 Eureka 服務都會儲存註冊的服務資訊,當註冊的客戶端與 Eureka 的心跳無法保持時,有可能是網路原因,也有可能是服務掛掉了。
在這種情況下,Eureka 中還會在一段時間內儲存註冊資訊。這個時候客戶端就有可能拿到已經掛掉了的服務資訊,故 Ribbon 就有可能拿到已經失效了的服務資訊,這樣就會導致發生失敗的請求。
這種問題我們可以利用重試機制來避免。重試機制就是當 Ribbon 發現請求的服務不可到達時,重新請求另外的服務。
1. RetryRule 重試
解決上述問題,最簡單的方法就是利用 Ribbon 自帶的重試策略進行重試,此時只需要指定某個服務的負載策略為重試策略即可:
ribbon-config-demo.ribbon.NFLoadBalancerRuleClassName=com.netflix.loadbalancer.RetryRule
2. Spring Retry 重試
除了使用 Ribbon 自帶的重試策略,我們還可以通過整合 Spring Retry 來進行重試操作。
在 pom.xml 中新增 Spring Retry 的依賴,程式碼如下所示。
<dependency>
<groupId>org.springframework.retry</groupId>
<artifactId>spring-retry</artifactId>
</dependency>
配置重試次數等資訊:
# 對當前例項的重試次數
ribbon.maxAutoRetries=1
# 切換例項的重試次數
ribbon.maxAutoRetriesNextServer=3
# 對所有操作請求都進行重試
ribbon.okToRetryOnAllOperations=true
# 對Http響應碼進行重試
ribbon.retryableStatusCodes=500,404,502
Feign
Feign是一個宣告式WebService客戶端。使用Feign能讓編寫Web Service客戶端更加簡單, 它的使用方法是定義一個介面,然後在上面添加註解,同時也支援JAX-RS標準的註解。Feign也支援可拔插式的編碼器和解碼器。SpringCloud對Feign進行了封裝,使其支援了Spring MVC標準註解和HttpMessageConverters。Feign可以與Eureka和Ribbon組合使用以支援負載均衡。
Feign能幹什麼
Feign旨在是編寫Java Http客戶端變得更加容易。
- Feign 是宣告式的web service客戶端,它讓微服務之間的呼叫變得更加簡單了
- SpringCloud集成了Ribbon和Eureka,可在使用Feign時提供負載均衡的http客戶端
- 使用起來也比ribbon方便很多,只需要建立介面,然後使用註解@FeignClient("服務名")即可
Feign的用途
- 因為在實際開發中,由於對服務依賴的呼叫可能不止一處,往往一個介面會被多處呼叫,所以通常都會針對每個微服務自行封裝一些客戶端類來包裝這些依賴服務的呼叫,Feign在此基礎上進行了進一步的封裝,由他來幫助我們定義和實現依賴服務介面的定義
- 在Feign的是線下,我們只需要建立一個介面並使用註解的方式來裝配它@FeignClient("服務名"),即可完成對服務提供方的介面繫結,簡化了Ribbon自動封裝服務呼叫客戶端的開發量
Feign與Ribbon的關係
- Feign集成了Ribbon
- Feign利用了Ribbon維護了服務列表資訊,並且通過輪詢的方式實現了客戶端的負載均衡,而與Ribbon不同的是,通過Feign只需要定義服務繫結介面且以宣告式的方法,更加簡單的實現了服務的呼叫
Feign實現遠端呼叫流程圖:
Feign解決什麼問題
Feign旨在是編寫java http客戶端變得更加容易,Feign簡化了RestTemplate程式碼,實現了Ribbon負載均衡,使程式碼變得更加簡潔,也少了客戶端呼叫的程式碼,使用Feign實現負載均衡是首先方案。只需要你建立一個介面,然後在上面添加註解即可。
Feign是宣告式服務呼叫元件,其核心就是:像呼叫本地方法一樣呼叫遠端方法,無感知遠端HTTP請求。
-
它解決了讓開發者呼叫遠端介面就跟呼叫本地方法一樣的體驗,開發者完全感知不到這是遠端方法,更感知不到這是HTTP請求。無需關注與遠端的互動細節,更無需關注分散式環境開發。
-
它像Dubbo一樣,Consumer直接呼叫Provider介面方法,而不需要通過常規的Http Client構造請求再解析返回資料。
Feign vs OpenFeign
-
OpenFeign是Spring Cloud在Feign的基礎上支援了SpringMVC的註解,如果@RequstMapping、@Pathvariable等等。
-
OpenFeign的@FeignClient可以解析SpringMVC的@RequestMapping註解下的介面,並通過動態代理的方式產生實效類,實效類中做負載均衡並呼叫服務。