ngx_mrubyで環境変数からPORTとTCPの接続先を決定したい


何がしたい

  • TCPの接続先を環境変数から決定したい
  • TCPで受けるサーバのポートを環境変数から決定したい

どうする?

ngx_mrubyを使って解決する

TCPの接続先を環境変数から決定したい

まず環境変数を

$ export BACKENDS="172.17.0.3:9999,172.17.0.2:9999"

と設定しておくこの環境変数を読んでTCPの接続先を決定してほしい.

nginx.confを編集する

nginxでは環境変数を受け取る仕組み?があります.
それがenv 環境変数;です.これをやっておかないと,ngixで環境変数を使えないので注意.
そうするとnginxのmruby内でBACKENDSを使えるようになる.

worker_processes  1;

env BACKENDS;
env LISTENER;

events {
    worker_connections  1024;
}
error_log   logs/error.log  debug;

stream {
    # proxy_protocol off;

    upstream tcpback {
        server 172.17.0.4:8888;
    }

    server {
        mruby_stream_server_context_code '
            Nginx::Stream.add_listener({address: ENV["LISTENER"]})
        ';

        mruby_stream_code '
            backendList = ENV["BACKENDS"].split(",")
            t = Nginx::Stream::Connection.new "tcpback"
            t.upstream_server = backendList[rand(backendList.length)]
        ';
        proxy_pass tcpback;
    }
}

backendList = ENV["BACKENDS"].split(",")の部分が環境変数を取得してリストにしているところです.
それをランダムにTCPサーバに接続させる処理をしています.
詳しく知りたい方は -> https://hb.matsumoto-r.jp/entry/2015/11/03/173605
これで環境変数から後ろにあるTCPサービスに接続させてくれます.

TCPで受けるサーバのポートを環境変数から決定したい

環境変数を取得するためにあらかじめ$ export LISTENER="0.0.0.0:2565"と設定しておく.
そうするとngx_mrubyで受け取れるようになるので

mruby_stream_server_context_code '
    Nginx::Stream.add_listener({address: ENV["LISTENER"]})
';

Nginx::Stream.add_listenerに環境変数LISTENERの値を渡してあげると待ち受けるポートを環境変数から決定することができます.

まとめ

環境変数でngixの接続先と待ち受けるポートの二つを決定することができるようになりました.
割と簡単にできて自分でもびっくりしてます.
まだまだよく分からずに使っている部分もあるので今後さらに理解できればいいなぁと思ってます.

全体のコード

worker_processes  1;


env BACKENDS;
env LISTENER;

events {
    worker_connections  1024;
}

error_log   logs/error.log  debug;
http {
    server {
        listen       8837;
        server_name  localhost;
        location /mruby {
            mruby_content_handler_code '

            backendList = ENV["BACKENDS"].split(",")
            for i in backendList do
                Nginx.echo i
            end
            ';
        }
    }
}

stream {
    # proxy_protocol off;

    upstream tcpback {
        # server 172.17.0.3:8888;
        server 172.17.0.4:8888;
    }
    # backendList = ["172.17.0.3:8888","172.17.0.4:8888"] 

    server {
        mruby_stream_server_context_code '
            Nginx::Stream.add_listener({address: ENV["LISTENER"]})
        ';

        mruby_stream_code '
            backendList = ENV["BACKENDS"].split(",")
            c = Nginx::Stream::Connection.new "tcpback"
            c.upstream_server = backendList[rand(backendList.length)]
        ';
        proxy_pass tcpback;
    }
}

参考