勿論、各クライアントでDNSキャッシュをリフレッシュを手動で行うことで、正常なプロキシを見にいくようにさせる事は可能ですが現実的では無いと思われます。
なお、DNSラウンドロビンによって"proxy"という名前に複数のIPアドレスを定義したとしても、同じ理由によって問題が発生する事でしょう。
Proxyを複数構成にするとともに、ロードバランサを組み合わせることでクライアントからは単一のProxyして見せかけ、かつ、ロードバランサを冗長化することで、比較的低コストで高性能なProxy環境を構築できます。
クライアントから見た場合、見かけ上はロードバランサがProxyとして見えますが、ロードバランサーの上位に複数のProxyを用意することで、Proxyの障害に備えるとともにロードバランサによるProxyサーに対するアクセスの分配により高速なアクセスが可能になります。
ロードバランサとしては F5 の製品が有名ですが、フリーソフトを使ったロードバランサでも十分に実用に耐えます。 別章では、ロードバランサとして「HAProxy」、冗長化に「heartbeat」を使った構成について述べていきます。
この構成をとった場合、ロードバランサの障害はハートビートによる機器の冗長化で対処するとともに、Proxyの障害には複数のProxyサーバを用意することで対応します。 また、ロードバランサ上位のProxyを増やすことで容易にProxyの性能向上を図ることが可能です。
予算が潤沢な企業であれば、複数のプロキシサーバをクラスタとして設計して、代替えのプロキシサーバをホットスタンドバイさせて、主系のサーバが停止した場合に、同じIPアドレスや環境で代替えのプロキシを自動的に切り替える方法もあります。
(クラスタによる切り替え概念図)
Proxyの障害は、組織内のWebサーバサービス利用全体に影響を与える可能性があるため、その構築については連続稼働時間性能を高めた構成をとることが望ましいでしょう。
そのために一番簡単な方法は、複数のProxyサーバを用意しておきあるルール単位(例えば、地域やサブネット)で利用できるProxyサーバを分ける方法が考えられます。
この方法ではProxyサーバの障害発生時に全クライアントがアクセス不能にならない為、比較的低コストでProxyサーバの障害時の影響を軽減することが可能です。 また下記で説明するスクリプトファイルの併用によって、障害におけるクライアントへの影響をほぼなくす事が可能です。
反面、地域の数が増えたりスクリプトの変更などのといった運用コストは増大する可能性があり、特にユーザにどのProxyを利用させるかといった管理は常に必要になります。
また、Proxyの性能に問題があってもその性能向上を図ることはハードウェアの性能を上げる必要があり容易では無いでしょう。
// (proxy.pac)
// このJavascriptでは、
// 社内全体のネット : 172.16.0.0/12 (172.16.0.0 - 172.31.255.255)
// Tokyo-LAN(東京) : 172.16.0.0/16
// Osaka-LAN(大阪) : 172.17.0.0/16
// Fukuoka-LAN(福岡) : 172.18.0.0/16
// として、各拠点にプロキシを配置し、それぞれのセグメントに接続された時に最寄りのプロキシを
// 自動的に選択する処理を行う。 // もし、最寄りのプロキシが反応しない場合にはサブのプロキシを使うようにする。
// また、社内のWebサーバへのアクセスにはプロキシを経由しないようにする。
//
function FindProxyForURL(url, host) {
MyDomain = ".hogehoge.jp";
MyIP = myIpAddress();
NetworkID = 0 ; // Default = 0(Tokyo), 1(Osaka), 2(Fukuoka)
ProxyTokyo="PROXY proxy-tk.hogehoge.jp:8080; PROXY proxy-osaka.thogehoge.jp.co.jp:8080" ;
ProxyOsaka="PROXY proxy-osaka.hogehoge.jp:8080; PROXY proxy-tk.hogehoge.jp:8080" ;
ProxyFukuoka="PROXY proxy-fukuoka.hogehoge.jp:8080; PROXY proxy-tk.hogehoge.jp:8080" ;
// まず、社内のWebサーバのアクセスかどうかを確認。
if ( isInNet(host, "172.16.0.0" , "255.240.0.0" ) || dnsDomainIs(host, MyDomain) || isPlainHostName(host) ) {
return "DIRECT" ;
}
if (isInNet(MyIP, "172.17.0.0", "255.255.0.0")) NetworkID = 1 ;
if (isInNet(MyIP, "172.18.0.0", "255.255.0.0")) NetworkID = 2 ;
switch ( NetworkID ) {
case 1: // 大阪LAN
return ProxyOsaka ;
break;
case 2: // 福岡LAN
return ProxyFukuoka ;
break;
default: // 東京LAN
return ProxyTokyo ;
break;
}
}
参考: