简体   繁体   中英

Does nginx have a Routing API?

I am trying to see if nginx (OSS, not commercial) can be used not only as a load balancer, but as a network router/switch in the event that I need to shut my app down and redirect traffic to a CDN/static page, etc.

I was hoping to find a REST API that might allow me to configure routing rules on the fly but alas, I see nothing.

Does nginx provide this functionality out of the box? Or can I pair it with something that does? This would be a Java app it is balancing, and I see there is an nginx-clojure module. So perhaps I could expose a REST endpoint through Java (running on the nginx server) somehow...thoughts?

If you use nginx-clojure to do such work you need

  • a java/clojure rewrite handler which is used as a router
  • a java/clojure content handler which acts as a router API endpoint
  • a shared map which is used to share state/rules among nginx worker processes (this is needed if the number of nginx worker processes > 1)

eg

In nginx.conf

## InitHandler is used to initialize shared map
jvm_init_handler_name my.InitHandler;

upstream myApp {
  .....
}

## requests will be redirected to upstream staticBackend when my app is down
upstream staticBackend {
 ....
}

server {

....

## share state/rules among nginx worker processes
shared_map routerRules tinymap?space=32k&entries=256;

## $mybackend will be changed by rewrite handler MyRouter
set $mybackend "";

location / {
  rewrite_handler_type java;
  rewrite_handler_name my.MyRouter;

  proxy_pass http://$mybackend;
}

location /restapi {
  content_handler_type java;
  content_handler_name my.MyRouterApi;
}

}

In InitHandler.java

public class InitHandler implements NginxJavaRingHandler {
  public static NginxSharedHashMap<String, String> rules;

  public Object[] invoke(Map<String, String> fakeRequest) {
     rules = NginxSharedHashMap.build("routerRules");
  }
}

In MyRouter.java

public class MyRouter implements  NginxJavaRingHandler {
   public Object[] invoke(Map<String, String> req) {
       String backend = InitHandler.rules.get("mybackend");
       if (backend == null) {
            backend = "myApp"; 
        }
       ((NginxJavaRequest)req).setVariable("mybackend", backend);
       return nginx.clojure.java.Constants.PHASE_DONE;
   }
}

In MyRouterApi.java

public class MyRouterApi implements  NginxJavaRingHandler {
   public Object[] invoke(Map<String, String> req) {

       String backend = req.get(MiniConstants.QUERY_STRING);

       /*chek backend ...... */

       //update the entry whose key is "mybackend" in the shared map
       InitHandler.rules.put("mybackend", backend);

        return new Object[] {200, null, "OK"};
   }
}

More docs can be found from https://nginx-clojure.github.io/ .

BTW the embedding API will make dev/testing with nginx-clojure quite easy.

There is no API out of the box. You have to write some endpoint-snippets and use variables in your upstream config.

Take a look at:

https://github.com/openresty/lua-nginx-module#readme

It's fairly simple.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM