Spring Cloud官方文档中文版-客户端负载均衡:Ribbon

官方文档地址为:http://cloud.spring.io/spring-cloud-static/Dalston.SR2/#_spring_cloud_netflix

文中例子我做了一些测试在:http://git.oschina.net/dreamingodd/spring-cloud-preparation

Client Side Load Balancer: Ribbon 客户端负载均衡:Ribbon

Ribbon is a client side load balancer which gives you a lot of control over the behaviour of HTTP and TCP clients. Feign already uses Ribbon, so if you are using @FeignClient then this section also applies.

Ribbon是一个客户端负载均衡器,它给开发人员提供了对HTTP和TCP客户端行为很多的控制权。Feigh已经在使用Ribbon,因此如果开发人员使用@FeignClient,本节依然适用。

A central concept in Ribbon is that of the named client. Each load balancer is part of an ensemble of components that work together to contact a remote server on demand, and the ensemble has a name that you give it as an application developer (e.g. using the @FeignClient annotation). 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的核心概念是命名的客户端。每一个负载均衡器都是组件组合的一部分,它们在需要的时候一起工作去和远程服务器通信,开发人员可以给这个组合起一个名字(例如使用@FeignClient注解)。Spring Cloud使用RibbonClientConfiguration为每个命名的客户端根据需要创建一个新的集合作为应用上下文(ApplicationContext)。集合包括ILoadBalancer,RestClient和ServerListFilter(当然还有其他未列出的)。

How to Include Ribbon 如何引入Ribbon

To include Ribbon in your project use the starter with group org.springframework.cloud and artifact id spring-cloud-starter-ribbon. See the Spring Cloud Project page for details on setting up your build system with the current Spring Cloud Release Train.

引入org.springframework.cloud的spring-cloud-starter-ribbon项目。详见Spring Cloud Project page

Customizing the Ribbon Client

You can configure some bits of a Ribbon client using external properties in <client>.ribbon.*, which is no different than using the Netflix APIs natively, except that you can use Spring Boot configuration files. The native options can be inspected as static fields in CommonClientConfigKey (part of ribbon-core).

开发人员可以用<client>.ribbon.*外部配置来开启Ribbon的功能,这种方式除了使用了Spring Boot 配置文件外,和使用原生的Nexflix APIs没什么不同。原生的选项在CommonClientConfigKey的常量中可以看到(是ribbon-core的一部分)。

Spring Cloud also lets you take full control of the client by declaring additional configuration (on top of the RibbonClientConfiguration) using @RibbonClient. Example:

Spring Cloud也允许开发人员声明额外的配置(在RibbonClientConfiguration之上)-@RibbonClient来取得客户端的全部控制权。例如:

@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).

本例中,客户端由已在RibbonClientConfiguration中的组件以及FooConfiguration中的任意组件组成(后者通常覆盖前者)。

WARNING The FooConfiguration has to be @Configuration but take care that it is not in a @ComponentScan for the main application context, otherwise it will be shared by all the @RibbonClients. If you use @ComponentScan (or @SpringBootApplication) you need to take steps to avoid it being included (for instance put it in a separate, non-overlapping package, or specify the packages to scan explicitly in the @ComponentScan).

警告 FooConfiguration必须有@Configuration,但注意它并不在主应用上下文的@ComponentScan中,否则它会被所有的@RibbonClients分享(意思就是覆盖所有客户端的默认值)。如果开发人员使用@ComponentScan(或@SpringBootApplication),那就必须采取措施避免被覆盖到(例如将其放入一个独立的,不重叠的包中,或以@ComponentScan指明要扫描的包。

Spring Cloud Netflix provides the following beans by default for ribbon (BeanType beanName: ClassName):

Spring Cloud Netflix默认为Ribbon提供以下bean(BeanType beanName: ClassName):

  • IClientConfig ribbonClientConfig: DefaultClientConfigImpl
  • IRule ribbonRule: ZoneAvoidanceRule
  • IPing ribbonPing: NoOpPing
  • ServerList<Server> ribbonServerList: ConfigurationBasedServerList
  • ServerListFilter<Server> ribbonServerListFilter: ZonePreferenceServerListFilter
  • ILoadBalancer ribbonLoadBalancer: ZoneAwareLoadBalancer
  • ServerListUpdater ribbonServerListUpdater: PollingServerListUpdater

Creating a bean of one of those type and placing it in a @RibbonClient configuration (such as FooConfiguration above) allows you to override each one of the beans described. Example:

创建以上Bean中的一个并放入@RibbonClient配置中(可以是上面的FooConfiguration),可以覆盖默认的Bean。例如:

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

This replaces the NoOpPing with PingUrl.

上面的@Bean用PingUrl覆盖了NoOpPing。

Customizing the Ribbon Client using properties 用属性自定义Ribbon客户端

Starting with version 1.2.0, Spring Cloud Netflix now supports customizing Ribbon clients using properties to be compatible with the Ribbon documentation

从1.2.0开始,Spring Cloud Netflix开始支持并兼容属性自定义Ribbon客户端,详见Ribbon documentation

This allows you to change behavior at start up time in different environments.

这样开发人员就可以在启动时根据不同环境来改变客户端行为。

The supported properties are listed below and should be prefixed by <clientName>.ribbon.:

下列属性加上<clientName>.ribbon.前缀就是Ribbon支持的属性配置。

  • NFLoadBalancerClassName: should implement ILoadBalancer
  • NFLoadBalancerRuleClassName: should implement IRule
  • NFLoadBalancerPingClassName: should implement IPing
  • NIWSServerListClassName: should implement ServerList
  • NIWSServerListFilterClassName should implement ServerListFilter

NOTE Classes defined in these properties have precedence over beans defined using @RibbonClient(configuration=MyRibbonConfig.class) and the defaults provided by Spring Cloud Netflix.

注意 这些类比使用@RibbonClient(configuration=MyRibbonConfig.class)定义的Bean和由Spring Cloud Netflix提供的默认的Bean优先定义。

To set the IRule for a service name users you could set the following:

要为服务名称用户设置IRule,开发人员可以设置以下内容:

application.yml

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

See the Ribbon documentation for implementations provided by Ribbon.

Ribbon实现详见: Ribbon documentation

Using Ribbon with Eureka 和Eureka一起使用

When Eureka is used in conjunction with Ribbon (i.e., both are on the classpath) the ribbonServerList is overridden with an extension of DiscoveryEnabledNIWSServerList which populates the list of servers from Eureka. It also replaces the IPing interface with NIWSDiscoveryPing which delegates to Eureka to determine if a server is up. The ServerList that is installed by default is a DomainExtractingServerList and the purpose of this is to make physical metadata available to the load balancer without using AWS AMI metadata (which is what Netflix relies on). By default the server list will be constructed with "zone" information as provided in the instance metadata (so on the remote clients set eureka.instance.metadataMap.zone), and if that is missing it can use the domain name from the server hostname as a proxy for zone (if the flag approximateZoneFromHostname is set). Once the zone information is available it can be used in a ServerListFilter. By default it will be used to locate a server in the same zone as the client because the default is a ZonePreferenceServerListFilter. The zone of the client is determined the same way as the remote instances by default, i.e. via eureka.instance.metadataMap.zone.

当Eureka与Ribbon结合使用时(也就是说都在classpath中),RibbonServerList将被扩展为DiscoveryEnabledNIWSServerList,该扩展从Eureka缓存信息中获取并填充服务器列表信息。DiscoveryEnabledNIWSServerList还用NIWSDiscoveryPing代替了IPing接口,NIWSDiscoveryPing委托Eureka确认服务是否启动。默认情况下安装的ServerList是一个DomainExtractingServerList,其目的是使物理元数据可用于负载均衡器,而不使用AWS AMI元数据(Netflix依赖于此)。服务器列表默认由实例元数据提供的“zone”信息构建,如果这些信息缺失,那么会使用服务器主机的域名作为一个zone的代理(前提是设定了approximateZoneFromHostname标志)。一旦zone信息确定,ServerListFilter就会使用。只要默认值为ZonePreferenceServerListFilter,它将用于查找与客户端相同的区域中的服务器。默认情况下,客户端的zone与远程实例的方式相同,即通过eureka.instance.metadataMap.zone。

NOTE The orthodox "archaius" way to set the client zone is via a configuration property called "@zone", and Spring Cloud will use that in preference to all other settings if it is available (note that the key will have to be quoted in YAML configuration).

注意 设置客户端区域的正统“archaius”方式是通过一个名为“@zone”的配置属性,如果可用Spring Cloud将优先于所有其他设置使用。(请注意,该配置项必须在YAML配置中引用)。

NOTE 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).

注意 如果没有其他的zone数据源,那么可以基于客户端配置(与实例配置相反)进行猜测, 我们将eureka.client.availabilityZones(从区域名称映射到区域列表),并拉出实例本身region的第一个zone(即eureka.client.region,默认为“us-east-1” “为了与本机Netflix的兼容性)。

Example: How to Use Ribbon Without Eureka 如何单独使用Ribbon

Eureka is a convenient way to abstract the discovery of remote servers so you don’t have to hard code their URLs in clients, but if you prefer not to use it, Ribbon and Feign are still quite amenable. Suppose you have declared a @RibbonClient for "stores", and Eureka is not in use (and not even on the classpath). The Ribbon client defaults to a configured server list, and you can supply the configuration like this:

Eureka是一个便利的抽象远程服务发现的方式,有了它,开发人员就不用在代码中将URL写死,如果你想写死也不是不可以,Ribbon和Feign是很灵活的。假设你已经声明了给“stores”一个@RibbonClient,而且没有使用Eureka(甚至在classpath中也不出现)。Ribbon客户端有一个默认的服务器列表,它支持以下配置:

application.yml

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

Example: Disable Eureka use in Ribbon 干掉Eureka

Setting the property ribbon.eureka.enabled = false will explicitly disable the use of Eureka in Ribbon. 设置ribbon.eureka.enabled = false。

application.yml

ribbon:
eureka:
enabled: false

Using the Ribbon API Directly 直接使用Ribbon API

You can also use the LoadBalancerClient directly. Example:

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
}
}

Caching of Ribbon Configuration Ribbon配置缓存

Each Ribbon named client has a corresponding child Application Context that Spring Cloud maintains, this application context is lazily loaded up on the first request to the named client. This lazy loading behavior can be changed to instead eagerly load up these child Application contexts at startup by specifying the names of the Ribbon clients.

Spring Cloud为每一个命名的Ribbon客户端维护了相应的子应用上下文,这个上下文在客户端第一次被请求的时候懒加载。不过明确指定这些Ribbon客户端的名字可以让它们在启动时就加载。(这里不是很清楚client的名字是什么)

application.yml

ribbon:
eager-load:
enabled: true
clients: client1, client2, client3
dreamingodd原创文章,如转载请注明出处。
上一篇:mysql 内连接 左连接 右连接 外连接


下一篇:SQL-内连接、外连接(左、右)、交叉连接