プロキシグループが解決するのは「どのノードを選ぶか」という問題
Clash / Clash Meta(mihomo)の設定ファイルでは、proxiesにすべての利用可能なノードが列挙され、実際にトラフィックの向き先を決めるのがproxy-groupsである。ルール(rules)が担うのは、あるコネクションをどのプロキシグループに渡すかの判定だけで、具体的にどのノードに出すかはプロキシグループ側が決める。selectタイプの手動グループだけを1つ用意した場合、ノード選択は完全に人の手による操作になり、ノードが落ちても自動で切り替わることはない。そのため、ほとんどの設定では自動化プロキシグループをいくつか追加で用意する。それぞれのアルゴリズムに従って「ノードを選ぶ」作業を人ではなくプログラムに任せるわけだ。
mihomoが対応する自動化プロキシグループには主に3種類ある。url-test(自動測速)、fallback(フェイルオーバー)、load-balance(負荷分散)。3つとも同じヘルスチェック機構を共有しているが、判定ロジックと適用場面は全く異なり、混同して使うと効果が半減する。以下、パラメータ・動作・場面ごとに1つずつ分解して説明する。
url-test:遅延に基づいて自動で最速ノードを選ぶ
url-testは最も一般的な自動化タイプで、コアロジックはこうだ。定期的にグループ内の各ノードを使ってテスト用URLへリクエストを送り、応答時間を記録した上で、現在のトラフィックを応答時間が最も短いノードへ振り分ける。これは「これだけのノードの中で、今どれが一番速いか」を解決する仕組みで、遅延を主な指標にする日常的な用途の大半に向いている。
proxy-groups:
- name: 自動選択
type: url-test
proxies:
- 香港01
- 香港02
- シンガポール01
- 日本01
url: "https://www.gstatic.com/generate_204"
interval: 300
tolerance: 50
lazy: true
- url:測速リクエストを送る先のアドレス。通常は軽量で安定して204を返すアドレスを使い、テストリクエスト自体が帯域を圧迫したり検閲の影響を受けたりして判定を狂わせないようにする。
- interval:測速を行う間隔で、単位は秒。上の例では300秒ごとに1回測速する。間隔が短すぎるとノードへの測速リクエストが頻発し、長すぎるとノードが遅くなってもなかなか切り替わらない。
- tolerance:許容差で、単位はミリ秒。新たに測定した最速ノードが、現在使用中のノードよりこの許容差以上速くなった場合にのみ実際に切り替わる。この仕組みは、遅延が近い2つのノードが頻繁に切り替わってコネクションが度々切断されるのを防ぐためのものだ。
- lazy:trueの場合、グループ内に実際に使用中のコネクションがある時だけ測速が行われ、待機中はスキップされる。通信量とノード側の負荷を節約できる。falseの場合は使用状況にかかわらずintervalどおりに定期測速する。
注意すべきは、toleranceが「遅延の閾値」ではなく「切り替えの発生条件」だという点だ。例えば現在使用中のノードの遅延が120ms、別のノードが100msと測定され、toleranceが50msに設定されているなら、20msの差では切り替わらない。差が50msを超えて初めて実際にノードが切り替わる。この設計は、わずかな差のために頻繁に行き来してしまうのを防ぐためのものだ。
fallback:最優先ノードが機能しなくなった時だけ次に切り替える
fallbackの判定ロジックはurl-testとは全く異なり、どちらが速いかは比較せず、「ノードが生きているか」だけを見る。グループ内のノードは設定順に優先順位が決まり、常にリストの先頭でヘルスチェックに通っているノードが優先的に使われる。現在使用中のノードの測速が失敗(タイムアウトまたは接続不能)した場合にのみ、順に次のノードを試し、接続できるノードが見つかるまでこれを繰り返す。
proxy-groups:
- name: フェイルオーバー
type: fallback
proxies:
- メインノード-香港
- バックアップノード-シンガポール
- バックアップノード-日本
url: "https://www.gstatic.com/generate_204"
interval: 180
tolerance: 0
ここでの順番がそのまま優先度になる。メインノード-香港が先頭にあれば、それがヘルスチェックを通っている限りずっとトラフィックはそこを通り、後続のノードの遅延が低くても取って代わることはない。これはurl-testの「速い方を使う」という利益優先の戦略とは正反対で、fallbackが目指すのは安定性と予測可能性だ。すでにどのノードの線質が一番良いか分かっていて、そのノードが不安定になった時のための保険を用意したい場面に向いている。例えば固定の専用線ノードに1つか2つの控えを配置するようなケースだ。
fallbackにおけるtoleranceパラメータの意味はほとんどない。速さの比較で切り替えるわけではなく、「接続できるかどうか」の二値判定しか行わないため、大半の設定では0にするか省略してよい。実際に効いてくるのはurlとintervalで、この2つがヘルスチェックの実行頻度と対象アドレスを決める。間隔が長すぎると、メインノードに障害が起きてもしばらくトラフィックが失効ノードに流れ続けてしまう。
load-balance:トラフィックを複数ノードに分散させる
load-balanceが解決するのは別種の課題だ。「一番速い1つを選ぶ」のではなく「並行するコネクションを複数ノードに分散させる」ことが目的で、単一ノードの帯域負荷を分けたり、質が近い複数のノードにバランスよく仕事を回して、特定のノードだけが常に満負荷で他が空いている状態を避けたりするのが一般的な狙いだ。
proxy-groups:
- name: 負荷分散
type: load-balance
proxies:
- 香港01
- 香港02
- 香港03
url: "https://www.gstatic.com/generate_204"
interval: 300
strategy: consistent-hashing
strategyパラメータがこのタイプの要で、mihomoは2種類の割り当てアルゴリズムを提供している。
- consistent-hashing(コンシステントハッシュ):コネクションの送信元アドレスや宛先アドレスなどの情報からハッシュ値を計算し、固定的に特定のノードへ割り振る。同じ宛先サイト・同じ送信元であればほぼ常に同じノードに落ち着くため、セッション中にノードが切り替わってログイン状態が失われたりダウンロードが中断したりする心配が少ない。長時間接続やセッション維持が必要な場面に向く。
- round-robin(ラウンドロビン):新しいコネクションを順番にグループ内のノードへ交代で割り振る。より均等に分散できるが、同じサイトへの異なるリクエストが別々のノードに落ちる可能性があり、IPの一致性に敏感なサービス(認証コードやログイン状態がIPに紐づくサイトなど)では問題が起きやすい。
注意しておきたいのは、load-balanceは失効したノードを除外して全トラフィックを再配分するような処理はしない、という点だ。あくまでヘルスチェックでノードの生存を判定し、失効ノードは一時的にスキップされるだけで、割り当てロジック自体に「フェイルオーバー的な優先順位」の並べ替えは組み込まれていない。グループ内のノードの質が大きく異なる場合、負荷分散を使うと一部のコネクションが遅いノードに落ちてしまい、体感はurl-testより不安定になる。そのため、このタイプは「ノードの質がほぼ揃っていて負荷を分けたい」場面に向いており、「ノードの質がまちまちで良いものを選びたい」場面には向かない。
urlのアドレスは各ノードから正常にアクセスでき、安定して応答が返ってくる必要がある。テストアドレス自体が一部地域で干渉を受けていると、ヘルスチェックの結果が歪み、切り替えるべき時に切り替わらなかったり、不要な切り替えが起きたりする。トラブル対処のしやすさを考えると、同一の測速アドレスを固定して使うのがおすすめだ。
3種類の選び方:場面別の対応表
| タイプ | 判定基準 | 典型的な場面 | 主要パラメータ |
|---|---|---|---|
| url-test | 遅延が最も低いものを優先 | 日常利用、速度を重視したい | interval / tolerance |
| fallback | 生存優先順位に従う | 優先ノードが決まっていて控えが欲しい | proxiesの順序 / interval |
| load-balance | 並行コネクションを分散 | 複数ノードの質が近く、負荷を分けたい | strategy |
実際の設定では、3種類を入れ子にして組み合わせることもできる。よくあるやり方は、まずurl-testで「自動選択」グループを作ってデフォルトの出口とし、優先度の高い特定サイト(動画配信サービスやダウンロードツールなど)には別途load-balanceグループを用意して帯域を分散させ、さらに重要なノードにはfallbackグループを保険としてかけておくというものだ。プロキシグループ同士は相互に参照できる。selectグループの選択肢には具体的なノードだけでなく、別のプロキシグループの名前も置ける。そうすると上位のルールは最も外側のselectだけを指せばよく、内部の自動化ロジックは内側のプロキシグループが担うことになり、設定の構造がかなり分かりやすくなる。
よくある誤解とトラブル対処の考え方
「url-testを設定したのにノードがなかなか切り替わらない」という相談は多いが、大抵はtoleranceを大きく設定しすぎているか、グループ内のノード間で遅延差がそもそも小さく、システムが「切り替える必要なし」と判断しているケースだ。toleranceを一時的に1桁台まで下げて切り替わるか確認し、ロジックが正常だと分かったら妥当な値に戻すとよい。もう1つよくある問題は、fallbackグループで「メインノードが明らかに繋がらないのに使われ続けている」というもので、これは大抵intervalが長すぎてヘルスチェックの次のサイクルがまだ来ていないか、測速アドレスが期待した204を返さずに誤って「生存」と判定されているケースだ。
もう1つの誤解は、load-balanceを「もっと速いurl-test」として使い、自動で最良のノードを選んでくれると期待してしまうことだ。しかし本来の設計目的は分散であって選抜ではない。グループ内に明らかに質の悪いノードが混ざっていると、一部のコネクションの体感がそれに引き寄せられる。この場合は遅いノードをグループから外すか、いさぎよくurl-testに切り替えるべきだ。この種の問題を調べる際は、クライアント画面で各ノードの現在の測速値とプロキシグループが実際に選択しているノードを確認するとよい。Clash VergeやClash for Windows系クライアントなど、多くのGUIクライアントはプロキシグループ画面で各ノードの遅延と現在の選択状況をリアルタイムに表示してくれるため、ログを1行ずつ追うよりずっと分かりやすい。