如果使用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开发/测试相当容易。
非常感谢你这么好的回答@xfeep(+1) - 如果你不介意的话,两个快速跟进问题! **(1)**假设通常'myApp'应该在'myapp01.example.org'和'myapp02.example.org'之间进行负载平衡。假设我决定将流量重新路由到静态CDN,应该提供的URL是“mycdn.example.org”。上游myApp,上游staticBackend和MyRouterApi#invoke现在看起来像什么? – smeeb
**(2)**如果地图的大小为32k,并且允许256个条目,那么我认为这会为每个条目留下128个字节,是的? **每个条目代表什么(一个HTTP请求?)并且128字节足够的存储空间?** – smeeb
啊,对不起,我撒了谎!我还有一个最后一个问题(对不起!):**(3)**是否可以在此解决方案中使用HTTPS和身份验证(BasicAuth,JWT等)?理想情况下,'/ restapi'“端点”(内容处理程序)将受到外界的保护......思考? – smeeb