負荷均衡拡張インターフェース再構成
自分の会社でのブログに移行します.
http://pt.alibaba-inc.com/wp/experience_1003/loadbalance_refactor.
プロジェクトの中の一つの再構成の過程と理由は、知会チームのメンバーに使用され、ここで一つを準備します.
RPC遠隔呼び出しフレームには多くのオプションの負荷均衡ポリシーがあります.
例えば:ランダム、サイクル、最小接続など、
この時はSPIの拡張点が必要です.今後新たな戦略を追加することが可能です.
再構成前:
元のインターフェースの形式は以下の通りです.
下記の符号を返して、インターフェースの入出力が一致しないようにして、資源の包装を制限しました.
拡張インターフェースとして、すなわち汎型を使用して、ポリシーがリソースタイプを制限しないことを実現することを表し、インターフェース自体が汎型を定義することは意味がない.
拡張インターフェースとしては、重み情報の伝達が特殊化しすぎ、
例えば、現在の最小接続数戦略は現在のアクティブ接続数を使います.
新しいパラメータのactivesを追加したいです.
上のように、後に何のパラメータが入るかは分かりません.インターフェースの契約は広がりません.
もう一つの方法は、最小接続数ポリシーの実現において、TをRpcInvokerインターフェースに強制的に変換し、次いでgetActive()を呼び出し、
しかし、activeの数はget側で得られます.なぜweightは他のパラメータを通して入ってきたのですか?明らかに違います.
また、ここでの強制的な転換は、従来の期待通りにはいかない戦略の実現にもつながります.
一つのフレームの拡張点としては、一般的な意味は大きくなく、通用すればするほど使いにくくなります.
直接RpcInvokerをパラメータとして使用すると、契約の完全性が保証されます.
クライアントの一貫性に基づいて、RpcInvokerのいずれかを選択して実行するのではなく、すべてのRpcInvokerを実行する必要がある.
既存の実現は、それを特例として、コードの中に書き込んだもので、上のLoadBalanceインターフェースに基づいて、
導入されたRpcInvoker[]は全部RpcInvokerに包装できます.中はfor循環ですべての呼び出しを委任します.
w+r>n(書き込みノード+読み出しノード>全体ノード)の一貫性のある要求があれば、対応する方法で処理しても良いし、いくつかの構成項目を追加するだけでよい.
ある策略の実現は状態があるので、例えばサイクル戦略は順番を記録しなければなりません.
つまり、インスタンスだけでLoadBalanceを使用することはできません.
これはフレームのメンテナンスに非常に不利で、後から来るメンテナに地雷を埋めやすいです.
また、同じresource集合は、同じLoadBalanceのインスタンスを使用しなければならない.
すなわち、LoadBalanceの例の変更は、resourceの集合に従う変更であり、
すなわち、リソースセットの設定は、select()の前に決定されてもよい.
例えばランダムポリシーは、総重みを統計する必要があります.init()方法で統計すると、
select()の時に一回のforサイクルを減らすことができます.
また、単一のLoadBalanceの例は、init()方法を反復して呼び出すことによって多重化されてもよい.
もちろん、LoadBalanceの実現はスレッドの安全性を確保する必要があります.
--------------
Dubbo設計共有シリーズ:
いくつかの設計上の基本常識
汎化式の拡張と組合せ式の拡張を話します。
http://pt.alibaba-inc.com/wp/experience_1003/loadbalance_refactor.
プロジェクトの中の一つの再構成の過程と理由は、知会チームのメンバーに使用され、ここで一つを準備します.
RPC遠隔呼び出しフレームには多くのオプションの負荷均衡ポリシーがあります.
例えば:ランダム、サイクル、最小接続など、
この時はSPIの拡張点が必要です.今後新たな戦略を追加することが可能です.
再構成前:
元のインターフェースの形式は以下の通りです.
public class LoadBalance<T> {
// ,
int select(T[] resources, int[] weights);
}
問題1:下記の符号を返して、インターフェースの入出力が一致しないようにして、資源の包装を制限しました.
public class LoadBalance {
// ,
<T> T select(T[] resources, int[] weights);
}
問題二:拡張インターフェースとして、すなわち汎型を使用して、ポリシーがリソースタイプを制限しないことを実現することを表し、インターフェース自体が汎型を定義することは意味がない.
public class LoadBalance {
// ,
<T> T select(T[] resources, int[] weights);
}
問題三:拡張インターフェースとしては、重み情報の伝達が特殊化しすぎ、
例えば、現在の最小接続数戦略は現在のアクティブ接続数を使います.
新しいパラメータのactivesを追加したいです.
public class LoadBalance {
// ,
<T> T select(T[] resources, int[] weights, int[] actives);
}
問題四:上のように、後に何のパラメータが入るかは分かりません.インターフェースの契約は広がりません.
もう一つの方法は、最小接続数ポリシーの実現において、TをRpcInvokerインターフェースに強制的に変換し、次いでgetActive()を呼び出し、
しかし、activeの数はget側で得られます.なぜweightは他のパラメータを通して入ってきたのですか?明らかに違います.
また、ここでの強制的な転換は、従来の期待通りにはいかない戦略の実現にもつながります.
一つのフレームの拡張点としては、一般的な意味は大きくなく、通用すればするほど使いにくくなります.
直接RpcInvokerをパラメータとして使用すると、契約の完全性が保証されます.
public class LoadBalance {
// RpcInvoker getWeight(), getActive()
// ,
RpcInvoker select(RpcInvoker[] resources);
}
共通性の需要があれば、もう一つのインターフェースを抽出することも考えられます.
public class LoadBalance {
// ,
Selectable select(Selectable[] resources);
}
問題5:クライアントの一貫性に基づいて、RpcInvokerのいずれかを選択して実行するのではなく、すべてのRpcInvokerを実行する必要がある.
既存の実現は、それを特例として、コードの中に書き込んだもので、上のLoadBalanceインターフェースに基づいて、
導入されたRpcInvoker[]は全部RpcInvokerに包装できます.中はfor循環ですべての呼び出しを委任します.
w+r>n(書き込みノード+読み出しノード>全体ノード)の一貫性のある要求があれば、対応する方法で処理しても良いし、いくつかの構成項目を追加するだけでよい.
public class AllLoadBalance {
public RpcInvoker select(RpcInvoker[] resources) {
return new AllRpcInvoker(resources);
}
}
class AllRpcInvoker implements RpcInvoker {
private RpcInvoker[] invokers;
public AllRpcInvoker(RpcInvoker[] invokers) {
this.invokers = invokers;
}
// Delegate all methods to invokers
}
問題六:ある策略の実現は状態があるので、例えばサイクル戦略は順番を記録しなければなりません.
つまり、インスタンスだけでLoadBalanceを使用することはできません.
これはフレームのメンテナンスに非常に不利で、後から来るメンテナに地雷を埋めやすいです.
また、同じresource集合は、同じLoadBalanceのインスタンスを使用しなければならない.
すなわち、LoadBalanceの例の変更は、resourceの集合に従う変更であり、
すなわち、リソースセットの設定は、select()の前に決定されてもよい.
public class LoadBalance {
//
void init(RpcInvoker[] resources);
//
RpcInvoker select();
}
このような利点は、LoadBalanceの実現はinit()の時に前処理とキャッシュをすることができ、例えばランダムポリシーは、総重みを統計する必要があります.init()方法で統計すると、
select()の時に一回のforサイクルを減らすことができます.
また、単一のLoadBalanceの例は、init()方法を反復して呼び出すことによって多重化されてもよい.
もちろん、LoadBalanceの実現はスレッドの安全性を確保する必要があります.
--------------
Dubbo設計共有シリーズ:
いくつかの設計上の基本常識
汎化式の拡張と組合せ式の拡張を話します。