yangyang12138

导航

ribbon

1.概述

  ribbon是一个负载均衡的抽象管理层,主要完成负载均衡的策略管理,规则管理和服务接口管理,资源管理,服务接口在ribbon中是一个抽象接口,在ribbon-eureka中有对应的实现。

2.功能

  负载均衡最顶层接口。  

/*
*
* Copyright 2013 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.loadbalancer;

import java.util.List;

/**
 * Interface that defines the operations for a software loadbalancer. A typical
 * loadbalancer minimally need a set of servers to loadbalance for, a method to
 * mark a particular server to be out of rotation and a call that will choose a
 * server from the existing list of server.
 * 
 * @author stonse
 * 
 */
public interface ILoadBalancer {

    /**
     * Initial list of servers.
     * This API also serves to add additional ones at a later time
     * The same logical server (host:port) could essentially be added multiple times
     * (helpful in cases where you want to give more "weightage" perhaps ..)
     * 
     * @param newServers new servers to add
     */
    public void addServers(List<Server> newServers);
    
    /**
     * Choose a server from load balancer.
     * 
     * @param key An object that the load balancer may use to determine which server to return. null if 
     *         the load balancer does not use this parameter.
     * @return server chosen
     */
    public Server chooseServer(Object key);
    
    /**
     * To be called by the clients of the load balancer to notify that a Server is down
     * else, the LB will think its still Alive until the next Ping cycle - potentially
     * (assuming that the LB Impl does a ping)
     * 
     * @param server Server to mark as down
     */
    public void markServerDown(Server server);
    
    /**
     * @deprecated 2016-01-20 This method is deprecated in favor of the
     * cleaner {@link #getReachableServers} (equivalent to availableOnly=true)
     * and {@link #getAllServers} API (equivalent to availableOnly=false).
     *
     * Get the current list of servers.
     *
     * @param availableOnly if true, only live and available servers should be returned
     */
    @Deprecated
    public List<Server> getServerList(boolean availableOnly);

    /**
     * @return Only the servers that are up and reachable.
     */
    public List<Server> getReachableServers();

    /**
     * @return All known servers, both reachable and unreachable.
     */
    public List<Server> getAllServers();
}
View Code

  只有服务的管理和接口的选择,IRule定义了选择方式, 具体的实现类定义了具体的选择方式如随机选择,权重选择等。

package com.netflix.loadbalancer;

/**
 * Interface that defines a "Rule" for a LoadBalancer. A Rule can be thought of
 * as a Strategy for loadbalacing. Well known loadbalancing strategies include
 * Round Robin, Response Time based etc.
 * 
 * @author stonse
 * 
 */
public interface IRule{
    /*
     * choose one alive server from lb.allServers or
     * lb.upServers according to key
     * 
     * @return choosen Server object. NULL is returned if none
     *  server is available 
     */

    public Server choose(Object key);
    
    public void setLoadBalancer(ILoadBalancer lb);
    
    public ILoadBalancer getLoadBalancer();    
}
View Code

  另外ribbon提供了一套将http接口以资源的形式进行管理的方式。

/*
 * Copyright 2014 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.ribbon;

import com.netflix.client.config.ClientConfigFactory;
import com.netflix.client.config.IClientConfig;
import com.netflix.client.config.IClientConfigKey;
import com.netflix.hystrix.HystrixObservableCommand;
import com.netflix.ribbon.hystrix.FallbackHandler;

public abstract class ResourceGroup<T extends RequestTemplate<?, ?>> {
    protected final String name;
    protected final IClientConfig clientConfig;
    protected final ClientConfigFactory configFactory;
    protected final RibbonTransportFactory transportFactory;

    public static abstract class GroupBuilder<T extends ResourceGroup> {
        public abstract T build();

        public abstract GroupBuilder withClientOptions(ClientOptions options);
    }

    public static abstract class TemplateBuilder<S, R, T extends RequestTemplate<S, R>> {
        public abstract TemplateBuilder withFallbackProvider(FallbackHandler<S> fallbackProvider);

        public abstract TemplateBuilder withResponseValidator(ResponseValidator<R> transformer);

        /**
         * Calling this method will enable both Hystrix request cache and supplied external cache providers
         * on the supplied cache key. Caller can explicitly disable Hystrix request cache by calling
         * {@link #withHystrixProperties(com.netflix.hystrix.HystrixObservableCommand.Setter)}
         *
         * @param cacheKeyTemplate
         * @return
         */
        public abstract TemplateBuilder withRequestCacheKey(String cacheKeyTemplate);

        public abstract TemplateBuilder withCacheProvider(String cacheKeyTemplate, CacheProvider<S> cacheProvider);

        public abstract TemplateBuilder withHystrixProperties(HystrixObservableCommand.Setter setter);

        public abstract T build();
    }

    protected ResourceGroup(String name) {
        this(name, ClientOptions.create(), ClientConfigFactory.DEFAULT, RibbonTransportFactory.DEFAULT);
    }

    protected ResourceGroup(String name, ClientOptions options, ClientConfigFactory configFactory, RibbonTransportFactory transportFactory) {
        this.name = name;
        clientConfig = configFactory.newConfig();
        clientConfig.loadProperties(name);
        if (options != null) {
            for (IClientConfigKey key: options.getOptions().keySet()) {
                clientConfig.set(key, options.getOptions().get(key));
            }
        }
        this.configFactory = configFactory;
        this.transportFactory = transportFactory;
    }

    protected final IClientConfig getClientConfig() {
        return clientConfig;
    }

    public final String name() {
        return name;
    }
    
    public abstract <S> TemplateBuilder<S, ?, ?> newTemplateBuilder(String name, Class<? extends S> classType);
}
View Code

3.eureka上实现负载均衡

  要在eureka上实现负载均衡执行在eureka的instanceInfo的基础上实现ribbon的Server接口。

/*
*
* Copyright 2013 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.niws.loadbalancer;


import com.netflix.appinfo.InstanceInfo;
import com.netflix.appinfo.InstanceInfo.PortType;
import com.netflix.loadbalancer.Server;

/**
 * Servers that were obtained via Discovery and hence contain
 * meta data in the form of InstanceInfo
 * @author stonse
 *
 */
@edu.umd.cs.findbugs.annotations.SuppressWarnings(value = "EQ_DOESNT_OVERRIDE_EQUALS")
public class DiscoveryEnabledServer extends Server{

    private final InstanceInfo instanceInfo;
    private final MetaInfo serviceInfo;

    public DiscoveryEnabledServer(final InstanceInfo instanceInfo, boolean useSecurePort) {
        this(instanceInfo, useSecurePort, false);
    }

    public DiscoveryEnabledServer(final InstanceInfo instanceInfo, boolean useSecurePort, boolean useIpAddr) {
        super(useIpAddr ? instanceInfo.getIPAddr() : instanceInfo.getHostName(), instanceInfo.getPort());
        if(useSecurePort && instanceInfo.isPortEnabled(PortType.SECURE))
            super.setPort(instanceInfo.getSecurePort());
        this.instanceInfo = instanceInfo;
        this.serviceInfo = new MetaInfo() {
            @Override
            public String getAppName() {
                return instanceInfo.getAppName();
            }

            @Override
            public String getServerGroup() {
                return instanceInfo.getASGName();
            }

            @Override
            public String getServiceIdForDiscovery() {
                return instanceInfo.getVIPAddress();
            }

            @Override
            public String getInstanceId() {
                return instanceInfo.getId();
            }
        };
    }
    
    public InstanceInfo getInstanceInfo() {
        return instanceInfo;
    }

    @Override
    public MetaInfo getMetaInfo() {
        return serviceInfo;
    }
}

 

posted on 2020-06-24 00:33  杨杨09265  阅读(105)  评论(0编辑  收藏  举报