Ribbon是一个客户端负载均衡器,可以让您对HTTP和TCP客户端的行为进行大量控制。 Feign已使用Ribbon,因此如果您使用的是@FeignClient,则此部分也适用。
Ribbon中的一个核心概念是指定客户端的概念.每个负载均衡器都是组件集成的一部分,这些组件协同工作以按需联系远程服务器,并且集成有共开发人员引用的名称(例如,使用@FeignClient注解)。Spring Cloud使用RibbonClientConfiguration按需为每个命名客户端创建一个新的集合作为ApplicationContext。 这包含 ILoadBalancer,RestClient和ServerListFilter。
org.springframework.cloud
spring-cloud-starter-ribbon
您可以使用
Spring Cloud还允许您通过使用@RibbonClient声明其他配置(在RibbonClientConfiguration之上)来完全控制客户端。 例:
@Configuration
@RibbonClient(name = "foo", configuration = FooConfiguration.class)
public class TestConfiguration {
}
上述配置,name为微服务名称,FooConfiguration为为微服务指定的配置文件。在这种情况下,客户端由RibbonClientConfiguration中已有的组件以及FooConfiguration中的任何组件组成(后者优先级高)。
注意:
FooConfiguration必须是@Configuration,但要注意它应该在主应用程序上下文的@ComponentScan中,否则它将由所有@RibbonClients共享。 如果使用@ComponentScan(或@SpringBootApplication),则需要采取措施以避免包含它(例如将其放在单独的非重叠包中,或指定要在@ComponentScan中显式扫描的包)。
Spring Cloud Netflix默认为Rbbion提供以下bean:
IClientConfig
ribbonClientConfig: 默认为DefaultClientConfigImpl Ribbon的客户端配置
IRule
ribbonRule: 默认为ZoneAvoidanceRule Ribbon的负载均衡策略,该策略能够在环境下选出最佳区域的实例进行访问
IPing
ribbonPing: DummyPing Rbbion Ribbon的实例检测策略
ServerList
ribbonServerList: ConfigurationBasedServerList 服务实例清单的维护机制
ServerListFilter
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();
}
}
这将使用PingUrl替换NoOpPing并提供自定义serverListFilter
可以使用@RibbonClients注解为所有Rbbion客户端提供默认配置,并注册默认配置,如以下示例所示:
@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 ribbonServerList(IClientConfig config) {
return new RibbonClientDefaultConfigurationTestsConfig.BazServiceList(config);
}
@Bean
public ServerListSubsetFilter serverListFilter() {
ServerListSubsetFilter filter = new ServerListSubsetFilter();
return filter;
}
}
从版本1.2.0开始,Spring Cloud Netflix现在支持使用属性自定义Rbbion客户端以与功能区文档兼容。
这允许您在不同环境中的启动时更改行为。
支持的属性如下所示,并应以
NFLoadBalancerClassName
: 配置ILoadBalancer的实现类
NFLoadBalancerRuleClassName
: 配置should implement IRule的实现类
NFLoadBalancerPingClassName
: 配置should implement IPing的实现类
NIWSServerListClassName
: 配置should implement ServerList的实现类
NIWSServerListFilterClassName
配置should implement ServerListFilter的实现类
这些属性中定义的类优先于使用@RibbonClient(configuration = MyRibbonConfig.class)定义的bean以及Spring Cloud Netflix提供的默认值。
如:
要为服务名称"users"设置IRule,您可以设置以下内容:
application.yml.
users:
ribbon:
NIWSServerListClassName: com.netflix.loadbalancer.ConfigurationBasedServerList
NFLoadBalancerRuleClassName: com.netflix.loadbalancer.WeightedResponseTimeRule
当Eureka与Ribbon一起使用时(即同时引入了Spring cloud ribbon 和Spring cloud eureka),会触发eureka中实现对ribbon的自动化配置,这时ribbonServerList被覆盖,其扩展名为DiscoveryEnabledNIWSServerList,该实现将服务清单列表交给Eureka的服务治理机制来进行维护。它还用NIWSDiscoveryPing替换IPing接口,NIWSDiscoveryPing委托Eureka确定服务器是否启动。默认情况下安装的ServerList是DomainExtractingServerList,其目的是在不使用AWS AMI元数据的情况下使负载均衡器可以使用物理元数据(这是Netflix所依赖的)为了让实例维护策略更加通用。默认情况下,服务器列表将使用实例元数据中提供的“区域”信息构建(因此在远程客户端上设置eureka.instance.metadataMap.zone),如果缺少它,则可以使用服务器主机名中的域名作为区域的代理(如果设置了flagsZoneFromHostname标志)。一旦区域信息可用,它就可以在ServerListFilter中使用。默认情况下,它将用于在与客户端相同的区域中查找服务器,因为默认值为ZonePreferenceServerListFilter。默认情况下,客户端区域的确定方式与远程实例相同,即通过eureka.instance.metadataMap.zone。
Eureka是一种抽象远程服务器发现的便捷方式,因此您无需在客户端对其URL进行硬编码,但如果您不想使用它,则Ribbon和Feign仍然非常适合。 假设您已为“stores”声明了@RibbonClient,并且Eureka未被使用(甚至在类路径中也没有)。 Ribbon客户端默认为已配置的服务器列表,您可以提供此类配置:
application.yml.
stores:
ribbon:
listOfServers: http://localhost:8000,http://localhost:8001
设置属性ribbon.eureka.enabled = false将明确禁用在Ribbon中使用Eureka。
application.yml.
ribbon:
eureka:
enabled: false
您也可以直接使用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
}
}
每个名为client的Ribbon都有一个Spring Cloud维护的相应子应用程序上下文,这个应用程序上下文在第一次请求指向客户端时被延迟加载。 通过指定Ribbon客户端的名称,可以将此延迟加载行为更改为在启动时急切地加载这些子应用程序上下文。
application.yml
ribbon:
eager-load:
enabled: true
clients: client1, client2, client3
如果将zuul.ribbonIsolationStrategy更改为THREAD,Hystrix的线程隔离策略将用于所有路由。 在这种情况下,HystrixThreadPoolKey默认设置为“RibbonCommand”。 这意味着所有路由的HystrixCommands将在同一个Hystrix线程池中执行。 可以使用以下配置更改此行为,这将导致在Hystrix线程池中为每个路由执行HystrixCommands
application.yml
zuul:
threadPool:
useSeparateThreadPools: true
在这种情况下,默认的HystrixThreadPoolKey与每个路由的服务ID相同。 要向HystrixThreadPoolKey添加前缀,请将zuul.threadPool.threadPoolKeyPrefix设置为要添加的值。
application.yml
zuul:
threadPool:
useSeparateThreadPools: true
threadPoolKeyPrefix: zuulgw
微信公众号:
JAVA程序猿成长之路
分享资源,记录程序猿成长点滴。专注于Java,Spring,SpringBoot,SpringCloud,分布式,微服务。