码迷,mamicode.com
首页 > 其他好文 > 详细

ribbon源码之Client

时间:2018-04-08 19:44:54      阅读:672      评论:0      收藏:0      [点我收藏+]

标签:end   ESS   headers   gimp   namespace   color   etl   .net   div   

  客户端模块的核心是提供便于用户操作的请求接口,并且实现了负载均衡功能。客户端模块的核心是IClient接口,定义了客户端网络请求的方法。

public interface IClient<S extends ClientRequest, T extends IResponse> {
    public T execute(S request, IClientConfig requestConfig) throws Exception; 
}

  客户端模块提供了一个客户端工厂类(ClientFactory)用于通过配置文件来创建IClient实例和负载均衡器(ILoadBalancer)实例。

public static synchronized IClient getNamedClient(String name) {//根据配置获取iclient实例,默认使用DefaultClientConfigImpl配置类。
        return getNamedClient(name, DefaultClientConfigImpl.class);
    }
public static synchronized IClient getNamedClient(String name, Class<? extends IClientConfig> configClass) {
...
return createNamedClient(name, configClass);
...
}
public static synchronized IClient createNamedClient(String name, Class<? extends IClientConfig> configClass) throws ClientException {
IClientConfig config = getNamedConfig(name, configClass);//实例化配置类
return registerClientFromProperties(name, config);//通过配置文件创建iclient
}
public static synchronized ILoadBalancer getNamedLoadBalancer(String name) {
return getNamedLoadBalancer(name, DefaultClientConfigImpl.class);
}
public static synchronized ILoadBalancer getNamedLoadBalancer(String name, Class<? extends IClientConfig> configClass) {
...
lb = registerNamedLoadBalancerFromProperties(name, configClass);
...
}
public static synchronized IClient<?, ?> registerClientFromProperties(String restClientName, IClientConfig clientConfig) throws ClientException { 
        IClient<?, ?> client = null;
        ILoadBalancer loadBalancer = null;
        ...
            String clientClassName = (String) clientConfig.getProperty(CommonClientConfigKey.ClientClassName);//通过配置文件获取client的实现类
            client = (IClient<?, ?>) instantiateInstanceWithClientConfig(clientClassName, clientConfig); //通过配置文件创建client实例
            boolean initializeNFLoadBalancer = Boolean.parseBoolean(clientConfig.getProperty(
                    CommonClientConfigKey.InitializeNFLoadBalancer, DefaultClientConfigImpl.DEFAULT_ENABLE_LOADBALANCER).toString());
            if (initializeNFLoadBalancer) {//如果需要初始化负载均衡器,则通过配置文件创建一个负载均衡器
                loadBalancer  = registerNamedLoadBalancerFromclientConfig(restClientName, clientConfig);
            }
            if (client instanceof AbstractLoadBalancerAwareClient) {//如果client实现AbstractLoadBalancerAwareClient,则注入负载均衡器
                ((AbstractLoadBalancerAwareClient) client).setLoadBalancer(loadBalancer);
            }
        ...return client;
    }
public static ILoadBalancer registerNamedLoadBalancerFromclientConfig(String name, IClientConfig clientConfig) throws ClientException {
...
ILoadBalancer lb = null;
...
String loadBalancerClassName = (String) clientConfig.getProperty(CommonClientConfigKey.NFLoadBalancerClassName);//
lb = (ILoadBalancer) ClientFactory.instantiateInstanceWithClientConfig(loadBalancerClassName, clientConfig);
...
return lb;
...
}
//初始化指定的class类
public static Object instantiateInstanceWithClientConfig(String className, IClientConfig clientConfig)
          throws InstantiationException, IllegalAccessException, ClassNotFoundException {
Class clazz = Class.forName(className);
if (IClientConfigAware.class.isAssignableFrom(clazz)) {
IClientConfigAware obj = (IClientConfigAware) clazz.newInstance();
obj.initWithNiwsConfig(clientConfig);
return obj;
} else {
try {
if (clazz.getConstructor(IClientConfig.class) != null) {
return clazz.getConstructor(IClientConfig.class).newInstance(clientConfig);
}
} catch (Throwable e) { // NOPMD
}
}
return clazz.newInstance();
}

  使用客户端工厂类(ClientFactory)涉及的配置:

属性 实现 默认值
clientname.ribbon.ClientClassName client使用的IClient实现类 com.netflix.niws.client.http.RestClient
clientname.ribbon.InitializeNFLoadBalancer 是否初始化负载均衡器 true
clientname.ribbon.NFLoadBalancerClassName 负载均衡器的实现类 com.netflix.loadbalancer.ZoneAwareLoadBalancer

 

 HttpRequest

  用于http请求,内部定义了http请求的各个内容,并且使用了builder模式。

public class HttpRequest extends ClientRequest {protected CaseInsensitiveMultiMap httpHeaders = new CaseInsensitiveMultiMap();//head参数
    protected Multimap<String, String> queryParams = ArrayListMultimap.create();//query参数
    private Object entity;//消息体
    protected Verb verb;//http请求的method:post get head delete等。默认get
}

 

类图

技术分享图片

 

配置管理

  用于管理ribbon配置,配置主要有三个部分:配置管理器客户端(IClientConfig),配置管理器工场(ClientConfigFactory),配置key对象(IClientConfigKey)。IClientConfig定义了获取配置的方法,ClientConfigFactory是IClientConfig的工厂类,子类DefaultClientConfigFactory创建DefaultClientConfigImpl配置管理器。IClientConfigKey为配置的key对象,本质上内部是一个string类型字段。IClientConfig也实现了builder模式,也可以通过builder方式进行初始化。

  每个DefaultClientConfigImpl获取的对应配置项格式为:<clientName>.<nameSpace>.<propertyName>,如果IClientConfig没有clientName,则对应格式为:<nameSpace>.<propertyName>。 默认通过Archauis获取配置信息,如果没有配置文件,ribbon也为各个配置项设置了默认值。

public Object getProperty(IClientConfigKey key){
        String propName = key.key();
        Object value = getProperty(propName);
        return value;
    }
protected Object getProperty(String key) {
        if (enableDynamicProperties) {
            String dynamicValue = null;
            DynamicStringProperty dynamicProperty = dynamicProperties.get(key);
            if (dynamicProperty != null) {
                dynamicValue = dynamicProperty.get();
            }
            if (dynamicValue == null) {
                dynamicValue = DynamicProperty.getInstance(getConfigKey(key)).getString();
                if (dynamicValue == null) {
                    dynamicValue = DynamicProperty.getInstance(getDefaultPropName(key)).getString();
                }
            }
            if (dynamicValue != null) {
                return dynamicValue;
            }
        }
        return properties.get(key);
    }

类图

技术分享图片

 

ribbon源码之Client

标签:end   ESS   headers   gimp   namespace   color   etl   .net   div   

原文地址:https://www.cnblogs.com/zhangwanhua/p/8328283.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!