六、实现负载均衡-Ribbon

一、负载均衡的两种方式

  • 服务器端负载均衡
  • 客户端侧负载均衡

二、手写一个客户端侧负载均衡器

修改内容中心代码

在用户中心启动两个实例
在这里插入图片描述
访问并多次刷新浏览器http://localhost:8010/shares/1,实现随机负载均衡算法

三、使用Ribbon实现负载均衡

引入Ribbon后架构的演进

在这里插入图片描述
添加@LoadBalanced注解
在这里插入图片描述
修改ShareService
在这里插入图片描述
启动相关服务,测试访问
在这里插入图片描述

四、Ribbon的组成

在这里插入图片描述

五、Ribbon内置负载均衡规则

在这里插入图片描述

六、细粒度配置自定义

1、Java代码配置

在这里插入图片描述

2、配置属性配置

在这里插入图片描述

3、两种方式的比较

在这里插入图片描述

4、总结

尽量使用属性配置,属性方式实现不了的情况下在考虑使用代码配置

在同一个微服务内尽量保持单一性,比如统一使用属性配置,不要两种方式混用,增加定位代码的复杂性。


七、全局配置

在这里插入图片描述

八、支持的配置项

在这里插入图片描述

九、Ribbon的饥饿加载

解决第一次访问http://localhost:8010/shares/1地址加载缓慢的问题

在这里插入图片描述

十、扩展Ribbon支持Nacos权重

在configuration包下新建NacosWeightedRule类
@Slf4j
public class NacosWeightedRule extends AbstractLoadBalancerRule {

    @Autowired
    NacosDiscoveryProperties nacosDiscoveryProperties;

    @Override
    public void initWithNiwsConfig(IClientConfig iClientConfig) {
        // 读取配置文件并初始化NacosWeightedRule
    }

    @Override
    public Server choose(Object o) {
        try {
            BaseLoadBalancer loadBalancer = (BaseLoadBalancer) this.getLoadBalancer();
//            log.info("lb = {}",loadBalancer);
            // 想要请求的微服务的名称
            String name = loadBalancer.getName();
            // 拿到服务发现相关的API
            NamingService namingService = nacosDiscoveryProperties.namingServiceInstance();
            // nacos client自动通过基于权重的负载均衡算法,给我们选择一个实例
            Instance instance = namingService.selectOneHealthyInstance(name);

            log.info("选择的实例是:port = {},instance = {}",instance.getPort(),instance);
            return new NacosServer(instance);

        } catch (NacosException e) {
            return null;
        }

    }
}

修改RibbonConfiguration类
在这里插入图片描述
将8081的端口的实例的权重值置为0
在这里插入图片描述
测试结果

在这里插入图片描述

十一、扩展Ribbon同集群优先

在configuration包下新建NacosSameClusterWeightedRule类

@Slf4j
public class NacosSameClusterWeightedRule extends AbstractLoadBalancerRule {

    @Autowired
    NacosDiscoveryProperties nacosDiscoveryProperties;
    
    @Override
    public void initWithNiwsConfig(IClientConfig iClientConfig) {

    }

    @Override
    public Server choose(Object o) {
        try {
            // 拿到配置文件中集群的名称 BJ
            String clusterName = nacosDiscoveryProperties.getClusterName();

            BaseLoadBalancer loadBalancer = (BaseLoadBalancer) this.getLoadBalancer();
            // 想要请求的微服务的名称
            String name = loadBalancer.getName();
            // 拿到服务发现相关的API
            NamingService namingService = nacosDiscoveryProperties.namingServiceInstance();

            // 1.找到指定服务的所有实例 A
            List<Instance> instances = namingService.selectInstances(name, true);

            // 2.过滤出相同集群下的所有实例 B
            List<Instance> sameClusterInstances = instances.stream()
                    .filter(instance -> {
                        return Objects.equals(instance.getClusterName(),clusterName);
                    })
                    .collect(Collectors.toList());

            // 3.如果B为空,就使用A
            List<Instance> instancesToBeChosen = new ArrayList<>();
            if (CollectionUtils.isEmpty(sameClusterInstances)){
                instancesToBeChosen = instances;
                log.warn("发生跨集群的调用,name = {}, clusterName = {}, instances = {}",name,clusterName,instances);
            }
            else {
                instancesToBeChosen = sameClusterInstances;
            }

            // 4.基于权重的负载均衡算法,返回一个实例
            Instance instance = ExtendBalancer.getHostByRandomWeight2(instancesToBeChosen);

            log.info("选择的实例是 port = {}, instance = {}",instance.getPort(),instance);

            return new NacosServer(instance);
        } catch (NacosException e) {
            log.error("发生异常了",e);
            return null;
        }
    }
}
class ExtendBalancer extends Balancer{
    public static Instance getHostByRandomWeight2(List<Instance> hosts) {
        return getHostByRandomWeight(hosts);
    }
}

修改RibbonConfiguration
在这里插入图片描述
修改application.yml
在这里插入图片描述
测试结果
在这里插入图片描述

十二、扩展Ribbon基于元数据的版本控制

详情请参考 手记

十三、深入理解Nacos的namespace

在user-center下指定namespace,而content-center未指定
在这里插入图片描述
在这里插入图片描述
说明服务之间不能跨namespace调用,namespace实现了隔离。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值