【Spring Cloud总结】8.通过代码自定义配置Ribbon

接上篇《7.Ribbon的基本使用》  Spring Cloud版本为Finchley.SR2

上一篇介绍了服务端、客户端负载均衡的基本原理,介绍了如何通过Ribbon进行一个应用名节点选取和负载均衡的操作。本篇我们来介绍如何使用Java代码的方式来配置Ribbon。
本部分官方文档:https://cloud.spring.io/spring-cloud-static/Finchley.SR2/single/spring-cloud.html#netflix-ribbon-starter

Spring Cloud在ApplicationContext中创建了RibbonClientConfiguration,用于配置Ribbon的各项机制。它提供了诸如ILoadBalancer、RestClient和ServerListFilter等的Bean配置项。例如ILoadBalancer是负载均衡器,RestClient是调用Rest服务的客户端,ServerListFilter是服务列表过滤机制,通过这些组件在RibbonClientConfiguration中的配置,最终实现了Ribbon进行远程服务的客户端负载均衡调用。

Spring Cloud支持开发者完全控制Ribbon客户端,去配置一些参数、机制(如负载均衡策略、过滤机制)等。
Ribbon客户端有配置文件配置和代码配置两种方式。我们先来了解一下如何使用代码配置。一般情况下,我们在配置类(有用@Configuration注解的类)结构上方添加@RibbonClient注解来声明额外的配置,例如:

@Configuration
@RibbonClient(name="foo",configuration= FooConfiguration.class)
public class TestConfiguration{

}

上面这种情况就是该配置类同时由RibbonClientConfiguration和FooConfiguration一起组成。
“configuration= FooConfiguration.class”指向的就是我们自己配置的Ribbon配置类,该配置类就是一个添加了@Configuration注解的普通类,在该类中依照RibbonClientConfiguration的规则去配置相关的参数,则会在Ribbon客户端被初始化的时候被加载。
我们可以在之定义Ribbon配置类中覆盖RibbonClientConfiguration配置的默认组件Bean,下表展示了Spring Cloud Netflix默认为Ribbon提供的bean:

关于上面的相关bean,在翟永超老师的《Spring Cloud微服务实战》一书中,有详细的解释:

创建其中一种类型的bean并将其放在@RibbonClient配置中的“configuration”参数对应的配置类中,可以覆盖所描述的每一个bean,下面就是一个例子(Spring Cloud官方提供):

@Configuration
protected static class FooConfiguration {
    @Bean
    public ZonePreferenceServerListFilter serverListFilter() {
        ZonePreferenceServerListFilter filter = new ZonePreferenceServerListFilter();
        filter.setZone("myTestZone");
        return filter;
    }

    @Bean
    public IPing ribbonPing() {
        return new PingUrl();
    }
}

官方注意事项:本例中,FooConfiguration必须用@Configuration注解标注,但是它不应该在主Application Context的组件扫描之中,否则它将被所有的Ribbon客户端共享。如果你用@ComponentScan(或者@SpringBootApplication),那么你应该采取措施来避免它被包含到扫描的范围中。

该例子覆盖了原来RibbonClientConfiguration的ServerListFilter(服务实例清单过滤机制)以及IPing(Ribbon的实例检查策略),其中serverListFilter()中只过滤Zone为"myTestZone"的服务,而ribbonPing()中返回了PingUrl()实现,这个实现类的作用是真实的去ping某个url,判断其是否alive。

这里Spring Cloud针对每种Bean提供的各个类以及各个类的功能,由于知识点比较多,我们后面再展开讲。下面我们现在原来的microserver-consumer-movie工程中通过代码的方式来自定义一个Ribbon的配置:
首选在我们的启动类上,添加@RibbonClient注解,name为负载均衡的目标应用实例名(这里是microserver-provider-user工程的实例名),configuration为我们下面要自定义的配置类:

package com.microserver.cloud;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.ribbon.RibbonClient;

import com.microserver.config.TestConfiguration;

@SpringBootApplication
@RibbonClient(name = "microserver-provider-user",configuration=TestConfiguration.class )
public class MicroserverSimpleConsumerMovieApplication {

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

}

然后在com.microserver.config包(防止它在主Application Context的组件扫描之中,不与启动类在同一个包下)下,创建一个配置类TestConfiguration:

package com.microserver.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import com.netflix.client.config.IClientConfig;
import com.netflix.loadbalancer.IRule;
import com.netflix.loadbalancer.RandomRule;

@Configuration
public class TestConfiguration {
    
    @Bean
    public IRule ribbonRule(IClientConfig config) {
        return new RandomRule();
    }
}

这里我们覆盖了原来默认的负载均衡策略器,默认的负载均衡器为ZoneAvoidanceRule,其策略为轮询选择,这一点我们在之前的测试中已经验证了。这里我们的覆盖类为RandomRule(),该类提供的策略为随机的负载均衡策略,便于我们测试出来。

启动microserver-consumer-movie工程,以及两个不同端口(7900和7902)的microserver-provider-user工程,以及注册中心,然后再重复访问microserver-consumer-movie服务的http://localhost:7901/movie/1请求,获取ID为1的用户信息,观察两个不同端口(7900和7902)的microserver-provider-user工程的日志,可以看到访问的频率两边都是随机的,说明我们的自定义配置是成功的:

上面我们一共请求了18次,按照轮询应该是每边9次,而实际上是一边为8次,一边为10次,说明我们配置的RandomRule()随机负载均衡策略是成功的。这里我们除了统计服务端的日志以外,也可以在客户端编写一个测试服务,来打印每一次访问的服务信息。我们在MovieController中添加以下服务:

@Autowired
private LoadBalancerClient loadBalanceClient;

@GetMapping("/testRibbon")
public String testRibbon(){
    ServiceInstance serviceInstance  = this.loadBalanceClient.choose("microserver-provider-user");
    System.out.println(serviceInstance.getServiceId()+":"+serviceInstance.getHost()+":"+serviceInstance.getPort());
    return "test success! o(* ̄︶ ̄*)o";
}

这里的loadBalanceClient就是负载均衡器,而其choose()方法是选择具体服务实例的一个方法,会返回一个服务实例对象,该对象中包含了请求获取到的服务实例的详细信息。
我们用上面的测试请求再请求6次,可以看到依然能够验证我们自己配置的随机负载均衡策略:

这里7900服务被访问了4次,7902服务被访问了2次。

如果需要为不同的实例进行不同的Ribbon配置,新建不同的@RibbonClient注解,指定相关name以及配置类即可。例如还有FooServiceA和FooServiceB服务,其Ribbon为FooConfiguration1和FooConfiguration2我们在启动类上继续添加以下注解即可:

@RibbonClient(name = "FooServiceA",configuration=FooConfiguration1.class )
@RibbonClient(name = "FooServiceB",configuration=FooConfiguration2.class )

其中FooConfiguration1和FooConfiguration2可以分别指定不同的Bean配置,例如FooConfiguration1中配置根据权重进行负载均衡(IRule为WeightedResponseTimeRule),FooConfiguration2中配置根据请求最小数进行负载均衡(IRule为BestAvailableRule) ,此时当同一个服务消费者去访问FooServiceA实例的集群时,就会采用权重进行负载均衡,而去访问FooServiceB实例的集群时,会采用请求最小数进行负载均衡。

这里还是要再强调一遍(重要的事情说三遍!!!),Ribbon自定义配置类不应该在主Application Context的组件扫描之中,否则它将被所有的Ribbon客户端共享(不要同包或包下!!)。

下一篇我们继续讲解另一种Ribbon自定义配置方式,并且介绍一下Spring Cloud提供的所有Ribbon配置Bean实现类的功能。

本部分参考源码下载:https://download.csdn.net/download/u013517797/11418845

参考:《51CTO学院Spring Cloud高级视频》
https://www.cnblogs.com/cjsblog/p/7986628.html

转载请注明出处:https://blog.csdn.net/acmman/article/details/95312786

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

光仔December

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

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

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

打赏作者

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

抵扣说明:

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

余额充值