カスタムribbon負荷分散ポリシー


ribbonのデフォルトでは、マルチクロック負荷分散ポリシーが提供されていますが、ビジネスロジックに適合するルールをカスタマイズする必要がある場合があります.
プロファイルの使用方法:プロファイルにプロファイルを追加するだけです
    serviceId.ribbon.NFLoadBalancerRuleClassName=カスタムロード・バランシング・ポリシー・クラス
ここでserviceIdは具体的なサービス名である
これにより、対応するサービスを呼び出すときに、カスタマイズされた負荷ポリシーが使用され、便利になります.
このプロファイルspringcloudがどのように解析されるかについて、次に、この構成がなぜ有効になったのかを分析します.
重要クラスRibbonClientConfigurationの導入
        @Bean
	@ConditionalOnMissingBean
	public IRule ribbonRule(IClientConfig config) {
		if (this.propertiesFactory.isSet(IRule.class, name)) {
			return this.propertiesFactory.get(IRule.class, config, name);
		}
		ZoneAvoidanceRule rule = new ZoneAvoidanceRule();
		rule.initWithNiwsConfig(config);
		return rule;
	}
        

1行目:現在の環境にIruleクラスが設定されているかどうかを判断します.
public boolean isSet(Class clazz, String name) {
		return StringUtils.hasText(getClassName(clazz, name));
	}

getClassNameは、次のように具体的に実装されています.
public String getClassName(Class clazz, String name) {
		if (this.classToProperty.containsKey(clazz)) {
			String classNameProperty = this.classToProperty.get(clazz);
			String className = environment.getProperty(name + "." + NAMESPACE + "." + classNameProperty);
			return className;
		}
		return null;
	}

classToPropertyとは何でしょうか
public PropertiesFactory() {
		classToProperty.put(ILoadBalancer.class, "NFLoadBalancerClassName");
		classToProperty.put(IPing.class, "NFLoadBalancerPingClassName");
		classToProperty.put(IRule.class, "NFLoadBalancerRuleClassName");
		classToProperty.put(ServerList.class, "NIWSServerListClassName");
		classToProperty.put(ServerListFilter.class, "NIWSServerListFilterClassName");
	}

中にはIrule.class対応NFLoadBalancerRuleClassName
getClassNameクラスを振り返る
String className = environment.getProperty(name + "." + NAMESPACE + "." + classNameProperty);

名前はribbonですclient.nameつまり私たちのサービス名です
NAMESPACEはribbon
className PropertyはNFLoadBalancerRuleClassName
だからgetClassNameメソッドで最終的に戻ったのは私たちのシステムで設定したサービスIdです.ribbon.NFLoadBalancerRuleClassName属性値
次にribbonRuleの2行目のコードを見てみましょう
return this.propertiesFactory.get(IRule.class, config, name);

具体的なget実装:
public  C get(Class clazz, IClientConfig config, String name) {
		String className = getClassName(clazz, name);
		if (StringUtils.hasText(className)) {
			try {
				Class> toInstantiate = Class.forName(className);
				return (C) instantiateWithConfig(toInstantiate, config);
			} catch (ClassNotFoundException e) {
				throw new IllegalArgumentException("Unknown class to load "+className+" for class " + clazz + " named " + name);
			}
		}
		return null;
	}

これにより、最終的には、構成された負荷ポリシークラスのフルパスに基づいて対応するインスタンスが生成されることが明らかになりました.
一方、1つのサービスがNマルチサービスの呼び出しに依存する必要がある場合、このような構成方式を採用するのは、少し煩雑で、私たちの負荷構成はグローバル化できません.
どのように処理しますか?
もちろんorgを広げることができますspringframework.cloud.netflix.ribbon.PropertiesFactoryクラスはグローバル構成をサポートしますが、springcloud公式では推奨されていません.
現在のプロジェクトの処理方法と結びつけて、ここではもう一つの考え方を示します.
プロファイルにプロパティを追加します
loadbalanced.services = service-A,service-B
RibbonLoadBalancerRuleConfigurationクラスを追加
@Configuration
@ConditionalOnClass(com.netflix.loadbalancer.ZoneAvoidanceRule.class)
public class RibbonLoadbalancerRuleConfiguration implements InitializingBean {

	private final static Logger log = LoggerFactory.getLogger(RibbonLoadbalancerRuleConfiguration.class);

	
	@Value("#{'${loadbalanced.services}'.split(',')}")
	private List loadbalancedServices;
	
	/**
	 *               
	 */
	@Value("${ribbon.NFLoadBalancerRuleClassName}")
	private String ribbonLoadBancerRule;

	@Override
	public void afterPropertiesSet() throws Exception {
		if (null != loadbalancedServices)) {
			for (String service : loadbalancedServices)) {
				String key = service + ".ribbon.NFLoadBalancerRuleClassName";
				System.setProperty(key, ribbonLoadBancerRule);
			}
		}
	}

}

これにより、プロファイルでは構成のみが必要になります.
ribbon.NFLoadBalancerRuleClassName=         
loadBalancedService=                

もっと完全なribbon負荷均衡原理分析を整理する時間がありますので、ご期待ください.