zoukankan      html  css  js  c++  java
  • 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 成功。


            參考资料

    版权声明:本文博客原创文章。博客,未经同意,不得转载。

  • 相关阅读:
    opstack 笔记 (一) 概念
    Redis学习汇总
    MongoDB添加删除节点
    Redis主从及Cluster区别及注意事项
    叶问18
    Redis慢日志取出来
    Redis的AOF重写脚本
    使用Python比较MySQL数据库中两个数据库的表结构--转载
    关于InnoDB存储引擎 text blob 大字段的存储和优化
    MongoDB进阶之路:不仅仅是技术研究,还有优化和最佳实践--转载
  • 原文地址:https://www.cnblogs.com/blfshiye/p/4630839.html
Copyright © 2011-2022 走看看