SpringCloud之负载均衡 --(Ribbon)

Ribbon介绍

Spring Cloud Ribbon是一个基于HTTP和TCP的客户端负载均衡工具,它基于Netflix Ribbon实现。通过Spring Cloud的封装,可以让我们轻松地将面向服务的REST模版请求自动转换成客户端负载均衡的服务调用。Spring Cloud Ribbon虽然只是一个工具类框架,它不像服务注册中心、配置中心、API网关那样需要独立部署,但是它几乎存在于每一个Spring Cloud构建的微服务和基础设施中。

怎么映入Maven
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
        </dependency>

        <!--重试机制-->
        <dependency>
            <groupId>org.springframework.retry</groupId>
            <artifactId>spring-retry</artifactId>
        </dependency>

Ribbon 实现了负载均衡

  1. 它是怎么实现的负载均衡算法,有哪些负载均衡算法
  2. 怎么通过实例名获取IP的(肯定是依赖于注册中心EnableDiscoveryClient 也是可以脱离注册中型 指定server)

zk注册的例子

{"name":"zk-service","id":"01a5f6f9-9977-4601-90e8-79c5dd7862a3","address":"SF0001371805LA.sf.com","port":8010,"sslPort":null,"payload":{"@class":"org.springframework.cloud.zookeeper.discovery.ZookeeperInstance","id":"application-1","name":"zk-service","metadata":{}},"registrationTimeUTC":1560935528331,"serviceType":"DYNAMIC","uriSpec":{"parts":[{"value":"scheme","variable":true},{"value":"://","variable":false},{"value":"address","variable":true},{"value":":","variable":false},{"value":"port","variable":true}]}}
Ribbon的使用
  1. 使用RestTemplate来做实现的,去访问Rest的资源的,而Ribbon是在 patchForObject 里面的 实现类
    RibbonHttpRequest 的
HttpResponse response = client.executeWithLoadBalancer(request, config);


public T executeWithLoadBalancer(final S request, final IClientConfig requestConfig) throws ClientException {
        RequestSpecificRetryHandler handler = getRequestSpecificRetryHandler(request, requestConfig);
        LoadBalancerCommand<T> command = LoadBalancerCommand.<T>builder()
                .withLoadBalancerContext(this)
                .withRetryHandler(handler)
                .withLoadBalancerURI(request.getUri())
                .build();
                 try {
            return command.submit(
                new ServerOperation<T>() {
                    @Override
                    public Observable<T> call(Server server) {
                        URI finalUri = reconstructURIWithServer(server, request.getUri());
                        S requestForServer = (S) request.replaceUri(finalUri);
                        try {
                            return Observable.just(AbstractLoadBalancerAwareClient.this.execute(requestForServer, requestConfig));
                        } 
                        catch (Exception e) {
                            return Observable.error(e);
                        }
                    }
                })
                .toBlocking()
                .single();
        } catch (Exception e) {
            Throwable t = e.getCause();
            if (t instanceof ClientException) {
                throw (ClientException) t;
            } else {
                throw new ClientException(e);
            }
        }

这里面提现了负载均衡和重试策略,另外体现了响应式编程和流式编程,只不过这里面是用了阻塞的方式toBlocking

Ribbon加载流程(可以和Eureka个Zk继承)
  1. Ribbon的初始化(使用了autoconfig的)RibbonAutoConfiguration 类
    在这里插入图片描述
  2. 如果没有和任何的注册中心集成(集成是直接引入atuoconfig)的话,就使用默认的
	@Bean
	@ConditionalOnMissingBean(LoadBalancerClient.class)
	public LoadBalancerClient loadBalancerClient() {
		return new RibbonLoadBalancerClient(springClientFactory());
	}

默认的话实现了RibbonClientConfiguration 维护我们的Server使用的配置server方式
在这里插入图片描述
如果使用的是Eureka(EurekaRibbonClientConfiguration)
在这里插入图片描述
使用zk(ZookeeperRibbonClientConfiguration)

Ribbon的负载均衡的策略

负载均衡的类的及继承图在这里插入图片描述
负载均衡的规则接口是IRule 实现他的不同的规则类有
默认策略:ZoneAvoidanceRule ===> RibbonClientConfiguration#ribbonRule()
• ZoneAvoidanceRule 规避区域策略
• AbstractLoadBalancerRule 策略的抽象类,它在内部定义了ILoadBalancer对象,这个对象主要是用来在具体选择哪种策略的时候,获取到负载均衡器中维护的信息的。
• AvailabilityFilteringRule该策略继承自抽象策略PredicateBasedRule所以也继承了"先过滤清单,再轮询选择"的基本处理逻辑,该策略通过线性抽样的方式直接尝试可用且较空闲的实例来使用,优化了父类每次都要遍历所有实例的开销。
• BestAvailableRule继承自ClientConfigEnabledRoundRobinRule该策略的特性是可选出最空闲的实例
• ClientConfigEnabledRoundRobinRule该策略较为特殊,我们一般不直接使用它。因为它本身并没有实现什么特殊的处理逻辑。通过继承该策略,默认的choose就实现了线性轮询机制,在子类中做一些高级策略时通常可能存在。一些无法实施的情况,就可以用父类的实现作为备选
• PredicateBasedRule抽象策略,继承自ClientConfigEnabledRoundRobinRule,基于Predicate的策略 Predicateshi Google Guava Collection工具对集合进行过滤的条件接口
• RandomRule 随机数策略,它就是通过一个随机数来获取uplist的某一个下标,再返回。
• RetryRule 带重试机制策略,它在内部还定义了一个IRule,默认使用了RoundRobinRule,在内部实现了反复重试的机制,如果重试能够得到一个服务,就返回,如果不能就会根据之前设置的时间来决定,时间一到就返回null.
• RoundRobinRule 一个轮询策略,通过一个count计数变量,每次循环都会累加,注意,如果一直没有server可供选择达到了10次,就会打印一个警告信息。
• WeightedResponseTimeRule 这个策略是对轮询策略的扩展,增加了根据实例的运行情况来计算权重,并根据权重来挑选实例,用以达到更好的分配结果。

获取服务列表

进入到RibbonLoadBalancerClient中找到reconstructURI()方法,可以看到有一个RibbonLoadBalancerContext类,进入这个类,会发现它在构造器中传入了一个ILoadBalancer
在ILoadBalancer这个接口中存在addServers(List newServers)在内部我们可以得到一个结论,
我们所有的host:port形式的东西都存放在RibbonLoadBalancerContext中,它会去通过一个实例去获取到我们的

在做注册中心的时候会调用这个把注册的服务信息初始化到LoadBalancerContext里面

怎么实现一个简单服务的高可用的方式

高可用的实现点

  1. 把你们需要高可用的节点地址注册到注册中心(eureka zk redis 数据库)
  2. 实现高可用的节点断开的一个失效方式(redis采用的key的失效时间 数据库可以采用时间戳间隔设置)
  3. 实现客户端的负载均衡算法(ribbon 来做)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值