Django服务器设置之旅--第二部分

Python部落(python.freelycode.com)组织翻译,禁止转载,欢迎转发。

外部服务-对象存储


把文件存储从Web服务器推到“对象存储”很常见,“对象存储”基本上是一个好的API后面的文件系统,通常用django-storages完成,我很喜欢用。对象存储通常用于用户上传的“媒体”,例如文档、照片和视频。为此,我用AWS S3(简单存储服务),但是每个大型云托管提供商都提供某种“对象存储”服务。


9.png


这么做有以下这些好处:


  • 你已经把应用程序的所有状态(文件、数据库)移出了服务器,现在可以移动、销毁和重建Django服务器,而不丢失数据

  • 文件下载触发对象存储服务,而不是服务器,这意味着你可以更容易地扩展文件下载

  • 不用担心任何文件系统管理,比如磁盘空间不足

  • 多个服务器可以轻松共享同一组文件


希望你能在这里看到一个重点,我们在把我们不关心的问题变成别人要关心的问题。付费让别人管理我们的文件和数据库,我们就有了更多时间去做更重要的事情。


外部服务-Web服务器


你还可以在与“应用程序服务器”(Gunicorn + Django)不同的虚拟机上运行“ Web服务器”(NGINX):


10.png


Nginx外部设置这似乎毫无意义,为什么要这么做呢?其一,为了处理冗余和高流量,你可能设置了多个相同的应用服务器,NGINX可以作为不同服务器间的负载均衡器。


11.png


也可以用现成的负载均衡器替代NGINX,比如AWS 弹性负载均衡器或类似这种)。


注意,把我们的服务放在它们自己的服务器上,我们就可以在多个虚拟机上对它们进行扩展。如果同时有文件系统的三个副本和三个数据库,就不能在三个服务器上同时运行Django应用程序。


外部服务-任务队列


你也可以把“脱机任务”服务推到它们自己的服务器上。通常,代理服务有自己的机器,辅助进程在另一台机器运行:


12.png


把辅助进程分到它自己的服务器上很有用,因为:


  • 可以保护Django Web应用程序免受“噪音邻居”(占用所有RAM和CPU的辅助进程)的影响

  • 可以为辅助进程服务器提供所需的额外资源:CPU、RAM或访问GPU

  • 现在,你可以更改辅助进程服务器,而不必担心损坏任务队列或Web服务器


既然已经分离了辅助进程,还可以扩展辅助进程,同时运行更多任务:


13.png


你可能会把自己管理的代理(Redis或RabbitMQ)换成Amazon SQS那样的管理队列。


外部服务-最终形式


如果考虑以上所有内容,可以这么设置Django应用程序:


14.png


如你所见,可以把Django应用程序的所有部分拆分到多个服务器。虽然这么做有很多好处,但缺点是要提供、更新、监控、维护多个服务器。有时候这些额外的付出是值得的,有时候是浪费时间。也就是说,这么设置有很多好处:


  • Web服务器和辅助服务器是完全可替换的,可以在不影响正常运行时间的情况下进行销毁、创建和更新

  • 可以在Web应用不停机的情况下进行蓝绿部署

  • 文件和数据库容易在多个服务器和应用程序间共享

  • 可以为不同的工作量提供不同大小的服务器

  • 可以把自己管理的服务器换成托管的基础架构,比如把任务代理移到AWS SQS,或者把数据库移到AWS RDS

  • 现在,你可以自动缩放服务器(稍后会详细介绍)


有了像这样复杂的基础架构,就要开始实现基础架构设置和服务器配置的自动化。一旦设置里包含了这么多活动的部分,手动管理就不可行了。我在一个有关配置管理的视频(https://mattsegal.dev/intro-config-management.html)里介绍了这些概念。你需要开始研究诸如Ansible和Packer之类的工具来配置虚拟机,还有像Terraform或CloudFormation之类的工具来配置云服务。


自动缩放组


现在,你已经知道如何让多个Web服务器运行同一个应用程序,或者多个辅助进程服务器都从一个队列中提取任务。这些服务器每小时要花很多钱,运行比所需更多的服务器可能会很贵。


这就是自动缩放的切入点。你可以设置云服务,通过某种诱因(例如虚拟机CPU使用率),从映像自动创建新的虚拟机,将其添加到自动缩放组。


以任务辅助服务器为例。如果你有缩略图服务,可以把上传的大型照片缩小,一台服务器大约每秒处理几十个文件上传。如果在一天中的某些时段(比如下班后6点左右),你看到文件上传数量从每秒几十个激增到每秒几千个,怎么办?需要更多服务器!有了自动缩放设置,辅助服务器上的CPU使用率将激增,触发创建越来越多辅助服务器,直到足以处理所有上传。当文件上传速度下降时,多余的服务器会自动销毁,所以不用总是付费。


容器集群


我还没有详细介绍整个容器集群,因为:


  • 我不太了解

  • 对于这篇文章的目标受众来说,这有点复杂

  • 我认为大多数人都不需要


完整起见,我会快速介绍一些可以用容器做的又酷又疯狂的事情。你可以用Kubernetes和Docker Swarm之类的工具和一组配置文件,把所有服务定义为Docker容器,规定它们如何相互通信。所有容器都在Kubernetes / Swarm集群中运行,但是作为开发人员,你并不关心它们在哪个服务器上。只需构建Docker容器,编写配置文件,然后将其推送到基础架构。


15.png


使用这些“容器编排”工具,可以将容器与其底层基础结构分离。多个团队可以把应用程序部署到同一组服务器上,这些应用程序之间不会有任何冲突。这种基础结构允许团队部署微服务。像Target这样的大企业有专业团队设置和维护容器编排系统,其他团队可以直接用,而无需考虑基础服务器。这些团队实质上是为组织的其余部分提供“平台即服务”(PaaS)。


正如你可能注意到的,这些容器编排工具可能过于复杂,对单个开发人员甚至是小团队来说,都不值得花时间。如果对这些感兴趣,你可能会喜欢Dokku,它声称是“你见过的最小的PaaS实现”。


旅途结束


以上就是我知道的关于在生产环境中如何设置Django的所有内容。如果你对培养基础结构技能感兴趣,建议你尝试一下本文中提到的设置或工具。希望你已经建立了Django部署的心智模型,这样下次有人提到“任务代理”或“自动缩放”的时候,你对他们的谈论内容有一定了解。


如果喜欢这篇文章,你可能也会喜欢我写的其他内容,包括尽可能简单地部署Django(https://mattsegal.dev/simple-django-deployment.html)、如何执行脱机任务(https://mattsegal.dev/offline-tasks.html)、如何记录文件(https://mattsegal.dev/file-logging-django.html)和跟踪产品中的错误(https://mattsegal.dev/sentry-for-django-error-monitoring.html)、以及我对配置管理的介绍(https://mattsegal.dev/intro-config-management.html)。


如果喜欢本文的方框图,请移步Exalidraw(https://excalidraw.com/)。


英文原文:https://mattsegal.dev/django-prod-architectures.html
译者:momo