文档章节

[Spring Cloud] 4.5 Client Side Load Balancer: Ribbon

秋雨霏霏
 秋雨霏霏
发布于 2016/12/08 20:42
字数 1274
阅读 422
收藏 3

4.5 Client Side Load Balancer: Ribbon

客户端负载均衡:Ribbon

Ribbon是一个HTTP/TCP客户端的负载均衡实现。Feign已经集成了Ribbon,因此,如果你已经使用@FeignClient那么,你可以直接使用Ribbon。

Ribbon中有个核心概念:客户端命名。每一个负载均衡器都是指集群中处理某个请求的一组组件,开发者需要给每一个这样的小组进行命名。(比如使用@FeignClient注解) Spring Cloud使用了一种新的方式来分组,在业务处理端在ApplicationContext中注册一个RibbonClientConfiguration,通过这个RibbonClientConfiguration来进行分组配置。这其中就会包含一个ILoadBalancer,一个RestClient,以及一个ServerListFilter

4.5.1 How to Include Ribbon 如何引入Ribbon

引入Ribbon,需要在工程中增加如下依赖:group:org.springframework.cloud artifact id:spring-cloud-starter-ribbon。如何构建Spring Cloud 工程,参见Spring Cloud文档

4.5.2 Customizing the Ribbon Client :Ribbon客户端配置

可以通过扩展配置属性:<client>.ribbon.*,来配置Ribbon客户端相关属性,这和直接使用Netflix API没什么区别。除此之外,还可以通过Spring Boot配置文件来配置Ribbon。 配置属性可以参见CommonClientConfigKey(在ribbon-core中)。

Spring Cloud也允许通过@RibbonClient对Ribbon进行完全的控制(基于RibbonClientConfiguration)。 例如:

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

在这个例子中,会使用一个自定义的FooConfiguration整合到RibbonClientConfiguration配置过程。

警告:

需要确保FooConfiguration不会被@Configuration或者@ComponentScan扫描到,否则,就会被所有@RibbonClients共享了(自动注入)。如果使用@ComponentScan或者@SpringBootApplication时,也需要避免FooConfiguration被自动扫描。

Spring Cloud Netfix 默认情况下为Ribbo自动生成了下列Bean:

Bean类型 | Bean名称 | 类名 | 备注 ---|----|---|- IClientConfig | ribbonClientConfig | DefaultClientConfigImpl | IRule | ribbonRule | ZoneAvoidanceRule | IPing | ribbonPing | NoOpPing | ServerList<Server> | ribbonServerList | ConfigurationBasedServerList | ServerListFilter<Server> | ribbonServerListFilter | ZonePreferenceServerListFilter | ILoadBalancer | ribbonLoadBalancer | ZoneAwareLoadBalancer |

@RibbonClient配置的配置类(如上例中的 FooConfiguration),允许对上面表格中的Bean进行自定义。例如:

@Configuration
public class FooConfiguration {
    @Bean
    public IPing ribbonPing(IClientConfig config) {
        return new PingUrl();
    }
}

这个例子中使用了PingUrl来替换默认的NoOpPing

4.5.3 Customizing the Ribbon Client using properties 使用配置属性定制化Ribbon客户端

从1.2.0版本开始,Spring Cloud Netflix支持使用属性对于Ribbon客户端进行配置。属性名同Ribbon文档中一样。

这样应用启动时可以在不同的环境中使用不同的Ribbon配置信息。

配置项只需要在下列配置前加上<clientName>.ribbon.前缀就行:

  • NFLoadBalancerClassName:指定一个ILoadBalancer实现类 — NFLoadBalancerRuleClassName: 指定一个IRule实现类
  • NFLoadBalancerPingClassName:指定一个IPing实现类
  • NIWSServerListClassName:指定一个ServerList实现类
  • NIWSServerListFilterClassName:指定一个ServerListFilter实现类

注意: 这些属性指定的类,会覆盖使用@RibbonClient(configuration=MyRibbonConfig.class)注解中的定义,同时也会覆盖Spring Cloud Netflix的默认策略。

如果需要在users服务中指定一个IRule,可以这样做:

application.yml

users:
  ribbon:
    NFLoadBalancerRuleClassName: com.netflix.loadbalancer.WeightedResponseTimeRule

4.5.4 Using Ribbon with Eureka 在Eureka中使用Ribbon

当需要在Eureka中整合Ribbon,可以在Eureka中配置DiscoveryEnabledNIWSServerList来覆盖Ribbon的服务列表。也可以配置NIWSDiscoveryPing来替代Ribbon的IPing。 默认情况下Ribbon的服务列表会被替换成DomainExtractingServerList,这样就可以达到负载均衡使用配置的元数据而不是去使用AWS AMI元数据。

默认情况下,在实例的元数据中,服务列表会被封装成一个"区域"信息。(因此,在远程客户端中可以设置eureka.instance.metadataMap.zone) 当发生错误时,可以从服务端获取一个域名作为代理区域(需要打开approximateZoneFromHostname配置项)。

一旦在ServerListFilter区域信息可用,那默认的ZonePreferenceServerListFilter,就会在区域中的定位一个服务为客户端提供服务。

默认的,区域中的客户端也会以同样的方式来作为远程实例。如:eureka.instance.metadataMap.zone

注意: 按"archaius"规范,使用一个"@zone"来设置客户端区域,Spring Cloud将会优先使用这个策略(需要在YAML中配置)

注意: 如果不指定区域,那就会按照客户端配置信息中去推测。通过eureka.client.availabilityZones对区域名进行映射,使用第一个列表中的第一个作为区域信息。(例如:eureka.client.region默认就是"us-east-1")

4.5.5 Example: How to Use Ribbon Without Eureka 例子:如何不使用Eureka,直接使用Ribbon

如果不想在客户端手动指定服务端,Eureka是一个很方便的服务发现方案。但是如果你就是不想用它,Ribbon和Feign也是可以使用的。

假设,你已经为"stores"服务定义好一个@RibbonClient(不使用Eureka),在Ribbon客户端可以额外的配置一个服务列表,如下:

application.yml

stores:
  ribbon:
    listOfServers: example.com,google.com

4.5.6 Example: Disable Eureka use in Ribbon 例子:在Eureka中关闭Ribbon

可以配置ribbon.eureka.enabled = false可以在Eureka中关闭Ribbon。例如:

application.yml

ribbon:
  eureka:
   enabled: false

4.5.7 Using the Ribbon API Directly 直接操作Ribbon API

可以直接使用LoadBalancerClient。例如:

public class MyClass {
    @Autowired
    private LoadBalancerClient loadBalancer;

    public void doStuff() {
        ServiceInstance instance = loadBalancer.choose("stores");
        URI storesUri = URI.create(String.format("http://%s:%s", instance.getHost(), instance.getPort()));
        // ... do something with the URI
    }
}

© 著作权归作者所有

共有 人打赏支持
秋雨霏霏
粉丝 148
博文 91
码字总数 160620
作品 0
杭州
CTO(技术副总裁)
聊聊RibbonLoadBalancerClient的choose方法

序 本文主要研究一下RibbonLoadBalancerClient的choose方法 RibbonLoadBalancerClient.choose spring-cloud-netflix-ribbon-2.0.0.RC1-sources.jar!/org/springframework/cloud/netflix/rib......

go4it
05/28
0
0
聊聊spring cloud的LoadBalancerAutoConfiguration

序 本文主要研究一下spring cloud的LoadBalancerAutoConfiguration RibbonAutoConfiguration spring-cloud-netflix-ribbon-2.0.0.RC2-sources.jar!/org/springframework/cloud/netflix/ribb......

go4it
07/16
0
0
Spring Cloud 1.0.0 正式发布

Spring Cloud 1.0.0.RELEASE 现已提供在 Maven Central (和 repo.spring.io),相比 RC3 版本并没有太大改进,修复了一些 bug。 Spring Cloud 为开发者提供了在分布式系统(如配置管理、服务发...

oschina
2015/03/05
2.9K
3
SpringCloud之服务提供与调用(Ribbon,Feign)

本系列介绍的配置均基于 Spring Boot 2.0.1.RELEASE 版本和 Spring Cloud Finchley.SR1 eureka注册续约流程 启动注册中心 服务提供者生产服务并注册到服务中心中 消费者从服务中心中获取服务...

熊小飞呀
08/28
0
0
聊聊spring cloud的AbstractLoadBalancingClient

序 本文主要研究一下spring cloud的AbstractLoadBalancingClient AbstractLoadBalancingClient spring-cloud-netflix-ribbon-2.0.0.RELEASE-sources.jar!/org/springframework/cloud/netfli......

go4it
07/18
0
0

没有更多内容

加载失败,请刷新页面

加载更多

Flask 开发填坑

插件的选择: flask-security 真的是个鸡肋啊。自带的页面,好丑。还不如用flask-login来做呢。

pearma
40分钟前
2
0
讲述下 :LVM逻辑卷管理遇到的问题

LVM学习逻辑卷管理创建逻辑卷遇到的问题 1 实验环境 系统 内核 发行版本 CentOS 2.6.32-754.2.1.el6.x86_64 CentOS release 6.10 (Final) 由于是最小化安装没有xfs命令,yum安装如下包支持此...

linuxprobe16
今天
1
0
day95-20180922-英语流利阅读-待学习

Hey Jude 半个世纪传唱不衰的背后故事 毛西 2018-09-22 1.今日导读 2004 年,The Beatles 被《滚石》杂志选为“历史上最伟大的 50 位流行音乐家的第一位”。这四名来自英国利物浦的男孩不仅对...

飞鱼说编程
今天
2
0
OSChina 周六乱弹 —— 放假前期焦虑症晚期

Osc乱弹歌单(2018)请戳(这里) 【今日歌曲】 @andonny :分享Matteo的单曲《Panama》: 《Panama》- Matteo 手机党少年们想听歌,请使劲儿戳(这里) @新垣吉衣OSC :我发现只要去有小朋友...

小小编辑
今天
270
10
wait()被notify()后,接着执行wait()后面的语句

wait()被notify()后,接着执行wait()后面的语句

noteman
今天
2
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部