Spring Cloud Alibaba - 11 Ribbon 自定义负载均衡策略(同集群优先权重负载均衡算法)

本文涉及的产品
应用型负载均衡 ALB,每月750个小时 15LCU
网络型负载均衡 NLB,每月750个小时 15LCU
传统型负载均衡 CLB,每月750个小时 15LCU
简介: Spring Cloud Alibaba - 11 Ribbon 自定义负载均衡策略(同集群优先权重负载均衡算法)

6735aa4777de402592fbe82e8b40ee3d.png

Pre

Spring Cloud Alibaba - 05 Nacos 领域模型_NameSpac/Group/Cluster

中提到了同一个Namespace下 + 同一个Group下, 不同Cluster 内的服务,可以互相访问.


c83749688c704b76b5f4111e86751ee5.png


如果我们要想实现一个 同集群优先权重负载均衡算法, 怎么办呢?

比如实现如下调用

2e506ec1dbab4d238332248076d9a2eb.png


需求


举个例子: 有两个微服务artisan-order-center, artisan-product-center 。我们在北京机房部署一套artisan-order-center,artisan-product-center。为了容灾处理,我们在广东同样部署一套artisan-order-center,artisan-product-center 。


但是 北京的artisan-order-center 访问广东的 artisan-product-center 毕竟不如调用本地的artisan-product-center快。 如果本地的artisan-product-center挂掉了,那么再访问广东的artisan-product-center。


工程


接着 Spring Cloud Alibaba - 10 Ribbon 自定义负载均衡策略(权重算法) 中的工程,我们继续改造。


Code

继承AbstractLoadBalancerRule实现自定义Rule

package com.artisan.customrules;
import com.alibaba.cloud.nacos.NacosDiscoveryProperties;
import com.alibaba.cloud.nacos.ribbon.NacosServer;
import com.alibaba.nacos.api.exception.NacosException;
import com.alibaba.nacos.api.naming.NamingService;
import com.alibaba.nacos.api.naming.pojo.Instance;
import com.netflix.client.config.IClientConfig;
import com.netflix.loadbalancer.AbstractLoadBalancerRule;
import com.netflix.loadbalancer.BaseLoadBalancer;
import com.netflix.loadbalancer.Server;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import java.util.ArrayList;
import java.util.List;
/**
 * @author 小工匠
 * @version 1.0
 * @description: 同一个集群优先调用策略
 * @date 2022/2/3 0:47
 * @mark: show me the code , change the world
 */
@Slf4j
public class SameClusterPriorityRule extends AbstractLoadBalancerRule {
    @Autowired
    private NacosDiscoveryProperties discoveryProperties;
    @Override
    public void initWithNiwsConfig(IClientConfig iClientConfig) {
    }
    @Override
    public Server choose(Object key) {
        try {
            //第一步:获取当前服务所在的集群
            String currentClusterName = discoveryProperties.getClusterName();
            //第二步:获取一个负载均衡对象
            BaseLoadBalancer baseLoadBalancer = (BaseLoadBalancer) getLoadBalancer();
            //第三步:获取当前调用的微服务的名称
            String invokedSerivceName = baseLoadBalancer.getName();
            //第四步:获取nacos clinet的服务注册发现组件的api
            NamingService namingService = discoveryProperties.namingServiceInstance();
            //第五步:获取所有的服务实例
            List<Instance> allInstance = namingService.getAllInstances(invokedSerivceName);
            List<Instance> theSameClusterNameInstList = new ArrayList<>();
            //第六步:过滤筛选同集群下的所有实例
            for (Instance instance : allInstance) {
                if (StringUtils.endsWithIgnoreCase(instance.getClusterName(), currentClusterName)) {
                    theSameClusterNameInstList.add(instance);
                }
            }
            Instance toBeChooseInstance;
            //第七步:选择合适的一个实例调用
            if (theSameClusterNameInstList.isEmpty()) {
                toBeChooseInstance = ArtisanWeightedBalancer.chooseInstanceByRandomWeight(allInstance);
                log.info("发生跨集群调用--->当前微服务所在集群:{},被调用微服务所在集群:{},Host:{},Port:{}",
                        currentClusterName, toBeChooseInstance.getClusterName(), toBeChooseInstance.getIp(), toBeChooseInstance.getPort());
            } else {
                toBeChooseInstance = ArtisanWeightedBalancer.chooseInstanceByRandomWeight(theSameClusterNameInstList);
                log.info("同集群调用--->当前微服务所在集群:{},被调用微服务所在集群:{},Host:{},Port:{}",
                        currentClusterName, toBeChooseInstance.getClusterName(), toBeChooseInstance.getIp(), toBeChooseInstance.getPort());
            }
            return new NacosServer(toBeChooseInstance);
        } catch (NacosException e) {
            log.error("同集群优先权重负载均衡算法选择异常:{}", e);
        }
        return null;
    }
}

随机权重策略

package com.artisan.customrules;
import com.alibaba.nacos.api.naming.pojo.Instance;
import com.alibaba.nacos.client.naming.core.Balancer;
import java.util.List;
/**
 * @author 小工匠
 * @version 1.0
 * @description: 根据权重选择随机选择一个
 * @date 2022/2/3 0:28
 * @mark: show me the code , change the world
 */
public class ArtisanWeightedBalancer extends Balancer {
    public static Instance chooseInstanceByRandomWeight(List<Instance> hosts) {
        return getHostByRandomWeight(hosts);
    }
}


配置

artisan-cloud-customcfg-ribbon-order 中的 nacos配置

spring:
  cloud:
    nacos:
      discovery:
        server-addr: 1.117.97.88:8848
        cluster-name: BeiJingCluster
  application:
    name: artisan-order-center


artisan-cloud-customcfg-ribbon-product 中的 nacos配置

spring: 
  cloud:
    nacos:
      discovery:
        server-addr: 1.117.97.88:8848
        cluster-name: GuangDongCluster
  application:
    name: artisan-product-center


验证

artisan-cloud-customcfg-ribbon-order      ----    cluster-name: BeiJingCluster 
artisan-cloud-customcfg-ribbon-product   ----     cluster-name: BeiJingCluster   
artisan-cloud-customcfg-ribbon-product   ----     cluster-name: GuangDongCluster   


启动一个artisan-cloud-customcfg-ribbon-order和两个 artisan-cloud-customcfg-ribbon-product 工程后,


通过artisan-cloud-customcfg-ribbon-order 【BeiJingCluster 】访问 artisan-cloud-customcfg-ribbon-product

ecf2b12b8697473f90674f5dc7f6a13a.png


查看artisan-cloud-customcfg-ribbon-order 日志

6e2e47397ed04b368d7dbfaefbe2223d.png

我们下线 artisan-cloud-customcfg-ribbon-order 【BeiJingCluster 】


e66a6080007646cfb62d75b8b31c8c0f.png

再次调用 ,观察日志

a888a48a4cec434fa7de22cffa0ae6b4.png


这样就实现了刚才的需求


源码


https://github.com/yangshangwei/SpringCloudAlibabMaster

相关实践学习
SLB负载均衡实践
本场景通过使用阿里云负载均衡 SLB 以及对负载均衡 SLB 后端服务器 ECS 的权重进行修改,快速解决服务器响应速度慢的问题
负载均衡入门与产品使用指南
负载均衡(Server Load Balancer)是对多台云服务器进行流量分发的负载均衡服务,可以通过流量分发扩展应用系统对外的服务能力,通过消除单点故障提升应用系统的可用性。 本课程主要介绍负载均衡的相关技术以及阿里云负载均衡产品的使用方法。
相关文章
|
22天前
|
负载均衡 Java Nacos
常见的Ribbon/Spring LoadBalancer的负载均衡策略
自SpringCloud 2020版起,Ribbon被弃用,转而使用Spring Cloud LoadBalancer。Ribbon支持轮询、随机、加权响应时间和重试等负载均衡策略;而Spring Cloud LoadBalancer则提供轮询、随机及Nacos负载均衡策略,基于Reactor实现,更高效灵活。
54 0
|
3月前
|
负载均衡 Java Nacos
SpringCloud基础1——远程调用、Eureka,Nacos注册中心、Ribbon负载均衡
微服务介绍、SpringCloud、服务拆分和远程调用、Eureka注册中心、Ribbon负载均衡、Nacos注册中心
SpringCloud基础1——远程调用、Eureka,Nacos注册中心、Ribbon负载均衡
|
3月前
|
负载均衡 Java 开发者
Ribbon框架实现客户端负载均衡的方法与技巧
Ribbon框架为微服务架构中的客户端负载均衡提供了强大的支持。通过简单的配置和集成,开发者可以轻松地在应用中实现服务的发现、选择和负载均衡。适当地使用Ribbon,配合其他Spring Cloud组件,可以有效提升微服务架构的可用性和性能。
48 0
|
SpringCloudAlibaba 网络协议 Cloud Native
Spring Cloud Alibaba-全面详解(学习总结---从入门到深化)
Spring Cloud Alibaba致力于提供微服务开发的一站式解决方案。
8845 2
Spring Cloud Alibaba-全面详解(学习总结---从入门到深化)
|
Java Nacos Sentinel
Spring Cloud Alibaba学习指南
由于在2018年Netflix公司宣布对其核心组件Hystrix、Ribbon、zuul、Eureka等进入维护状态,也就是Spring Cloud Netflix系列。由此Spring Cloud Alibaba就诞生了,值得注意的是Spring Cloud Alibaba完全兼容了Spring Cloud Netflix中的Ribbon、Feign、Eureka等组件,所以基于Spring Cloud Netflix的项目可以无缝迁移到Spring Cloud Alibaba。
562 0
|
敏捷开发 运维 资源调度
Spring Cloud Alibaba学习之开幕
Spring Cloud Alibaba学习之开幕
|
Java Nacos Sentinel
spring coud alibaba与云服务学习
在学习分布式过程中用到spring cloud alibaba以及云服务的相关内容
|
2月前
|
人工智能 自然语言处理 前端开发
SpringBoot + 通义千问 + 自定义React组件:支持EventStream数据解析的技术实践
【10月更文挑战第7天】在现代Web开发中,集成多种技术栈以实现复杂的功能需求已成为常态。本文将详细介绍如何使用SpringBoot作为后端框架,结合阿里巴巴的通义千问(一个强大的自然语言处理服务),并通过自定义React组件来支持服务器发送事件(SSE, Server-Sent Events)的EventStream数据解析。这一组合不仅能够实现高效的实时通信,还能利用AI技术提升用户体验。
244 2
|
2天前
|
Java 数据库连接 Maven
最新版 | 深入剖析SpringBoot3源码——分析自动装配原理(面试常考)
自动装配是现在面试中常考的一道面试题。本文基于最新的 SpringBoot 3.3.3 版本的源码来分析自动装配的原理,并在文未说明了SpringBoot2和SpringBoot3的自动装配源码中区别,以及面试回答的拿分核心话术。
最新版 | 深入剖析SpringBoot3源码——分析自动装配原理(面试常考)
|
9天前
|
NoSQL Java Redis
Spring Boot 自动配置机制:从原理到自定义
Spring Boot 的自动配置机制通过 `spring.factories` 文件和 `@EnableAutoConfiguration` 注解,根据类路径中的依赖和条件注解自动配置所需的 Bean,大大简化了开发过程。本文深入探讨了自动配置的原理、条件化配置、自定义自动配置以及实际应用案例,帮助开发者更好地理解和利用这一强大特性。
52 14