客户端负载均衡:Ribbon

Ribbon是一个客户端的负载均衡器,可以提供很多HTTP和TCP的控制行为。Feign已经使用了Ribbon,所以如果你使用了@FeignClient,Riboon也同样被应用了。

Ribbon核心的概念是named client。每个负载均衡器都是共同体的一部分,可以一起运行去连接远程服务器,你会给你的应用设置一个名字(比如使用@FeignClient注解)。Spring Cloud creates a new ensemble as an ApplicationContext on demand for each named client using RibbonClientConfiguration. This contains (amongst other things) an ILoadBalancer, a RestClient, and a ServerListFilter.

如何引入Ribbon

org.springframework.cloud and artifact id spring-cloud-starter-ribbon. 查看详情 Spring Cloud Project page

定制Ribbon Clietn

你可以配置一些Ribbon client的属性在外部的属性文件里(application.properties/yml),如.ribbon.*,这个和Netflix APIS本身没有什么不同。本机选项可以被检查使用CommonClientConfigKey等静态字段。

Spring cloud还允许你完全控制客户端通过声明额外的配置,使用@RibbonClient(位于RibbonClientConfiguration的顶部)。 
例如:

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

In this case the client is composed from the components already in RibbonClientConfiguration together with any in FooConfiguration (where the latter generally will override the former).

警告:FooConfiguration已经设置为@Configuration,但是注意它不是@ComponentScan在主程序上下文,另外它会被所有的@RibbonClients共享。如果你使用了@ComponentScan(或者@SpringBootApplication)你需要采取措施去避免引入。(例如把他分割开来,不要重叠包,或者指定明确的包路径在@ComponentScan)。

Spring Cloud Netflix默认为Ribbon提供了如下beans(BeanType beanName:ClassName): 

* IClientConfig ribbonClientConfig: DefaultClientConfigImpl 
* IRule ribbonRule: ZoneAvoidanceRule 
* IPing ribbonPing: NoOpPing 
* ServletList ribbonServerList: ConfigurationBasedServerlList 
* ServerListFilter ribbonServerListFilter: 
* ILoadBalancer ribbonLoadBalancer: ZoneAwareLoadBalancer

 

创建一个这些类型的一个Bean放置到@RibbonClient配置类中(就像上面的FooConfiguration一样),它允许你重写每一个bean的描述。例如:

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

这里使用PingUrl替换了NoOpPing。

Customizing the ribbon client using properties

从1.2.0版本开始,sping cloud netflix支持使用配置文件的方式定制RibbOn clients并且与文档兼容 Ribbon documentation

这允许你在不同环境中,改变启动时的行为。

这些属性都列在下面,并且他们必须使用 .ribbon.作为前缀。 

* NFLoadBalancerClassName: should implement ILoadBalancer 
* NFLoadBalanceerRuleClassName: should implement IRuld 
* NFLoadBalancePingClassName: should implement IPing 
* NIWSServerListClassName: should implement ServerList 
* NIWServerListFilterClassName: should implement ServerListFilter

 

注意: 类中定义了这些属性将会优先于@RibbonClient(configuration=MyRibbonConfig.class),默认的是Spring Cloud Netflix提供了。

给服务名为user设置IRule,你可以如下设置:

application.yml
user:
    ribbon:
        NFLoadBalancerRuleClassName:com.netflix.loadbalancer.WeightedResponseTimeRule

 

从 Ribbon documentation 查看Ribbon的实现。

Using Ribbon with Eureka

当Eureka跟Ribbon结合使用的时候(都在classpath),ribbonServerList会被一个外部的DiscoveryEnabledNIWServerList重写,它填充了服务懒得列表从Eureka中。它同样使用了NIWDiscoveryPing替换了IPing,它让Eureka去确定一个server是否启动。serverList默认使用的是DomainExtractingServerList,目的是让物理元数据用于负载均衡器而不是AWS AMI(这是Netflix依赖的)。默认srverlist会构造”zone”信息提供给实例使用(远程客户端设置eureka.instance.metadataMap.zone),如果没有设置它可以使用域名服务器的主机名作为区域代理(如果approximateZoneFromHostname被设置了)。一旦zone信息可用,它也会被用在ServerListFilter。默认它会用来定位一个客户端在同一个zone,因为默认的是ZonePrefeerenceServerListFilter。client的zone默认跟远程实例的一样。i.e. eureka.instance.metadataMap.zone。

注意:正统的“archaius”方式设置client zone是通过配置属性”@zone”,Sping Cloud将会优先使用这个设置(它会去引用YAML的配置)。

注意:If there is no other source of zone data then a guess is made based on the client configuration (as opposed to the instance configuration). We take eureka.client.availabilityZones, which is a map from region name to a list of zones, and pull out the first zone for the instance’s own region (i.e. the eureka.client.region, which defaults to “us-east-1” for comatibility with native Netflix).

Example:How to Use Ribbon Without Eureka

Eureka是一个方便的方式去抽象远程服务发现,所以你不需要在客户端硬编码他们的URLS。但是如果你不想用eureka,Ribbon和Feign仍然可用。假设你已经在“stores”定义了@RibbOnClient,而且没有使用Eureka(没有在classpath中)。Ribbon client默认要配置server list,你可以提供配置像这样:

application.yml
stores:
    ribbon:
        listOfServers: example.com.google.com

 

Example:Disable Eureka use in Ribbon

设置property ribbon.eureka.enable=false将会明确的让Eureka的ribbon失效。

application.yml
ribbon:
    eureka:
        enabled: false

 

Using the Ribbon API Directly

你也可以直接使用 LoadBalancerClient。例如:

public class MyClass {
    @Autowired
    private LoadBalancerClient loadBalancer;

    public void dostuff(){
        ServiceInstance instance = loadBalancer.choose("stors");
        URI storeUri = URI.create(String.format("httP://%s:%s",instance.getHost(),instance.getPort()));
        //... do something with the URI
    }
}

 

posted on 2017-03-20 23:13  ilinux_one  阅读(1170)  评论(0编辑  收藏  举报

导航