Ribbon 和 Eureka 的集成_JAVA_编程开发_程序员俱乐部

中国优秀的程序员网站程序员频道CXYCLUB技术地图
热搜:
更多>>
 
您所在的位置: 程序员俱乐部 > 编程开发 > JAVA > Ribbon 和 Eureka 的集成

Ribbon 和 Eureka 的集成

 2016/6/11 5:30:28  hoochiang  程序员俱乐部  我要评论(0)
  • 摘要:Ribbon是Netflix发布的云中间层服务开源项目,其主要功能是提供客户侧软件负载均衡算法,将Netflix的中间层服务连接在一起。Eureka是一个RESTful服务,用来定位运行在AWS域(Region)中的中间层服务。本文介绍Eureka和Ribbon的集成,附带Ribbon自定义负载均衡算法示例。Ribbon和Eureka的集成,其实也就是让Ribbon充当Eureka架构中的ApplicationClient角色。本文示例基于前边相关博客中的demo而写。阅读本文最好参考一下
  • 标签:

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?

??? myclient.ribbon.NIWSServerListClassName=com.netflix.niws.loadbalancer.DiscoveryEnabledNIWSServerList?
?????
?????
??? # refresh every minute??
??? myclient.ribbon.ServerListRefreshInterval=60000?
?????
?????
??? # movieservice is the virtual address that the target server(s) uses to register with Eureka server?
??? myclient.ribbon.DeploymentContextBasedVipAddresses=movieservice?
??????????? 配置文件的初始化仍然采用《Eureka 的 Application Client 客户端的运行示例》中的配置初始化方法:?
??????????? // Register with Eureka?
??????????? DiscoveryManager.getInstance().initComponent(?
??????????????????? new MyDataCenterInstanceConfig(),?
??????????????????? new DefaultEurekaClientConfig());?
??????????? ApplicationInfoManager.getInstance().setInstanceStatus(?
??????????????????? InstanceStatus.UP);?


??????? 3. 自定义负载均衡算法
??????? 负载均衡算法,简单 demo 起见,使用随机算法,就用 ribbon-core 类库里的 com.netflix.loadbalancer.RandomRule 所提供的随机负载算法,拿到侍服主机:
[java] view plain copy print?

??? // get LoadBalancer instance from configuration, properties file?
??? DynamicServerListLoadBalancer lb = (DynamicServerListLoadBalancer) ClientFactory.getNamedLoadBalancer("myclient");?
??? // use RandomRule 's RandomRule algorithm to get a random server from lb 's server list?
??? RandomRule randomRule = new RandomRule();?
??? Server randomAlgorithmServer = randomRule.choose(lb, null);?
??? 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?

??? /*
???? * Copyright 2012 Netflix, Inc.
???? *
???? *??? Licensed under the Apache License, Version 2.0 (the "License");
???? *??? you may not use this file except in compliance with the License.
???? *??? You may obtain a copy of the License at
???? *
???? *??????? http://www.apache.org/licenses/LICENSE-2.0
???? *
???? *??? Unless required by applicable law or agreed to in writing, software
???? *??? distributed under the License is distributed on an "AS IS" BASIS,
???? *??? WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
???? *??? See the License for the specific language governing permissions and
???? *??? limitations under the License.
???? */?
?????
?????
??? package com.netflix.eureka;?
?????
?????
??? import java.io.BufferedReader;?
??? import java.io.IOException;?
??? import java.io.InputStreamReader;?
??? import java.io.PrintStream;?
??? import java.net.InetSocketAddress;?
??? import java.net.Socket;?
??? import java.util.Date;?
??? import java.util.Iterator;?
??? import java.util.List;?
?????
?????
??? import org.slf4j.Logger;?
??? import org.slf4j.LoggerFactory;?
?????
?????
??? import com.netflix.appinfo.ApplicationInfoManager;?
??? import com.netflix.appinfo.InstanceInfo.InstanceStatus;?
??? import com.netflix.appinfo.MyDataCenterInstanceConfig;?
??? import com.netflix.client.ClientFactory;?
??? import com.netflix.discovery.DefaultEurekaClientConfig;?
??? import com.netflix.discovery.DiscoveryManager;?
??? import com.netflix.loadbalancer.DynamicServerListLoadBalancer;?
??? import com.netflix.loadbalancer.RandomRule;?
??? import com.netflix.loadbalancer.Server;?
?????
?????
??? /**
???? * Sample Eureka client that discovers the service using Eureka and sends
???? * requests.
???? *
???? * @author Karthik Ranganathan
???? *
???? */?
??? public class SampleEurekaRibbonClient {?
??????? private static final Logger logger = LoggerFactory?
??????????????? .getLogger(SampleEurekaRibbonClient.class);?
?????
?????
??????? public void sendRequestToServiceUsingEureka() {?
?????
?????
??????????? // Register with Eureka?
??????????? DiscoveryManager.getInstance().initComponent(?
??????????????????? new MyDataCenterInstanceConfig(),?
??????????????????? new DefaultEurekaClientConfig());?
??????????? ApplicationInfoManager.getInstance().setInstanceStatus(?
??????????????????? InstanceStatus.UP);?
??????????? // get LoadBalancer instance from configuration, properties file?
??????????? DynamicServerListLoadBalancer lb = (DynamicServerListLoadBalancer) ClientFactory.getNamedLoadBalancer("myclient");?
??????????? // show all servers in the list?
??????????? List<Server> list = lb.getServerList(false);?
??????????? Iterator<Server> it = list.iterator();?
??????????? while (it.hasNext()) {?
??????????????? Server server = it.next();?
??????????????? logger.debug("application service host:" + server.getHost() + ";port=" + server.getPort());?
??????????? }?
??????????? // use RandomRule 's RandomRule algorithm to get a random server from lb 's server list?
??????????? RandomRule randomRule = new RandomRule();?
??????????? Server randomAlgorithmServer = randomRule.choose(lb, null);?
??????????? logger.debug("random algorithm server host:" + randomAlgorithmServer.getHost() + ";port:" + randomAlgorithmServer.getPort());?
??????????? // communicate with the server?
??????????? Socket s = new Socket();?
??????????? try {?
??????????????? s.connect(new InetSocketAddress(randomAlgorithmServer.getHost(), randomAlgorithmServer.getPort()));?
??????????? } catch (IOException e) {?
??????????????? logger.error("Could not connect to the server :"?
??????????????????????? + randomAlgorithmServer.getHost() + " at port " + randomAlgorithmServer.getPort());?
??????????? }?
??????????? try {?
??????????????? logger.debug("Connected to server. Sending a sample request");?
??????????????? PrintStream out = new PrintStream(s.getOutputStream());?
??????????????? out.println("Sample request " + new Date());?
??????????????? String str = null;?
??????????????? logger.debug("Waiting for server response..");?
??????????????? BufferedReader rd = new BufferedReader(new InputStreamReader(?
??????????????????????? s.getInputStream()));?
??????????????? str = rd.readLine();?
??????????????? if (str != null) {?
??????????????????? logger.debug("Received response from server. Communication all fine using Eureka :");?
??????????????????? logger.debug("Exiting the client. Demo over..");?
??????????????? }?
??????????????? rd.close();?
??????????? } catch (IOException e) {?
??????????????? e.printStackTrace();?
??????????????? logger.error(e.getMessage(), e);?
??????????? }?
??????????? this.unRegisterWithEureka();?
??????? }?
?????
?????
??????? public void unRegisterWithEureka() {?
??????????? // Un register from eureka.?
??????????? DiscoveryManager.getInstance().shutdownComponent();?
??????? }?
?????
?????
??????? public static void main(String[] args) {?
??????????? SampleEurekaRibbonClient sampleEurekaRibbonClient = new SampleEurekaRibbonClient();?
??????????? sampleEurekaRibbonClient.sendRequestToServiceUsingEureka();?
?????
?????
??????? }?
??? }?


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

??? https://github.com/Netflix/ribbon/wiki/Programmers-Guide

本文来源:http://blog.csdn.net/defonds/article/details/38016301

  • 相关文章
发表评论
用户名: 匿名