Auth0 为所有技术栈上的任一平台(移动,Web,本机)应用程序提供身份验证,授权和单点登录服务。身份验证对绝大多数应用程序至关重要。我们从一开始就设计了 Auth0,以便它可以在任何地方运行:在我们的云上,在您的云上,甚至在您自己的私有基础架构上。
在这篇文章中,我们将更多地讨论我们的公共 SaaS 部署,并简要介绍 auth0.com 背后的基础架构以及我们用于保持高可用性并保持运行的策略。
从那以后在 Auth0 中发生了很多变化。这些是一些亮点:
我们从每月处理数百万次到每月 15 亿次登录,为数千名客户提供服务,包括 FuboTV,Mozilla,JetPrivilege 等。
我们实施了新功能,如自定义域,扩展的 bcrypt 操作,大大改进的用户搜索等等。
为了扩展我们的组织和处理日益增长,服务数量由原有的 10 个增加到 30 个。
云资源的数量也大幅增长; 我们曾经在一个环境(美国)中拥有几十个节点,现在我们在四个环境(美国,美国-2,欧盟,澳大利亚)上拥有超过一千个节点。
我们决定为每个环境使用单一云提供商,并将所有公共云基础架构迁移到 AWS。
核心服务架构
核心服务由不同的层组成:
核心应用层:自动扩展运行不同服务的服务器组(身份验证,管理 API,多因素身份验证 API 等等)。
数据存储层:MongoDB,Elasticsearch,Redis 和 PostgreSQL 的集群,为不同的应用程序和功能存储各种数据集。
传输/队列层:Kinesis 流和 RabbitMQ,SNS 和 SQS 队列。
基本服务层:速率限制,bcrypt 集群,功能标志等服务。
路由层:AWS 负载均衡器(来自 AWS 的 ALB,NLB 和 ELB)以及一些运行 NGINX 作为代理的节点。
高可用
2014 年,我们使用了多云架构(使用 Azure 和 AWS,在 Google 云上使用了一些额外的资源),并且多年来为我们提供了很好的服务。随着我们的使用(和负载)迅速增加,我们发现自己越来越依赖 AWS 资源。
首先,我们将我们环境中的主要区域切换到 AWS,将 Azure 保留为灾备。当我们开始使用更多 AWS 资源(如 Kinesis 和 SQS)时,我们开始难以在两个提供程序中保留相同的功能集。 随着我们的需求的日益增长,我们会继续在 Azure 部署一些新功能。如果部署在 AWS 上的服务全部不可用,我们仍然可以使用 Azure 群集支持核心身份验证功能。
(编者:多云环境保持同步增加功能,复杂度问题)
在 2016 年发生一些故障后,我们决定最终融入 AWS。我们停止了与保持服务和自动化平台无关的所有工作,并聚焦于以下内容:
在 AWS 内部启用主备,每个区域使用多个区域和至少 3 个可用区。
增加 AWS 特定资源的使用,例如自动扩展组(而不是使用固定的节点集群),应用程序负载平衡器(ALB)等。
编写更好的自动化:我们改进了自动化,完全采用基础架构作为代码,使用 TerraForm 和 SaltStack 来配置新的 Auth0 环境(以及替换现有的环境)。这使我们能够从每秒约 300 次登录的部分自动化环境发展到每秒执行超过 3.4 万次登录的全自动环境; 使用新工具可以更容易地向上扩展(并且只要有意义就向下扩展)。我们实现的自动化水平并不完美,但允许我们以更加便捷的方式发展到新的地区并创造新的环境。
编写更好的脚本文件:我们看到除了自动化之外,我们还需要更好的脚本文件,以便理解,管理和响应与我们不断增长的服务网格相关的事件。这大大提高了可扩展性和可靠性,同时也允许我们让新人可以更快的上手。
我们来看看我们的美国环境架构。我们有这个总体结构:
这是单个 AZ 内部的结构:
在这种情况下,我们使用两个 AWS 区域:us-west-2(主集群)和 us-west-1(备份集群)。在正常情况下,所有请求都将转到 us-west-2,由三个单独的可用区域提供服务。
这就是我们实现高可用性的方式:所有服务(包括数据库)都在每个可用区(AZ)上运行实例。如果一个 AZ 由于数据中心故障而关闭,我们仍有两个 AZ 来处理来自的请求。如果整个区域出现故障或出现错误,我们可以更新 Route53 以故障转移到 us-west-1 并恢复操作。
我们通过在每个 AWS 可用区域上运行所有服务实例来实现高可用性
我们在服务故障转移方面有不同的成熟度级别:某些服务,例如用户搜索 v2(在 Elasticsearch 上构建缓存)可能有效,但数据稍有延迟;另外,核心功能保持按预期工作。
在数据层中,我们使用:
MongoDB 的跨区域集群。
PostgreSQL 的 RDS 复制。
Elasticsearch 的每个区域的群集具有自动快照和恢复,定期运行以解决缺少跨区域群集的问题。
我们每年至少进行一次故障演练,我们有手册和自动化,以帮助新的基础设施工程师快速了解如何做到这一点以及产生什么影响。
(编者:每年至少一次故障演练,对于真正发生区域不可用的时候指导意义是否足够?)
我们的部署通常由 Jenkins 节点触发; 根据服务,我们使用 Puppet,SaltStack 和/或 Ansible 来更新单个节点或节点组,或者我们更新 AMI 并为不可变部署创建新的自动缩放组。 我们为新旧服务部署了不同类型的部署。维护文档和监控应该统一的内容,在我们需要维护自动化的同时,作用上很大程度上显得微乎其微。
自动化测试
除了每个项目的单元测试覆盖率外,我们还提供多个功能测试套件,可在各种环境中运行; 我们在部署到生产之前在预生产环境中运行它,并在完成部署后再次在生产环境中运行它们以确保一切正常。
亮点:
在不同的项目中有数千个单元测试。
每分钟执行 Pingdom 来探测核心功能。
我们在每次部署之前和之后都使用 Selenium 和基于 CodeceptJS 的功能测试。 功能测试套件测试不同的 API 端点,身份验证流程,身份提供程序等等。
除了每个项目的单元测试覆盖率外,我们还有多个功能测试套件,可在各种环境中运行:在部署到生产之前进行分段,在完成部署后再次进行生产。
CDN
直到 2017 年,我们在多个地区使用 NGINX,Varnish 和 EC2 节点运行我们自己定制的 CDN。从那时起,我们转向 CloudFront,这给了我们几个好处,包括:
更多位置接入,这意味着我们的客户延迟更少。
降低维护成本。
配置更简单。
有一些缺点,比如我们需要运行 Lambdas 来执行某些配置(比如将自定义标头添加到 PDF 文件等等)。 不过,好处远远大于这些。
Extend
(译者补充:Extend [https://goextend.io/]是 Auth0 开发的一个平台,用于实现 SaaS 的自定义和集成)
我们提供的功能之一是能够通过身份验证规则或自定义数据库连接将自定义代码作为登录事务的一部分运行。 这些功能由 Extend 提供支持,Extend 是一个可扩展性平台,由 Auth0 开发,现在也被其他公司使用。 通过 Extend,我们的客户可以在这些脚本和规则中编写他们想要的任何内容,允许他们扩展配置文件,规范化属性,发送通知等等。
我们专门为 Auth0 扩展了集群; 他们使用 EC2 自动扩展组,Docker 容器和自定义代理的组合来处理来自租户的请求,每秒处理数千个请求并快速响应负载变化。 有关如何构建和运行它的更多详细信息,请查看有关如何构建自己的无服务器平台的帖子。
监控
我们使用不同工具的组合来监控和调试问题:
CloudWatch
DataDog
Pingdom 的
SENTINL
我们的绝大多数警报都来自 CloudWatch 和 DataDog。
我们倾向于通过 TerraForm 配置 CloudWatch 警报,我们在 CloudWatch 上保留的主要监视器是:
来自主负载均衡器的 HTTP 错误。
目标组中的不健康实例。
SQS 处理延迟。
CloudWatch 是基于 AWS 生成的指标(如来自负载均衡器或自动扩展组的指标)的最佳警报工具。 CloudWatch 警报通常发送给 PagerDuty,从 PagerDuty 发送到 Slack / phones。
DataDog 是我们用来存储时间序列指标并采取行动的服务。 我们从 Linux 机箱,AWS 资源,现成服务(如 NGINX 或 MongoDB)以及我们构建的自定义服务(如我们的 Management API)发送指标。
我们有很多 DataDog 监视器。 几个例子:
service 的响应时间增加。
ip_address)中 $ volume 的空间不足。
host( process 问题。
service 的处理时间增加。
NTP 在 ip_address)上漂移/关闭时钟问题。
MongoDB 副本设置在 $ environment 上发生了变化。
从上面的示例中可以看出,我们监控了低级指标(如磁盘空间)和高级指标(如 MongoDB 副本集更改,例如如果主节点定义发生更改,则会提醒我们)。 我们做了很多,并在一些服务周围有一些非常复杂的监视器。
DataDog 警报的输出非常灵活,我们通常会将它们全部发送给 Slack,只向那些应该“唤醒人们”的人发送给 PagerDuty(如错误峰值,或者我们确定会对客户产生影响的大多数事情)。
对于日志记录,我们使用 Kibana 和 SumoLogic; 我们使用 SumoLogic 来记录审计跟踪和许多 AWS 生成的日志,我们使用 Kibana 来存储来自我们自己的服务和其他“现成”服务(如 NGINX 和 MongoDB)的应用程序日志。
未来
随着业务发展,我们的平台增长了,而且我们的工程组织规模不断扩大:我们有许多新团队建立自己的服务,并且需要自动化,工具和可扩展性指导。 考虑到这一点,这些是我们不仅要扩展我们的平台而且要扩展我们的工程实践的举措:
构建 PaaS 风格的平台:正如前面所提到的,今天我们有不同的自动化和部署流程;这会造成混乱并为工程师设置了障碍,因为很难在没有涉及太多存储库的情况下进行实验和扩展。我们正在开发一个平台的 PoC(目前运行在 ECS 之上),工程师可以在其中配置 YAML 文件并将其部署以获取计算资源,监控,日志记录,备份等等。所有这些都无需明确配置。这项工作还处于早期阶段,可能仍会发生很大变化(EKS?)。但是,鉴于我们不断扩大的规模和可扩展性限制,我们认为我们正在采取正确的方向。
为每个新的 PR(pull request)实施冒烟测试:除了单元测试(已经在每个新 PR 上运行),我们希望在可能的情况下在短暂环境中运行集成测试。
将我们的日志记录解决方案集中到一个提供商这可能意味着远离 Kibana 并仅使用 SumoLogic,但我们仍需要评估功能集,数据量等。
自动化指标:现在我们的指标数据太多是手动的:在部署时添加与代码相关的指标调用,并使用 DataDog 界面构建仪表板和监视器。如果我们使用标准格式和命名,我们可以自动构建仪表板/监视器,从日志中提取度量而不是显式添加对代码的调用等等。
本文转载自技术琐话公众号。
原文链接:https://mp.weixin.qq.com/s/idXfqnKHK9NEjBWVBoXxkg
评论