8分钟了解Ribbon的使用

介绍

Ribbon是一个客户端负载均衡器,通过一定的逻辑选择服务。高级功能可以根据客户端划分的区域来建立联系以减少延迟。
图

基础组件

IRule

决定使用哪个一个服务器去提供服务。

实现类描述
RandomRule随机选择已经有的server
BestAvailableRule选择并发请求最少的server
RoundRobinRule轮询
RetryRule传入一个IRule,当IRule失败的时候重试一次
ClientConfigEnabledRoundRobinRule抽象类,一般不用。通过继承该策略,默认的choose就实现了线性轮询机制。可以基于它来做扩展。
WeightedResponseTimeRule每30秒计算一次服务器响应时间,以响应时间作为权重,响应时间越短的服务器被选中的概率越大。
AvailabilityFilteringRule过滤掉一直连接失败的被标记为circuit tripped的Server,并过滤掉高并发的Server或者使用一个AvailabilityPredicate来包含过滤server的逻辑,其实就就是检查status里记录的各个Server的运行状态;
ZoneAvoidanceRule复合判断Server所在区域的性能和Server的可用性选择Server
IPing

运行在后台,确定服务器是否还活着。下面感觉就PingUrl有实际作用。

实现类描述
DummyPing永远返回true,仿造的ping。
NoOpPing永远返回true。可理解服务器永久可用,不需要检查服务器是否可用。
PingConstant默认永远返回true,可设置永远返回false。
PingUrlping返回的状态码是200,返回true。
ServerList

可以是静态的,也可以是动态的,这个集合里面放了服务器地址,例:localhost:8080、localhost:8081…

ServerListFilter

用于DynamicServerListLoadBalancer过滤从ServerList实现返回的服务器的组件。功能区中有ServerListFilter的两种实现。

ZoneAffinityServerListFilter
筛选出与客户端不在同一区域中的服务器,除非客户端区域中没有可用的服务器。可以通过指定以下属性来启用此过滤器(假设客户端名称为“ myclient”,客户端属性名称空间为“ ribbon”):

myclient.ribbon.EnableZoneAffinity=true

ServerListSubsetFilter
此筛选器确保客户端仅看到由ServerList实现返回的所有服务器的固定子集。它还可以定期用新服务器替换可用性较差的子集中的服务器。要启用此过滤器,请指定以下属性.

myClient.ribbon.NIWSServerListClassName=com.netflix.niws.loadbalancer.DiscoveryEnabledNIWSServerList 
# 服务器必须使用VipAddress "myservice"向Eureka server 注册自己
myClient.ribbon.DeploymentContextBasedVipAddresses=myservice
myClient.ribbon.NIWSServerListFilterClassName=com.netflix.loadbalancer.ServerListSubsetFilter
# 只显示5个服务,默认是20个
myClient.ribbon.ServerListSubsetFilter.size=5
ILoadBalancer

增加、选择、标志下线、取得当前可用实例、取得所有服务实例方法。它管理所有实例,并通过获取实例方法的中的负载均衡策略选择合适实例返回。

实现类描述
NoOpLoadBalancer继承AbstractLoadBalancer,什么也不做
DynamicServerlistloadBalancer实现了服务清单在运行过程中动态更新的能力,同时具备服务清单过滤的功能
ZoneAwareLoadBalancer由于DynamicServerlistloadBalancer使用轮询方式调用实例,在区域不同的情况下,可能存在网络延迟等情况影响性能,所以出现了ZoneAwareLoadBalancer,它具有区域亲和性,会优先选择同区域的实例。它使用ZoneAvoidanceRule作为负载均衡策略。

使用类配置

定义一个配置类

/**
 * Ribbon的类配置
 * @author Chiang
 */
public class SayHelloConfiguration {

    @Autowired
    IClientConfig ribbonClientConfig;

    @Bean
    public IPing ribbonPing(IClientConfig config) {
//        使用ping的方式检查服务器是否存活
        return new PingUrl();
    }

    @Bean
    public IRule ribbonRule(IClientConfig config) {
//        过滤掉一直连接失败、高并发的Server或AvailabilityPredicate来包含过滤server
        return new AvailabilityFilteringRule();
    }
    
//    服务器地址、服务器过滤等等配置....

}

启动这个配置类

@SpringBootApplication
@RestController
// 打开注解代表启用类配置,可以与yml配置同时存在
@RibbonClients(
        value = {
                @RibbonClient(name = "say-hello", configuration = SayHelloConfiguration.class),
                @RibbonClient(name = "say-bye", configuration = SayHelloConfiguration.class)
        }
)
public class UserApplication {

//  loadBalance开启RestTemplate的负载均衡
    @LoadBalanced
    @Bean
    RestTemplate restTemplate() {
        return new RestTemplate();
    }

    @Autowired
    RestTemplate restTemplate;

    @RequestMapping("/hi")
    public String hi(@RequestParam(value = "name", defaultValue = "Artaban") String name) {
//       只使用say-hello配置的服务器
        String greeting = this.restTemplate.getForObject("http://say-hello/greeting", String.class);
        return String.format("%s, %s!", greeting, name);
    }

    @RequestMapping("/bye")
    public String bye(@RequestParam(value = "name", defaultValue = "ZhangSan") String name) {
//         只使用say-bye配置的服务器
        String greeting = this.restTemplate.getForObject("http://say-bye/greeting", String.class);
        return String.format("%s, %s!", greeting, name);
    }

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

使用yml配置

直接使用yml配置就去掉了@RibbonClient的注解了

@SpringBootApplication
@RestController
public class UserApplication {

//  loadBalance开启RestTemplate的负载均衡
    @LoadBalanced
    @Bean
    RestTemplate restTemplate() {
        return new RestTemplate();
    }

    @Autowired
    RestTemplate restTemplate;

    @RequestMapping("/hi")
    public String hi(@RequestParam(value = "name", defaultValue = "Artaban") String name) {
//       只使用say-hello配置的服务器
        String greeting = this.restTemplate.getForObject("http://say-hello/greeting", String.class);
        return String.format("%s, %s!", greeting, name);
    }

    @RequestMapping("/bye")
    public String bye(@RequestParam(value = "name", defaultValue = "ZhangSan") String name) {
//         只使用say-bye配置的服务器
        String greeting = this.restTemplate.getForObject("http://say-bye/greeting", String.class);
        return String.format("%s, %s!", greeting, name);
    }

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

yml配置

spring:
  application:
    name: user
  port: 8888

say-hello:
  ribbon:
    eureka:
      # 如果你不需要使用到Eureka就设置false,服务使用listOfServer指定
      enabled: false
    listOfServers: localhost:9092,localhost:9999
    # 刷新服务器的时间间隔
    ServerListRefreshInterval: 15000
    # 配置为随机使用listOfServer中的一个服务器
    NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule
    # 使用PingUrl检查服务器是否存活
    NFLoadBalancerPingClassName: com.netflix.loadbalancer.PingUrl
    # 请求连接的超时时间
    ConnectTimeout: 2000
    # 请求处理的超时时间
    ReadTimeout: 5000
say-bye:
  ribbon:
    eureka:
      enabled: false
    listOfServers: localhost:8090
    ServerListRefreshInterval: 15000
    NFLoadBalancerRuleClassName: com.netflix.loadbalancer.AvailabilityFilteringRule
    NFLoadBalancerPingClassName: com.netflix.loadbalancer.PingUrl

在yml里通过类来配置ping、rule等规则的方式代表say-bye的命名

# 指定LoadBalancer实现类,负载均衡器
<clientName>.ribbon.NFLoadBalancerClassName: 实现 ILoadBalancer
# 指定IRule实现类,选择服务规则
<clientName>.ribbon.NFLoadBalancerRuleClassName: 实现 IRule
# 指定IPing,探测服务是否存活
<clientName>.ribbon.NFLoadBalancerPingClassName: 实现 IPing
# 指定ServerList实现类,服务列表
<clientName>.ribbon.NIWSServerListClassName: 实现 ServerList
# 指定ServerListFilter实现类,筛选服务列表
<clientName>.ribbon.NIWSServerListFilterClassName: 实现 ServerListFilter

Demo运行

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值