Is there any way to configure nginx (or other quick reverse proxy) dynamically?
Asked Answered
J

8

27

Suppose we have several identical nodes which are the application servers of some n-tier service. And suppose we use Apache ZooKeeper to keep all the config's of our distributed application. Plus we have an nginx as a load balancer and reverse proxy in front of this application.

So let's say we perform a command which changes data only on node1, and for some period of time node2 differs from node1. And we want proxy to redirect all that special requests (which need that specific data) to node1 until all the infomation has migrated to node2 and node2 has the same data as node1.

Is there any way to make nginx (or other proxy) read its config from Apache ZooKeeper? Or more broader: is there any way to effectively switch proxy configuration on fly? And of course it should be done without (or with minimal) downtime of the whole system - so restarting nginx is not the option.

Justinjustina answered 24/1, 2012 at 6:12 Comment(1)
until the information fully migrated to a given node can you return a 5xx code from that node?Daynadays
W
50

Nginx has two methods of changing configuration:

  • HUP signal to the master process results in "reload". Nginx starts a bunch of new workers and lets the old workers to shutdown gracefully, i.e. they finish existing requests. There is no interruption of service. This method of configuration change is very lightweight and quick, but has few limitations: you cannot change cache zones or re-compile Perl scripts.

  • USR2 signal, then WINCH and then QUIT to the master process result in "executable upgrade" and this sequence lets completely re-read whole configuration and even upgrade the Nginx executable. It reloads disk caches as well (which maybe time consuming). This method results in no interruption of service too.

Official documentation

Whiskey answered 24/1, 2012 at 14:46 Comment(2)
Thank you! I'm far from being expert in nginx, you gave me a good piece of information to think about.Justinjustina
this should be the official answerCalabrese
B
7

Please try Nginx-Clojure. We can use a clojure/java/groovy rewrite handler to access zookeeper then update some nginx variables to dynamically change proxy target. e.g.

In nginx.conf

set $mytarget "";

location / {
   rewrite_handler_type java;
   ## We will change $mytarget in MyRewriteHandler
   rewrite_handler_name my.MyRewriteHandler;
   proxy_pass $mytarget;
}

In MyRewriteHandler.java

public static class MyRewriteHandler implements NginxJavaRingHandler {

        @Override
        public Object[] invoke(Map<String, Object> request) {
           //access zookeeper
           ...............
           //change nginx variable mytarget
           ((NginxJavaRequest)request).setVaraible("mytarget", "http://some-host-or-url");
        }
Boozy answered 14/8, 2015 at 2:31 Comment(0)
B
3

This may be late but if you have the money. Nginx plus is exactly for you. It uses a simple url call to get new configurations on the fly.

Bevin answered 8/7, 2014 at 14:56 Comment(1)
It's $1900 per year for a single instance.Conserve
L
2

As an update:Hipache stores its host configuration in redis, which can easily be manipulated at runtime. It's also based on node.js and node-http-proxy.

Labrie answered 15/6, 2013 at 8:51 Comment(0)
L
2

There is an interesting project using nginx Lua to allow dynamic configuration of nginx and doing exactly what you want (https://github.com/samalba/hipache-nginx)

It is written by the guys behind Hipache.

Lysenkoism answered 22/7, 2013 at 17:29 Comment(0)
S
2

It is possible using HAProxy and its UNIX domain socket interface: http://cbonte.github.io/haproxy-dconv/configuration-1.5.html#9.2.

It supports switching a server or an entire front-end from down to up and back again on the fly. With a configuration file that defines two sets of front-ends, each configured for one specific state, you would be able to achieve what you want.

Seminal answered 8/7, 2014 at 15:13 Comment(0)
S
0

Not sure that it is possible to dynamicaly change nginx configuration without restarting a server.

If I had a same requirement I'd probably dug into nodejs and zookeeper integration.

There are several interesting opensource projects:

node-zookeeper integrates nodejs with zookeeper;

node-http-proxy proxy http server that can be used for load balancing.

Of course they lack maturity but they might be interesting for you.

Spruill answered 24/1, 2012 at 8:54 Comment(2)
It is possible: nginx reloadNickel
httpd RewriteMap directive using a database/file mappingFlotation
M
-1

From Docs:

nginx -s reload

-s is for 'signal', where signal can be 'quit', 'reload', 'reopen', or 'stop'.

Michelinamicheline answered 11/6, 2018 at 10:58 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.