Skip to content

Instantly share code, notes, and snippets.

@gmr
Created July 14, 2014 17:03
Show Gist options
  • Save gmr/82801bf32c62e5fedb3f to your computer and use it in GitHub Desktop.
Save gmr/82801bf32c62e5fedb3f to your computer and use it in GitHub Desktop.
Dynamic Nginx upstream nodes using Consul
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 ok, code, headers, status, body = hc:request {
url = "http://127.0.0.1:8500/v1/catalog/service/" .. service,
port = 8500,
method = "GET"
}
if body then
local nodes = json.decode(body)
node = math.random(1, #nodes)
upstream = nodes[node]["Address"] .. ":" .. nodes[node]["ServicePort"]
end
return upstream
end
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;
}
}
}
@outrunthewolf
Copy link

Been searching for this all day. Nice one! 👍

@NeMO84
Copy link

NeMO84 commented Mar 19, 2015

Kudos!!

How would you make the above call with basic auth enabled on the consul api; assuming consul service isn't running on localhost?

@foxx
Copy link

foxx commented Apr 3, 2018

Doesn't this result in every request hitting Consul? Shouldn't it be using a background thread instead?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment