Ribbon 和 Eureka 的集成

Ribbon 是 Netflix 发布的云中间层服务开源项目,其主要功能是提供客户侧软件负载均衡算法,将 Netflix 的中间层服务连接在一起。Eureka 是一个 RESTful 服务,用来定位运行在 AWS 域(Region)中的中间层服务。本文介绍 Eureka 和 Ribbon 的集成,附带 Ribbon 自定义负载均衡算法示例。
        Ribbon 和 Eureka 的集成,其实也就是让 Ribbon 充当 Eureka 架构中的 Application Client 角色。本文示例基于前边相关博客中的 demo 而写。阅读本文最好参考一下《 云中间层服务 - 区域感知负载均衡器 Ribbon 》、《 Eureka 的 Application Client 客户端的运行示例 》。
         Why Eureka need Ribbon?
        Eureka 附带客户端库,为何还要 Ribbon 呢?
         Ribbon 的负载均衡算法、区域感知负载均衡器久经考验,可以直接拿来使用。
         Why Ribbon need Eureka?
        熟悉 Ribbon 的同学都知道,Ribbon 维护了一个服务器列表,如果服务器有宕机现象,Ribbon 能够自行将其剔除;但如果该服务器故障排除,重新启动,或者增加新的负载节点,我们需要手工调用 Ribbon 的接口将其动态添加进 Ribbon 的服务器列表。这样明显不够尽如人意。如何能够在服务节点启动时,自行添加服务列表?—— Eureka。Eureka 提供了 Application Service 客户端的自行注册的功能。此外,Eureka 的缓存机制能够防止大规模宕机带来的灾难性后果。
        下面开始我们的集成。进行以下操作之前,请确保 Eureka Server 已启动,Eureka Application Service 客户端已注册到 Server(参考《 Eureka 的 Application Client 客户端的运行示例 》)。
         1. 加入 ribbon-eureka 依赖包
         http://mvnrepository.com/artifact/com.netflix.ribbon/ribbon-eureka  选择合适的版本下载,作者下载的是  ribbon-eureka-0.3.12.jar
         2. 配置的初始化

        配置文件基本采用《Eureka 的 Application Client 客户端的运行示例》Eureka Application Client 客户端配置。另外增添以下配置项:

  • 启用客户端负载均衡器并将其配置为 DynamicServerListLoadBalancer 或其子类(这个无须在配置中体现,因为这个是 Eureka 和 Ribbon 集成默认为 true 的)。
  • 将 ServerList 配置为 com.netflix.niws.loadbalancer.DiscoveryEnabledNIWSServerList。
  • 配置服务器(负载均衡节点)的刷新频率(可选。默认是为 30 秒)。
  • 为 Eureka 客户端配置服务器的虚拟地址(VIP 地址),并确保这个地址匹配到服务器(Application Service)注册 Eureka Server 时所用到的那个。
        总之就是在《 Eureka 的 Application Client 客户端的运行示例 》基础上添加了以下配置项:
[plain]  view plain  copy
 print ?
  1. myclient.ribbon.NIWSServerListClassName=com.netflix.niws.loadbalancer.DiscoveryEnabledNIWSServerList  
  2.   
  3.   
  4. # refresh every minute   
  5. myclient.ribbon.ServerListRefreshInterval=60000  
  6.   
  7.   
  8. # movieservice is the virtual address that the target server(s) uses to register with Eureka server  
  9. myclient.ribbon.DeploymentContextBasedVipAddresses=movieservice  
  10.         配置文件的初始化仍然采用《Eureka 的 Application Client 客户端的运行示例》中的配置初始化方法:  
  11.         // Register with Eureka  
  12.         DiscoveryManager.getInstance().initComponent(  
  13.                 new MyDataCenterInstanceConfig(),  
  14.                 new DefaultEurekaClientConfig());  
  15.         ApplicationInfoManager.getInstance().setInstanceStatus(  
  16.                 InstanceStatus.UP);  

         3. 自定义负载均衡算法
        负载均衡算法,简单 demo 起见,使用随机算法,就用 ribbon-core 类库里的 com.netflix.loadbalancer.RandomRule 所提供的随机负载算法,拿到侍服主机:
[java]  view plain  copy
 print ?
  1. // get LoadBalancer instance from configuration, properties file  
  2. DynamicServerListLoadBalancer lb = (DynamicServerListLoadBalancer) ClientFactory.getNamedLoadBalancer("myclient");  
  3. // use RandomRule 's RandomRule algorithm to get a random server from lb 's server list  
  4. RandomRule randomRule = new RandomRule();  
  5. Server randomAlgorithmServer = randomRule.choose(lb, null);  
  6. logger.debug("random algorithm server host:" + randomAlgorithmServer.getHost() + ";port:" + randomAlgorithmServer.getPort());  

         4. Application Client 网络请求
        请求代码和《 Eureka 的 Application Client 客户端的运行示例 》中的一般无二,在此不再赘述。
         5. Application Client 关闭时取消注册
        取消代码和《 Eureka 的 Application Client 客户端的运行示例 》中的一般无二,在此不再赘述。
         6. 运行 demo
        新建一个项目(不要和 Application Service 的 demo 跑在同一个项目下),现在我们把完整的 Eureka Application Client 和 Ribbon Client 集成的代码整理一下。
[java]  view plain  copy
 print ?
  1. /* 
  2.  * Copyright 2012 Netflix, Inc. 
  3.  * 
  4.  *    Licensed under the Apache License, Version 2.0 (the "License"); 
  5.  *    you may not use this file except in compliance with the License. 
  6.  *    You may obtain a copy of the License at 
  7.  * 
  8.  *        http://www.apache.org/licenses/LICENSE-2.0 
  9.  * 
  10.  *    Unless required by applicable law or agreed to in writing, software 
  11.  *    distributed under the License is distributed on an "AS IS" BASIS, 
  12.  *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
  13.  *    See the License for the specific language governing permissions and 
  14.  *    limitations under the License. 
  15.  */  
  16.   
  17.   
  18. package com.netflix.eureka;  
  19.   
  20.   
  21. import java.io.BufferedReader;  
  22. import java.io.IOException;  
  23. import java.io.InputStreamReader;  
  24. import java.io.PrintStream;  
  25. import java.net.InetSocketAddress;  
  26. import java.net.Socket;  
  27. import java.util.Date;  
  28. import java.util.Iterator;  
  29. import java.util.List;  
  30.   
  31.   
  32. import org.slf4j.Logger;  
  33. import org.slf4j.LoggerFactory;  
  34.   
  35.   
  36. import com.netflix.appinfo.ApplicationInfoManager;  
  37. import com.netflix.appinfo.InstanceInfo.InstanceStatus;  
  38. import com.netflix.appinfo.MyDataCenterInstanceConfig;  
  39. import com.netflix.client.ClientFactory;  
  40. import com.netflix.discovery.DefaultEurekaClientConfig;  
  41. import com.netflix.discovery.DiscoveryManager;  
  42. import com.netflix.loadbalancer.DynamicServerListLoadBalancer;  
  43. import com.netflix.loadbalancer.RandomRule;  
  44. import com.netflix.loadbalancer.Server;  
  45.   
  46.   
  47. /** 
  48.  * Sample Eureka client that discovers the service using Eureka and sends 
  49.  * requests. 
  50.  * 
  51.  * @author Karthik Ranganathan 
  52.  * 
  53.  */  
  54. public class SampleEurekaRibbonClient {  
  55.     private static final Logger logger = LoggerFactory  
  56.             .getLogger(SampleEurekaRibbonClient.class);  
  57.   
  58.   
  59.     public void sendRequestToServiceUsingEureka() {  
  60.   
  61.   
  62.         // Register with Eureka  
  63.         DiscoveryManager.getInstance().initComponent(  
  64.                 new MyDataCenterInstanceConfig(),  
  65.                 new DefaultEurekaClientConfig());  
  66.         ApplicationInfoManager.getInstance().setInstanceStatus(  
  67.                 InstanceStatus.UP);  
  68.         // get LoadBalancer instance from configuration, properties file  
  69.         DynamicServerListLoadBalancer lb = (DynamicServerListLoadBalancer) ClientFactory.getNamedLoadBalancer("myclient");  
  70.         // show all servers in the list  
  71.         List<Server> list = lb.getServerList(false);  
  72.         Iterator<Server> it = list.iterator();  
  73.         while (it.hasNext()) {  
  74.             Server server = it.next();  
  75.             logger.debug("application service host:" + server.getHost() + ";port=" + server.getPort());  
  76.         }  
  77.         // use RandomRule 's RandomRule algorithm to get a random server from lb 's server list  
  78.         RandomRule randomRule = new RandomRule();  
  79.         Server randomAlgorithmServer = randomRule.choose(lb, null);  
  80.         logger.debug("random algorithm server host:" + randomAlgorithmServer.getHost() + ";port:" + randomAlgorithmServer.getPort());  
  81.         // communicate with the server  
  82.         Socket s = new Socket();  
  83.         try {  
  84.             s.connect(new InetSocketAddress(randomAlgorithmServer.getHost(), randomAlgorithmServer.getPort()));  
  85.         } catch (IOException e) {  
  86.             logger.error("Could not connect to the server :"  
  87.                     + randomAlgorithmServer.getHost() + " at port " + randomAlgorithmServer.getPort());  
  88.         }  
  89.         try {  
  90.             logger.debug("Connected to server. Sending a sample request");  
  91.             PrintStream out = new PrintStream(s.getOutputStream());  
  92.             out.println("Sample request " + new Date());  
  93.             String str = null;  
  94.             logger.debug("Waiting for server response..");  
  95.             BufferedReader rd = new BufferedReader(new InputStreamReader(  
  96.                     s.getInputStream()));  
  97.             str = rd.readLine();  
  98.             if (str != null) {  
  99.                 logger.debug("Received response from server. Communication all fine using Eureka :");  
  100.                 logger.debug("Exiting the client. Demo over..");  
  101.             }  
  102.             rd.close();  
  103.         } catch (IOException e) {  
  104.             e.printStackTrace();  
  105.             logger.error(e.getMessage(), e);  
  106.         }  
  107.         this.unRegisterWithEureka();  
  108.     }  
  109.   
  110.   
  111.     public void unRegisterWithEureka() {  
  112.         // Un register from eureka.  
  113.         DiscoveryManager.getInstance().shutdownComponent();  
  114.     }  
  115.   
  116.   
  117.     public static void main(String[] args) {  
  118.         SampleEurekaRibbonClient sampleEurekaRibbonClient = new SampleEurekaRibbonClient();  
  119.         sampleEurekaRibbonClient.sendRequestToServiceUsingEureka();  
  120.   
  121.   
  122.     }  
  123. }  

        之后是把配置文件、log4j 文件整理一下,运行 SampleEurekaRibbonClient,日志显示 demo 成功。
         参考资料
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

蒙奇·D·路飞-

感谢老板您就是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值