2016-02-12 76 views
1

我想看看nginx(OSS,不是商业)不仅可以用作负载平衡器,还可以用作网络路由器/交换机,以防止我需要关闭应用并将流量重定向到CDN /静态页面等。nginx是否有路由API?

我希望能找到一个REST API,可以让我动态地配置路由规则,但是唉,我一无所知。

nginx是否提供开箱即用的功能?或者我可以将它与一些东西配对吗?这将是一个平衡的Java应用程序,并且我看到有一个nginx-clojure模块。所以也许我可以通过Java(在nginx服务器上运行)公开一个REST端点......想法?

回答

2

如果使用nginx的,Clojure中做这样的工作,你需要它作为一个路由器的

  • 一个Java/Clojure的重写处理
  • 充当路由器API端点的Java/Clojure的内容处理程序
  • 共享地图被用来共享nginx的工作进程中的状态/规则(这是需要如果nginx的工作进程的数量> 1)

例如

在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; 
} 

} 

在InitHandler.java

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

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

在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; 
    } 
} 

在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"}; 
    } 
} 

更多文档可以从https://nginx-clojure.github.io/找到。

顺便提一下,embedding API将使用nginx-clojure开发/测试相当容易。

+0

非常感谢你这么好的回答@xfeep(+1) - 如果你不介意的话,两个快速跟进问题! **(1)**假设通常'myApp'应该在'myapp01.example.org'和'myapp02.example.org'之间进行负载平衡。假设我决定将流量重新路由到静态CDN,应该提供的URL是“mycdn.example.org”。上游myApp,上游staticBackend和MyRouterApi#invoke现在看起来像什么? – smeeb

+0

**(2)**如果地图的大小为32k,并且允许256个条目,那么我认为这会为每个条目留下128个字节,是的? **每个条目代表什么(一个HTTP请求?)并且128字节足够的存储空间?** – smeeb

+0

啊,对不起,我撒了谎!我还有一个最后一个问题(对不起!):**(3)**是否可以在此解决方案中使用HTTPS和身份验证(BasicAuth,JWT等)?理想情况下,'/ restapi'“端点”(内容处理程序)将受到外界的保护......思考? – smeeb