Ribbon是SpringCloud體系中用來實(shí)現(xiàn)負(fù)載均衡的組件仁热,通常來說榜揖,它不是一個獨(dú)立的組件,而是存在于各個微服務(wù)上的抗蠢。
負(fù)載均衡一般分為兩種:
- 服務(wù)器端負(fù)載均衡,比如Nginx迅矛,是一臺獨(dú)立的服務(wù)器作為應(yīng)用服務(wù)的前置妨猩,反向代理實(shí)現(xiàn)服務(wù)集群的負(fù)載均衡。
- 客戶端負(fù)載均衡秽褒,比如Ribbon壶硅,是進(jìn)程級別的威兜,存在于各個Consumer微服務(wù)上的負(fù)載均衡機(jī)制。
一庐椒、項目準(zhǔn)備
本文是在如下這篇Eureka入門案例的基礎(chǔ)上擴(kuò)展實(shí)現(xiàn)的椒舵,所以,要先按照如下的文章先搭建好Eureka的服務(wù)端和客戶端约谈。
有了上述案例的代碼后笔宿,我們從start.spring.io
上一鍵下載一個自帶Eureka-client
和Ribbon
的工程,命名為ribbon-demo
棱诱,并做如下內(nèi)容的修改措伐。
1.1 啟動類
@SpringBootApplication
@EnableEurekaClient
public class RibbonDemoApplication {
public static void main(String[] args) {
SpringApplication.run(RibbonDemoApplication.class, args);
}
@Bean
@LoadBalanced
RestTemplate restTemplate(){
return new RestTemplate();
}
}
- Ribbon客戶端本身作為一個Eureka客戶端存在,因此需要
@EnableEurekaClient
注解军俊,并且向注冊中心注冊服務(wù)侥加; -
@Bean
和@LoadBalanced
注解是注入一個RestTemplate實(shí)例,并標(biāo)明是負(fù)載均衡使用的粪躬;
1.2 配置文件
作為一個Eureka客戶端担败,我們?nèi)匀恍枰缦碌呐渲眯畔ⅲ员WC注冊服務(wù)到注冊中心服務(wù)器上镰官。
server.port=8090
# 當(dāng)前應(yīng)用名稱
spring.application.name=ribbon-client
# eureka注冊中心地址
eureka.client.serviceUrl.defaultZone=http://127.0.0.1:8761/eureka/
1.3 創(chuàng)建一個Rest請求類
我們打算對外暴露一個接口提前,接收來自瀏覽器的請求,然后將這些請求以負(fù)載均衡的方式發(fā)送給真正的服務(wù)端泳唠。
@RestController
public class RibbonTestController {
private static String EUREKA_URL = "http://eureka-client/getHello";
@Autowired
private RestTemplate restTemplate;
@GetMapping("/getRibbonHello")
public String getRibbonHello(HttpServletRequest request){
String result = restTemplate.getForObject(EUREKA_URL, String.class);
System.out.println(result);
return result;
}
}
如此狈网,我們就準(zhǔn)備好了一個最簡單的Ribbon案例。
二笨腥、入門實(shí)例
現(xiàn)在我們有了如下這些服務(wù):
Eureka服務(wù)端拓哺,在8761端口提供服務(wù);
-
Eureka客戶端A脖母,在8088端口提供服務(wù)士鸥;
對其中的Rest請求案例稍作修改:
@RestController public class RibbonTestController { @GetMapping("/getHello") public String getRibbonHello(HttpServletRequest request){ return "From port:" + request.getServerPort(); } }
Eureka客戶端B,在8089端口提供服務(wù)谆级,除了啟動端口外其余內(nèi)容和客戶端A一樣烤礁;
Ribbon客戶端,在8090端口提供服務(wù)肥照;
現(xiàn)在脚仔,我們按照如上順序啟動所有的服務(wù),訪問注冊中心控制臺舆绎,就能看到這些服務(wù)鲤脏。
我們開始多次請求Ribbon客戶端的接口http://localhost:8090/getRibbonHello
,就會發(fā)現(xiàn)亿蒸,Ribbon客戶端是在默認(rèn)采用輪詢的方式對所有名稱為eureka-client
的服務(wù)發(fā)起請求并返回接口給瀏覽器凑兰。
三掌桩、Ribbon配置
3.1 負(fù)載均衡策略
- 輪詢RoundRobinRule,這也是默認(rèn)的策略姑食;
- 隨機(jī)RandomRule
- 響應(yīng)時間權(quán)重ResponseTimeWeightedRule波岛,為每個服務(wù)設(shè)置權(quán)重,響應(yīng)時間越短音半,權(quán)重越大则拷,下次越有可能被選中;
- 最少并發(fā)數(shù)策略BestAvailableRule
- 重試策略RetryRule
- 可用性敏感策略AvailabilityFilteringRule
- 區(qū)域性敏感策略ZoneAvoidanceRule
總共有七種負(fù)載均衡策略可供選擇曹鸠,可以根據(jù)自己的業(yè)務(wù)場景進(jìn)行選擇煌茬。
默認(rèn)情況下,系統(tǒng)采用的是輪詢策略彻桃,那么如何通過配置來更換負(fù)載均衡策略呢坛善?
方法一、增加一個配置類
@Configuration
public class RibbonBalancedStrategyConfig {
@Bean
public IRule ribbonRule(){
return new RandomRule();
}
}
該配置類對全局Ribbon生效邻眷,當(dāng)我們再次重啟Ribbon客戶端的時候眠屎,多次訪問http://localhost:8090/getRibbonHello
就會得到如下的隨機(jī)結(jié)果。
方法二肆饶、使用配置文件
有時候改衩,我們Ribbon可能會負(fù)載均衡多個服務(wù)源,對于某個服務(wù)源我們想更改負(fù)載均衡策略驯镊,而不是全部葫督,那么就可以在配置文件中進(jìn)行配置。
# 指定eureka-client服務(wù)源的負(fù)載均衡策略
eureka-client.ribbon.NFLoadBalancerRuleClassName=com.netflix.loadbalancer.RandomRule
同樣的板惑,我們多次訪問得到的也是隨機(jī)負(fù)載的策略效果橄镜。
3.2 超時與重試
同樣的,在配置文件中進(jìn)行配置即可洒放。
eureka-client.ribbon.ConnectTimeout=1
eureka-client.ribbon.ReadTimeout=1
eureka-client.ribbon.MaxAutoRetries=1
eureka-client.ribbon.MaxAutoRetriesNextServer=1
eureka-client.ribbon.OkToRetryOnAllOperations=true
3.3 饑餓加載
我們的ribbon-client客戶端在啟動的時候并不會立即加載上下文蛉鹿,需要在請求真正到來時才會創(chuàng)建滨砍,如此會有可能導(dǎo)致第一次調(diào)用某個服務(wù)源的時候出現(xiàn)很慢的情況往湿,我們可以通過如下配置項的方式來指定具體的服務(wù)名稱開啟饑餓加載,即在啟動的時候就加載所有服務(wù)應(yīng)用上下文惋戏。
ribbon.eager-load.enabled=true
ribbon.eager-load.clients=eureka-client,eureka-client2