本文目录
- Client Side Load Balancer:Ribbon
- How to Include Ribbon
- Customizing the Ribbon Client
- Customizing the Default for All Ribbon Clients
- Customizing the Ribbon Client by Setting Properties
- Using Ribbon with Eureka
- Example: How to Use Ribbon Without Eureka
- Example: Disable Eureka Use in Ribbon
- Using the Ribbon API Directly
- Caching of Ribbon Configuration
- How to Configure Hystrix Thread Pools
- How 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
作为方法参数。