44

每月处理15亿次登录,Auth0高可用架构实践

 6 years ago
source link: http://developer.51cto.com/art/201809/583004.htm?amp%3Butm_medium=referral
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

6raMBv2.jpg!web

【51CTO.com原创稿件】如今,身份验证对绝大多数应用程序而言至关重要。Auth0 可以为任何堆栈上的各类(移动、Web 和原生)应用程序提供身份验证、授权和单点登录服务。

我们设计的 Auth0 一开始就可以在任何地方运行:我们的云、你的云,甚至在你自己的私有基础设施上。

在本文中我们将详细探讨我们的公共 SaaS 部署,并简要介绍 auth0.com 背后的基础设施,以及用来确保它顺畅运行的高可用性策略。

我们曾在 2014 年撰文介绍了 Auth0 的架构,自那以来 Auth0 已发生了很大的变化,下面是几大要点:

  • 我们从每月处理数百万次登录升级至每月处理逾 15 亿次登录,为成千上万的客户提供服务,包括 FuboTV、Mozilla 和 JetPrivilege 等。
  • 我们实施了新功能,比如自定义域、扩展的 bcrypt 操作以及大大改进的用户搜索等。
  • 为了扩展我们组织的规模并处理流量的增加,我们产品的服务数量从不到 10 个增加到了 30 多个。
  • 云资源的数量也大幅增长,我们过去在一个环境(美国)中有几十个节点,现在我们在四个环境(美国、美国-2、欧盟和澳大利亚)有 1000 多个节点。
  • 我们决定为自己的每个环境使用单一云提供商,并将所有公共云基础设施迁移到了 AWS。

核心服务架构

yAvme2u.jpg!web

图 1:Auth0.com 的核心服务架构

我们的核心服务包括如下不同的层:

  • 核心应用程序:可自动扩展的服务器组,这些服务器运行我们堆栈的不同服务(身份验证、管理 API 和多因子身份验证 API 等)。
  • 数据存储:MongoDB、Elasticsearch、Redis 和 PostgreSQL 集群,为不同的应用程序和功能特性存储众多数据集。
  • 传输/队列:Kinesis 数据流以及 RabbitMQ、SNS 和 SQS 队列。
  • 基础服务:针对速率限制、bcrypt 集群和功能标志等其他的服务。
  • 路由:AWS 负载均衡系统(来自 AWS 的 ALB、NLB 和 ELB)以及一些运行 Nginx 充当代理的节点。

高可用性

2014 年,我们使用了多云架构(使用 Azure 和 AWS,还有谷歌云上的一些额外资源),多年来该架构为我们提供了良好的服务。随着使用量(和负载)迅速增加,我们发现自己越来越依赖 AWS 资源。

最初,我们将环境中的主区域切换到 AWS,Azure 留作故障切换区域。我们开始使用更多的 AWS 资源(比如 Kinesis 和 SQS)时,将同样的功能特性放在这两家提供商处开始遇到了麻烦。

随着移动(和扩展)的速度越来越快,我们选择继续支持 Azure,但功能同等性(feature parity)有限。

如果 AWS 上的一切出现故障,我们仍可以使用 Azure 集群来支持身份验证等核心功能,但是不支持我们一直在开发的许多新功能。

2016 年出现几次严重宕机后,我们决定最终集中到 AWS 上。我们停止了与确保服务和自动化平台无关的全部工作,而是专注于:

  • 在 AWS 内部提供更好的故障切换机制,使用多个区域,每个区域至少 3 个可用区。
  • 增加使用 AWS 特有的资源,比如自动扩展组(而不是使用固定的节点集群)和应用程序负载均衡系统(ALB)等。
  • 编写更好的自动化:我们改进了自动化,完全采用基础设施即代码,使用 TerraForm 和 SaltStack 来配置新的 Auth0 环境(以及替换现有环境)。

这让我们从每秒处理约 300 次登录的部分自动化环境升级到每秒处理逾 3400 次登录的全自动化环境;使用新工具更容易向上扩展(必要的话还可以向下扩展)。

我们实现的自动化水平并不完美,但让我们极其方便地扩大到新的区域、创建新的环境。

  • 编写更好的剧本(playbook):随着时间的推移,我们发现除了自动化外,还需要更好的剧本,以便了解、管理和响应与我们越来越庞大的服务网格相关的事件。

这极大地提高了可扩展性和可靠性,同时加快了新员工的入职。

比如说,不妨看看我们的美国环境架构。我们有这个总体结构,如下图:

bi26NnU.jpg!web

图 2:Auth0 美国环境架构

下图是单一可用区内部的结构:

Yrqq6rb.jpg!web

图 3:Auth0 单一可用区

在这种情况下,我们使用两个 AWS 区域:

  • us-west-2(我们的主区域)
  • us-west-1(故障切换区域)

正常情况下,所有请求都流向 us-west-2,由三个独立的可用区处理请求。

这就是我们实现高可用性的方式:所有服务(包括数据库)在每个可用区(AZ)上都有运行中的实例。

如果一个可用区因数据中心故障而宕机,我们仍有两个可用区来处理请求;如果整个区域宕机或出现错误,我们可以通知 Route53 故障切换到 us-west-1、恢复操作。

我们在服务故障切换方面有不同的成熟度级别:一些服务(比如在 Elasticsearch 上构建缓存的用户搜索 v2)可正常运行,但数据稍显陈旧,不过核心功能按预期运行。

在数据层中,我们使用:

  • 面向 MongoDB 的跨区域集群。
  • 面向 PostgreSQL 的 RDS 复制。
  • 面向 Elasticsearch 的每个区域的集群,自动快照和恢复定期运行,以解决缺少跨区域集群的问题。

我们每年至少进行一次故障切换演练,我们有剧本和自动化,帮助新的基础设施工程师尽快了解如何演练以及由此带来的影响。

我们的部署通常由 Jenkins 节点触发;视服务而定,我们使用 Puppet、SaltStack 及/或 Ansible 来更新单个节点或一组节点,或者我们更新 AMI,为不可变的部署创建新的自动扩展组。

我们为新旧服务部署了不同类型的环境;由于我们需要为应该统一的系统维护自动化、文档和监控,结果证明这基本上很低效。

我们目前在为一些核心服务推出蓝/绿部署(blue/green deployment),我们打算为每个核心的支持服务实施同样的一套。

自动化测试

除了每个项目的单元测试覆盖外,我们还有在每个环境中运行的多个功能测试套件。

我们在部署到生产环境之前先在试运行环境上运行,完成部署后再在生产环境中运行,以确保一切正常。

我们的自动化测试要点:

  • 在不同的项目中有数千个单元测试。
  • 使用每分钟运行的 Pingdom 探针(probe)来检查核心功能。
  • 在每次部署前后结合使用基于 Selenium 的功能测试和基于 CodeceptJS 的功能测试。功能测试套件测试不同的 API 端点、身份验证流程和身份提供者等。

CDN

2017 年之前我们运行自己专门定制的 CDN,在多个区域运行 Nginx、Varnish 和 EC2 节点。

2017 年以后,我们改用 CloudFront,它为我们带来了几个好处,包括:

  • 更多的边缘位置,这意味着为我们的客户缩短了延迟。
  • 降低维护成本。
  • 配置起来更轻松。

但同时也有几个缺点,比如我们需要运行 Lambdas 来执行一些配置(比如将自定义标头添加到 PDF 文件等等)。不过,好处绝对压倒缺点。

Extend

我们提供的功能之一是能够通过身份验证规则或自定义数据库连接,运行自定义代码,作为登录事务的一部分。

这些功能由 Extend(https://goextend.io/)提供支持,Extend 是一个可扩展性平台,由 Auth0 发展而来,现在还被其他公司所使用。

有了 Extend,我们的客户就可以用那些脚本和规则编写所需的任何服务,扩展配置文件、规范属性和发送通知等。

我们有专门针对 Auth0 的 Extend 集群,它们结合使用 EC2 自动扩展组、Docker 容器和自定义代理,以处理来自我们用户的请求,每秒处理数千个请求,并快速响应负载变化。

想了解这如何构建和运行的更多信息,请参阅这篇介绍如何构建自己的无服务器平台的文章(https://tomasz.janczuk.org/2018/03/how-to-build-your-own-serverless-platform.html)。

监控

我们结合使用不同的工具来监控和调试问题:

  • CloudWatch
  • DataDog
  • Pingdom
  • SENTINL

我们的绝大多数警报来自 CloudWatch 和 DataDog。

我们往往通过 TerraForm 来配置 CloudWatch 警报,用 CloudWatch 来监控的主要问题有:

  • 来自主负载均衡系统的 HTTP 错误。
  • 目标组中不健康的实例。
  • SQS 处理延迟。

CloudWatch 是基于 AWS 生成的指标(比如来自负载均衡系统或自动扩展组的指标)来监控警报的最佳工具。

CloudWatch 警报通常发送给 PagerDuty,再从 PagerDuty 发送给 Slack/手机。

DataDog 是我们用来存储时间序列指标并采取相应操作的服务。我们发送来自 Linux 系统、AWS 资源和现成服务(比如 Nginx 或 MongoDB)的指标,还发送来自我们构建的自定义服务(比如 Management API)的指标。

我们有许多 DataDog 监控指标,举几个例子:

  • $environment 上的 $service 响应时间增加。
  • $instance 中的 $volume($ ip_address)空间不足。
  • $environment / $ host 上的 $process($ ip_address)出现问题。
  • $environment 上的 $service 处理时间增加。
  • $host($ip_address)上出现 NTP 漂移/时钟问题。
  • $environment 上的 MongoDB 副本集变更。

从上面例子中可以看出,我们监控低级指标(如磁盘空间)和高级指标(如 MongoDB 副本集变更,这提醒我们主节点定义是否发生了变化)。我们做了大量的工作,设计了一些相当复杂的指标来监控一些服务。

DataDog 警报的输出非常灵活,我们通常将它们全部发送给 Slack,只把那些“引人注意”的警报发送给 PagerDuty,比如错误高峰,或者我们确信对客户产生影响的大多数事件。

至于日志记录方面,我们使用 SumoLogic 和 Kibana;我们使用 SumoLogic 来记录审计跟踪记录和 AWS 生成的许多日志,我们使用 Kibana 存储来自我们自己的服务和其他“现成”服务(如 Nginx 和 MongoDB)的应用程序日志。

未来设想

我们的平台经历了很大的变化,以处理额外负载和对客户来说很重要的众多使用场景,但我们仍有优化的空间。

不仅我们的平台在扩大,我们的工程部门规模也在扩大:我们有许多新团队构建自己的服务,而且需要自动化、工具和可扩展性方面的指导。

有鉴于此,我们落实了这些计划,不仅扩展平台,还夯实工程实践:

  • 构建类似 PaaS 的平台:如前所述,今天我们有不同的自动化和部署流程,这导致了混乱,给工程师设置了门槛,因为很难在不接触众多代码库的情况下进行试验和扩展。

我们正在为目前在 ECS 上运行的平台开发概念证明(PoC)代码,工程师们可以配置 YAML 文件,只需部署它,即可获取计算资源、监控、日志记录和备份等。

所有这一切都无需明确配置。这项工作还处于早期阶段,可能会发生很大变化。然而,鉴于我们不断扩大的规模和可扩展性方面的限制,我们认为我们的方向正确。

  • 针对每个新的合并请求实施冒烟测试(smoke test):除了单元测试(已经在每个新的 PR 上运行)外,我们希望尽可能在短暂环境上进行集成测试。
  • 将我们的日志记录解决方案集中到一家提供商。这可能意味着远离 Kibana,只使用 SumoLogic,但我们仍需要评估功能集和数据量等。
  • 自动衡量指标:现在我们的指标好多都是手动的――部署时添加与指标有关的代码调用,以及使用 DataDog 接口来构建仪表板和监控器。

如果我们使用标准格式和命名,可以实现一些任务,比如自动构建仪表板/监控器,从日志提取指标而不是明确添加代码调用等。

  • 确保我们针对每个核心服务都有自动扩展和蓝/绿部署。这应该是我们新平台的默认功能,但在构建和测试时,我们需要为这方面仍然不足的核心服务改进扩展/部署/回滚机制。

作者:Dirceu Tiegs(沈建苗编译)

简介:Auth0 是身份即服务(IDaaS)的全球领导者,为成千上万的企业客户提供用于其 Web、移动、物联网和内部应用程序的通用身份平台。其可扩展的平台每月为逾 15 亿次登录验证身份和确保安全,因而备受开发人员的喜爱和全球企业的信赖。该公司的美国总部位于华盛顿州贝尔维尤,在布宜诺斯艾利斯、伦敦、东京和悉尼设有办事处,为 70 多个国家的客户提供支持。

【51CTO原创稿件,合作站点转载请注明原文作者和出处为51CTO.com】

322I3iQ.jpg!web


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK