Spring Cloud 應用篇 之 Ribbon 的基本使用
上一篇文章初步體驗了 Eureka 的基本使用,講了關於服務的註冊與發現。這一篇主要講解基於 Ribbon 實現的服務呼叫。
(一)簡介
Spring Cloud Ribbon 是一個基於 Http 和 TCP 的客服端負載均衡工具,它是基於 Netflix Ribbon 實現的。
客戶端負載均衡即是當瀏覽器向後臺發出請求的時候,客戶端會向 Eureka Server 讀取註冊到伺服器的可用服務資訊列表,然後根據設定的負載均衡策略(沒有設定即用預設的),抉擇出向哪臺伺服器傳送請求。
(二)搭建服務環境
1. 基於上一篇的工程,啟動 eureka-service,spring-demo-service
啟動完畢後,更改 spring-demo-service 的埠號,再啟動一個 spring-demo-service 的例項,訪問 http://localhost:8761,如下
spring-demo-service 在 eureka server 註冊了兩個例項。
2. 新建立一個 module(spring-demo-service-ribbon),建立過程參考上一篇
3. 新增 pom 依賴
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-ribbon</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency>
4. 啟動類
@SpringBootApplication
@EnableEurekaClient
public class ServiceRibbonApplication {
public static void main(String[] args) {
SpringApplication.run(ServiceRibbonApplication.class, args);
}
@Bean
@LoadBalanced
RestTemplate restTemplate() {
return new RestTemplate();
}
}
在啟動類中,通過 @EnableEurekaClient 向 eureka server 註冊,並向容器中注入 restTemplate,同時通過 @LoadBalanced 開啟 restTemplate 負載均衡功能。
5. 建立 SpringDemoRibbonService,通過 restTemplate 消費 spring-demo-service 服務的 port 介面
@Service
public class SpringDemoRibbonService {
@Autowired
RestTemplate restTemplate;
public String port() {
return restTemplate.getForObject("http://SPRING-DEMO-SERVICE/port", String.class);
}
}
在這裡,restTemplate 呼叫服務介面的方法不是僅此一種,API 大致如下,具體怎麼選擇應用,可以檢視相關 API 文件,我們直接使用 getForObject 第一種,在這裡我們直接用的程式名替代了具體的 url 地址,在 Ribbon 中它會根據服務名來選擇具體的服務例項,根據服務例項在請求的時候會用具體的 url 替換掉服務名
6. 建立 SpringDemoRibbonController
@RestController
public class SpringDemoRibbonController {
@Autowired
SpringDemoRibbonService springDemoRibbonService;
@RequestMapping("hello")
public String port() {
return springDemoRibbonService.port();
}
}
7. 配置檔案 application.yaml
eureka:
client:
serviceUrl:
defaultZone: http://localhost:8761/eureka/
server:
port: 8381
spring:
application:
name: spring-demo-service-ribbon
8. 啟動 spring-demo-service-ribbon,在瀏覽器中多次訪問 localhost:8381/hello,瀏覽器會輪流顯示如下
此時說明基本使用 Ribbon 實現了客戶端負載均衡的功能,當用 restTemplate 呼叫服務介面時,訪問了不同埠的服務例項。
(三)稍作延伸:負載均衡策略常見的還有使用 Nginx 作為反向代理伺服器,對服務的呼叫進行負載均衡,這種方式是伺服器端負載均衡。
Ribbon 實現的是客戶端負載均衡,它可以在客戶端經過一系列演算法來均衡呼叫服務。Ribbon 比 Nginx 更注重的是承擔併發而不是請求分發,Ribbon 工作時分兩步:
第一步:選擇 Eureka Server,它優先選擇在同一個 Zone 且負載較少的 Server。
第二步:根據使用者指定的策略,在從 Server 取到的服務註冊列表中選擇一個地址,其中 Ribbon 提供了多種策略,例如輪詢 RoundRobinRule、隨機 RandomRule等。
下面以隨機策略進行進一步的配置
配置檔案修改如下:
eureka:
client:
serviceUrl:
defaultZone: http://localhost:8761/eureka/
server:
port: 8381
spring:
application:
name: spring-demo-service-ribbon
#新增配置策略
spring-demo-service:
ribbon:
NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule
啟動類修改如下:@SpringBootApplication
@EnableEurekaClient
@EnableCircuitBreaker
public class ServiceRibbonApplication {
public static void main(String[] args) {
SpringApplication.run(ServiceRibbonApplication.class, args);
}
@Bean
@LoadBalanced
RestTemplate restTemplate() {
return new RestTemplate();
}
//新增注入隨機策略 Bean
@Bean
public IRule ribbonRule() {
return new RandomRule(); //這裡配置策略,和配置檔案對應
}
}
SpringDemoRibbonService 修改如下
@Service
public class SpringDemoRibbonService {
@Autowired
RestTemplate restTemplate;
@Autowired
LoadBalancerClient loadBalancerClient;
public String port() {
this.loadBalancerClient.choose("spring-demo-service"); //隨機訪問策略
return restTemplate.getForObject("http://SPRING-DEMO-SERVICE/port", String.class);
}
}
修改完成後,修改 spring-demo-service 的埠號,再啟動一個服務例項,然後重啟 spring-demo-service-ribbon,在瀏覽器中多次訪問 localhost:8381/hello,此時會發現,對 spring-demo-service 的服務例項呼叫是隨機呼叫,而不再是之前輪流呼叫,說明負載策略配置成功。