Alibaba微服務元件 - Spring Cloud LoadBalancer
阿新 • • 發佈:2022-04-11
1. 什麼是Spring Cloud LoadBalance
Spring Cloud LoadBalancer是Spring Cloud官方自己提供的客戶端負載均衡器, 用來替代Ribbon
Spring官方提供了兩種負載均衡的客戶端:
-
RestTemplate
RestTemplate是Spring提供的用於訪問Rest服務的客戶端,RestTemplate提供了多種便捷訪問遠端Http服務的方法,能夠大大提高客戶端的編寫效率。預設情況下,RestTemplate預設依賴jdk的HTTP連線工具。 -
WebClient
WebClient是從Spring WebFlux 5.0版本開始提供的一個非阻塞的基於響應式程式設計的進行Http請求的客戶端工具。它的響應式程式設計的基於Reactor的。WebClient中提供了標準Http請求方式對應的get、post、put、delete等方法,可以用來發起相應的請求。
2. RestTemplate整合LoadBalancer
2.1 引入依賴
<!-- LoadBalancer --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-loadbalancer</artifactId> </dependency> <!-- 提供了RestTemplate支援 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- nacos服務註冊與發現 移除ribbon支援--> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> <exclusions> <exclusion> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-ribbon</artifactId> </exclusion> </exclusions> </dependency>
注意:
- nacos-discovery中引入了ribbon,需要移除ribbon的包
- 如果不移除,也可以在yml中配置不使用ribbon
spring: application: name: order-server cloud: nacos: server-addr: 127.0.0.1:8848 discovery: username: nacos password: macos namespace: 6325e312-7f95-48d7-8d06-810047ed3956 # 不使用ribbon loadbalancer: ribbon: enabled: false
原理:
預設情況下,如果同時擁有RibbonLoadBalancerClient和BlockingLoadBalancerClient,為了保持向後相容性,將使用RibbonLoadBalancerClient。要覆蓋它,可以設定spring.cloud.loadbalancer.ribbon.enabled屬性為false。
2.2 使用@LoadBalanced註解配置RestTemplate
@Configuration
public class RestConfig {
@Bean
@LoadBalanced
public RestTemplate restTemplate() {
return new RestTemplate();
}
}
2.3 使用
package com.xiexie.order.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.loadbalancer.reactive.ReactorLoadBalancerExchangeFilterFunction;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Mono;
/**
* @Description
* @Date 2022-04-07 14:46
* @Author xie
*/
@RestController
@RequestMapping("/order")
public class OrderController {
@Autowired
private RestTemplate restTemplate;
@Autowired
private WebClient webClient;
@Autowired
private ReactorLoadBalancerExchangeFilterFunction lbFunction;
@RequestMapping("/add")
public String add() {
System.out.println("下單成功");
//String msg = restTemplate.getForObject("http://localhost:8011/stock/reduct", String.class);
String msg = restTemplate.getForObject("http://stock-server/stock/reduct", String.class);
// 基於WebClient
Mono<String> bodyToMono = webClient.get().uri("http://stock-server/stock/reduct").retrieve().bodyToMono(String.class);
// 基於WebClient+webFlux
Mono<String> stringMono = WebClient.builder()
.filter(lbFunction)
.build()
.get()
.uri("http://stock-server/stock/reduct")
.retrieve()
.bodyToMono(String.class);
return "Hello order add " + msg;
}
}
3. WebClient整合LoadBalance
3.1 引入依賴
<!-- LoadBalancer -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>
<!-- webflux -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
<!-- nacos服務註冊與發現 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
</exclusion>
</exclusions>
</dependency>
3.2 配置WebClient作為負載均衡器的client
@Configuration
public class WebClientConfig {
@LoadBalanced
@Bean
WebClient.Builder webClientBuilder() {
return WebClient.builder();
}
@Bean
WebClient webClient() {
return webClientBuilder().build();
}
}
3.3 使用(WebClient、WebClient + webFlux)
package com.xiexie.order.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.loadbalancer.reactive.ReactorLoadBalancerExchangeFilterFunction;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Mono;
/**
* @Description
* @Date 2022-04-07 14:46
* @Author xie
*/
@RestController
@RequestMapping("/order")
public class OrderController {
@Autowired
private RestTemplate restTemplate;
@Autowired
private WebClient webClient;
@Autowired
private ReactorLoadBalancerExchangeFilterFunction lbFunction;
@RequestMapping("/add")
public String add() {
System.out.println("下單成功");
//String msg = restTemplate.getForObject("http://localhost:8011/stock/reduct", String.class);
String msg = restTemplate.getForObject("http://stock-server/stock/reduct", String.class);
// 基於WebClient
Mono<String> bodyToMono = webClient.get().uri("http://stock-server/stock/reduct").retrieve().bodyToMono(String.class);
// 基於WebClient+webFlux
Mono<String> stringMono = WebClient.builder()
.filter(lbFunction)
.build()
.get()
.uri("http://stock-server/stock/reduct")
.retrieve()
.bodyToMono(String.class);
return "Hello order add " + msg;
}
}
原理:
底層會使用ReactiveLoadBalancer