Ribbon是什么?
学而时习之,不亦说乎!
--《论语》
Ribbon使用版本2.2.2
Ribbon是什么?
开始接触Ribbon的时候,网上以及很多书上都说Ribbon是一个负载均衡的工具,提供各种负载均衡算法。
但是分析完源码后,在我的理解里,Ribbon是一个http客户端,它具备了负载均衡,失败重试,ping等功能。
比如httpclient就是一个http客户端,它就是用来发送http请求的,但是Ribbon在httpclient上做了更多的封装,满足更好的使用,当然,也可以使用其他的http客户端。
所以,Ribbon并不是很多人说的负载均衡工具,而是一个具有负载均衡等功能的http客户端。
即:Ribbon是http客户端。
示例
package org.crazyit.cloud;
import com.netflix.client.ClientFactory;
import com.netflix.client.IClient;
import com.netflix.client.config.DefaultClientConfigImpl;
import com.netflix.client.config.IClientConfig;
import com.netflix.client.config.IClientConfigKey;
import com.netflix.client.http.HttpRequest;
import com.netflix.client.http.HttpRequest.Verb;
import com.netflix.client.http.HttpResponse;
import com.netflix.config.ConfigurationManager;
import com.netflix.loadbalancer.ILoadBalancer;
import com.netflix.loadbalancer.Server;
import com.netflix.niws.client.http.RestClient;
/**
*
* @author zby
* @date 2019年1月23日
* @Description ↓↑←→↘↙↖↗↔
*/
@SuppressWarnings("all")
public class RibbonMain {
public static final String DELIMITER = ".";
public static final String DEFAULT = "default";
public static final String CUSTOM = "custom";
public static void main(String[] args) throws Exception {
// 创建指定名称的客户端配置,会使用默认配置进行初始化,然后使用archaius读取自定义的配置
// IClientConfig iClientConfig = ClientFactory.getNamedConfig("default");↓
IClientConfig defaltClientConfig = ClientFactory.getNamedConfig(DEFAULT, DefaultClientConfigImpl.class);
// 使用archaius设置自定义配置,配置结构为:name+namespace+key。name由我们指定,namespace是固定的,Ribbon的namespace就是ribbon,key是配置的名称
ConfigurationManager.getConfigInstance().setProperty(getPropertyKey(CUSTOM, IClientConfigKey.Keys.ListOfServers),
"http://www.spring.io,http://www.apache.org");
ConfigurationManager.getConfigInstance().setProperty(getPropertyKey(CUSTOM, IClientConfigKey.Keys.MaxAutoRetriesNextServer), 0);
// ConfigurationManager.getConfigInstance().setProperty(getPropertyKey(CUSTOM, IClientConfigKey.Keys.ClientClassName),
// "com.netflix.client.IClient子类全路径");
// ConfigurationManager.getConfigInstance().setProperty(getPropertyKey(CUSTOM, IClientConfigKey.Keys.NIWSServerListClassName),
// "com.netflix.loadbalancer.ServerList子类全路径");
// ConfigurationManager.getConfigInstance().setProperty(getPropertyKey(CUSTOM, IClientConfigKey.Keys.NFLoadBalancerClassName),
// "com.netflix.loadbalancer.ILoadBalancer子类全路径");
// ConfigurationManager.getConfigInstance().setProperty(getPropertyKey(CUSTOM, IClientConfigKey.Keys.NFLoadBalancerPingClassName),
// "com.netflix.loadbalancer.IPing子类全路径");
// ConfigurationManager.getConfigInstance().setProperty(getPropertyKey(CUSTOM, IClientConfigKey.Keys.NFLoadBalancerRuleClassName),
// "com.netflix.loadbalancer.IRule子类全路径");
IClientConfig customClientConfig = ClientFactory.getNamedConfig(CUSTOM, DefaultClientConfigImpl.class);
printAllRibbonConfig(defaltClientConfig, customClientConfig);
// 默认配置
// ClientClassName=com.netflix.niws.client.http.RestClient
// NIWSServerListClassName=com.netflix.loadbalancer.ConfigurationBasedServerList
// NFLoadBalancerClassName=com.netflix.loadbalancer.ZoneAwareLoadBalancer
// NFLoadBalancerPingClassName=com.netflix.loadbalancer.DummyPing
// NFLoadBalancerRuleClassName=com.netflix.loadbalancer.AvailabilityFilteringRule
// IClient iClient = ClientFactory.getNamedClient("zby");↓
IClient iClient = ClientFactory.getNamedClient(CUSTOM, DefaultClientConfigImpl.class);
RestClient restClient = (RestClient) iClient;
HttpRequest httpRequest = HttpRequest.newBuilder().uri("/").verb(Verb.GET).build();
System.out.println(httpRequest.getUri());
HttpResponse httpResponse = restClient.executeWithLoadBalancer(httpRequest, null);
System.out.println(httpResponse.getStatus());
// ILoadBalancer iLoadBalancer = ClientFactory.getNamedLoadBalancer(CUSTOM);↓
ILoadBalancer iLoadBalancer = ClientFactory.getNamedLoadBalancer(CUSTOM, DefaultClientConfigImpl.class);
for (int i = 0; i < 6; i++) {
Server server = iLoadBalancer.chooseServer(null);
System.out.println(server);
}
}
/**
*
* @author zby
* @date 2019年1月23日
* @param name
* @param iClientConfigKey
* @return
* @Description 获取Ribbon配置的key
*/
public static String getPropertyKey(String name, IClientConfigKey<?> iClientConfigKey) {
return name + DELIMITER + DefaultClientConfigImpl.DEFAULT_PROPERTY_NAME_SPACE + DELIMITER + iClientConfigKey.key();
}
public static void printAllRibbonConfig(IClientConfig iClientConfig1, IClientConfig iClientConfig2) {
for (IClientConfigKey iClientConfigKey : IClientConfigKey.Keys.values()) {
println(iClientConfig1, iClientConfig2, iClientConfigKey);
}
}
private static void println(IClientConfig iClientConfig1, IClientConfig iClientConfig2, IClientConfigKey<?> iClientConfigKey) {
System.out.println(iClientConfigKey.key());
System.out.println(
"\t\t\t\t\t\t【" + iClientConfig1.get(iClientConfigKey) + "】" + "←--------→【" + iClientConfig2.get(iClientConfigKey) + "】");
}
}
输出结果:
RequestIdHeaderName 【null】←--------→【null】 EnableGZIPContentEncodingFilter 【false】←--------→【false】 ServerListRefreshInterval 【null】←--------→【null】 UseIPAddrForServer 【false】←--------→【false】 MaxTotalHttpConnections 【200】←--------→【200】 PoolKeepAliveTimeUnits 【SECONDS】←--------→【SECONDS】 VipAddressResolverClassName 【com.netflix.client.SimpleVipAddressResolver】←--------→【com.netflix.client.SimpleVipAddressResolver】 VipAddress 【null】←--------→【null】 EnablePrimeConnections 【false】←--------→【false】 ForceClientPortConfiguration 【null】←--------→【null】 NFLoadBalancerPingClassName 【com.netflix.loadbalancer.DummyPing】←--------→【com.netflix.loadbalancer.DummyPing】 MinPrimeConnectionsRatio 【1.0】←--------→【1.0】 MaxHttpConnectionsPerHost 【50】←--------→【50】 PoolKeepAliveTime 【900】←--------→【900】 ConnectionManagerTimeout 【2000】←--------→【2000】 ProxyPort 【null】←--------→【null】 PrioritizeVipAddressBasedServers 【true】←--------→【true】 EnableMarkingServerDownOnReachingFailureLimit 【null】←--------→【null】 ReadTimeout 【5000】←--------→【5000】 ServerDownFailureLimit 【null】←--------→【null】 IsHostnameValidationRequired 【null】←--------→【null】 listOfServers 【】←--------→【http://spring.io,http://www.apache.org】 FollowRedirects 【false】←--------→【false】 KeyStorePassword 【null】←--------→【null】 ProxyHost 【null】←--------→【null】 MaxAutoRetries 【0】←--------→【0】 StaleCheckingEnabled 【null】←--------→【null】 EnableZoneExclusivity 【false】←--------→【false】 MaxRetriesPerServerPrimeConnection 【9】←--------→【9】 RequestSpecificRetryOn 【null】←--------→【null】 ConnIdleEvictTimeMilliSeconds 【30000】←--------→【30000】 TargetRegion 【null】←--------→【null】 InitializeNFLoadBalancer 【null】←--------→【null】 EnableConnectionPool 【true】←--------→【true】 ClientClassName 【com.netflix.niws.client.http.RestClient】←--------→【com.netflix.niws.client.http.RestClient】 MaxTotalTimeToPrimeConnections 【30000】←--------→【30000】 ConnectionCleanerRepeatInterval 【30000】←--------→【30000】 Version 【null】←--------→【null】 ReceiveBufferSize 【null】←--------→【null】 PoolMaxThreads 【200】←--------→【200】 PoolMinThreads 【1】←--------→【1】 CustomSSLSocketFactoryClassName 【null】←--------→【null】 PrimeConnectionsClassName 【com.netflix.niws.client.http.HttpPrimeConnection】←--------→【com.netflix.niws.client.http.HttpPrimeConnection】 EnableZoneAffinity 【false】←--------→【false】 Linger 【null】←--------→【null】 MaxConnectionsPerHost 【50】←--------→【50】 OkToRetryOnAllOperations 【false】←--------→【false】 KeyStore 【null】←--------→【null】 TrustStorePassword 【null】←--------→【null】 BackoffTimeout 【null】←--------→【null】 NFLoadBalancerClassName 【com.netflix.loadbalancer.ZoneAwareLoadBalancer】←--------→【com.netflix.loadbalancer.ZoneAwareLoadBalancer】 ServerListUpdaterClassName 【null】←--------→【null】 NIWSServerListClassName 【com.netflix.loadbalancer.ConfigurationBasedServerList】←--------→【com.netflix.loadbalancer.ConfigurationBasedServerList】 MaxTotalConnections 【200】←--------→【200】 ServerDownStatWindowInMillis 【null】←--------→【null】 DeploymentContextBasedVipAddresses 【null】←--------→【null】 ConnectionPoolCleanerTaskEnabled 【true】←--------→【true】 IgnoreUserTokenInConnectionPoolForSecureClient 【null】←--------→【null】 TrustStore 【null】←--------→【null】 GZipPayload 【null】←--------→【null】 NFLoadBalancerMaxTotalPingTime 【null】←--------→【null】 IsSecure 【null】←--------→【null】 MaxAutoRetriesNextServer 【1】←--------→【0】 SendBufferSize 【null】←--------→【null】 NFLoadBalancerRuleClassName 【com.netflix.loadbalancer.AvailabilityFilteringRule】←--------→【com.netflix.loadbalancer.AvailabilityFilteringRule】 NIWSServerListFilterClassName 【null】←--------→【null】 AppName 【null】←--------→【null】 ConnectTimeout 【2000】←--------→【2000】 IsClientAuthRequired 【false】←--------→【false】 PrimeConnectionsURI 【/】←--------→【/】 NFLoadBalancerPingInterval 【null】←--------→【null】 SecurePort 【null】←--------→【null】 Port 【7001】←--------→【7001】 RulePredicateClasses 【null】←--------→【null】 / 200 spring.io:80 www.apache.org:80 spring.io:80 www.apache.org:80 spring.io:80 www.apache.org:80
留下的疑问?
1.ClientFactory242行和248行是否重复???
2.个人觉得ClientFactory70行的loadBalancer = registerNamedLoadBalancerFromclientConfig(restClientName, clientConfig);改为loadBalancer = getNamedLoadBalancer(restClientName, clientConfig);是否更好???

浙公网安备 33010602011771号