有没有办法动态配置 nginx(或其他快速反向代理)?

Posted

技术标签:

【中文标题】有没有办法动态配置 nginx(或其他快速反向代理)?【英文标题】:Is there any way to configure nginx (or other quick reverse proxy) dynamically? 【发布时间】:2012-02-17 10:57:45 【问题描述】:

假设我们有几个相同的节点,它们是某个 n 层服务的应用服务器。假设我们使用 Apache ZooKeeper 来保存我们分布式应用程序的所有配置。另外,我们在这个应用程序前面有一个 nginx 作为负载均衡器和反向代理。

假设我们执行了一个仅在 node1 上更改数据的命令,并且在一段时间内 node2 与 node1 不同。我们希望代理将所有特殊请求(需要特定数据)重定向到 node1,直到所有信息都迁移到 node2 并且 node2 具有与 node1 相同的数据。

有没有办法让 nginx(或其他代理)从 Apache ZooKeeper 读取其配置?或更广泛地说:有什么方法可以有效地即时切换代理配置?当然,它应该在整个系统没有(或最少)停机时间的情况下完成 - 所以重启 nginx 不是选项。

【问题讨论】:

在信息完全迁移到给定节点之前,您能否从该节点返回 5xx 代码? 【参考方案1】:

不确定是否可以在不重新启动服务器的情况下动态更改 nginx 配置。

如果我有同样的要求,我可能会深入研究 nodejszookeeper 集成。

有几个有趣的开源项目:

node-zookeeper 将nodejszookeeper 集成;

node-http-proxy代理http服务器,可用于负载均衡。

当然他们不够成熟,但他们可能对你很感兴趣。

【讨论】:

谢谢!非常有趣的想法,我会检查一下。 可能的:nginx reload httpd RewriteMap 使用数据库/文件映射的指令【参考方案2】:

Nginx 有两种更改配置的方法:

HUP 向主进程发送信号会导致“重新加载”。 Nginx 启动了一堆新的 worker 并让旧的 worker 优雅地关闭,即他们完成现有的请求。 没有服务中断。这种配置更改方法非常轻量且快速,但限制很少:您无法更改缓存区域或重新编译 Perl 脚本。

USR2 信号,然后WINCH,然后QUIT 到主进程导致“可执行升级”,这个序列可以完全重新读取整个配置,甚至升级 Nginx 可执行文件。它还会重新加载磁盘缓存(这可能很耗时)。此方法也导致不会服务中断。

Official documentation

【讨论】:

谢谢!我远不是 nginx 方面的专家,你给了我一个很好的信息来思考。 这应该是官方的回答【参考方案3】:

作为更新:Hipache 将其主机配置存储在 redis 中,可以在运行时轻松操作。它也基于 node.js 和 node-http-proxy。

【讨论】:

【参考方案4】:

有一个有趣的项目使用 nginx Lua 允许动态配置 nginx 并做你想做的事 (https://github.com/samalba/hipache-nginx)

它是由 Hipache 背后的人编写的。

【讨论】:

【参考方案5】:

这可能会迟到,但如果你有钱的话。 Nginx plus is exactly for you. 它使用一个简单的 url 调用来即时获取新配置。

【讨论】:

单个实例每年 1900 美元。【参考方案6】:

可以使用 HAProxy 及其 UNIX 域套接字接口:http://cbonte.github.io/haproxy-dconv/configuration-1.5.html#9.2。

它支持动态切换服务器或整个前端从下到上再返回。使用定义了两组前端的配置文件,每组配置一个特定的状态,您将能够实现您想要的。

【讨论】:

【参考方案7】:

请尝试Nginx-Clojure。我们可以使用 clojure/java/groovy 重写处理程序来访问 zookeeper,然后更新一些 nginx 变量以动态更改代理目标。例如

在 nginx.conf 中

set $mytarget "";

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

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

【讨论】:

【参考方案8】:

来自Docs:

nginx -s reload

-s 用于“信号”,其中信号可以是“退出”、“重新加载”、“重新打开”或“停止”。

【讨论】:

以上是关于有没有办法动态配置 nginx(或其他快速反向代理)?的主要内容,如果未能解决你的问题,请参考以下文章

Nginx负载均衡与反向代理的配置和优化

haproxy反向代理功能配置

Nginx 最全操作——nginx反向代理(5)

用快速替换nginx作为反向代理

nginx反向代理为啥不成功

Nginx实例之反向代理Tomcat