筆記:Spring Cloud Ribbon 客戶端負載均衡
Spring Cloud Ribbon 是一個基於 HTTP 和 TCP 的客戶端負載均衡工具,基於 Netflix Ribbon 實現,通過Spring Cloud 的封裝,可以讓我們輕松的將面向服務的REST 模板請求自動轉換為客戶端負載均衡的服務調用。客戶端負載均衡在系統架構中是一個非常重要的,並且是不得不去實施的內容,因為負載均衡是對系統的高可用、網絡壓力的緩解和處理能力擴容的重要手段,客戶端負載均衡需要通過心跳去維護服務端清單的健康性,這個需要服務註冊中心配合完成,在Spring Cloud 實現的服務治理框架中,默認會創建針對各個服務治理框架的 Ribbon 自動化整合配置,比如 Eureka 中的 org.springframework.cloud.netflix.ribbon.eureka.RibbonEurekaAutoConfiguration 。
通過 Spring Cloud Ribbon 的封裝,我們在微服務架構中使用客戶端負載均衡調用非常簡單,只需要分為兩步:
- 服務提供者只需要啟動多個服務實例並註冊到一個註冊中心或是多個相關聯的服務註冊中心
- 服務消費者直接通過調用被 @LoadBalanced 註解修飾過的 RestTemplate 來實現面向服務的接口調用。
調用示例如下:
- 在 pom.xml 文件中需要增加 spring-cloud-starter-ribbon 和 spring-cloud-starter-eureka 依賴,代碼如下:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
??????????????????xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
????????<modelVersion>4.0.0</modelVersion>
? ?
????????<groupId>org.drsoft.consumer</groupId>
????????<artifactId>consumer-helloservice</artifactId>
????????<version>0.0.1-SNAPSHOT</version>
????????<packaging>jar</packaging>
? ?
????????<name>consumer-helloservice</name>
????????<description>Demo project for Spring Boot</description>
? ?
????????<parent>
????????????????<groupId>org.springframework.boot</groupId>
????????????????<artifactId>spring-boot-starter-parent</artifactId>
????????????????<version>1.5.6.RELEASE</version>
????????????????<relativePath/>
????????</parent>
? ?
????????<properties>
????????????????<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
????????????????<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
????????????????<java.version>1.8</java.version>
????????????????<spring-cloud.version>Dalston.SR2</spring-cloud.version>
????????</properties>
? ?
????????<dependencies>
????????????????<dependency>
????????????????????????<groupId>org.springframework.cloud</groupId>
????????????????????????<artifactId>spring-cloud-starter-eureka</artifactId>
????????????????</dependency>
????????????????<dependency>
????????????????????????<groupId>org.springframework.cloud</groupId>
????????????????????????<artifactId>spring-cloud-starter-ribbon</artifactId>
????????????????</dependency>
????????????????<dependency>
????????????????????????<groupId>org.springframework.boot</groupId>
????????????????????????<artifactId>spring-boot-starter-web</artifactId>
????????????????</dependency>
? ?
????????????????<dependency>
????????????????????????<groupId>org.springframework.boot</groupId>
????????????????????????<artifactId>spring-boot-starter-test</artifactId>
????????????????????????<scope>test</scope>
????????????????</dependency>
????????</dependencies>
? ?
????????<dependencyManagement>
????????????????<dependencies>
????????????????????????<dependency>
????????????????????????????????<groupId>org.springframework.cloud</groupId>
????????????????????????????????<artifactId>spring-cloud-dependencies</artifactId>
????????????????????????????????<version>${spring-cloud.version}</version>
????????????????????????????????<type>pom</type>
????????????????????????????????<scope>import</scope>
????????????????????????</dependency>
????????????????</dependencies>
????????</dependencyManagement>
? ?
????????<build>
????????????????<plugins>
????????????????????????<plugin>
????????????????????????????????<groupId>org.springframework.boot</groupId>
????????????????????????????????<artifactId>spring-boot-maven-plugin</artifactId>
????????????????????????</plugin>
????????????????</plugins>
????????</build>
</project>
- 創建應用主類 ConsumerHelloserviceApplication ,通過 @EanbleDiscoveryClient 註解將應用註冊為Eureka 客戶端應用,增加 @Bean 註解的返回 RestTemplate 類型的方法:
@EnableDiscoveryClient
@SpringBootApplication
public class ConsumerHelloserviceApplication {
? ?
????????public static void main(String[] args) {
????????????????SpringApplication.run(ConsumerHelloserviceApplication.class, args);
????????}
? ?
????????@LoadBalanced
????????@Bean
????????public RestTemplate createRestTemplate() {
????????????????return new RestTemplate();
????????}
}
- 創建 ConsumerController 類,並實現 /consumer 接口,在類中註入 RestTemplate 並通過該類實例來調用服務,在接口中對服務的調用,這裏使用的是服務的名而不是一個具體的地址,服務消費Java代碼:
@RestController
public class ConsumerController {
????????@Autowired
????????private RestTemplate restTemplate;
???????? ?
????????@RequestMapping (value = "/ribbonconsumer", method = RequestMethod.GET)
????????public String ribbonConsumer() {
? ?
????????????????ResponseEntity<String> responseEntity = null;
????????????????try {
????????????????????????responseEntity =
????????????????????????????????????????restTemplate.getForEntity("http://ORG.DRSOFT.WEBSERVICE.HELLOSERVICE/hello/get",
String.class);
? ?
????????????????????????if (responseEntity.getStatusCode() == HttpStatus.OK) {
????????????????????????????????return responseEntity.getBody();
????????????????????????}
? ?
????????????????????????return "response status " + responseEntity.getStatusCodeValue();
????????????????} catch (UnsupportedEncodingException e) {
????????????????????????e.printStackTrace();
????????????????????????return "error";
????????????????}
????????}
}
- 在 application.properties 中,增加服務註冊中的地址配置需要和服務提供者的一致,否則是無法發現服務的,同時設置該消費者的端口號,代碼如下:
server.port=8090
spring.application.name=consumer-helloservice
? ?
eureka.client.service-url.defaultZone=http://eurekaserver1:1111/eureka/,http://eurekaserver2:1112/eureka
- 啟動應用,訪問地址 http://localhost:8090/ribbonconsumer
,即可看到請求返回信息
? ?
? ?
? ?
筆記:Spring Cloud Ribbon 客戶端負載均衡