云中间层服务 - 区域感知负载均衡器 Ribbon
Ribbon 简介
Ribbon 是 Netflix 发布的云中间层服务开源项目,其主要功能是提供客户侧软件负载均衡算法,将 Netflix 的中间层服务连接在一起。
Why Ribbon?
Ribbon 的区域感知负载均衡器的功能久经考验。区域感知负载均衡器内置电路跳闸逻辑,可被配置基于区域同源关系(Zone Affinity,也就是更倾向于选择发出调用的服务所在的托管区域内,这样可用降低延迟,节省成本)选择目标服务实例。它监控每个区域中运行的实例的运维行为,而且能够实时快速丢弃一整个区域。在面对整个区域的故障时,这帮我们提升了弹性。简单的来说,在配置文件中列出LB后面所有的机器,ribbon 会自动帮你去连这些机器(基于某种规则,如随机连接、轮流连接,基于响应时间等等)。我们很方便地使用 Ribbon 实现自定义负载均衡算法。
Ribbon 的其他一些特性
![云中间层服务 - 区域感知负载均衡器 Ribbon 云中间层服务 - 区域感知负载均衡器 Ribbon](/default/index/img?u=aHR0cHM6Ly9waWFuc2hlbi5jb20vaW1hZ2VzLzQwNi8zY2E5Y2QyNzgxNjk0NGUyYjFmYjgzMWNkYzFkYjI1Ni5wbmc=)
Ribbon 时序图
![云中间层服务 - 区域感知负载均衡器 Ribbon 云中间层服务 - 区域感知负载均衡器 Ribbon](/default/index/img?u=aHR0cHM6Ly9waWFuc2hlbi5jb20vaW1hZ2VzLzk5OS9iOTEzY2NlYWEyZDJiODJmMmY1MTVlMjlmNDQ2ZGY5Zi5KUEVH)
如何使用 Ribbon?
Ribbon 提供了框架来支持通用的 LB 机制,同时也提供了对 Netflix eureka 框架的支持。接下来我们来看一下如何在 Java 项目里使用 Ribbon。
配置文件(sample-client.properties)
每个条目的格式是为
<clientName>.<nameSpace>.<propertyName>=<value>
clientName 将被接下来的工厂用于创建客户端。nameSpace 是可配置的,默认是 "ribbon"。常用属性名可以从 CommonClientConfigKey 获取。
这些属性也可以被定义作系统属性进行获取,也可以以 Archaius 加载的任何属性资源进行获取。
Java 代码测试
代码解释:
关于 Ribbon 客户端使用的小 demo(包括 LB 调用、动态调整负载均衡节点)请参考博客《Ribbon 和 wowza 的集成开发》。
参考资料
Ribbon 是 Netflix 发布的云中间层服务开源项目,其主要功能是提供客户侧软件负载均衡算法,将 Netflix 的中间层服务连接在一起。
Why Ribbon?
Ribbon 的区域感知负载均衡器的功能久经考验。区域感知负载均衡器内置电路跳闸逻辑,可被配置基于区域同源关系(Zone Affinity,也就是更倾向于选择发出调用的服务所在的托管区域内,这样可用降低延迟,节省成本)选择目标服务实例。它监控每个区域中运行的实例的运维行为,而且能够实时快速丢弃一整个区域。在面对整个区域的故障时,这帮我们提升了弹性。简单的来说,在配置文件中列出LB后面所有的机器,ribbon 会自动帮你去连这些机器(基于某种规则,如随机连接、轮流连接,基于响应时间等等)。我们很方便地使用 Ribbon 实现自定义负载均衡算法。
Ribbon 的其他一些特性
- 发现服务,比如需要增加一些机器,可以实现 Ribbon 的一个接口将这个机器加到列表里(请参考《Ribbon 和 wowza 的集成开发》的动态修改负载节点案例);
- 对 Cloud 平台的支持:比如对 AWS 来说,有参数支持只返回同一个 zone 的服务器地址,这样避免跨 zone 调用所引起的网络延时;
- 故障恢复能力:可以将一些不可用的服务器剔除。
Ribbon 时序图
如何使用 Ribbon?
Ribbon 提供了框架来支持通用的 LB 机制,同时也提供了对 Netflix eureka 框架的支持。接下来我们来看一下如何在 Java 项目里使用 Ribbon。
配置文件(sample-client.properties)
# Max number of retries on the same server (excluding the first try)sample-client.ribbon.MaxAutoRetries=1# Max number of next servers to retry (excluding the first server)sample-client.ribbon.MaxAutoRetriesNextServer=1# Whether all operations can be retried for this clientsample-client.ribbon.OkToRetryOnAllOperations=true# Interval to refresh the server list from the sourcesample-client.ribbon.ServerListRefreshInterval=2000# Connect timeout used by Apache HttpClientsample-client.ribbon.ConnectTimeout=3000# Read timeout used by Apache HttpClientsample-client.ribbon.ReadTimeout=3000# Initial list of servers, can be changed via Archaius dynamic property at runtimesample-client.ribbon.listOfServers=www.microsoft.com:80,www.yahoo.com:80,www.google.com:80
每个条目的格式是为
<clientName>.<nameSpace>.<propertyName>=<value>
clientName 将被接下来的工厂用于创建客户端。nameSpace 是可配置的,默认是 "ribbon"。常用属性名可以从 CommonClientConfigKey 获取。
这些属性也可以被定义作系统属性进行获取,也可以以 Archaius 加载的任何属性资源进行获取。
Java 代码测试
public static void main(String[] args) throws Exception { ConfigurationManager.loadPropertiesFromResources("sample-client.properties"); // 1 System.out.println(ConfigurationManager.getConfigInstance().getProperty("sample-client.ribbon.listOfServers")); RestClient client = (RestClient) ClientFactory.getNamedClient("sample-client"); // 2 HttpClientRequest request = HttpClientRequest.newBuilder().setUri(new URI("/")).build(); // 3 for (int i = 0; i < 20; i++) { HttpClientResponse response = client.executeWithLoadBalancer(request); // 4 System.out.println("Status code for " + response.getRequestedURI() + " :" + response.getStatus()); } ZoneAwareLoadBalancer lb = (ZoneAwareLoadBalancer) client.getLoadBalancer(); System.out.println(lb.getLoadBalancerStats()); ConfigurationManager.getConfigInstance().setProperty( "sample-client.ribbon.listOfServers", "www.linkedin.com:80,www.google.com:80"); // 5 System.out.println("changing servers ..."); Thread.sleep(3000); // 6 for (int i = 0; i < 20; i++) { HttpClientResponse response = client.executeWithLoadBalancer(request); System.out.println("Status code for " + response.getRequestedURI() + " : " + response.getStatus()); response.releaseResources(); } System.out.println(lb.getLoadBalancerStats()); // 7}
代码解释:
- 使用 Archaius ConfigurationManager 加载属性;
- 使用 ClientFactory 创建客户端和负载均衡器;
- 使用 builder 构建 http 请求。注意我们只支持 URI 的 "/" 部分的路径,一旦服务器被负载均衡器选中,会由客户端计算出完整的 URI;
- 调用 API client.executeWithLoadBalancer(),不是 exeucte() API;
- 动态修正配置中的服务器池;
- 等待服务器列表刷新(配置文件中定义的刷新间隔是为 2 秒钟);
- 打印出负载均衡器记录的服务器统计信息。
关于 Ribbon 客户端使用的小 demo(包括 LB 调用、动态调整负载均衡节点)请参考博客《Ribbon 和 wowza 的集成开发》。
参考资料
再分享一下我老师大神的人工智能教程吧。零基础!通俗易懂!风趣幽默!还带黄段子!希望你也加入到我们人工智能的队伍中来!https://blog.csdn.net/jiangjunshow