1.什么是Spring Cloud LoadBalancer

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

RestTemplate、WebClient 整合LoadBalancer详细项目请参考:https://gitee.com/tea-Sir/spring-cloud-alibaba.git

1)引入依赖

org.springframework.cloud

spring-cloud-starter-loadbalancer

org.springframework.boot

spring-boot-starter-web

com.alibaba.cloud

spring-cloud-starter-alibaba-nacos-discovery

org.springframework.cloud

spring-cloud-starter-netflix-ribbon

注意: nacos-discovery中引入了ribbon,需要移除ribbon的包

如果不移除,也可以在yml中配置不使用ribbon

spring:

application:

name: mall-user-loadbalancer-demo

cloud:

nacos:

discovery:

server-addr: 127.0.0.1:8848

# 不使用ribbon

loadbalancer:

ribbon:

enabled: false

原理:默认情况下,如果同时拥有RibbonLoadBalancerClient和BlockingLoadBalancerClient,为了保持向后兼容性,将使用RibbonLoadBalancerClient。要覆盖它,可以设置spring.cloud.loadbalancer.ribbon.enabled属性为false。

2)使用@LoadBalanced注解配置RestTemplate

@Bean

@LoadBalanced

public RestTemplate restTemplate() {

return new RestTemplate();

}

3) 使用

@RestController

@RequestMapping("/user")

public class UserController {

@Autowired

private RestTemplate restTemplate;

@RequestMapping(value = "/findOrderByUserId/{id}")

public R findOrderByUserId(@PathVariable("id") Integer id) {

String url = "http://mall-order/order/findOrderByUserId/"+id;

//基于RestTemplate

R result = restTemplate.getForObject(url,R.class);

return result;

}

}

3.WebClient整合LoadBalancer

1)引入依赖

org.springframework.cloud

spring-cloud-starter-loadbalancer

org.springframework.boot

spring-boot-starter-webflux

com.alibaba.cloud

spring-cloud-starter-alibaba-nacos-discovery

org.springframework.cloud

spring-cloud-starter-netflix-ribbon

2) 配置WebClient作为负载均衡器的client

@Configuration

public class WebClientConfig {

@LoadBalanced

@Bean

WebClient.Builder webClientBuilder() {

return WebClient.builder();

}

@Bean

WebClient webClient() {

return webClientBuilder().build();

}

}

3) 使用

@Autowired

private WebClient webClient;

@RequestMapping(value = "/findOrderByUserId2/{id}")

public Mono findOrderByUserIdWithWebClient(@PathVariable("id") Integer id) {

String url = "http://mall-order/order/findOrderByUserId/"+id;

//基于WebClient

Mono result = webClient.get().uri(url)

.retrieve().bodyToMono(R.class);

return result;

}

原理: 底层会使用ReactiveLoadBalancer

引入webFlux

@Autowired

private ReactorLoadBalancerExchangeFilterFunction lbFunction;

@RequestMapping(value = "/findOrderByUserId3/{id}")

public Mono findOrderByUserIdWithWebFlux(@PathVariable("id") Integer id) {

String url = "http://mall-order/order/findOrderByUserId/"+id;

//基于WebClient+webFlux

Mono result = WebClient.builder()

.filter(lbFunction)

.build()

.get()

.uri(url)

.retrieve()

.bodyToMono(R.class);

return result;

}

4.RestTemplate和WebClient区别

使用webClient在等待响应的同时不会阻塞正在执行的线程 ;这种异步编程的方式避免了线程阻塞,线程处理完一个请求紧接着可以处理下一个,能够提高系统的吞吐量;而restTemplate 这种方式是阻塞的,会一直占用当前线程资源,直到http返回响应。如果等待的请求发生了堆积,应用程序将创建大量线程,直至耗尽线程池和所有可用内存。同时伴随着频繁的CPU上下文切换,可能导致性能下降。

但是作为上述两种方式的调用者(消费者)而言,其最终获得http响应结果的耗时并未减少。比如浏览器访问上述ProductController 的两个接口时,返回数据的耗时相同。最终获取(消费)数据的地方还会等待。

使用webclient替代restTemplate的好处是可以异步等待http响应,使得线程不需要阻塞;单位时间内有限资源下支持更高的并发量。

总结

1、Spring Cloud官方自己提供的客户端负载均衡器中,建议采用WebClient作为异步响应式Http请求客户端工具。

WebClient发送Http请求支持异步响应,无需阻塞线程,相同条件下支持更高的并发。

推荐阅读

评论可见,请评论后查看内容,谢谢!!!评论后请刷新页面。