共計(jì) 7539 個(gè)字符,預(yù)計(jì)需要花費(fèi) 19 分鐘才能閱讀完成。
這篇文章主要介紹了 Spring Cloud 如何使用 Ribbon,具有一定借鑒價(jià)值,感興趣的朋友可以參考下,希望大家閱讀完這篇文章之后大有收獲,下面讓丸趣 TV 小編帶著大家一起了解一下。
8 Spring Cloud 與 RibbonRibbon8.1 準(zhǔn)備工作
為了本小節(jié)的測(cè)試做準(zhǔn)備,按順序進(jìn)行以下工作:
? 新建 Eureka 服務(wù)器端項(xiàng)目,命名為“cloud-server”,端口 8761,
代碼目錄 codes\04\4.4\cloud-server。
? 新建 Eureka 服務(wù)提供者項(xiàng)目,命名為“cloud-provider”,
代碼目錄 codes\04\4.4\cloud-provider,該項(xiàng)目主要進(jìn)行以下工作:
1. 在控制器里面,發(fā)布一個(gè) REST 服務(wù),地址為“/person/{personId}”,
請(qǐng)求后返回 Person 實(shí)例,其中 Person 的 message 為 HTTP 請(qǐng)求的 URL。
2. 服務(wù)提供者需要啟動(dòng)兩次,因此在控制臺(tái)中需要輸入啟動(dòng)端口。
? 新建 Eureka 服務(wù)調(diào)用者項(xiàng)目,命名為“cloud-invoker”,對(duì)外端口為 9000,
代碼目錄 codes\04\4.4\cloud-invoker。本例的負(fù)載均衡配置主要針對(duì)服務(wù)調(diào)用者。
以上項(xiàng)目準(zhǔn)備完成并啟動(dòng)后,結(jié)構(gòu)如圖 4 - 2 所示。
圖 4 -2 準(zhǔn)備的項(xiàng)目結(jié)構(gòu)圖
注意:Eureka 相關(guān)項(xiàng)目的建立,可參見前面章節(jié)。
8.2 使用代碼配置 Ribbon
在前面章節(jié)講述了負(fù)載規(guī)則以及 Ping,在 Spring Cloud 中,可將自定義的負(fù)載規(guī)則以及 Ping 類,放到服務(wù)調(diào)用者中,查看效果。新建自定義的 IRule 與 IPing,兩個(gè)實(shí)現(xiàn)類請(qǐng)見代碼清單 4 -11。
代碼清單 4 -11:
codes\04\4.4\cloud-invoker\src\main\java\org\crazyit\cloud\MyRule.java
codes\04\4.4\cloud-invoker\src\main\java\org\crazyit\cloud\MyPing.java
package org.crazyit.cloud;
import java.util.List;
import com.netflix.loadbalancer.ILoadBalancer;
import com.netflix.loadbalancer.IRule;
import com.netflix.loadbalancer.Server;
public class MyRule implements IRule {
private ILoadBalancer lb;
public Server choose(Object key) {List Server servers = lb.getAllServers();
System.out.println( 這是自定義服務(wù)器定規(guī)則類,輸出服務(wù)器信息:for(Server s : servers) {System.out.println( + s.getHostPort());
return servers.get(0);
public void setLoadBalancer(ILoadBalancer lb) {
this.lb = lb;
public ILoadBalancer getLoadBalancer() {return this.lb;}
package org.crazyit.cloud;
import com.netflix.loadbalancer.IPing;
import com.netflix.loadbalancer.Server;
public class MyPing implements IPing {public boolean isAlive(Server server) {System.out.println( 自定義 Ping 類,服務(wù)器信息: + server.getHostPort());
return true;
}
根據(jù)兩個(gè)自定義的 IRule 和 IPing 類可知,實(shí)際上跟 4.3 章節(jié)中的自定義實(shí)現(xiàn)類似,服務(wù)器選擇規(guī)則中只返回集合中的第一個(gè)實(shí)例,IPing 實(shí)現(xiàn)僅僅是控制輸入服務(wù)器信息。接下來,新建配置類,返回規(guī)則與 Ping 的 Bean,請(qǐng)見代碼清單 4 -12。
代碼清單 4 -12:
codes\04\4.4\cloud-invoker\src\main\java\org\crazyit\cloud\config\MyConfig.java
codes\04\4.4\cloud-invoker\src\main\java\org\crazyit\cloud\config\CloudProviderConfig.java
package org.crazyit.cloud.config;
import org.crazyit.cloud.MyPing;
import org.crazyit.cloud.MyRule;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import com.netflix.loadbalancer.IPing;
import com.netflix.loadbalancer.IRule;
public class MyConfig {
@Bean
public IRule getRule() {return new MyRule();
@Bean
public IPing getPing() {return new MyPing();
}
package org.crazyit.cloud.config;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.cloud.netflix.ribbon.RibbonClient;
import org.springframework.context.annotation.Configuration;
@RibbonClient(name= cloud-provider , configuration=MyConfig.class)
public class CloudProviderConfig {}
代碼清單 4 -12 中,CloudProviderConfig 配置類,使用了 @RibbonClient 注解,配置了 RibbonClient 的名稱為“cloud-provider”,對(duì)應(yīng)的配置類為“MyConfig”,也就是名稱為“cloud-provider”的客戶端,將使用 MyRule 與 MyPing 兩個(gè)類。在服務(wù)調(diào)用者的控制器中,加入對(duì)外服務(wù),服務(wù)中調(diào)用 RestTemplate,如代碼清單 4 -13。
代碼清單 4 -13:
codes\04\4.4\cloud-invoker\src\main\java\org\crazyit\cloud\InvokerController.java
@RestController
@Configuration
public class InvokerController {
@LoadBalanced
@Bean
public RestTemplate getRestTemplate() {return new RestTemplate();
@RequestMapping(value = /router , method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
public String router() {RestTemplate restTpl = getRestTemplate();
// 根據(jù)名稱調(diào)用服務(wù)
String json = restTpl.getForObject( http://cloud-provider/person/1 ,
String.class);
return json;
}
以上的控制器中,為 RestTemplate 加入了 @LoadBalanced 修飾,與前面章節(jié)類似,在此不再贅述,關(guān)于 RestTemplate 的原理,將在本章后面章節(jié)講述。進(jìn)行以下操作,查看本例效果:
? 啟動(dòng)一個(gè) Eureka 服務(wù)器(cloud-server)。
? 啟動(dòng)兩次 Eureka 服務(wù)提供者(cloud-provider),分別輸入 8080 與 8081 端口。
? 啟動(dòng)一個(gè) Eureka 服務(wù)調(diào)用者(cloud-invoker)。
? 打開瀏覽器訪問 http://localhost:9000/router,可以看到調(diào)用服務(wù)后返回的 JSON 字符串,不管刷新多少次,最終都只會(huì)訪問其中一個(gè)端口。
8.3 使用配置文件設(shè)置 Ribbon
在前面使用 Ribbon 時(shí),可以通過配置來定義各個(gè)屬性,在使用 Spring Cloud 時(shí),這些屬性同樣可以配置到 application.yml 中,以下的配置同樣生效:
cloud-provider:
ribbon:
NFLoadBalancerRuleClassName: org.crazyit.cloud.MyRule
NFLoadBalancerPingClassName: org.crazyit.cloud.MyPing
listOfServers: http://localhost:8080/,http://localhost:8081/
為 cloud-provider 這個(gè)客戶端,配置了規(guī)則處理類、Ping 類以及服務(wù)器列表,以同樣的方式運(yùn)行本小節(jié)例子,可看到同樣的效果,在此不再贅述。
代碼與配置文件的方式進(jìn)行配置,兩種方式的效果一致,但對(duì)比起來,明顯是配置文件的方式更加簡(jiǎn)便。
注意:本案例的 cloud-invoker 模塊中,默認(rèn)使用了代碼的方式來配置 Ribbon,配置文件中的配置已被注釋。
8.4 Spring 使用 Ribbon 的 API
Spring Cloud 對(duì) Ribbon 進(jìn)行封裝,例如像負(fù)載客戶端、負(fù)載均衡器等,我們可以直接使用 Spring 的 LoadBalancerClient 來處理請(qǐng)求以及服務(wù)選擇。代碼清單 4 -14,在服務(wù)器調(diào)用者的控制器中使用 LoadBalancerClient。
代碼清單 4 -14:
codes\04\4.4\cloud-invoker\src\main\java\org\crazyit\cloud\InvokerController.java
@Autowired
private LoadBalancerClient loadBalancer;
@RequestMapping(value = /uselb , method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
public ServiceInstance uselb() {
// 查找服務(wù)器實(shí)例
ServiceInstance si = loadBalancer.choose( cloud-provider
return si;
}
除了使用 Spring 封裝的負(fù)載客戶端外,還可以直接使用 Ribbon 的 API,代碼 4 -15,直接獲取 Spring Cloud 默認(rèn)環(huán)境中,各個(gè) Ribbon 的實(shí)現(xiàn)類。
代碼清單 4 -15:
codes\04\4.4\cloud-invoker\src\main\java\org\crazyit\cloud\InvokerController.java
@Autowired
private SpringClientFactory factory;
@RequestMapping(value = /defaultValue , method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
public String defaultValue() {
System.out.println( ==== 輸出默認(rèn)配置:// 獲取默認(rèn)的配置
ZoneAwareLoadBalancer alb = (ZoneAwareLoadBalancer) factory
.getLoadBalancer( default
System.out.println( IClientConfig:
+ factory.getLoadBalancer(default).getClass().getName());
System.out.println( IRule: + alb.getRule().getClass().getName());
System.out.println( IPing: + alb.getPing().getClass().getName());
System.out.println( ServerList:
+ alb.getServerListImpl().getClass().getName());
System.out.println( ServerListFilter:
+ alb.getFilter().getClass().getName());
System.out.println( ILoadBalancer: + alb.getClass().getName());
System.out.println( PingInterval: + alb.getPingInterval());
System.out.println( ==== 輸出 cloud-provider 配置:// 獲取 cloud-provider 的配置
ZoneAwareLoadBalancer alb2 = (ZoneAwareLoadBalancer) factory
.getLoadBalancer( cloud-provider
System.out.println( IClientConfig:
+ factory.getLoadBalancer(cloud-provider).getClass()
.getName());
System.out.println( IRule: + alb2.getRule().getClass().getName());
System.out.println( IPing: + alb2.getPing().getClass().getName());
System.out.println( ServerList:
+ alb2.getServerListImpl().getClass().getName());
System.out.println( ServerListFilter:
+ alb2.getFilter().getClass().getName());
System.out.println( ILoadBalancer: + alb2.getClass().getName());
System.out.println( PingInterval: + alb2.getPingInterval());
return
}
代碼中使用了 SpringClientFactory,通過該實(shí)例,可獲取各個(gè)默認(rèn)的實(shí)現(xiàn)類以及配置,分別輸出了默認(rèn)配置以及“cloud-provider”配置。運(yùn)行代碼清單 4 -15,瀏覽器中訪問地址 http://localhost:8080/defaultValue,可看到控制臺(tái)輸出如下:
==== 輸出默認(rèn)配置: IClientConfig: com.netflix.loadbalancer.ZoneAwareLoadBalancer
IRule: com.netflix.loadbalancer.ZoneAvoidanceRule
IPing: com.netflix.niws.loadbalancer.NIWSDiscoveryPing
ServerList: org.springframework.cloud.netflix.ribbon.eureka.DomainExtractingServerList
ServerListFilter: org.springframework.cloud.netflix.ribbon.ZonePreferenceServerListFilter
ILoadBalancer: com.netflix.loadbalancer.ZoneAwareLoadBalancer
PingInterval: 30
==== 輸出 cloud-provider 配置: IClientConfig: com.netflix.loadbalancer.ZoneAwareLoadBalancer
IRule: org.crazyit.cloud.MyRule
IPing: org.crazyit.cloud.MyPing
ServerList: org.springframework.cloud.netflix.ribbon.eureka.DomainExtractingServerList
ServerListFilter: org.springframework.cloud.netflix.ribbon.ZonePreferenceServerListFilter
ILoadBalancer: com.netflix.loadbalancer.ZoneAwareLoadBalancer
PingInterval: 30
根據(jù)輸出可知,cloud-provider 客戶端使用的負(fù)載規(guī)則類以及 Ping 類,是我們自定義的實(shí)現(xiàn)類。
一般情況下,Spring 已經(jīng)幫我們封裝好了 Ribbon,我們只需要直接調(diào)用 RestTemplate 等 API 來訪問服務(wù)即可。
感謝你能夠認(rèn)真閱讀完這篇文章,希望丸趣 TV 小編分享的“Spring Cloud 如何使用 Ribbon”這篇文章對(duì)大家有幫助,同時(shí)也希望大家多多支持丸趣 TV,關(guān)注丸趣 TV 行業(yè)資訊頻道,更多相關(guān)知識(shí)等著你來學(xué)習(xí)!