2015年03月08日

JavaServletで リバースプロキシ を実装する方法について[改訂]

JavaServletで リバースプロキシ を実装するサンプルプログラムです。
(mod_proxy_html、mod_substitueを意識しました。)

前提条件
・1バックエンドシステム=1サーブレットインスタンス。
・リバースプロキシを経由する場合と経由しない場合の並行運用を可能とした。
 (=バックエンドシステムにリバースプロキシの存在を意識させない。)
・HTTP/1.1の仕様を完全に網羅したわけではなく、あくまで私が事業にて必要とした仕様(主にGET、POST)のみに特化した。
 なお、セッション、Cookie、リダイレクト、ファイルアップロードには対応済み。
・一部、J2EEコンテナ(Tomcat)依存を含む。
・リバースプロキシ : J2EEコンテナ(Tomcat)、バックエンドシステム : J2EEコンテナ(Tomcat) にて検証済み。
 ただし、(リバースプロキシ・バックエンドシステム間の)HTTPS通信は未検証。

※ HttpComponents Client 4.3 にて大きくAPI仕様が変更されたため、最適化しました( deprecated を除去しました)。
  また、新たなコーディング方法でも CLOSE_WAIT が残存しないことを( netstat コマンドにて)確認済みです。

参考 : JavaServletで リバースプロキシ を実装する方法について

実行環境
Java SE : 8u31
HttpComponents Client : 4.3.6

【サンプルプログラム】



(コメント抜粋)
-------------------------
"http".
今回はルートがひとつ(http://127.0.0.1:8080)のため, 同値を指定する.
全ルート.
ルート毎.
正規表現をコンパイルするコストを削減する目的.
* : 最長一致, *? : 最短一致.
※Tomcat依存.
"org.apache.catalina.connector.ClientAbortException: java.io.IOException: 確立された接続がホスト コンピューターのソウトウェアによって中止されました。"を抑止するため.
※Tomcat依存.
(Tomcat停止時の)"
The web application [/webapp1] created a ThreadLocal with
key of type [org.apache.http.impl.cookie.DateUtils$DateFormatHolder$1] (value [org.apache.http.impl.cookie.DateUtils$DateFormatHolder$1@xxxxxxx])
and a
value of type [java.lang.ref.SoftReference] (value [java.lang.ref.SoftReference@xxxxxxx])
but failed to remove it when the web application was stopped.
Threads are going to be renewed over time to try and avoid a probable memory leak.
"を抑止するため.
POST(application/x-www-form-urlencoded)の場合は URLパラメータ を付与しない(パラメータが重複するため).
同じヘッダ名が存在する場合, (String)インスタンスは同一となる.
"Caused by: org.apache.http.ProtocolException: Content-Length header already present"を抑止するため.
※J2EEコンテナ依存.
上記のセッションIDはクライアント・ReverseProxy間のものであるため.
Pathによる送信制御はクライアントに委譲する.
上記のキープアライブ可否はクライアント・ReverseProxy間のものであるため.
同じパラメータ名が存在する場合, (String)インスタンスは同一となる.
日本語OK(setCharacterEncoding()は不要).
同じヘッダ名が存在する場合, (Header)インスタンスは不同となる.
URL置換を行うことでContent-Lengthに差が生じるため → コンテナに委譲する.
※J2EEコンテナ依存.
上記のセッションIDはReverseProxy・バックエンドシステム間のものであるため → (クライアント・ReverseProxy間のセッションIDについては)コンテナに委譲する.
上記のキープアライブ可否はReverseProxy・バックエンドシステム間のものであるため.
セキュリティ対策のため.
また, ReverseProxy分については,
・Apache( httpd.conf の Header unset Server )
・Tomcat( server.xml の Connectorタグ の server属性 )
にて対応する.
backEndResponseHeaders[i].getValues() : HeaderElement[] … ヘッダ値をさらに分割したもの.
URL置換を行う.
(主に同時アクセス時の)パフォーマンスダウンを軽減するため, メモリ負荷を軽減するため, DOMは利用しない.
そのため, 対の > が出現したタイミングで処理することで, コードを簡素化する.
また, 正規表現を利用することによるパフォーマンスダウンを軽減するため, HTMLコメント部は置換対象外とする.
closeはコンテナに委譲する.
対の > が出現しなかった場合.
closeはコンテナに委譲する.
HTTPコネクション(スレッド)プールに返却するため.
(返却しない場合, "org.apache.http.conn.ConnectionPoolTimeoutException: Timeout waiting for connection from pool"が発生する.)
default.
-------------------------
posted by red at 11:57| Comment(0) | TrackBack(0) | Java | このブログの読者になる | 更新情報をチェックする
この記事へのコメント
コメントを書く
お名前:

メールアドレス:

ホームページアドレス:

コメント:

※ブログオーナーが承認したコメントのみ表示されます。

この記事へのトラックバック