jobwat
10/26/2015 - 9:48 PM

Dynamic Nginx upstream nodes using Consul

Dynamic Nginx upstream nodes using Consul

worker_processes  1;

events {
    worker_connections  1024;
}

http {
    include       mime.types;
    default_type  application/octet-stream;
    lua_package_path "/etc/nginx/lua/?.lua;;";
    lua_code_cache off;
    init_by_lua 'consul = require "resty.consul"';

    sendfile        on;
    keepalive_timeout  65;

    server {
        listen       80;
        server_name  localhost;
        location / {
            set $upstream "";
            rewrite_by_lua 'ngx.var.upstream = consul.service_nodes("www")';
            proxy_buffering             off;
            proxy_set_header            Host $host;
            proxy_set_header            X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_redirect              off;
            proxy_connect_timeout       10;
            proxy_send_timeout          30;
            proxy_read_timeout          30;
            proxy_pass                  http://$upstream;          
        }
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
    }
}
module("resty.consul", package.seeall)

_VERSION = '0.1.0'

function service_nodes(service)
  local http = require "resty.http"
  local json = require "cjson"
  local hc = http:new()

  local upstream = ""
  
  local res, err = hc:request_uri("http://127.0.0.1:8500/v1/catalog/service/" .. service)
  
  if res.body then
    local nodes = json.decode(res.body)
    node = math.random(1, #nodes)
    upstream = nodes[node]["ServiceAddress"] .. ":" .. nodes[node]["ServicePort"]
  end
  
  return upstream
end