Ribbon 和 Eureka 积分

本文介绍了如何将Ribbon与Eureka集成,并演示了如何自定义负载均衡算法,包括引入依赖、配置初始化、实现自定义算法以及应用客户端网络请求的全过程。
        Ribbon 这是 Netflix 云服务的中间层宣布开放源代码项目,它的主要功能是提供客户机端软件的负载均衡算法,将 Netflix 中间层服务一起。

Eureka 是 RESTful 服务。用于定位执行 AWS 域(Region)中的中间层服务。本文介绍 Eureka 和 Ribbon 的集成,附带 Ribbon 自己定义负载均衡算法演示样例。
        Ribbon 和 Eureka 的集成,事实上也就是让 Ribbon 充当 Eureka 架构中的 Application Client 角色。本文演示样例基于前边相关博客中的 demo 而写。阅读本文最好參考一下《云中间层服务 - 区域感知负载均衡器 Ribbon》、《Eureka 的 Application Client client的执行演示样例》。


        Why Eureka need Ribbon?
        Eureka 附带client库,为何还要 Ribbon 呢?
        Ribbon 的负载均衡算法、区域感知负载均衡器久经考验,可以直接拿来使用。
        Why Ribbon need Eureka?
        熟悉 Ribbon 的同学都知道,Ribbon 维护了一个服务器列表,假设服务器有宕机现象,Ribbon 可以自行将其剔除;但假设该服务器故障排除,又一次启动,或者添加新的负载节点。我们须要手工调用 Ribbon 的接口将其动态加入进 Ribbon 的服务器列表。这样明显不够尽如人意。怎样可以在服务节点启动时,自行加入服务列表?—— Eureka。Eureka 提供了 Application Service client的自行注冊的功能。此外。Eureka 的缓存机制可以防止大规模宕机带来的灾难性后果。


        下面開始我们的集成。进行下面操作之前,请确保 Eureka Server 已启动,Eureka Application Service client已注冊到 Server(參考《Eureka 的 Application Client client的执行演示样例》)。
        1. 加入 ribbon-eureka 依赖包
        http://mvnrepository.com/artifact/com.netflix.ribbon/ribbon-eureka 选择合适的版本号下载,作者下载的是 ribbon-eureka-0.3.12.jar
        2. 配置的初始化

        配置文件基本採用《Eureka 的 Application Client client的执行演示样例》Eureka Application Client client配置。另外增添下面配置项:

  • 启用client负载均衡器并将其配置为 DynamicServerListLoadBalancer 或其子类(这个无须在配置中体现。由于这个是 Eureka 和 Ribbon 集成默觉得 true 的)。

  • 将 ServerList 配置为 com.netflix.niws.loadbalancer.DiscoveryEnabledNIWSServerList。
  • 配置服务器(负载均衡节点)的刷新频率(可选。默认是为 30 秒)。

  • 为 Eureka client配置服务器的虚拟地址(VIP 地址),并确保这个地址匹配到服务器(Application Service)注冊 Eureka Server 时所用到的那个。
        总之就是在《 Eureka 的 Application Client client的执行演示样例》基础上加入了下面配置项:
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 client的执行演示样例》中的配置初始化方法:
		// Register with Eureka
		DiscoveryManager.getInstance().initComponent(
				new MyDataCenterInstanceConfig(),
				new DefaultEurekaClientConfig());
		ApplicationInfoManager.getInstance().setInstanceStatus(
				InstanceStatus.UP);

        3. 自己定义负载均衡算法
        负载均衡算法,简单 demo 起见,使用随机算法。就用 ribbon-core 类库里的 com.netflix.loadbalancer.RandomRule 所提供的随机负载算法。拿到侍服主机:
		// 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 client的执行演示样例》中的一般无二,在此不再赘述。


        5. Application Client 关闭时取消注冊
        取消代码和《Eureka 的 Application Client client的执行演示样例》中的一般无二,在此不再赘述。
        6. 执行 demo
        新建一个项目(不要和 Application Service 的 demo 跑在同一个项目下)。如今我们把完整的 Eureka Application Client 和 Ribbon Client 集成的代码整理一下。


/*
 * 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://www.cnblogs.com/blfshiye/p/4630839.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值