设置反向代理环境时,服务器复制是如何实现的?

设置反向代理环境时,服务器复制是如何实现的?

我一直在阅读并尝试设置一些不同的服务器集群环境。我使用各种 Linux 发行版都能够正常工作。

基本设置如下:

                -----  App Server 1
                |                        Database Server 1
Load Balancer --|                        Database Server 2
                |
                -----  App Server 2

如您所见,这是一个基本的从属-主设置。我的问题是,我不确定复制应用服务器部分的最佳方法。因此,如果对应用服务器 1 进行了新的脚本文件或更改,这些更改如何级联到第二台应用服务器?

数据库服务器运行 MySQL,因此对一个数据库服务器的任何更新都会自动传递到其他数据库服务器。

答案1

其 TL;DR 版本如下:这取决于应用程序

作为关于如何构建现代软件的良好参考,我强烈建议阅读十二因素应用

脚本和代码不会被复制,而是“发布”到应用服务器(您也可以通过发布到所有服务器并使用另一种机制(例如符号链接)从旧代码切换到新代码来启动服务器)。

但是,客户端经常具有“状态”,应用服务器可能需要记住这些状态才能正确地处理请求。

一般来说,为了使应用服务器能够水平扩展,您希望它们尽可能“无状态”。这意味着应用服务器无需记住任何内容,所有内容都存储在外部,并且任何请求都可以通过请求中收到的数据来满足。但是,您的客户端(Web 浏览器)通常需要状态,例如登录,因此您需要能够以某种方式处理状态数据。

一种解决方法是使用在负载均衡器上实现的“粘性会话”。通常,这是通过注入 cookie 来实现的,负载均衡器会使用该 cookie 来记住应该将请求发送到哪个服务器。这很容易实现,不需要更改代码,但有一个相当大的缺点,即每次重新启动应用服务器时状态都会丢失。

另一种方法是通过将所有内容存储在 cookie 中来实现应用无状态化。我完全不推荐这样做,因为状态数据将在每次请求时上传。客户端还可以修改这些数据并执行意外操作,如果有人捕获 cookie,可能会对隐私产生巨大影响。

这些都不能解决磁盘文件问题,因为它们依赖于 cookie,而用户可能会丢失 cookie,或者他们可能只是从其他地方登录。

最后一种也是推荐的方法是将客户端状态存储在数据库(或键值存储)中,以便任何应用实例在收到请求时都可以查询它。您仍然需要客户端记住“会话 ID”,但由于客户端存储的数据较少,因此更安全。传统上,具有一致性哈希的 memcached 节点集群将充当此角色,但现在有更强大的解决方案,例如Redis

关于磁盘上的文件 - 不要在应用服务器磁盘上存储任何内容,除了可以作为部署的一部分“发布”的应用程序代码和静态资产。日志可能是一个例外,但将它们推送到远程 syslog 服务器或类似 logstash 的服务器总是更好的选择。

如果你的应用程序必须存储文件(比如客户端上传的文件),那么可以将它们存储在某种数据存储中(Cassandra 是个不错的选择),或者某种存储服务中,比如 Openstack 的迅速或者,如果您的规模不够大,无法自己做,也可以使用 Amazon S3。

如果应用程序规模较小并且您正确处理文件锁定,则 NFS 或 samba 共享也可以工作,但在采用这条路线之前,我建议使用 Amazon S3。

答案2

通常,您需要一个环境,您可以在其中测试代码更改,然后将其分批推广到您的应用服务器(在您的图中,先是一台服务器,然后是另一台服务器)。但是,如果您有数据库架构更改,这会变得有点复杂,您可能需要编写代码来考虑到这一点。

如果你想要复制文件系统的更改,你可以使用类似DRBD或者格鲁斯特拥有一个共享文件系统。或者,rsync根据您的要求,使用类似 --- 的内容创建您自己的自定义解决方案。

相关内容