如何从多台机器上为我的 django 网站提供服务,即如何使其分布式?

Posted

技术标签:

【中文标题】如何从多台机器上为我的 django 网站提供服务,即如何使其分布式?【英文标题】:How can I serve my django website from multiple machines, that is how can I make it distributed? 【发布时间】:2020-03-23 18:41:36 【问题描述】:

我有我的 django 网站,我想做分布式,我知道系统设计和分布式系统的所有概念,但仍然不知道如何使用多个服务器为它提供服务。我正在尝试使我的系统分布式,以便我可以从两台机器上为我的网站提供服务(这就是分布式系统的工作方式)。我已经用 Django 编写了我的网站。我想知道让我的同一个网站由两台机器提供服务的步骤。这就是两个系统将如何相互了解,它们将如何连接以及每当请求进入时将选择其中一个服务器来处理请求。在这种情况下,我应该使用什么软件或工具来加入我的服务器以及哪些软件会接受请求,以便它可以决定将请求发送到哪台机器以及在这种情况下应该如何配置数据库?

P.S:我唯一知道的是如何使用一台服务器为我的 django 网站提供服务(从 Linode、DigitalOcean 获取机器实例)。我想为我的网站实现系统设计分布式系统概念,以便我可以通过亲自实现它来学习系统设计的所有概念

【问题讨论】:

您愿意实现的几乎可以作为客户端-服务器架构工作,您将拥有各种 Django 网页(客户端),它们将通过 API 与集中式数据库服务器(服务器)进行通信,以执行因此,您只需从客户端向数据库进行 AJAX 调用即可对数据进行 CRUD。 您的应用程序将部署在哪里/如何部署? HAProxy 是伟大的开源负载均衡器,nginx(和大多数 Web 服务器)可以配置为负载均衡器。如果您使用任何流行的数据库解决方案,拥有集中式数据库应该没有问题 @IainShelvington 有没有在 Django 中实现相同的教程 @FarhanAhmed 这真的取决于你打算如何部署你的应用程序。如果您打算在一堆虚拟机上部署,那么如果您打算在 kubernetes 上容器化您的应用程序,这是一个非常不同的解决方案。此页面可能对django-book.readthedocs.io/en/latest/chapter12.html 有所帮助,“实施负载平衡和冗余”部分与您的要求相关 【参考方案1】:

从单一服务器设置到分布式(高可用性)的步骤不是一个非常简单的步骤,并且与 Django 没有太大关系,而与通用服务器基础架构更相关。但是,有很多资源可以帮助您入门。

考虑到您提到了 DigitalOcean,我相信他们网站上的以下教程将引导您朝着正确的方向前进:Building for Production: Web Applications — Overview。

在完整阅读该文章之前,请务必阅读5 Common Server Setups For Your Web Application。它很好地概述了常见的服务器设置,从单个服务器到您想要的状态。

【讨论】:

【参考方案2】:

您要做的是为您的应用程序实现分布式系统概念。为此,您需要了解分布式系统和系统设计的概念。 Django 与将您的网站扩展到多个服务器无关。它现在都掌握在分布式系统技术和软件的手中。无论我在这个答案中解释了什么,都可以让您对分布式系统的工作方式有一个基本而全面的了解。

我可以简要解释一下如何实现这一目标。我假设您有两台服务器,您希望请求进入并由任何一台服务器提供服务。(就像任何分布式系统的工作方式一样)。

首先您应该熟悉负载平衡器、Web 服务器、应用程序服务器、数据库服务器的概念。

当我们有一台服务器时,一切都容易多了,我们有一台服务器来设置我们的 web 服务器(例如 apache),我们需要一些接口,以便我们的 web 服务器和 web 框架可以相互通信,所以我们安装了 mod_wsgi apache 模块,该模块可以通过 WSGI 接口规范与 Django 进行通信。从那时起,我们只需要编辑我们的 apache conf 文件就可以开始了。

现在,我们知道单个 Web 服务器不足以处理这些请求。我们又购买了一台服务器以减少一台服务器的负载。您需要做的第一件事是将相同的 Django 网站代码复制到另一台服务器。这样两者都将运行相同的前端代码,并且我们的应用程序服务器(Django)可以处理请求。现在,当一个请求进来时,我们需要将它转发到任何一个服务器,为了实现这一点,我们配置一个负载均衡器来一个一个地向它们发送请求(或者您可以使用其他算法)。现在,只要有请求进来,负载均衡器就会接收请求并将其转发到我们的任何一台服务器。您应该在两台机器上都有 Web 服务器(例如 apache),因为这里的负载均衡器的任务只是将请求定向到任何一台服务器。负载均衡器是一台服务器(通常)——它位于一组应用程序服务器的前面并管理它们之间的流量。传入的 Web 流量通过负载均衡器在 Web 和应用程序服务器之间分配。

为了更好的理解让我们理解这个图,

其中有两个负载平衡器,但它们位于主动/被动对 - 也称为 HA(高可用性)对。让我们将它们视为一个(因为另一个是故障转移)。另一个只有在第一个失败时才会出现。在它们后面是两个 Web 服务器。这些可能是 Apache Web 服务器。负载均衡器具有应用程序服务器的内部 IP。负载均衡器接受传入的请求并将它们转发到准备接受它们的服务器。负载均衡器只执行接收初始请求并确保它得到 Web 服务器响应的功能。 Web 服务器是一个用信息响应请求的软件。应用服务器接受一个请求并处理它,并通过一个作为中介的 Web 服务器返回一个回复。 应用服务器的示例可以是 Ruby/Rails、php、Django 等。这些服务器是应用程序“代码”执行的地方。缓存、正向和反向代理都是在 Web 服务器层之前执行的,以减轻 Web 服务器的压力。 其中一项技术是 HAProxy,它是一种免费的开源软件,可为基于 TCP 和 HTTP 的应用程序提供高可用性负载平衡器和代理服务器,从而将请求分散到多个服务器。

现在进入 数据库 部分,您可以将数据库托管在任何一台机器上(使用 mysql 服务器),并使用您的数据库地址使两台服务器连接到同一个数据库。您可以拥有一个集中式数据库,您的应用程序框架将从该数据库中读取数据。数据将由数据库服务器(例如 MYSQL)提供服务,并且所有并发性和可用性概念都将由它处理,以防两个服务器同时请求访问相同的数据。

另外请注意,您的负载均衡器还将在任何一台运行的机器上接收请求并将其转发到您的任何一台服务器。

当我们有多个服务器时,又会出现一个问题:

当您的网站仅由一个网络服务器提供服务时,对于每个 客户端-服务器对,会话对象被创建并保留在 Web 服务器的内存。来自客户端的所有请求都到这里 Web 服务器并更新此会话对象。如果需要一些数据 在交互期间存储在会话对象中,它是 存储在此会话对象中,并在会话期间一直存在 存在。如果您的网站由多个 Web 服务器提供服务,这些服务器位于 在负载均衡器后面,负载均衡器决定哪个实际 (物理)网络服务器应该每个请求去。例如,如果有 是负载均衡器后面的 3 个 Web 服务器 A、B 和 C,有可能 www.mywebsite.com/index.jsp 由服务器 A 提供服务, www.mywebsite.com/login.jsp 由服务器 B 提供,并且 www.mywebsite.com/acoutdetails.php 由服务器 C 提供服务。

现在,如果请求是从(物理上)3 个不同的 服务器,每个服务器都为您创建了一个会话对象,因为 这些会话对象位于三个独立的盒子上,没有 直接知道会话对象中有什么的方法 其他。

有多种方法可以为会话维护同一台服务器:

通过存储会话

您必须将会话存储在一个公共存储中 服务器可以访问,您可以将会话存储在文件中(由 NFS 可供两台服务器访问)通常不建议这样做 因为它很慢。您可以将会话存储在 DB 中。最好的方法是 使用 Redis/Memcached 类型的设置来存储您的会话和 检索它们,它们很快,它们可以在很多人之间共享 节点。

使用粘性会话

如果指示负载平衡器使用粘性会话,则您的所有 交互将发生在同一个物理服务器上,即使 存在其他服务器。因此,您的会话对象将是相同的 在您与本网站的整个互动过程中。路由器或负载 具有粘性会话支持的平衡器可以将单个服务器分配给 特定用户,基于他们的 HTTP 会话或 IP 地址。这 分配的服务器被路由器记住一定数量的 时间,确保发送同一会话的所有未来请求 到同一台服务器。

注意:如果有人在答案中发现任何可能与实际概念不符的信息,请建议编辑或在 cmets 中回复,因为这将有助于相互理解分布式系统概念。

【讨论】:

这是否回答了您的问题,还是您需要更多解释? 非常全面的答案。谢谢@Himanshu。

以上是关于如何从多台机器上为我的 django 网站提供服务,即如何使其分布式?的主要内容,如果未能解决你的问题,请参考以下文章

如何让 nginx 从不同的端口提供 django admin css 文件

如何通过 Django 正确地为我的 React 生产构建提供服务。当前配置存在 MIME 类型问题

如何在网站上为多个用户运行 Gmail API?

从 MVC / IIS Web 应用程序向子域提供服务

如何从 EKS 集群为 Django 提供静态文件?

如何在 iTune Connect 上为我的 iPhone 应用程序设置自动更新应用程序内购买?