【loadbalancer】还在用Ribbon?试试Spring自带的LoadBalancer吧

news/2025/1/24 7:11:47/

Spring Cloud LoadBalancer是Spring Cloud官方自己提供的客户端负载均衡器, 用来替代Ribbon。

Spring官方提供了两种客户端都可以使用loadbalancer:

  • RestTemplate:Spring提供的用于访问Rest服务的客户端,RestTemplate提供了多种便捷访问远程Http服务的方法,能够大大提高客户端的编写效率。默认情况下,RestTemplate默认依赖jdk的HTTP连接工具。
  • WebClient:从Spring WebFlux 5.0版本开始提供的一个非阻塞的基于响应式编程的进行Http请求的客户端工具。它的响应式编程的基于Reactor的。WebClient中提供了标准Http请求方式对应的get、post、put、delete等方法,可以用来发起相应的请求。

RestTemplate整合LoadBalancer

引入LoadBalancer的依赖

<!-- 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。

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

spring:application:name: user-servicecloud:nacos:discovery:server-addr: 127.0.0.1:8848# 不使用ribbon,使用loadbalancerloadbalancer:ribbon:enabled: false

使用@LoadBalanced注解修饰RestTemplate,开启客户端负载均衡功能

package com.morris.user.config;import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;@Configuration
public class RestConfig {/*** 默认的RestTemplate,不带负载均衡* @return*/@Beanpublic RestTemplate restTemplate() {return new RestTemplate();}/*** 有负责均衡能力的RestTemplate* @return*/@Bean@LoadBalancedpublic RestTemplate restTemplate2() {return new RestTemplate();}
}

RestTemplate的使用:

package com.morris.user.controller;import com.morris.user.entity.Order;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;import javax.annotation.Resource;
import java.util.Arrays;
import java.util.List;@RestController
@RequestMapping("user")
public class RestTemplateController {@Resourceprivate RestTemplate restTemplate;@Resourceprivate RestTemplate restTemplate2;@GetMapping("findOrderByUserId")public List<Order> findOrderByUserId(Long userId) {Order[] orders = restTemplate.getForObject("http://127.0.0.1:8020/order/findOrderByUserId?userId=", Order[].class, userId);return Arrays.asList(orders);}@GetMapping("findOrderByUserId2")public List<Order> findOrderByUserId2(Long userId) {Order[] orders = restTemplate2.getForObject("http://order-service/order/findOrderByUserId?userId=", Order[].class, userId);return Arrays.asList(orders);}
}

WebClient整合LoadBalancer

引入依赖webflux,WebClient位于webflux内:

<!-- 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>

同样需要在配置文件中禁用ribbon:

spring:application:name: user-servicecloud:nacos:discovery:server-addr: 127.0.0.1:8848# 不使用ribbon,使用loadbalancerloadbalancer:ribbon:enabled: false

使用@LoadBalanced注解修饰WebClient.Builder,开启客户端负载均衡功能

package com.morris.user.config;import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.reactive.function.client.WebClient;@Configuration
public class WebClientConfig {@BeanWebClient.Builder webClientBuilder() {return WebClient.builder();}@Bean@LoadBalancedWebClient.Builder webClientBuilder2() {return WebClient.builder();}}

WebClient负载均衡的使用:

package com.morris.user.controller;import com.morris.user.entity.Order;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Mono;import javax.annotation.Resource;
import java.util.Arrays;
import java.util.List;@RestController
@RequestMapping("user2")
public class WebClientController {@Resourceprivate WebClient.Builder webClientBuilder;@Resourceprivate WebClient.Builder webClientBuilder2;@GetMapping("findOrderByUserId1")public Mono<List<Order>> findOrderByUserId1(Long userId) {return webClientBuilder.build().get().uri("http://127.0.0.1:8020/order/findOrderByUserId?userId=" + userId).retrieve().bodyToMono(Order[].class).map(t -> Arrays.asList(t));}@GetMapping("findOrderByUserId2")public Mono<List<Order>> findOrderByUserId2(Long userId) {return webClientBuilder2.build().get().uri("http://order-service/order/findOrderByUserId?userId=" + userId).retrieve().bodyToMono(Order[].class).map(t -> Arrays.asList(t));}}

原理:底层会使用ReactiveLoadBalancer

WebClient设置Filter实现负载均衡

与RestTemplate类似,@LoadBalanced注解的功能是通过SmartInitializingSingleton实现的。

SmartInitializingSingleton是在所有的bean都实例化完成之后才会调用的,所以在bean的实例化期间使用@LoadBalanced修饰的WebClient是不具备负载均衡作用的,比如在项目的启动过程中要使用调用某个微服务,此时WebClient是不具备负载均衡作用的。

可以通过手动为WebClient设置Filter实现负载均衡能力。

@Bean
WebClient.Builder webClientBuilder3(ReactorLoadBalancerExchangeFilterFunction lbFunction) {return WebClient.builder().filter(lbFunction);
}

http://www.ppmy.cn/news/1026404.html

相关文章

python小白之matplotlib使用实战项目:随机漫步

文章目录 随机漫步1.1 创建RandomWalk类1.2 选择方向1.3 绘制随机漫步图1.4 模拟多次随机漫步1.5 设置随机漫步图样式1.5.1 给点着色1.5.2 重新绘制起点和终点1.5.3 隐藏坐标轴1.5.4 增加点数1.5.5 调整图片尺寸以适应屏幕 附录&#xff08;项目代码&#xff09;random_walk.py…

3.3 Postman基础

1. Postman概述 Postman是一个接口测试工具&#xff0c;Postman相当于一个客户端&#xff0c;可以模拟用户发起的各类HTTP请求&#xff0c;将请求数据发送至服务端&#xff0c;获取对应的响应结果。 Postman版本&#xff1a;Postman-win64-9.15.2-Setup.exe。 2. Postman的参…

jQuery练习题

目录 1.制作QQ简易聊天框 2.制作课工场论坛发帖 1.制作QQ简易聊天框 <script>$(function () {var touxiang new Array("images/head01.jpg","images/head02.jpg","images/head03.jpg");var names new Array("时尚伊人", &qu…

自动驾驶数据集汇总下载链接

欢迎补充&#xff01; 下载数据集的官网有哪些&#xff1f; https://www.autodl.com/shareData 深度估计 NYU&#xff1a; 单目深度估计NYU数据集注&#xff1a;安装BTS论文&#xff0c;trainval一共3w左右&#xff0c;很多地方下载的数据不全&#xff0c;或者下载很多不相关的…

【博客699】docker daemon预置iptables剖析

docker daemon预置iptables剖析 没有安装docker的机器&#xff1a;iptables为空&#xff0c;且每个链路的默认policy均为ACCEPT [root~]# iptables-save[root ~]# iptables -t raw -nvL Chain PREROUTING (policy ACCEPT 0 packets, 0 bytes)pkts bytes target prot opt …

阿里云对象存储服务OSS

1、引依赖 <dependency><groupId>com.aliyun.oss</groupId><artifactId>aliyun-sdk-oss</artifactId><version>3.15.1</version> </dependency> <dependency><groupId>javax.xml.bind</groupId><artifa…

PyMySQL库版本引起的python执行sql编码错误

前言 长话短说&#xff0c;之前在A主机&#xff08;centos7.9&#xff09;上运行的py脚本拿到B主机上&#xff08;centos7.9&#xff09;运行报错&#xff1a; UnicodeEncodeError: latin-1 codec cant encode characters in position 265-266: ordinal not in range(256)两个…

最小覆盖子串

给你一个字符串 s 、一个字符串 t 。返回 s 中涵盖 t 所有字符的最小子串。如果 s 中不存在涵盖 t所有字符的子串&#xff0c;则返回空字符串 "" 。 注意&#xff1a; 对于 t 中重复字符&#xff0c;我们寻找的子字符串中该字符数量必须不少于 t 中该字符数量。如果…