Ribbon是客戶端的負(fù)載均衡器崎页,消費者可以通過服務(wù)別名調(diào)用服務(wù)時,需要Ribbon做負(fù)載均衡來以某種機制訪問實際的服務(wù)調(diào)用地址穷躁。
簡單類比四瘫,我們?nèi)フ襎ony老師汉嗽,一般理發(fā)店都會有多個Tony老師。但是也會有一個類似前臺的工作人員為我們安排有空的Tony老師理發(fā)莲组。工作人員就是類似Ribbon诊胞,是按照順序安排呢,還是隨機安排呢锹杈。
Ribbon + Eureka
創(chuàng)建項目
同樣創(chuàng)建一個Ribbon的空模塊撵孤,然后在Ribbon空模塊下創(chuàng)建一個ribbon-consume9101
子模塊。在父類也就是空模塊的pom文件中加入依賴
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
</dependency>
</dependencies>
當(dāng)你引入了Eureka相關(guān)的依賴的時候其實就已經(jīng)把Ribbon的依賴引入進來了竭望,所以如果使用的是Ribbon + Eureka邪码,可以不用寫上面的依賴也能運行。
創(chuàng)建完成后整體的項目結(jié)構(gòu)如圖所示
配置文件
application.yml
server:
port: 9101
spring:
application:
name: ribbon-consume
eureka:
client:
fetch-registry: true
register-with-eureka: true
service-url:
defaultZone: http://localhost:8001/eureka/
instance:
instance-id: ribbon-consume9101
啟動和業(yè)務(wù)類
注意我們的服務(wù)的提供者是eureka-provide
服務(wù)咬清,這個服務(wù)名字可能單取provide
更準(zhǔn)確點闭专,以后項目重構(gòu)的時候可能會修改。
涉及到服務(wù)與服務(wù)之間的調(diào)用旧烧,一般會選擇使用RestTemplate
影钉,同時需要把它注入Spring容器中,所以選擇使用配置類
@Configuration
public class ApplicationContextConfig {
@Bean
@LoadBalanced //負(fù)載均衡需要的注解
public RestTemplate getRestTemplate() {
return new RestTemplate();
}
}
接下來就是主啟動類
@SpringBootApplication
@EnableEurekaClient
@RestController
public class RibbonConsume9101 {
final String PROVIDE_URL = "http://eureka-provide";
RestTemplate restTemplate;
public RibbonConsume9101(RestTemplate restTemplate) {
this.restTemplate = restTemplate;
}
@GetMapping("/ribbon/consume")
public String getInfo() {
return "i am consumer, but actually invoke other service: [" + restTemplate.getForObject(PROVIDE_URL + "/eureka/provide", String.class) + "]";
}
public static void main(String[] args) {
SpringApplication.run(RibbonConsume9101.class, args);
}
}
測試
- 開啟Eureak注冊中心
EurekaServer8001
- 開啟3個不同端口的服務(wù)提供者
EurekaProvide7001
掘剪,EurekaProvide7002
,EurekaProvide7003
- 開啟剛剛建立的Ribbon消費者
RibbonConsume9101
首先看下Eureka注冊中心平委,可以看到3個服務(wù)提供者夺谁,1個消費者都已經(jīng)注冊到Eureka廉赔。
接著消費端訪問接口http://localhost:9101/ribbon/consume,看能不能從服務(wù)提供端中獲取到服務(wù)匾鸥,可以看到確實能夠調(diào)用3個不同端口的服務(wù)提供端蜡塌,并且是按照一定順序輪流調(diào)用(輪詢,也是默認(rèn)規(guī)則)勿负。
自定義配置類
上述調(diào)用服務(wù)的時候明顯是輪詢的方式馏艾,那如果想要其它方式去調(diào)用呢,這時候就需要自定義配置類笆环。
Ribbon主要有6個組件
-
ServerList:
定義獲取服務(wù)器列表 -
ServerListFilter:
對ServerList列表進行二次過濾 -
ServerListUpdater:
定義服務(wù)更新策略 -
Iping:
檢查服務(wù)列表是否存活 -
IRlue:
根據(jù)算法選擇調(diào)用服務(wù)列表中的某一個服務(wù) -
ILoadBalancer:
軟件負(fù)載均衡器入口攒至,整合以上所有的組件實現(xiàn)負(fù)載功能
@Configuration
public class RibbonCustomConfig {
@Bean
public IRule ribbonRule() {
return new RandomRule();
}
}
IRlue
接口就是以什么樣的規(guī)則去調(diào)用服務(wù)提供者,可以看下該接口的實現(xiàn)類
怎么讓這個配置文件被Ribbon感知到呢躁劣,就需要利用@RibbonClient
注解。建立一個空的注解類库菲,加上注解和配置類就能夠自定義Ribbon配置账忘。
@Configuration
@RibbonClient(name = "eureka-provide", configuration = RibbonCustomConfig.class)
public class RibbonConfig {
}
這里的名字就是我們需要調(diào)用的服務(wù)端的配置文件中的springcloud.application.name
的值。需要注意的是,在官方文檔里面有這樣一段話
在這個例子中翻譯過來就是RibbonCustomConfig
如果和主啟動類在同一個包下鳖擒,就會被掃描進Spring中溉浙,這樣會導(dǎo)致配置文件會被所有的@RibbonClients
所共享。當(dāng)然也可以用@ComponentScan
把配置文件排除在外蒋荚。
重啟RibbonConsume9101
服務(wù)本姥,其它的不用動寇钉,同樣調(diào)用消費端訪問接口http://localhost:9101/ribbon/consume
點的時候,啥,怎么一直調(diào)用的是7001端口牲芋,難道其它服務(wù)掛掉了,可以看到后面明顯加快了點的速度蕊肥,最后還好沒有翻車薪铜,確實是改成了隨機規(guī)則。
自定義配置文件
除了通過配置類來自定義Ribbon外容为,還可以通過配置文件來自定義
這里clientName
同樣是需要調(diào)用的服務(wù)端的配置文件中的springcloud.application.name
的值乓序。 如果是完全自己寫的類呢,需要實現(xiàn)對應(yīng)的接口坎背,這里同樣采用Netflix寫好的RandomRule
類替劈。
把RibbonCustomConfig
和RibbonConfig
刪掉或者全部注釋掉都可以,修改配置文件
server:
port: 9101
spring:
application:
name: ribbon-consume
eureka:
client:
fetch-registry: true
register-with-eureka: true
service-url:
defaultZone: http://localhost:8001/eureka/
instance:
instance-id: ribbon-consume9101
#其實就是加了下面的內(nèi)容
eureka-provide:
ribbon:
NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule
其中eureka-provide
就是clientName得滤。接著一樣重啟RibbonConsume9101
服務(wù)陨献,其它的不用動,同樣調(diào)用消費端訪問接口http://localhost:9101/ribbon/consume
值得注意的是耿戚,在配置文件中配置的變量是要比配置類中的優(yōu)先級要高的湿故。
Ribbon
上面是消費者端和服務(wù)端都注冊進了Eureka,相當(dāng)于消費者通過Eureka去找到了其它服務(wù)提供者的服務(wù)膜蛔。那在真正業(yè)務(wù)中接受了新的消費者端坛猪,并沒有注冊進Eureka,怎么解決這個問題呢皂股?
先來看看沒有注冊進去會發(fā)生什么情況墅茉,想都不用想肯定是直接報錯了
創(chuàng)建項目
同樣在Ribbon父模塊下面建立一個子模塊
配置文件
因為不用注冊進Eureka,所以配置文件也要做相應(yīng)的修改
server:
port: 9102
spring:
application:
name: ribbon-consume-without-eureka
#禁用掉Eureka呜呐,其實禁用不禁用都不影響就斤,因為根本就沒導(dǎo)入
ribbon:
eureka:
enabled: false
啟動和業(yè)務(wù)類
同樣需要導(dǎo)入RestTemplate
所以可以直接復(fù)制上一個子模塊
@Configuration
public class ApplicationContextConfig {
@Bean
@LoadBalanced
public RestTemplate getRestTemplate() {
return new RestTemplate();
}
}
主啟動類也可以直接復(fù)制,不需要用到Eureka蘑辑,去掉@EnableEurekaClient
注解并修改類名即可
@SpringBootApplication
@RestController
public class RibbonConsumeWithoutEureka9102 {
final String PROVIDE_URL = "http://eureka-provide";
RestTemplate restTemplate;
public RibbonConsumeWithoutEureka9102(RestTemplate restTemplate) {
this.restTemplate = restTemplate;
}
@GetMapping("/ribbon/consume")
public String getInfo() {
return "i am consumer, but actually invoke other service: [" + restTemplate.getForObject(PROVIDE_URL + "/eureka/provide", String.class) + "]";
}
public static void main(String[] args) {
SpringApplication.run(RibbonConsumeWithoutEureka9102.class, args);
}
}
那怎樣消費者調(diào)用的時候怎么知道去哪找提供者的服務(wù)呢洋机,就需要動配置文件了
server:
port: 9102
spring:
application:
name: ribbon-consume-without-eureka
ribbon:
eureka:
enabled: false
#以下為增加內(nèi)容
eureka-provide:
ribbon:
listOfServers: localhost:7001, localhost:7002, localhost:7003
其中eureka-provide
就是需要調(diào)用的服務(wù)端的配置文件中的springcloud.application.name
的值
開啟RibbonConsume9102
服務(wù),其它的不用動洋魂,調(diào)用消費端訪問接口http://localhost:9102/ribbon/consume 绷旗,可以看到也是能夠按照默認(rèn)輪詢的方式調(diào)用服務(wù)喜鼓。
創(chuàng)作不易,如果對你有幫助衔肢,歡迎點贊庄岖,收藏和分享啦!
文章持續(xù)更新角骤,可以關(guān)注微信公眾號CodeNone隅忿,基本2,3天1更技術(shù)文章0钭稹1惩!