2016-02-12 66 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