Spring Cloud Netflix - Ribbon使用篇

    技术2025-08-13  15

    本文目录

    Client Side Load Balancer:RibbonHow to Include RibbonCustomizing the Ribbon ClientCustomizing the Default for All Ribbon ClientsCustomizing the Ribbon Client by Setting PropertiesUsing Ribbon with EurekaExample: How to Use Ribbon Without EurekaExample: Disable Eureka Use in RibbonUsing the Ribbon API DirectlyCaching of Ribbon ConfigurationHow to Configure Hystrix Thread PoolsHow to Provide a Key to Ribbon's IRule

    Client Side Load Balancer:Ribbon

    Ribbon是一个客户端的负载均衡器,可以用来控制HTTP和TCP客户端的行为。

    Ribbon核心的概念是命名的客户端。每个负载均衡器作为组件团体的一部分,这些组件会按需共同协作去联络一个远程服务端。此外,这个团体通过在@FeignClient注解指定name属性的方式设定一个名字。Spring Cloud为每个命名的客户端通过使用RibbonClientConfiguration的方式创建了一个新的团体,作为一个ApplicationContext。这包含了一个ILoadBalancer,RestTemplate,ServerListFilter。

    How to Include Ribbon

    Customizing the Ribbon Client

    可以在配置文件中,指定<client>.ribbon.*,对一个Ribbon客户端进行配置。在CommonClientConfigKey这个类中根据需要,寻找对应的属性进行设置。

    可以指定一个配置类,作为该Ribbon客户端的配置。

    在@RibbonClient注解中指定的自定义的配置类,必须是一个@Configuration类。不要被主应用程序上下文的@ComponentScan注解扫描到,否则会被所有的@RibbonClients所共享。可以将它放到一个独立的、与@ComponentScan扫描的包不重叠的包中。

    Customizing the Default for All Ribbon Clients

    为所有的Ribbon客户端,提供一个默认的配置,注册它。

    Customizing the Ribbon Client by Setting Properties

    从版本1.2.0开始,Spring Cloud Netflix支持自定义Ribbon客户端,通过设置一些属性。

    可以对服务名叫做“users”的,进行设置。

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

    Using Ribbon with Eureka

    当Eureka和Ribbon组合使用(也就是,两者都在类路径中),ribbonServerList由DiscoveryEnabledNIWSServerList进行重写,其添加了来自Eureka的服务器列表。替换IPing为NIWSDiscoveryPing,委派Eureka判断服务器是否上线。ServerList,默认由一个DomainExtractingServerList设置。这个目的是使元数据对于负载均衡器可用,而没有使用AWS AMI元数据(这个是Netflix所依赖的)。默认,服务器列表使用“zone”信息进行构造(对于远程客户端,设置eureka.instance.metadataMap.zone)。如果这个缺失了,并且有设置approximateZoneFromHostname标识,可以使用服务器主机名的域名作为时区的一个代理。一旦时区信息可用,可以在ServerListFilter中被使用。默认,这个可以被用来定位和客户端相同的时区的服务器,因为默认是一个ZonePreferenceServerListFilter。默认,客户端的时区和远程实例使用相同的方式设置,即使用eureka.instance.metadataMap.zone。

    Example: How to Use Ribbon Without Eureka

    Eureka是一个远程服务发现的便捷的方式,不需要对客户端URL硬编码。如果不想使用Eureka,Ribbon和Feign也能正常工作。假设有一个声明@RibbonClient的"stores",没有使用Eureka(甚至都没有在类路径中)。Ribbon客户端默认使用一个配置过的服务器列表。如下:

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

    Example: Disable Eureka Use in Ribbon

    设置在Ribbon中关闭Eureka的使用,如下:

    ribbon: eureka: enabled: false

    Using the Ribbon API Directly

    可以直接使用LoadBalancerClient,如下:

    public class MyClass { @Autowired private LoadBalancerClient loadBalancer; public void doStuff() { ServiceInstance instance = loadBalancer.choose("stores"); URI storeUri = URI.create(String.format("https://%s:%s", instance.getHost(), instance.getPort())); // ... doSomething with the URI } }

    Caching of Ribbon Configuration

    每一个Ribbon命名的客户端,有一个对应的由Spring Cloud维护的子上下文。这个上下文是延迟加载的,直到有请求到命名的客户端时才加载。这个延迟加载的行为可以设置为启动时,就进行加载。如下:

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

    How to Configure Hystrix Thread Pools

    如果对zuul.ribbonIsolationStrategy设置为THREAD,线程隔离策略对于Hystrix来说,会用于所有的routes。这种情况下,HystrixThreadPoolKey默认设置为RibbonCommand。也就意味着,对于所有的routes的HystrixCommands会在同一个Hystrix线程池中执行。这个可以通过如下的方式改变:

    zuul: threadPool: useSeparateThreadPools: true

    这种设置,会导致HystrixCommands会在每一个route的Hystrix线程池中执行。这种情况下,默认的HystrixThreadPoolKey和每个route的service ID相同。可以通过如下方式添加一个自定义的前缀:

    zuul: threadPool: useSeparateThreadPools: true threadPoolKeyPrefix: zuulgw

    How to Provide a Key to Ribbon’s IRule

    如果要求IRule实现类,处理一个特殊的路由要求,比如一个“金丝雀测试”,那么在IRule的chosse方法中传递一些信息。

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

    此外,可以通过以下方式,传递一些信息:

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

    上面的代码要求在RibbonRoutingFilter执行之前被执行。Zuul的前置过滤器是最佳的方式去做这件事。你可以在其前置过滤器中使用 RequestContext,访问HTTP头和查询参数。所以可以用来设置LOAD_BALANCER_KEY。如果在RequestContext中没有设置LOAD_BALANCER_KEY任何值,那么对于choose方法会传递null作为方法参数。

    Processed: 0.009, SQL: 9