Undertowでリバースプロキシを書く
APIサーバーとWEBサーバーを分けて、その手前に認証用のリバースプロキシを建てたくなったのでやってみた。
Undertow?
さいきんのTomcat。 JBossがつくったTomcat。
くらいの理解しかしてない。 組み込みができる。あとリバースプロキシになれる。
## まずシンプルなやつ
実は公式が @Deprecated
な超絶シンプルなリバースプロキシの実装を置いておいてくれている。
undertow/SimpleProxyClientProvider.java at master · undertow-io/undertow · GitHub
これを見ると、どうやら僕は以下のものを実装しなければいけないらしいということがわかる。
- ProxyClientの実装クラス
- ClientCallbackの実装クラス
まずProxyClientは2つのメソッドを持ってて、それぞれ
- findTarget: プロキシ先を選定する。既存のProxyClientだとまともに使われてないので本当の役割は違うのかも。
- getConnection: プロキシ先とのコネクションを確立する。
をやれば良いらしいことがわかる。 ProxyClientを使うクラスであるProxyHandlerの中身を見るにURIとかクエリストリングとかはなんかよしなにやってくれるっぽい。実際よしなにやってくれた。(ref: https://github.com/undertow-io/undertow/blob/946e98e4e46b31cfe7eb1d290a9596f76698c567/core/src/main/java/io/undertow/server/handlers/proxy/ProxyHandler.java#L412-L423)
とりあえず真似して書いたら、一つのプロキシ先に通信を転送することはできた。
2つに振り分ける
今回は findTarget
内で振り分けることにした。これで良いのかは正直わからん。
で、 getConnection
では振分先に流すだけ。
わりとさっくりイケた。 ただ、コネクションがすでにあれば流用する、みたいなロジックが挟まってるとAPIに流れてほしいものがWEB側に流れたりしててうまくなかったので一旦消した。
すると、10秒くらいアクセスが途切れると次のアクセスがクソ雑魚パフォーマンスになる事象が発生した。多分内部で持ってるコネクションを手放すんだと思うけどわからん。現時点で完全に雰囲気で書いている。
でもできた。書いたものは以下にあげてあるので随意に見てくれ。
examples/undertowreverseproxy at master · blackawa/examples · GitHub