2021.0.5版本SpringcCloud集成Nacos设置负载均衡,让其优先寻找自己同集群下的服务

SpringCloud LoadBalancer是SpringCloud官方自己提供的客户端负载均衡器,用来替代Ribbon的。因为netfilx停更了,所以SpringCloud官方就自己开发了一块客户端负载均衡器这边用来替代Ribbon。但是目前是没有办法去替代Ribbon的。因为它目前的负载均衡算法还很少。

SpringCloud在早期是把Ribbon当做它的负载均衡器,在SpringCloud2021版的时候就移除了Ribbon,改用Loadbalancer为默认的负载均衡器

<!--nacos的管理依赖-->
            <dependency>
                <groupId>com.alibaba.cloud</groupId>
                <artifactId>spring-cloud-alibaba-dependencies</artifactId>
                <version>2.2.6.RELEASE</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>

<!--spring cloud loadbalancer 依赖-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-loadbalancer</artifactId>
            <version>2.2.6.RELEASE</version>
        </dependency>

使用LoadBalancer实现负载均衡

配置文件

注意是每个服务都需要配置此文件.

spring:
 # 添加服务名称
  application:
    name: orderservice
  cloud:
    # 负载均衡配置
    loadbalancer:
      ribbon:
        #禁用ribbon
        enabled: false # 爆红黄线的话不设置也可以
    #配置nacos的服务地址
    nacos:
      discovery:
        server-addr: localhost:8848 # nacos服务地址

配置负载均衡

使用@LoadBalanced注解将RestTemplate配置为具有负载均衡功能:

@Bean
@LoadBalanced
public RestTemplate restTemplate() {
    return new RestTemplate();
}

负载均衡-随机策略

注意,此方法不需要添加@Configuration注解

public class CustomLoadBalancerConfiguration {


    @Bean
    ReactorLoadBalancer<ServiceInstance> randomLoadBalancer(Environment environment,
                                                            LoadBalancerClientFactory loadBalancerClientFactory) {
        String name = environment.getProperty(LoadBalancerClientFactory.PROPERTY_NAME);
        return new RandomLoadBalancer(loadBalancerClientFactory
                .getLazyProvider(name, ServiceInstanceListSupplier.class),
                name);
    }
}

然后在配置类或者主启动类中使用@LoadBalancerClient注释

@SpringBootApplication
//name写微服务的服务名称,configuration写配置文件的类
@LoadBalancerClient(name = "userservice", configuration = CustomLoadBalancerConfiguration.class)
public class OrderApplication {

    public static void main(String[] args) {
        SpringApplication.run(OrderApplication.class, args);
    }

    /**
     * 创建RestTemplate对象并注入spring容器
     *
     * @return
     */
    @Bean
    @LoadBalanced//注册中心中拉取服务的实例列表,并且使用loadbalancer实现负载均衡
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }

注意此随机策略如果是环境隔离模式下则不生效,我想使用spring.cloud.loadbalancer.type=random发现yaml报错,欢迎大佬补充。

测试Nacos设置负载均衡(轮询),让其优先寻找自己同集群下的服务

实现方法是使用的环境隔离。

此处用一个案例演示,查询订单列表并返回用户的信息,订单服务和用户服务是两个服务:

订单查询的请求地址是:http://localhost:8080/order/{id}

端口号8080订单服务的nacos的yaml配置如下:

spring:
 # 添加服务名称
  application:
    name: orderservice
  cloud:
    # 负载均衡配置
    loadbalancer:
      ribbon:
        #禁用ribbon
        enabled: false
    #配置nacos的服务地址
    nacos:
      discovery:
        server-addr: localhost:8848 # nacos服务地址
        cluster-name: HZ # 集群名称:杭州
        group: test-group # 服务的分组名称

订单服务的业务代码:

@Service
public class OrderService {

    @Resource
    private OrderMapper orderMapper;

    @Resource
    private RestTemplate restTemplate;

    public Order queryOrderById(Long orderId) {
        // 1.查询订单
        Order order = orderMapper.findById(orderId);

        //请求地址
        String url = "http://userservice/user/" + order.getUserId();
        /**
         * 2.利用RestTemplate发送http请求,查询用户
         * 参数:
         *  1.发送请求的url地址
         *  2.返回值类型,默认是json格式
         */
        User user = restTemplate.getForObject(url, User.class);

        order.setUser(user);

        // 4.返回
        return order;
    }

用户查询的请求地址是:

http://localhost:8081/user/{id} 

http://localhost:8082/user/{id}

http://localhost:8083/user/{id}

端口号8081和8082的用户服务nacos的yaml配置如下

spring:
 # 添加服务名称
  application:
    name: orderservice
  cloud:
    # 负载均衡配置
    loadbalancer:
      ribbon:
        #禁用ribbon
        enabled: false
    #配置nacos的服务地址
    nacos:
      discovery:
        server-addr: localhost:8848 # nacos服务地址
        cluster-name: HZ # 集群名称:杭州
        group: test-group # 服务的分组名称

8083的用户服务nacos的yaml配置如下:

spring:
 # 添加服务名称
  application:
    name: orderservice
  cloud:
    # 负载均衡配置
    loadbalancer:
      ribbon:
        #禁用ribbon
        enabled: false
    #配置nacos的服务地址
    nacos:
      discovery:
        server-addr: localhost:8848 # nacos服务地址
        cluster-name: SH # 集群名称:杭州
        group: test-group01 # 服务的分组名称

注意,8083和8081、8082的集群名称和服务的命名空间不同。

这是因为当Spring Cloud应用程序调用服务时,它会首先查找具有相同Group(分组)和Cluster名称的服务,并尝试通过负载均衡算法选择其中一个。如果没有找到具有相同Group和Cluster名称的服务,则会使用默认的负载均衡算法来选择服务。

注意:但是这样设置后随机策略就不会生效了(他还是采用的轮询方案,至于随机负载均衡方案我暂时还没搞懂)。

用户的查询业务代码:

@Service
public class UserService {

    @Autowired
    private UserMapper userMapper;

    public User queryById(Long id) {
        return userMapper.findById(id);//此方法内的SQL是"select * from tb_user where id = #{id}"
    }
}

 然后开始测试:

先启动订单服务和两个集群名称为HZ(杭州)集群分组为test-group的用户服务:

然后启动集群名称为SH(上海)集群分组为test-group01的用户服务:

服务全部启动成功,去nacos管理页面查看:

然后查看三个userservice的集群:

ok,环境准备成功无异常,开始发送请求测试,它会首先查找具有相同Group(分组)和Cluster名称的服务,并尝试通过负载均衡算法选择其中一个,由于我们订单服务和8081、8082的两个用户服务的Group(分组)和Cluster名称的服务相同,所以我们发送的请求8083用户服务并不会接收到。

我们连续发送6个请求查看控制台日志:

可以看到订单服务被请求了六次,再来查看用户服务。

8081端口用户服务结果:

8082端口用户服务结果:

8083端口用户服务结果:

可以看到nacos负载均衡让其优先寻找自己同集群下的服务实现成功(但是随机负载均衡策略暂时还没研究明白,欢迎大佬补充)。

  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

贰陆.256

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值