豁免Azure宕机,Auth0的跨提供商多云架构

更新时间:2014-12-25 09:48:20点击次数:868次

摘要:Auth0的业务对服务可用性有着苛刻的要求,但却是个不折不扣的重度云用户,因此他们不得不使用一个可以避免豁免云服务宕机的架构,这里一起展开。


Auth0是一个“身份即服务”创业公司,同时也是重度的云服务用户。对于他们来说,服务中断意味着大量用户托管应用无法登陆,因此可用性对于他们来说至关重要。近日,Auth0工程主管Jose Romaniello分享了他们可以豁免大范围Microsoft Azure宕机的跨提供商多云架构。


以下为译文


Auth0是一个“身份即服务”创业公司,它可以让用户忽略底层基础设施,为移动、网络、本地等任何类型堆栈上的应用提供身份验证、授权及单点登录功能。


对绝大部分应用来说,身份验证都至关重要。因此,在设计时我们使用了多等级冗余的方式,其中一个等级就是托管。Auth0可以在任何地方运行:私有云、公有云,或者是租用机房的实体主机上。鉴于这个特性,Auth0同时选择了多个云服务提供商,并且备份在数个地理位置不同的区域中。


本文将是app.auth0.com 基础设施一个非常简单的介绍,同时也包括了app.auth0.com的高可用保证策略。


核心服务架构


核心服务的架构其实非常简单:


前端服务器:


由多个x-large VM以及运行在Microsoft Azure上的Ubuntu组成。

存储:MongoDB,运行在一些做过专门存储优化的 X-large VM上。

节点内服务路由:Nginx

Auth0的所有组件都备份在各个节点中,并且完全相同。


多云/高可用性


 

云架构


 

不久前,Azure发生了数个小时的全球性宕机。在这段时间,Auth0系统的HA策略被激活,服务非常灵活的切换到了AWS。

大部分服务主要运行在Microsoft Azure(IaaS)上,同时也在AWS上还设置了随时待命的辅助节点。

Auth0系统使用了搭载故障转移路由策略的Route53。TTL被设置为60秒。Route53健康检查会扫描主数据中心,如果这个数据中心没有响应(3次,间隔10秒),DNS入口则会被迅速切换到备用数据中心。因此,对于Auth0来说,最大故障时间不会超过2分钟。

Puppet被部署到每个“push to master”。puppet的使用允许配置/部署过程独立于云提供商特性。Puppet Master运行在我们建立的服务器上(当下是TeamCity)。

MongoDB通常会在辅助数据中心做备份,同时辅助数据中心会被设置为只读模式。

我们备份了所有登录所需要的配置,包括应用程序信息、连接、用户等。我们不会对事务数据进行备份,比如token和日志。

在故障转移发生时,仍然可能会发生多条日志记录丢失的情况。在这里,我们期望通过跨Azure和AWS的实时备份解决。

我们定制了chaos monkey以测试基础设施弹性,代码参见https://github.com/auth0/chaos-mona

 

自动化测试


我们进行了1000+的单元和集成测试。

我们使用 saucelabs做Lock和JavaScript登录窗口的跨浏览器(桌面/移动端)测试。

我们使用phantomjs/casper来做集成测试。

所有这些测试都会在产品推送到生产环境之前完成。

CDN


Auth0的CDN用例非常简单,我们需要使用它来服务JS库和(允许其他提供商等的)其他配置,assset和配置数据会被加载到S3。因此,我们的定制域名(https://cdn.auth0.com)必须要支持TLS。最终,我们选择构建自己的SDN。我们曾经尝试过3个知名的CDN提供商,在这个过程中遇到了各式各样的问题:


在我们还没有自己CDN域名时,我们就尝试了第一个CDN服务。也是那个时候,我们认识到必须拥有自己的SSL/TLS域名。在那个时候,如果需求使用自己的SSL和定制域名,这个CDN服务开销非常大。而在与S3和gzip搭配使用时,我们更遇到了一些配置问题。鉴于S3不能同时服务同一个文件的两种版本(zipped和非zipped),同时这个CDN也不具备内容协商机制(content negotiation),因此对一些浏览器并不是很好。因此,我们转移到了另一个CDN服务,一个非常便宜的CDN服务。

在使用第二个CDN服务时,我们遇到了太多问题,甚至有些问题根本找不到根结所在。该服务提供商只提供远程支持,因此我们需要花费大量的时间来寻求答案。有些问题看起来是S3引起的,而有些看起来则是路由问题,总之我们遇到了各种各样的问题。

在经历了第二个CDN服务,我们发现一味的省钱并不能解决问题,因此我们又换了一个CDN服务。鉴于这个CDN服务被GitHub等高负载应用选择,我们认为它应该能符合我们的需求。然而,随后我们便发现,我们的需求和GitHub有非常大的区别。因为,对于GitHub来说,如果CDN服务宕机,用户只是看不到一个README.md的镜像而已,然而对于我们这种身份即服务来说,应用服务的用户将无法登录。

最终,我们选择建立自己的CDN,使用Nginx、varnish和S3。它托管在AWS的每个region上,到目前为止,运行的非常不错,没有发生任何宕机。我们使用基于Route53延时的路由机制。

沙箱(用于运行未经验证的代码)


Auth0的一个特性就是允许用户运行自定义代码作为登录事务的一部分,用户可以根据需求编写自己的验证规则。当然,对于一些常用的规则,我们也构建了公共的知识库。


沙箱由 CoreOS、Docker等组件构成。

根据需求,为租户Docker分配实例池中的资源。

每个租户都会分配独立的Docker实例,同时使用了基于空闲时间的回收策略。

使用控制器执行回收策略,并使用代理服务器将请求路由到对应的容器。

 

 

更多的沙箱设计可以在2014年11月份的 演讲视频和 讲义中查看。


监视


开始时,我们使用了pingdom(在现在也没完全抛弃),但是随后我们发现了定制自己健康检查系统(可以基于node.js做任何健康测试)的必要性。下面的操作会运行在我们所有的AWS region上:


使用专为服务开发的沙箱。我们可以从一个HTTP API中调用沙箱,并将node.js脚本作为一个HTTP POST发布。

对所有组件进行监视,同时还会对服务做综合事务,比如登录事务。

 

 

如果健康检查通不过,我们会从Slack获取通知,我们拥有两个Slack频道——#p1和#p2。如果错误发生了1次,#p2频道的同事会收到消息,如果错误连续发生两次,警告则会通过#p1频道发布,我们所有的开发运营人员都会收到SMS(通过Twillio)。


 

我们使用statsd以获得更好的性能统计,并将度量发送给Librato。


 

我们同样基于派生度量设置提醒,比如某个值一段时间内增加或者减少多少。举个例子,我们有一个记录登录的度量:if Derivate(logins) > X,然后给Slack发送一条警报。


 

最后,我们还使用NewRelic为基础设施组件做监视。


 

在登录服务上,我们使用了ElasticSearch、Logstash和Kibana。在这里,我们使用Nginx和MongDB来储存日志。我们还使用 logstash解析Mongo日志来识别比较慢的查询。


网站


所有相关的网站,比如auth0.com、博客等,都与应用和运行时完全无关,它们运行在Ubuntu + Docker VM上。

未来


我们正迁移到CoreOS和Docker。我们一直想转移到一个模型,基于这个模型,我们可以从整体上管理集群,而不是单独做每个节点的配置管理。而毫无疑问的是,Docker可以帮助我们解决一部分基于镜像部署的操作。

在AWS和Azure之间做MongoDB的跨数据中心备份。当下,我们正在测试延时。

对于所有搜索相关的特性,我们正在迁移到ElasticSearch。在这个情景中,鉴于多租户的特性,MongoDB的表现并不是很好。



原文链接: Auth0 Architecture - Running In Multiple Cloud Providers And Regions

  • 项目经理 点击这里给我发消息
  • 项目经理 点击这里给我发消息
  • 项目经理 点击这里给我发消息
  • 项目经理 点击这里给我发消息