概要
Frontendの静的ファイルをNginxのアプリで配信し、Socket.IOの通信はBFFの別アプリへproxyする方法です。
前提
複数インスタンスでSocket.IOを使う場合、同一クライアントからの通信は同一インスタンスへ流れるように固定しないと、最初のハンドシェイクで失敗します。
FrontendとBFFが同じアプリの場合
ドキュメントにある通り、アプリからJSESSIONIDを発行すればルーター側でVCAP_IDを発行して以降の通信を最初のインスタンスに固定してくれます。
https://docs.cloudfoundry.org/concepts/http-routing.html#sessions
本題:FrontendとBFFが別アプリの場合
方針
Frontendはnginx-buildpackで静的ファイルを配信、Socket.IOの通信はproxyしてBFFへ流す。
問題
BFF側のルーターから発行されたVCAP_IDが、Front側のルーターを経由する時に上書きされてしまい、BFFへの通信が固定できない。
対策
FrontendのNginxを経由する時にJSESSIONIDとVCAP_IDのCookie名を変更する。
なおCookie名の書き換えにLuaライブラリを使うので、こちらを参考に実行バイナリをOpenRestyに変更してください。
https://qiita.com/proyuki02/items/431dd297804ad53f2717
http {
server {
header_filter_by_lua_block {
local cookies = ngx.header.set_cookie
if not cookies then return end
if type(cookies) ~= "table" then cookies = {cookies} end
local newcookies = {}
for i, val in ipairs(cookies) do
val = string.gsub(val, "JSESSIONID=", "JID=")
val = string.gsub(val, "__VCAP_ID__=", "VID=")
table.insert(newcookies, val)
end
ngx.header.set_cookie = newcookies
}
location /socket.io/ {
proxy_pass https://{{env "REDIRECT_HOST"}}/socket.io/;
proxy_set_header Host {{env "REDIRECT_HOST"}};
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
set $new_cookie $http_cookie;
if ($new_cookie ~ "(.*)(^|;)(\s*)JID=(.*)$") {
set $new_cookie "$1$2$3JSESSIONID=$4";
}
if ($new_cookie ~ "(.*)(^|;)(\s*)VID=(.*)$") {
set $new_cookie "$1$2$3__VCAP_ID__=$4";
}
proxy_set_header Cookie $new_cookie;
}
}
}
以上です。