Spring Cloud Document翻译(八)--客户端负载均衡器:Ribbon

16.客户端负载均衡器:Ribbon

Ribbon是一个客户端负载均衡器,可以让您对HTTP和TCP客户端的行为进行大量控制。Feign已使用Ribbon,因此,如果您使用@FeignClient,此部分也适用。

Ribbon中的一个核心概念是指定客户端的概念。每个负载均衡器都是一组组件的一部分,这些组件一起工作以按需联系远程服务器,并且该集合具有您作为应用程序开发人员提供的名称(例如,通过使用@FeignClient注释)。根据需要,Spring Cloud 通过使用RibbonClientConfiguration为每个命名客户端 创建一个新的ApplicationContext集合。这包含(除其他外)a ILoadBalancer,a RestClient和a ServerListFilter

16.1如何包含Ribbon

要在项目中包含Ribbon,请使用组ID为ID org.springframework.cloud且工件ID为 spring-cloud-starter-netflix-ribbon的starter。有关使用当前Spring Cloud Release Train设置构建系统的详细信息,请参阅Spring Cloud Project页面

16.2自定义Ribbon客户端

您可以使用<client>.ribbon.*中的外部属性配置Ribbon客户端的某些位,这类似于本机使用Netflix API,但您可以使用Spring Boot配置文件。可以将本机选项作为静态字段CommonClientConfigKey(ribbon-core的一部分)进行检查。

Spring Cloud还允许您通过使用声明@RibbonClient的其他配置(在RibbonClientConfiguration的上方)来完全控制客户端,如以下示例所示:

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

在这种情况下,客户端由已经存在在RibbonClientConfiguration中的组件CustomConfiguration中的组件组成(后者通常覆盖前者)。

[警告]

CustomConfiguration类必须是@Configuration的类,但要小心,它不被@ComponentScan扫入主应用程序上下文。否则,它由所有人共享@RibbonClients。如果使用@ComponentScan(或@SpringBootApplication),则需要采取措施以避免包含它(例如,您可以将其放在单独的非重叠包中或指定要在其中显式扫描的包@ComponentScan)。

下表显示了Spring Cloud Netflix默认为Ribbon提供的bean:

Bean类型 Bean名 类名称

IClientConfig

ribbonClientConfig

DefaultClientConfigImpl

IRule

ribbonRule

ZoneAvoidanceRule

IPing

ribbonPing

DummyPing

ServerList<Server>

ribbonServerList

ConfigurationBasedServerList

ServerListFilter<Server>

ribbonServerListFilter

ZonePreferenceServerListFilter

ILoadBalancer

ribbonLoadBalancer

ZoneAwareLoadBalancer

ServerListUpdater

ribbonServerListUpdater

PollingServerListUpdater

创建其中一种类型的bean并将其放在@RibbonClient配置中(FooConfiguration如上所述)可以覆盖所描述的每一个bean,如下例所示:

@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();
	}

}

前面示例中的include语句替换NoOpPingPingUrl并提供自定义serverListFilter

16.3自定义所有Ribbon客户端的默认值

可以使用@RibbonClients注释并注册默认配置为所有Ribbon客户端提供默认配置,如以下示例所示:

@RibbonClients(defaultConfiguration = DefaultRibbonConfig.class)
public class RibbonClientDefaultConfigurationTestsConfig {

	public static class BazServiceList extends ConfigurationBasedServerList {

		public BazServiceList(IClientConfig config) {
			super.initWithNiwsConfig(config);
		}

	}

}

@Configuration
class DefaultRibbonConfig {

	@Bean
	public IRule ribbonRule() {
		return new BestAvailableRule();
	}

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

	@Bean
	public ServerList<Server> ribbonServerList(IClientConfig config) {
		return new RibbonClientDefaultConfigurationTestsConfig.BazServiceList(config);
	}

	@Bean
	public ServerListSubsetFilter serverListFilter() {
		ServerListSubsetFilter filter = new ServerListSubsetFilter();
		return filter;
	}

}

16.4通过设置属性自定义Ribbon客户端

从版本1.2.0开始,Spring Cloud Netflix现在支持通过将属性设置为与Ribbon文档兼容来自定义Ribbon客户端。

这使您可以在不同环境中的启动时更改行为。

以下列表显示了支持的属性>:

  • <clientName>.ribbon.NFLoadBalancerClassName:应该实现 ILoadBalancer
  • <clientName>.ribbon.NFLoadBalancerRuleClassName:应该实现 IRule
  • <clientName>.ribbon.NFLoadBalancerPingClassName:应该实现 IPing
  • <clientName>.ribbon.NIWSServerListClassName:应该实现 ServerList
  • <clientName>.ribbon.NIWSServerListFilterClassName:应该实现 ServerListFilter
[注意]

这些属性中定义的类优先于使用@RibbonClient(configuration=MyRibbonConfig.class)Spring 定义的bean 和Spring Cloud Netflix提供的缺省值。

要设置IRule名为users的服务名称,您可以设置以下属性:

application.yml。 

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

 

有关Ribbon提供的实现,请参阅Ribbon文档

16.5在Eureka上使用Ribbon

当Eureka与Ribbon一起使用时(也就是说,两者都在类路径上)时,ribbonServerList会被覆盖为一个DiscoveryEnabledNIWSServerList的扩展,它会从Eureka获得服务器列表。它还替换了IPing接口用NIWSDiscoveryPing,该接口委托Eureka确定服务器是否已启动。该ServerList默认被安装的是DomainExtractingServerList。其目的是在不使用AWS AMI元数据的情况下使负载均衡器可以使用元数据(这是Netflix所依赖的)。默认情况下,服务器列表由“ 区域 ”信息构成,如实例元数据中所提供的(因此,在远程客户端上设置eureka.instance.metadataMap.zone)。如果缺少那个,如果approximateZoneFromHostname设置了标志,则可以使用服务器主机名中的域名作为区域的代理。区域信息可用后,可以在ServerListFilter中使用。默认情况下,它用于在与客户端相同的区域中查找服务器,因为默认值为a ZonePreferenceServerListFilter。默认情况下,客户端的区域以与远程实例相同的方式确定(即,通过eureka.instance.metadataMap.zone)。

[注意]

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

[注意]

如果没有其他区域数据源,则根据客户端配置(与实例配置相反)进行猜测。我们采用eureka.client.availabilityZones从区域名称到区域列表的映射,并拉出实例自己区域的第一个区域(即eureka.client.region,默认为“us-east-1”,以与本机Netflix兼容) 。

16.6示例:如何在没有Eureka的情况下使用Ribbon

Eureka是一种抽象远程服务器发现的便捷方式,因此您无需在客户端中对其URL进行硬编码。但是,如果您不想使用Eureka,Ribbon和Feign也可以使用。假设你已经@RibbonClient为“商店” 声明了一个,并且Eureka没有被使用(甚至没有在类路径上)。Ribbon客户端默认为已配置的服务器列表。您可以按如下方式提供配置:

application.yml。 

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

 

16.7示例:禁用Ribbon中的Eureka使用

设置该ribbon.eureka.enabled属性以false显式禁用在Ribbon中使用Eureka,如以下示例所示:

application.yml。 

ribbon:
  eureka:
   enabled: false

 

16.8直接使用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
    }
}

16.9Ribbon配置的缓存

名为client的每个Ribbon都有一个Spring Cloud维护的相应子应用程序上下文。在对指定客户端的第一个请求上延迟加载此应用程序上下文。通过指定Ribbon客户端的名称,可以将此延迟加载行为更改为在启动时急切地加载这些子应用程序上下文,如以下示例所示:

application.yml。 

ribbon:
  eager-load:
    enabled: true
    clients: client1, client2, client3

 

16.10如何配置Hystrix线程池

如果更改zuul.ribbonIsolationStrategyTHREAD,则Hystrix的线程隔离策略将用于所有路由。在这种情况下,将HystrixThreadPoolKey其设置RibbonCommand为默认值。这意味着所有路由的HystrixCommands都在同一个Hystrix线程池中执行。可以使用以下配置更改此行为:

application.yml。 

zuul:
  threadPool:
    useSeparateThreadPools: true

 

前面的示例导致HystrixCommands在Hystrix线程池中为每个路由执行。

在这种情况下,默认值HystrixThreadPoolKey与每个路由的服务ID相同。要添加前缀HystrixThreadPoolKey,请设置zuul.threadPool.threadPoolKeyPrefix为要添加的值,如以下示例所示:

application.yml。 

zuul:
  threadPool:
    useSeparateThreadPools: true
    threadPoolKeyPrefix: zuulgw

 

16.11如何为Ribbon提供密钥 IRule

如果您需要提供自己的IRule实现来处理特殊的路由要求,如“ canary ”测试,请将一些信息传递给choose方法IRule

com.netflix.loadbalancer.IRule.java。 

public interface IRule{
    public Server choose(Object key);
         :

 

您可以提供IRule实现用于选择目标服务器的一些信息,如以下示例所示:

RequestContext.getCurrentContext()
              .set(FilterConstants.LOAD_BALANCER_KEY, "canary-test");

如果将任何对象放入RequestContext带有键的对象中FilterConstants.LOAD_BALANCER_KEY,则将其传递给实现的choose方法IRule。必须在执行前RibbonRoutingFilter执行前面示例中显示的代码。Zuul的预过滤器是最好的选择。您可以通过RequestContext预过滤器访问HTTP标头和查询参数,因此可以用它来确定LOAD_BALANCER_KEY传递给Ribbon的内容。如果你不把任何值与LOAD_BALANCER_KEYRequestContext,null被作为一个参数传递choose方法。

17.外部配置:Archaius

Archaius是Netflix客户端配置库。它是所有Netflix OSS组件用于配置的库。Archaius是Apache Commons Configuration项目的扩展。它允许通过轮询源更改或允许源推送更改到客户端来更新配置。Archaius使用Dynamic <Type> Property类作为属性的句柄,如以下示例所示:

Archaius示例。 

class ArchaiusTest {
    DynamicStringProperty myprop = DynamicPropertyFactory
            .getInstance()
            .getStringProperty("my.prop");

    void doSomething() {
        OtherClass.someMethod(myprop.get());
    }
}

 

Archaius有自己的一组配置文件和加载优先级。Spring应用程序通常不应直接使用Archaius,但仍然需要本机配置Netflix工具。Spring Cloud有一个Spring Environment Bridge,因此Archaius可以从Spring环境中读取属性。此桥接器允许Spring Boot项目使用常规配置工具链,同时让他们按照文档(大多数情况下)配置Netflix工具。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章