SpringCloud-组件之一Ribbon 负载均衡

Ribbon是一种客户端负载平衡器,可让您对HTTP和TCP客户端的行为进行大量控制。Feign已使用Ribbon,因此,如果使用@FeignClient,则本节也适用。

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

1如何包括Ribbon

要将Ribbon包含在您的项目中,请使用起始者,其组ID为org.springframework.cloud,工件ID为​​spring-cloud-starter-netflix-ribbon。

2自定义Ribbon客户端

您可以使用.ribbon.*中的外部属性来配置Ribbon客户端的某些位,这与本地使用Netflix API相似,不同之处在于可以使用Spring Boot配置文件。可以将本机选项检查为CommonClientConfigKey(功能区核心的一部分)中的静态字段。

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提供的beans:

Bean类型Bean名称班级名称

IClientConfig
ribbonClientConfig
DefaultClientConfigImpl
IRule
ribbonRule
ZoneAvoidanceRule
IPing
ribbonPing
DummyPing
ServerList
ribbonServerList
ConfigurationBasedServerList
ServerListFilter
ribbonServerListFilter
ZonePreferenceServerListFilter
ILoadBalancer
ribbonLoadBalancer
ZoneAwareLoadBalancer
ServerListUpdater
ribbonServerListUpdater
PollingServerListUpdater

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

@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语句将NoOpPing替换为PingUrl,并提供了自定义serverListFilter。

3为所有Ribbon客户端自定义默认值

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


@Configuration
class DefaultRibbonConfig {
@Bean
public IRule ribbonRule() {
return new BestAvailableRule();
}
@Bean
public IPing ribbonPing() {
return new PingUrl();
}
@Bean
public ServerList ribbonServerList(IClientConfig config) {
return new RibbonClientDefaultConfigurationTestsConfig.BazServiceList(config);
}
@Bean
public ServerListSubsetFilter serverListFilter() {
ServerListSubsetFilter filter = new ServerListSubsetFilter();
return filter;
}
}

4通过设置Properties自定义Ribbon客户端

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

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

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

.ribbon.NFLoadBalancerClassName:应实施ILoadBalancer
.ribbon.NFLoadBalancerRuleClassName:应实施IRule
.ribbon.NFLoadBalancerPingClassName:应实施IPing
.ribbon.NIWSServerListClassName:应实施ServerList
.ribbon.NIWSServerListFilterClassName:应实施ServerListFilter

[注意]

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

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

application.yml。 
users:
  ribbon:
    NIWSServerListClassName: com.netflix.loadbalancer.ConfigurationBasedServerList
    NFLoadBalancerRuleClassName: com.netflix.loadbalancer.WeightedResponseTimeRule

5将Ribbon与Eureka一起使用

当Eureka与Ribbon结合使用时(也就是说,两者都在类路径上),ribbonServerList被扩展名DiscoveryEnabledNIWSServerList覆盖,这将填充{71中的服务器列表/}。它还用NIWSDiscoveryPing替换了IPing接口,该接口委托给Eureka确定服务器是否启动。默认安装的ServerList是DomainExtractingServerList。其目的是不使用AWS AMI元数据(这就是Netflix所依赖的)使元数据可用于负载均衡器。默认情况下,服务器列表是使用实例元数据中提供的“ zone ”信息构建的(因此,在远程客户端上,设置为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” ”,以与本机Netflix兼容)。

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

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

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

7示例:在Ribbon中禁用Eureka

将ribbon.eureka.enabled属性设置为false会显式禁用Ribbon中的Eureka,如以下示例所示:

application.yml。 
ribbon:
  eureka:
   enabled: false

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

9 Ribbon配置的缓存

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

application.yml:

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

10如何配置Hystrix线程池

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

application.yml:

zuul:
  threadPool:
    useSeparateThreadPools: true

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

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

application.yml:

zuul:
  threadPool:
    useSeparateThreadPools: true
    threadPoolKeyPrefix: zuulgw

11如何提供Ribbon的IRule的密钥

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

com.netflix.loadbalancer.IRule.java。 
public interface IRule{
    public Server choose(Object key);

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

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

如果您使用密钥FilterConstants.LOAD_BALANCER_KEY将任何对象放入RequestContext中,则该对象将传递到IRule实现的choose方法中。上例中显示的代码必须在执行RibbonRoutingFilter之前执行。Zuul的前置过滤器是执行此操作的最佳位置。您可以通过预过滤器中的RequestContext访问HTTP标头和查询参数,因此可以用来确定传递到Ribbon的LOAD_BALANCER_KEY。如果没有在RequestContext中用LOAD_BALANCER_KEY放置任何值,则将空值作为choose方法的参数传递。

你可能感兴趣的:(Spring,Cloud,spring,spring,cloud,ribbon)