2021年3月

亲测推荐 2021 年 SaaS 技术栈:Docker、Django、Traefik 和 IntercoolerJS

我最近发布了个人对Django做为一款优秀应用框架的一些考虑。本文基于此从架构角度做进一步扩展,介绍从开发到生产环境的整体技术栈考虑。

2018 年至今,我一直使用该技术栈构建一些小型 SaaS 应用。

本文最初发布于 www.simplecto.com,经原作者授权,由 InfoQ 翻译并分享。

整体技术栈

随处部署的 Linux 服务器和虚拟机:我使用了 Azure、Digital Ocean 和 Scaleway,并计划在 2021 年将所有部署迁移到Hetzner提供的专用服务器上。

Docker:就是我们常用的 Docker.

Traefik:使用 LetsEncrypt 证书的反向代理和 TLS。

Postgresql:运行在 Docker 中的数据库。

Django:同样运行在容器中。

IntercoolerJS:提供平滑易用的类 Ajax 前端应用支持。Intercooler 的创作者在 2021 年发布了HTMX,是 IntercoolerJS 的更新换代。

Sentry:捕获生产环境中软件缺陷。只需在配置文件中添加几行配置。

Bitbucket Pipelines 替代 CI/CD:鉴于 CI/CD 引入了过多繁琐无用的工具,我在 2021 年不再对个人项目考虑 CI/CD。

ZeroTier:实现 VPN 和控制层。

我在开发小型项目时,采用本地 Docker 容器运行测试,进而直接推送到生产环境。我不考虑使用繁琐的 CI/CD,而是选择了 Bitbucket Pipelines。

7597a5b78ab8a92a0bfadb3fecdfc653.jpeg

上图给出了我所采用技术栈的概览,图中有很多需要详细展开阐述的部分。下面换成列表方式展示。

  • 虚拟机
  • Docker
  • Django
  • 挂载数据磁盘卷
  • 使用长时间运行 Django 命令做为 Workers
  • 挂载数据磁盘卷
  • Postgres
  • 挂载数据磁盘卷
  • Traefik
  • Zero-Tier
  • SSH

托管环境

即便是无服务器架构,也需要一个云服务托管环境。我个人推荐Azure、Digital Ocean和Scaleway。每家都为计算、联网、存储和基本服务提供了充分的选项,支持用户任何构建需求。

同样推荐Hetzner,它提供了各服务层级的硬件、服务和价格。

虚拟机

一些企业应用和个人副业(side projects),并不需要同时为成千上万的用户提供 TB 级数据服务,因此可扩展性并非主要关注问题。对于此,我们可选用最小托管服务选项,通常不高于每月 20 美元。即便是服务价格相对最贵的 Azure,也可选用 Burstable 服务质量的虚拟机。个人推荐Scaleway的开发层级服务器。

注意:在我的技术栈中并没有 Kubernetes,因为我并未考虑可扩展性。

Docker

为确保新的虚拟机运行在最新版 Docker 上,我并没有依赖操作系统本身,而是使用了 curl|bash 方式,即:

curl -s https://get.docker.com | sudo bash

运行上面一行命令,就能获取最适用于当前运行环境的最新版本。

Traefik 实现反向代理

Traefik 对我简直是天赐之选。尽管 Nginx 也很强大,但其并非针对 Docker 环境构建。Traefik 的两个杀手级特性,为我节省了大量时间:

使用 LetsEncrypt 实现自动 TLS。简而言之,一旦设置,无需操心。结合适用的 API 和 DNS 服务提供商,还可以使用 DNS 验证。

使用 Docker label 实现无需重新加载的自动配置。一旦新服务发布,Traefik 通过监听所有 Docker 相关服务而自动发现更改。这使得服务的添加、移除和合并非常方便,不存在任何麻烦。

我对 Traefik 唯一意见是学习曲线略为陡峭。用户必须自行确定如何进行配置,包括配置文件、命令行选项、YAML、Docker label,乃至组合使用。

提示:我发布了自己使用的Traefik生产环境配置文件,供参考。

Postgres 数据库

亲测推荐,PostgreSQL 从不会令我失望。PostgreSQL 容器可毫无问题地添加到任何项目中。我只需简单地启动容器,绑定端口,挂接数据卷到主机磁盘,仅此足矣。

docker-compose.yml
version: '3.1'


services:


  db:
    container_name: postgres
    hostname: postgres
    image: postgres:11
    restart: always
    environment:
      POSTGRES_PASSWORD: secretsonly
    volumes:
      - ./data:/var/lib/postgresql/data
    ports:
      - 5432:5432
    networks:
      - web


networks:
    web:
        external: tr

用于 Web 的容器化 Django

Django 很好地支持发布到容器中,我多年以来一直这么用。我反复强调开发环境和生产环境匹配的重要性,Docker 为我实现了一切。

我在 2021 年新推出了一个 Django 项目,用做新项目的模板,参见https://github.com/simplecto/django-reference-implementation。

实现异步任务的 Django 命令

我使用做为标准框架组成的自定义Django命令实现异步任务。该模式采用具有 sleep()的 while 循环,轮询数据库相关操作,并采取相应的动作。

截止 2021 年,我已使用这一模式运行一个网站截屏项目一年多,回报丰厚。该项目每日对 1500 个网站做截屏,所有操作由 Django 命令计划和管理。项目地址:https://github.com/simplecto/screenshots。

IntercoolerJS 降低了复杂性

这里如果展开说,需推出多个帖子,恐怕内容太长,以至于不会有人愿意读。我结合 JQuery 和这个小型 JavaScript 库,实现部分类似单页应用的效果,尽管事实上并非单页应用。

IntercoolerJS 保留了 Ajax 的传统优点,从后端 HTML 更新 DOM,无缝且平滑,非常便于实现用户登录和更新小型表单等元素。

强力推荐访问IntercoolerJS官网。

其创立者在 2021 年继承发展了 IntercoolerJS,推出了HTMX。

Sentry 捕获生产中错误

任何应用都会出错,但不应向用户展示。Sentry 提供了一种捕获生产中软件缺陷的易用便捷方式,其特性包括:

开源许可,可在生产中任意部署。

只需在 Django 项目的 settings.py 中添加几行配置,即可生效。

与 Git 代码库和问题追踪系统紧密集成,提供全生产环境的缺陷可追踪能力。

另一个优点是,随时能在生产环境中禁用。

更多信息,可访问Sentry官网。

Bitbucket Pipelines 替代 CI/CD

2021 年,我不在个人项目的部署中使用 CI/CD。其中存在太多工具,复杂性高。我只是使用 PyCharm 运行测试,然后从开发设备直接交付生产环境。

当前存在多种 CI/CD 解决方案,但是我推荐 Bitbucket 提供的 Pipelines 的服务。该服务每月提供数百分钟的免费使用,只需很少费用就能提供自上而下的功能。我自己在使用中很少碰到问题,很喜欢它们的 YAML 配置文件。

我使用 bitbucket-pipelines.yml 文件,实现跨多个 Docker 容器的完全端到端测试,加载数据库,并在几分钟内执行数以百计的测试。该服务是我们团队高效的关键,支持生产环境中每日五次以上 Push。

更多信息,访问Bitbucket官网。

ZeroTier 实现 VPN

最后,推荐一种在很大程度上是可选的、但是最好应具备的技术。Zerotier 是一种独树一帜的网络/VPN 服务,我用其连接所有的个人计算机。它可穿透防火墙联通家庭和办公场所,一分钟即可配置好。

如果所有设备使用 ZeroTier,就可以避免 SSH 中令人头疼的密钥管理,单机上共享带宽。

Zerotier 可运行在 Linux、Mac、Windows、Android 和 iPhone 上,覆盖大部分设备。

ZeroTier 的一个问题在于,我并不完全了解它的工作机制。和 MacOS 和 iPhone 类似,它们会按用户期望工作,并不出问题,只是从用户体验角度看有些不爽。但对于一名 CTO,谁又会去关心具体的细节呢?

总结

希望上面的深入介绍能激发读者对 Docker、Django、Traefik,尤其是 IntercoolerJS 的兴趣。它们简单、易于使用,能在适当时大展身手。

原文链接: Docker, Django, Traefik, and IntercoolerJS is My Go-To Stack for Building a SaaS in 2021
https://www.infoq.cn/article/W4leI4XZ32eSTqFJ8qPl

我成功开发了一个 SaaS 项目,技术栈是这样的

作为一名忠于内心的工程师,每当我看到一家公司发布有关它们技术栈的文章时,我都会泡一杯咖啡,坐下来耐心阅读,看看有没有新的发现。了解其他公司业务背后隐藏的一些技术十分有趣。就像娱乐八卦一样,只不过这是技术层面的探索。

几个月前,我开始开发另一个 SaaS,该项目经历无数次迭代。幸运的是,尽管项目仍处于早期阶段,但是很多网站已经对其进行了集成。

作为一个自负盈亏的独立创业者,我相信正是由于专注于自动化,才让我能为来自 80 多个国家和地区的客户提供可靠服务,并且每周持续提供新功能。当我想要了解服务的运行情况或者其他方面的信息时,我会尝试利用我熟悉的工具。当然,我也明白,在一些特殊情况下这些工具并不会帮到我。

现在,我简要地介绍下平时使用的一些工具。

非常重要的一点是,虽然工具列表看起来很长,并且有一些是非常规且不常用的选项,但实际上我在基础架构上花费的时间很少,如果有的话,每个月平均下来也就是几个小时。还有一点就是个人推荐就像是开处方一样,我认为对我非常有用的一些工具,可能并不适合你。一定要考虑自己的实际情况,并利用好当下你熟悉的工具。

编程语言

多年来,我学习和使用过好几种编程语言,但是对于独立项目,我特别挑选出两种编程语言。这两种编程语言可以在生产力以及可靠性上取得很好的平衡。

Python:很多项目的后端代码都是用 Python 实现的。它可以让我能够以较快的速度发布新功能。另外,我使用 mypy 用于类型提示,这方便我进行代码管理。

Typescript:我以前会有意地避开前端开发的工作。直到大约 4 年前,我发现并开始使用 Typescript。它让我感觉写前端的工作体验更好了,现在我使用它并结合 React 框架一起构建我的项目。

框架

理论上,我会在这里介绍很多这方面的内容,但是相关论坛上有不少介绍,我也是站在巨人的肩膀上学到很多知识。因此我只想介绍几个非常不错的框架:

Django:该框架简直就是独立开发者的宝库。你在该行业中工作的时间越长,你越能体会到避免重复造轮子带来的幸福感。这一框架可以让你走的更远,因为它的功能实在是太全面了,应用场景也很广泛。推荐阅读Instagram如何优化Python提高服务性能、Sentry项目、10大Django构建的网站了解一下 Django 的使用场景。对我来说,该框架不管在性能还是功能方面都能满足我的需求。

React:数据展示相关的 Web 应用是使用 React + Webpack 构建的。在长时间使用 Angular 后,我最终切换到 React,因为它是支持可插拔的视图层,不会对其他功能造成影响。我使用性能表现不错的django-react-templatetags将 React 组件嵌入到我的 Django 模板中。

NextJS:我使用它进行页面、文档等的加载。它让我能重用各种 React 组件,并且可以提高静态页面的性能以及 SEO 优势。

Celery:我使用该框架用于后台/定时任务的管理。该框架的学习成本较高,但是一旦你了解了它的工作原理,并应用到项目中后,你就能体会到该框架的稳定性和可靠性了。

Bootstrap 4:我基于 Bootstrap 构建前端应用。它节省了我很多时间,并且文档资料详细丰富。这就是我选择使用它的原因。

数据库

我最初将所有数据都存储在 SQLite 数据库中,对数据进行备份意味着要将副本数据复制到 S3 之类的对象存储中。之前对于测试过的一些小型站点来说,没有什么问题。但是,随着项目的功能及页面越来越多,我需要更多专门的数据库来支持这些功能:

Clickhouse:我相信 Clickhouse 是为数不多的随着时间的推移而经久不衰的技术之一。说实话,这是一款十分给力的数据库,它能够实现原先在低配置硬件上几乎无法实现的功能。

PostgreSQL:我必用的关系数据库。默认配置合理,经历了充分的市场检验并且与 Django 深度集成。在 Panelbear 中,PostgreSQL 主要用于与分析无关的应用数据存储;对于分析用的数据,我使用 Django 实现了一个简单的接口从 Clickhouse 查询数据。

Redis:我在很多场景中使用了 Redis,比如缓存、速度限制、任务队列以及作为有生命周期的键值存储。Redis 功能强大且性能稳定,社区文档也十分丰富。

部署工具

与这篇文章描述的一样,我不会将我的基础设施视为宝贝一样对待。服务器和集群本来就是一个工具而已。所以如果某一台服务器出现问题,用另外一台正常的服务器替换一下就好了。这意味着所有的操作在 git 仓库中被描述为代码逻辑,并且我不会通过 SSH 登陆服务器进行一些操作。你可以将这个描述视为一个模板,可以通过一个命令将整个基础架构克隆到任何的 AWS 服务中。

这在灾难恢复时也会对我有所帮助。我只需要运行一些命令,几分钟后,我的应用服务就可以重建并能正常运行了。当我将应用从 DigitalOcean 迁移到 Linode,以及最近往 AWS 迁移时非常有用。所有的操作都通过代码描述和执行。因此,即使在几年后,我也很容易的跟踪项目的相关部署和运行情况。现在所有的公司都拥有 AWS IAM 策略或者 VPC 子网,这些都是通过一些 UI 界面点击操作完成的,现在所有人都离不开这一功能,因为确实给用户带来了很多便利。

Terraform:我使用 Terraform 来管理大部分云基础架构。在我的 Terraform 清单中声明了诸如 EKS 集群、S3 存储、角色和 RDS 实例之类的一些配置。这些数据会同步到另外的加密 S3 存储,以避免我开发用的笔记本电脑发生故障而无力回天。

Docker:我会将所有服务构建为 Docker 映像。甚至有状态的组件(比如 Clickhouse 或 Redis)也作为 Docker 容器打包并运行在我的集群中。这也让我的应用服务可移植性非常高,因为我可以在能够运行 Docker 的任何地方运行它。

Kubernetes:它极大地解放了我繁琐的工作。我并不是盲目地向所有人进行推荐,因为在工作的这些年里,我使用它解决了好几次大型的生产故障。为公司及时解决生产问题,让我感觉十分自豪。我还用它进行容器化应用的管理,这也帮我减轻了工作负担。

GitHub Actions:过去,我常常使用的是CircleCI(这个用起来也不错),但是对于这个项目,我更喜欢使用 GitHub Actions,因为它删除了需要访问代码库以及部署密码的一个不必要的服务。但是,CircleCI 同样具有很多不错的功能,我仍然向大家推荐它。

基础设施服务

我从最开始使用月费 5 美元的 DigitalOcean 单实例服务器开始,逐步转向使用 Kubernetes 来管理服务,因为我正在彻底改变 Kubernetes 提供的一些开箱即用的功能(比如:服务发现、TLS 认证、负载均衡、日志滚动管理、滚动发布、容量管理等)。

但是,即使在较大的服务器实例上,使用 Kubernetes 管理的 DigitalOcean 也同样存在可靠性问题。集群 API 服务经常会随机地停止工作并且无法恢复,这会破坏包括负载均衡在内的许多集群服务,也就意味着服务停机无法对外提供正常服务。每当发生这种情况时,我会重新创建一个新的集群,尽管使用 Terraform 可以很轻松的实现,但是这并不会增加大家对其托管服务可靠性的信心。我怀疑是他们的资源不是特别充足导致的,考虑到他们的服务收费较低,因此这是可以理解的。

不幸的是,几周后,我就无法解决上面提到的问题了。这就是为什么我决定迁移到Linode的原因,在接下来的一个半月的时间里,系统再也没有出现过任何问题。

但是,AWS 向我抛来了更加诱人的优惠,所以我最近又做了一次迁移。AWS 还支持使用托管服务比如 RDS 来减轻 PostgreSQL 的压力,这对我来讲是个很大的优势。我的迁移工作没有那么复杂,因为我的所有基础架构都是通过 Terraform 和 Kubernetes 配置清单进行描述的。系统迁移可能会花费或长或短的时间,所以一定要有耐心。这一方面的话题可以在其他文章中找到。

AWS:提供可预测服务以及大量的托管服务。我主要在全职工作的时候使用过它,所以我没有花费很多时间来处理问题。我使用过的 AWS 服务主要有 EKS、ELB、S3、RDS、IAM 以及专用 VPC,未来我可能会使用 Cloudfront 和 Kinesis 服务。

Cloudflare:我主要将其用于 DDoS 保护、DNS 服务以及负载各种静态资源的边缘缓存(目前减少了 AWS 的 80%网络出口带宽费用——它们的带宽定价是在是太贵了!)。

Let’s Encrypt:免费的 SSL 证书授权服务。我在 Kubernetes 集群中使用了 cert-manager,它根据我的入口规则自动颁发和更新证书。

Namecheap:我常常使用的域名注册服务商。它允许 MFA 登录,这是一个十分重要的安全功能。与其他域名服务商不同,它们不会每隔几年就会突然增加域名的高昂续费费用,十分的良心。

Kubernetes 组件
以下组件可以自动完成大部分开发运维工作。我也使用其他的一些组件,但是我最想推荐给大家的是下面几个:

ingress-nginx:一个性能稳定的使用 NGINX 作为反向代理和负载均衡的网络入口控制器,控制入口流量到集群节点的网络流量负载均衡。

cert-manager:该组件可以按照入口规则中的定义自动颁发和更新 TLS 证书。

external-dns:借助 DNS 服务(例如 Cloudflare)同步公开 Kubernetes 服务和网络入口。

prometheus-operator:可以自动监控大部分的服务,并可以通过 Grafana 对数据进行展示。

flux:可以实现在 Kubernetes 中进行连续交付。当我要发布新的 Docker 映像时,可以通过拉取镜像进行部署。

命令行工具

我使用的命令行工具有很多,但经常使用且值得推荐的就下面这几个:

kubectl:与 Kubernetes 集群进行交互的工具,可以对日志、pod 和服务进行监控,并且可以 SSH 登陆到运行中的容器。

stern:Kubernetes 的 pod 日志查看工具,方便易用。

htop:交互式系统进程查看工具,真的比系统自带的 top 工具好用。

cURL:网络请求工具,可以对请求头进行检查。

HTTPie:与 cURL 工具类似,但是对于 JSON API 而言更简单易用。

hey:网络负载测试工具,可以提供详细的延迟分布报告。

监控工具

Prometheus:可以高效地存储时间序列数据并进行监控。可以追踪所有群集和应用程序的性能指标。比使用 Cloudwatch 进行应用程序监控要便宜得多。

Grafana:可以对 Prometheus 监控数据进行展示。所有的展示数据以 JSON 文件进行描述,并在 git 仓库中进行版本控制。

Sentry:对应用程序异常情况进行监控。该工具在发现带有其他元数据的未处理错误时进行告警通知。

Loki:受 Prometheus 启发而发展出来的一款日志聚合系统。它附带了 prometheus-operator 功能,可以帮助我在整个群集中对海量日志进行搜索。

邮件工具

Fastmail:我优先选用的商务电子邮箱,功能齐全且稳定性高。

Postmark:我主要将其用于交易电子邮件(电子邮件验证、每周报告、登录安全警报、密码重置等)的收发。他们的电子邮件传输速度非常快,邮件移动应用程序在业界也是一流的。

开发工具

GitHub:源代码托管及版本控制工具。

PyCharm:可能是 Python 最好的 IDE 工具。使用它可以轻松地重构和导航整个项目代码,而不仅仅是单个代码文件。 即使使用大型动态代码库,该工具的使用表现也很好。

VS Code:非常适合 Typescript / React 编程,并且可以用作通用代码编辑器。

Poetry:Python 打包及有锁文件的依赖管理工具。

Yarn:具有本地缓存的快速 JS 依赖项管理工具。

Invoked:我使用它将所有代码库任务包装在可调用的命令中。例如,使用inv build可以准备静态资源,打包前端/后端环境依赖,并生成 docker 映像。这样,就可以在本地执行与 CI 运行的相同的命令。

其他工具

Panelbear:当然,除了 Panelbear,还有什么能比 Panelbear 更好的工具来跟踪 Panelbear 的网站分析呢?内部测试是有很大收益的,因为我就是我自己的客户。

Healthchecks.io:当计划作业未能正常运行时,就会通过电子邮件或者 whatsapp 通知到我。它也是基于 SaaS 的辅助程序,这个工具我使用了好几年了,非常高兴可以推荐给大家。

Trello:我使用它来记录和跟踪一些问题、需求及想法等等。

Figma:用于为目标页面快速制作模型、横幅和插图,它取代了Sketch作为我的入门工具。

原文链接

https://panelbear.com/blog/tech-stack/

/* * @Author: your name * @Date: 2016-09-06 00:00:00 * @LastEditTime: 2020-03-17 18:29:35 * @LastEditors: Please set LastEditors * @Description: In User Settings Edit * @FilePath: \htdocs\usr\themes\default\footer.php */