推荐阅读:
SpringCloud源码阅读0-SpringCloud必备知识
SpringCloud源码阅读1-EurekaServer源码的秘密
负载均衡提供客户端的软件负载均衡算法,理解一种负载均衡的内部结构,对理解其他种类负载均衡意义非凡。
1.核心组件
负载均衡组件包括:
- rule: 负载均衡策略
- ping:心跳检测
- ServerList: 服务列表
- ServerListUpdater: 服务列表更新
- ServerListFilter: 服务列表过滤
Spring Cloud Ribbon 是对 Netflix Ribbon的封装。
Spring Cloud Ribbon 默认情况下为Ribbon核心组件提供如下的实现:
2.自定义Ribbon客户端
对个别微服务,我们想替换其个别组件,怎么办?
2.1@RibbonClient
1.使用@RibbonClient 指定替换请求哪些服务的哪些组件。
@Configuration @RibbonClient(name = "user", configuration = UserConfiguration.class) public class UserRibbonConfiguration { } @Configuration protected static class UserConfiguration{ @Bean public IPing ribbonPing() { return new MyPingUrl(); } }
使用MyPingUrl 替换user对应的服务的Ribbon 客户端 中的IPing 组件。
注意: 需要说明的是自定义的类必须加上@Configuration注解且不能包含在@componentscan注解扫描的包中,否则自定义的类将由所有加@ribbonclient注解的地方共享,若用@ComponentScan(或@SpringBootApplication),应该采取措施来避免它被包含到扫描的范围中。
2.1属性配置
2.使用属性配置替换 从1.2.0版本开始,Spring Cloud Netflix支持自定义Ribbon客户端配置 支持配置的属性如下:
- .ribbon.NFLoadBalancerClassName: 配置ILoadBalancer的实现类
- .ribbon.NFLoadBalancerRuleClassName:配置IRule的实现类
- .ribbon.NFLoadBalancerPingClassName: 配置IPing的实现类
- .ribbon.NIWSServerListClassName: 配置ServerList的实现类
- .ribbon.NIWSServerListFilterClassName:配置ServerListFilter的实现类
在这些属性中定义的类优先于使用@RibbonClient()定义的bean和由Spring Cloud Netflix提供的默认值
例如: application.yml.
users: ribbon: NIWSServerListClassName: com.netflix.loadbalancer.ConfigurationBasedServerList NFLoadBalancerRuleClassName: com.netflix.loadbalancer.WeightedResponseTimeRule
替换users服务客户端对应的 ServerList 与LoadBalancerRule 组件
3.自定义所有默认Ribbon
3.1@RibbonClients
当我们想替换所有客户端的某个组件时,@RibbonClient就显的力不从心了。
@RibbonClients注解用于覆盖所有客户端配置。
@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; } }
4.与Eureka一起使用
当与Eureka一同使用时,部分组件被替换:
- DiscoveryEnabledNIWSServerList 替换默认的(ribbonServerList)ConfigurationBasedServerList。DiscoveryEnabledNIWSServerList是由Eureka服务治理维护。
- NIWSDiscoveryPing 替换默认的(IPing )DummyPing。 NIWSDiscoveryPing 也是由Eureka维护的。
- 默认情况下安装的ServerList是一个DomainExtractingServerList(其实这里DomainExtractingServerList是对coveryEnabledNIWSServerList的一个代理)。其目的是使物理元数据可用于负载平衡器,而不使用AWS AMI元数据(这是Netflix依赖的)
- Spring Cloud Ribbon默认使用eureka实例元数据中提供的“zone”信息构建服务器列表,通过设置eureka.instance.metadatamap.zone的值,可以实现跨区域的实例配置
- 如果没有配置区域,则可以使用服务器主机名中的域名作为代理用于区域(前提是设置了标志approximateZoneFromHostname)
- ServerListFilter:服务实例清单过滤机制,默认采用org.springframework.cloud.netflix.ribbon.ZonePreferenceServerListFilter实现,该策略能够优先过滤出与请求调用方处于同区域的服务实例
如果没有其他的区域数据源,则基于客户端配置(与实例配置相反)进行猜测。我们将eureka.client.availabilityZones(从区域名称映射到区域列表),并将实例自己的区域的第一个区域(即eureka.client.region,其默认为“us-east-1”为与本机Netflix的兼容性)。
如何使用呢:
- RestTemplate添加@LoadBalanced注解,启动RestTemplate客户端负载均衡
@LoadBalanced @Bean public RestTemplate restTemplate(){ return new RestTemplate(); }
- 直接使用Ribbon的api来实现负载均衡
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 } }
5.脱离Eureka使用
当我们单独使用Ribbon的时候,可以通过禁止Eureka来使用。
application.yml.
ribbon: eureka: enabled: false 复制代码
6.缓存Ribbon配置
所谓缓存Ribbon配置,其实就是饥饿加载(eager-load)模式。 Ribbon在第一次启动时,因为需要从注册中心获取服务列表。一般创建比较慢,针对这种情况。 可以通过饥饿模式来,加速客户端上下文的创建。
application.yml
ribbon: eager-load: enabled: true clients: client1, client2, client3
参考: