「Backconnect」という言葉は、プロキシのドキュメントに定義されないまま登場することが多い用語のひとつだ。たいていの場合、それを書いている人自身が、かつてこの言葉になじみがなかったことを忘れてしまっているからだ。これはひとつのアーキテクチャを指しており、そのアーキテクチャさえ理解すれば、製品の残りの部分にも納得がいく。なぜ設定すべきアドレスがひとつしかないのか、なぜターゲティングがユーザー名の中に存在するのか、そしてなぜHTTPクライアントが何も問題が起きていないように見えながら静かにローテーションを壊してしまうのか、という点だ。
名前の由来
以前のモデルはリストだった。プロキシのセットを購入すると、アドレスとポートが書かれたファイルを受け取り、コードはそれぞれに直接接続していた。それらの管理は自分の仕事だった。どれが生きているか、どれが特定のターゲットでブロックされているか、負荷をどう分散するか、リストが変わったときにどうするか、といったことだ。
Backconnectはこれを逆転させる。ひとつのゲートウェイアドレスに接続すると、ゲートウェイがあなたに代わって、そのネットワーク内にある多数のノードのひとつを通して外部に接続し直す。出口となるアドレスを事前に知ることは決してなく、リストを管理することもない。なぜならルーティングの判断は、リクエストの瞬間にプロバイダー側で行われるからだ。これが全体の考え方であり、安定したひとつの正面玄関と、ローテーションする多数の裏口、というわけだ。
実際のところ、「backconnect proxy」「rotating proxy」「gateway proxy」は今日ではほぼ同義に使われており、backconnectはアーキテクチャを強調し、rotationはそのアーキテクチャがもたらす挙動を強調している。
1回のリクエストで何が起きるか
具体的には、クライアントがbackconnectゲートウェイ経由でリクエストを送るとき、次のようなことが起きる。
- クライアントは
p.shifter.io:443というゲートウェイへの接続を開き、ユーザー名とパスワードで認証する。 - ゲートウェイはユーザー名を解析するが、これは単なる識別情報以上のものを運んでいる。国、地域、都市、ASNに関するターゲティングのフラグや、セッション識別子とTTLも、そこにエンコードされている。
- ゲートウェイは、現在利用可能なプール内から、その条件に合致する出口ノードを選択する。「利用可能」というのがここでの肝であり、このプールは絶え間なく入れ替わる母集団であることは、プロバイダーがプールをどう構築し更新しているかで扱っている。
- ゲートウェイはそのノードを通してリクエストを転送するため、ターゲット側からは、あなた自身やゲートウェイのアドレスではなく、そのノードのレジデンシャルアドレスが見える。
- レスポンスも同じ経路で戻ってくる。
セッション識別子を指定していた場合、ゲートウェイはそのマッピングを記憶し、その識別子を持つ以降のリクエストを、TTLが切れるかノードが落ちるまで、同じノードへとルーティングし続ける。指定していなければ、次のリクエストは独立に選ばれた出口を得る。
ターゲティングがユーザー名の中に存在するのはこのためだ。エンドポイントはひとつしかないので、リクエストごとの指示は、トンネルが確立される前にプロキシプロトコルが提供する、リクエストごとに変えられる唯一のフィールドを通じて運ばなければならない。
# same host and port, different behaviour, expressed entirely in the username
curl -x customer-USERNAME:PASSWORD@p.shifter.io:443 https://ipinfo.io/json
curl -x customer-USERNAME-country-de:PASSWORD@p.shifter.io:443 https://ipinfo.io/json
curl -x customer-USERNAME-country-de-sid-abc123-ttl-600:PASSWORD@p.shifter.io:443 https://ipinfo.io/json
これがコードにもたらす変化
このアーキテクチャからは3つの実務的な帰結が生じるが、最初のひとつが、この製品において他の何よりも混乱を招く原因になっている。
ローテーションはリクエストごとではなく、接続ごとに起きる。 出口が選ばれるのは、ゲートウェイへのトンネルが確立されるときだ。現代のHTTPクライアントは接続を維持し、再利用するので、クライアントがひとつのプールされた接続を通じて10回リクエストを送れば、その10回すべてが同じ出口から出ていくことになり、まるでローテーションが壊れているかのように見える。実際には壊れていない。クライアントは設計どおりに動作しているだけだ。修正方法と診断方法はIP not rotatingにまとめてあり、要点を言えば、別々のプロセスで動くcurlのループはローテーションするが、共有されたセッションオブジェクトはローテーションしない、ということだ。
管理すべきIPリストは存在せず、責めるべきIPも存在しない。 健全性とは、拒否リストに追加できるようなアドレスの性質ではなく、ターゲットと地理の組み合わせであるルートの性質であり、またセッションの性質でもある。これによって監視と障害対応のあり方は根本的に変わる。詳しくはmonitoring proxy health at scaleを参照のこと。
設定は静的で、挙動は動的だ。 ホストとポートは決して変わらないため、あるジョブをローテーティングする米国の出口から固定されたドイツの出口に切り替えるのは、再デプロイではなく文字列の変更で済む。だからこそ、複数市場でのデータ収集はインフラのプロジェクトではなく、設定の問題になるのだ。
Backconnect対ポートリストモデル
古いモデルは今も存在しており、この比較は、業界がなぜ移行したのかを説明する上で有用だ。
ポートリストではアドレスがあらかじめわかっていた。これは一見利点のように聞こえるが、たいていはそうではない。生存確認や負荷分散、置き換えといった作業を引き継ぐことになり、キャパシティは需要に応じて伸縮するものではなく、固定されたポート数になってしまう。価格設定も同じ形をたどり、作業単位ごとではなくポートごとになる。これはwhy the per-port era is overで論じているモデルだ。
Backconnectでは、出口を事前に知ることを諦める代わりに、それを管理する必要がなくなる。キャパシティは購入したポート数ではなく、帯域幅と同時接続数の問題になり、ローテーションは自分で書く実装ではなく、パラメータになる。
古い形がまだ勝る場面があるとすれば、それは本当に同じアドレスを持続させる必要がある場合であり、それこそが静的ISPプロキシが存在する理由だ。詳しくはISP versus residentialを参照。
Backconnectゲートウェイ内のスティッキーセッション
スティッキーセッションについては、それが実際に何であるかを理解しておく価値がある。それはゲートウェイが保持するマッピングであり、あなたが所有する割り当てではない。
識別子を選ぶと、ゲートウェイはそれをある出口ノードに関連付け、その識別子を伴うリクエストはTTLが切れるまで同じルートをたどる。ノードは実在する家庭のデバイスであるため、TTLが切れる前に消えてしまうこともあり得る。そのため、スティッキーセッションはリースではなく、ベストエフォートなのだ。連続処理の途中でアドレスが変わることを、通常の出来事ではなくエラーとして扱うコードは、プロバイダーとは無関係の理由で不安定になる。この挙動についてはsticky versus rotatingで、その背後にある入れ替わりについてはhow rotation worksで扱っている。
まとめ
Backconnectとは、ひとつのエンドポイントに接続すると、それが多数の出口へと接続し直し、その時点で利用可能なものの中からリクエストごとに出口を選ぶ、ということを意味する。このアーキテクチャこそが、ホストとポートがひとつしかない理由であり、国、都市、セッション、TTLがユーザー名にエンコードされる理由であり、アドレスのリストを管理する必要が一切ない理由だ。また、この製品で最もよくある混乱の原因もここから説明できる。ローテーションは接続が確立された時点で決まるため、プールされた接続を再利用するHTTPクライアントは、すべてのリクエストを同じ出口経由で送ってしまい、ローテーションに失敗しているように見えるのだ。出口ははかないものとして扱い、セッションは割り当てではなくマッピングとして扱い、健全性はルートの性質として扱う。そうすれば、このアーキテクチャがあなたを驚かせることはなくなる。
そのゲートウェイこそが、residential proxiesへのインターフェースのすべてだ。ひとつのホスト、ひとつの認証情報のペアで、ローテーション、地理、セッションの挙動をリクエストごとに表現でき、ポートごとではなくGBごとに課金される。この用語に不慣れであれば、glossaryがその他の部分をカバーしている。