Bitrix24:“快速上涨的不认为是下跌”

如今,Bitrix24 服务没有数百吉比特的流量,也没有庞大的服务器群(当然,现有的服务器数量相当多)。 但对于许多客户来说,它是公司工作的主要工具;它是真正的业务关键型应用程序。 所以,没有办法堕落。 如果崩溃确实发生了,但服务“恢复”得如此之快以至于没有人注意到任何事情怎么办? 如何在不损失工作质量和客户端数量的情况下实施故障转移? Bitrix24 云服务总监 Alexander Demidov 在我们的博客中谈到了该产品存在 7 年以来预订系统的演变情况。

Bitrix24:“快速上涨的不认为是下跌”

“我们 24 年前推出了 Bitrix7 作为 SaaS。 主要困难可能在于:在作为 SaaS 公开推出之前,该产品只是以盒装解决方案的形式存在。 客户从我们这里购买它,将其托管在他们的服务器上,建立一个企业门户——一个用于员工沟通、文件存储、任务管理、CRM 的通用解决方案,仅此而已。 到 2012 年,我们决定将其作为 SaaS 推出,自行管理,确保容错性和可靠性。 我们一路走来积累了经验,因为在那之前我们根本没有经验——我们只是软件制造商,而不是服务提供商。

在推出服务时,我们明白最重要的是确保服务的容错性、可靠性和持续可用性,因为如果你有一个简单的普通网站,例如一个商店,它落在你身上并坐在那里一个小时,只有你受苦,你失去了订单,你失去了客户,但是对于你的客户本人来说,这对他来说并不是很关键。 当然,他很沮丧,但他去另一个网站买了它。 而如果这是一个将公司内部的所有工作、沟通、决策都捆绑在一起的应用程序,那么最重要的就是获得用户的信任,也就是不让他们失望,不让他们跌倒。 因为如果内部的某些东西不起作用,所有的工作都会停止。

Bitrix.24 作为 SaaS

我们在公开发布前一年(即 2011 年)组装了第一个原型。 我们花了大约一周的时间组装它,查看它,旋转它 - 它甚至可以工作。 也就是说,您可以进入表单,在其中输入门户的名称,将打开一个新门户,并创建一个用户群。 我们看了它,原则上评估了这个产品,报废了它,然后继续完善它整整一年。 因为我们有一项艰巨的任务:我们不想制作两个不同的代码库,我们不想支持单独的打包产品、单独的云解决方案 - 我们希望在一个代码中完成这一切。

Bitrix24:“快速上涨的不认为是下跌”

当时典型的 Web 应用程序是一台服务器,运行一些 PHP 代码,一个 mysql 数据库,上传文件,将文档、图片放在上传文件夹中 - 好吧,这一切都有效。 可惜的是,使用它来启动极其稳定的 Web 服务是不可能的。 在那里,不支持分布式缓存,不支持数据库复制。

我们制定了需求:这是能够位于不同地点,支持复制,最好位于不同地理分布的数据中心。 将产品逻辑与数据存储分开。 能够根据负载动态扩展,并完全容忍静态。 事实上,从这些考虑出发,我们在这一年中对产品的要求进行了完善。 在此期间,在这个统一的平台上——对于盒装解决方案,对于我们自己的服务——我们为我们需要的东西提供了支持。 在产品本身层面支持mysql复制:也就是说,编写代码的开发人员不会考虑他的请求将如何分配,他使用我们的api,我们知道如何在master之间正确分配写入和读取请求和奴隶。

我们在产品层面对各种云对象存储提供了支持:google storage、amazon s3,以及对 open stack swift 的支持。 因此,这对于作为服务的我们和使用打包解决方案的开发人员来说都很方便:如果他们只是使用我们的 API 进行工作,他们不会考虑文件最终将保存在何处,在本地文件系统上还是在其他地方。在目标文件存储中。

于是,我们立即决定在整个数据中心层面进行预留。 2012 年,我们完全在亚马逊 AWS 上推出,因为我们已经拥有该平台的经验 - 我们自己的网站就托管在那里。 我们被亚马逊在每个地区都有多个可用区这一事实所吸引 - 事实上,(用他们的术语来说)多个数据中心或多或少彼此独立,并允许我们在整个数据中心的级别上进行预留:如果突然发生故障,数据库将进行主-主复制,备份 Web 应用程序服务器,并将静态数据移动到 s3 对象存储。 负载均衡——当时是由 Amazon elb 实现的,但不久之后我们就使用了自己的负载均衡器,因为我们需要更复杂的逻辑。

他们想要的就是他们得到的......

我们想要确保的所有基本事项 - 服务器本身、Web 应用程序、数据库的容错 - 一切都运行良好。 最简单的场景:如果我们的一个 Web 应用程序出现故障,那么一切都很简单 - 它们会关闭平衡。

Bitrix24:“快速上涨的不认为是下跌”

平衡器(当时是亚马逊的 elb)将出现故障的机器标记为不健康,并关闭它们的负载分配。 亚马逊自动扩展起作用了:当负载增长时,新机器被添加到自动扩展组中,负载被分配到新机器上 - 一切都很好。 对于我们的平衡器,逻辑大致相同:如果应用程序服务器发生问题,我们会删除其中的请求,扔掉这些机器,启动新机器并继续工作。 这些年来,该方案发生了一些变化,但仍然有效:它简单、易于理解,而且没有任何困难。

我们在世界各地工作,客户负载峰值完全不同,并且,以友好的方式,我们应该能够随时对我们系统的任何组件进行某些服务工作 - 不被客户注意到。 因此,我们有机会关闭数据库的运行,将负载重新分配到第二个数据中心。

它是怎么运行的? — 我们将流量切换到正在运行的数据中心 - 如果数据中心发生事故,那么完全如果这是我们计划使用一个数据库进行的工作,那么我们会将为这些客户端提供服务的部分流量切换到第二个数据中心,暂停它复制。 如果由于第二个数据中心的负载增加而需要新机器用于 Web 应用程序,它们将自动启动。 我们完成工作,恢复复制,然后返回整个负载。 如果我们需要在第二个 DC 中镜像某些工作,例如安装系统更新或更改第二个数据库中的设置,那么通常我们会重复相同的操作,只是在另一个方向上。 如果这是一个意外,那么我们做的一切都很简单:我们使用监控系统中的事件处理程序机制。 如果触发了多项检查并且状态变为严重,那么我们将运行此处理程序,该处理程序可以执行这个或那个逻辑。 对于每个数据库,我们指定哪台服务器是其故障转移,以及如果不可用则需要切换流量。 从历史上看,我们以一种或另一种形式使用 nagios 或其一些分叉。 原则上,几乎所有监控系统中都存在类似的机制;我们还没有使用任何更复杂的东西,但也许有一天我们会使用。 现在,监控是由不可用性触发的,并且能够切换某些内容。

我们已经预订了一切吗?

我们有很多来自美国的客户,很多来自欧洲的客户,还有很多靠近东方的客户——日本、新加坡等。 当然,很大一部分客户在俄罗斯。 也就是说,工作不在一个地区。 用户想要快速响应,需要遵守各种当地法律,并且在每个区域内我们预留两个数据中心,此外还有一些附加服务,这些服务同样可以方便地放置在一个区域内 - 对于位于该地区正在发挥作用。 REST 处理程序、授权服务器,它们对于整个客户端的操作不太重要,您可以在可接受的较小延迟下切换它们,但您不想在如何监视它们以及做什么方面重新发明轮子跟他们。 因此,我们试图最大限度地利用现有的解决方案,而不是在其他产品中开发某种能力。 在某些地方,我们通常会在 DNS 级别使用切换,并通过相同的 DNS 来确定服务的活跃度。 Amazon 有 Route 53 服务,但它不仅仅是一个可以输入条目的 DNS,仅此而已,它更加灵活和方便。 通过它,您可以使用地理位置构建地理分布式服务,当您使用它来确定客户端来自哪里并为其提供某些记录时,您可以在它的帮助下构建故障转移架构。 Route 53 本身也配置了相同的运行状况检查,您可以设置受监控的端点、设置指标、设置确定服务“活跃度”的协议 - tcp、http、https; 设置确定服务是否活动的检查频率。 在 DNS 本身中,您可以指定什么是主要的,什么是次要的,如果在路由 53 内触发健康检查,则在哪里切换。所有这些都可以使用其他一些工具来完成,但为什么它很方便 - 我们设置它启动一次,然后完全不用考虑我们如何进行检查、如何切换:一切都会自行运行。

第一个“但是”:如何以及用什么来预订 53 号公路本身? 谁知道,如果他出了什么事呢? 幸运的是,我们从来没有踩过这个耙子,但是,我会再讲一个故事,解释为什么我们认为我们仍然需要预订。 在这里我们提前为自己铺好了救命稻草。 我们每天多次彻底卸载 53 号公路上的所有区域。 亚马逊的 API 允许您轻松地以 JSON 格式发送它们,我们有几个备份服务器,我们可以在其中转换它,以配置的形式上传它,并且粗略地说,有一个备份配置。 如果出现问题,我们可以快速手动部署,而不会丢失 DNS 设置数据。

第二个“但是”:这张图里的什么东西还没有被预订? 平衡器本身! 我们按地区的客户分布变得非常简单。 我们有域名 bitrix24.ru、bitrix24.com、.de - 现在有 13 个不同的域名,在不同的区域运行。 我们得出以下结论:每个地区都有自己的平衡器。 这使得跨区域分发更加方便,具体取决于网络上的峰值负载所在的位置。 如果这是单个平衡器级别的故障,则只需将其停止服务并从 DNS 中删除即可。 如果一组平衡器出现问题,则将它们备份到其他站点,并使用相同的路由在它们之间进行切换53,因为由于 TTL 较短,切换最多会在 2、3、5 分钟内发生。

第三个“但是”: 什么还没有保留? S3,正确。 当我们把为用户存储的文件放在s3中时,我们真诚地相信它是穿甲弹的,不需要在那里保留任何东西。 但历史表明,事情的发生方式有所不同。 一般来说,Amazon 将 S3 描述为一项基础服务,因为 Amazon 本身使用 S3 来存储机器镜像、配置、AMI 镜像、快照……而如果 s3 崩溃了,就像这 7 年来发生过一次,只要我们一直在使用bitrix24,它像粉丝一样跟着它,出现了一大堆事情——无法启动虚拟机、api 故障等等。

S3 也可能会崩溃——这种事曾经发生过一次。 因此,我们得出了以下方案:几年前,俄罗斯还没有真正的公共对象存储设施,我们考虑了做一些我们自己的事情的选择......幸运的是,我们没有开始这样做,因为我们会挖掘了我们没有的专业知识,并且可能会搞砸。 现在 Mail.ru 拥有 s3 兼容存储,Yandex 拥有,许多其他提供商也拥有。 我们最终得出这样的想法:首先,我们希望拥有备份,其次,能够使用本地副本。 特别是对于俄罗斯地区,我们使用 Mail.ru Hotbox 服务,该服务的 API 与 s3 兼容。 我们不需要对应用程序内部的代码进行任何重大修改,我们做了以下机制:在 s3 中有触发器可以触发对象的创建/删除,Amazon 有一个名为 Lambda 的服务 - 这是代码的无服务器启动仅当触发某些触发器时才会执行。

Bitrix24:“快速上涨的不认为是下跌”

我们做得非常简单:如果触发器触发,我们执行代码将对象复制到 Mail.ru 存储。 为了全面启动本地数据副本的工作,我们还需要反向同步,以便俄罗斯部分的客户可以使用距离他们更近的存储。 邮件即将在其存储中完成触发器 - 将可以在基础设施级别执行反向同步,但目前我们正在我们自己的代码级别执行此操作。 如果我们看到客户端已发布文件,那么在代码级别,我们将事件放入队列中,对其进行处理并进行反向复制。 为什么它不好:如果我们在产品之外对我们的对象进行某种工作,也就是说,通过某种外部手段,我们不会考虑它。 因此,我们等到最后,当触发器出现在存储级别时,这样无论我们从哪里执行代码,到达我们的对象都会被复制到另一个方向。

在代码级别,我们为每个客户端注册两个存储:一个被视为主存储,另一个被视为备份存储。 如果一切顺利,我们会使用离我们更近的存储:也就是说,我们在亚马逊的客户,他们使用 S3,而那些在俄罗斯工作的客户,他们使用 Hotbox。 如果该标志被触发,则应连接故障转移,并且我们将客户端切换到另一个存储。 我们可以按区域单独选中此框,并可以来回切换它们。 我们还没有在实践中使用它,但我们已经提供了这种机制,我们认为有一天我们会需要这个开关并派上用场。 这种情况已经发生过一次了。

哦,亚马逊逃跑了……

今年四月是俄罗斯开始封锁 Telegram 的周年纪念日。 受影响最严重的提供商是亚马逊。 不幸的是,为全世界服务的俄罗斯公司遭受的损失更大。

如果公司是全球性的,而俄罗斯只是它的一小部分,3-5%——好吧,不管怎样,你可以牺牲他们。

如果这是一家纯粹的俄罗斯公司 - 我确信它需要位于当地 - 好吧,这对用户本身来说会很方便,舒适,并且风险会更少。

如果这是一家在全球范围内运营并且来自俄罗斯和世界各地的客户数量大致相同的公司怎么办? 各个部分的连接很重要,它们必须以某种方式相互协作。

2018 年 3 月底,Roskomnadzor 致信最大的运营商,表示他们计划封锁数百万个亚马逊 IP,以封锁……Zello Messenger。 感谢这些相同的提供商 - 他们成功地将这封信泄露给所有人,并且人们了解到与亚马逊的联系可能会破裂。 那是星期五,我们惊慌失措地跑给servers.ru的同事说:“朋友们,我们需要几台服务器,这些服务器不在俄罗斯,不在亚马逊,而是在阿姆斯特丹的某个地方。”为了至少能够以某种方式为我们无法以任何方式影响的某些端点(例如同一 sXNUMX 的端点)安装我们自己的 VPN 和代理 - 我们不能尝试提供新服务并获取不同的 ip,我们你还需要到达那里。 在短短几天内,我们就设置了这些服务器,让它们启动并运行,并且总体上为封锁开始的那一刻做好了准备。 奇怪的是,RKN 看着大家的大惊小怪和恐慌,却说:“不,我们现在不会阻止任何事情。” (但这正是直到 Telegram 开始被屏蔽的那一刻。)在设置了旁路功能并意识到屏蔽尚未引入之后,我们并没有开始解决整个问题。 是的,以防万一。

Bitrix24:“快速上涨的不认为是下跌”

而到了2019年,我们仍然生活在封锁的状况下。 我昨晚看了一下:大约有20万个IP继续被封锁。 确实,亚马逊几乎完全畅通无阻,在巅峰时期达到了 2 万个地址……总的来说,现实是可能没有连贯性,良好的连贯性。 突然。 由于技术原因,它可能不存在——火灾、挖掘机等等。 或者,正如我们所见,这并不完全是技术性的。 因此,拥有自己的 AS 的大公司可能可以通过其他方式来管理它 - 直接连接和其他东西已经处于 l3 级别。 但在像我们这样或更小的简单版本中,为了以防万一,您可以在其他地方提出的服务器级别上有冗余,提前配置 VPN、代理,并能够在这些段中快速将配置切换到它们这对于您的连接至关重要。 当亚马逊开始封锁时,这对我们来说不止一次派上用场;在最坏的情况下,我们只允许 SXNUMX 流量通过它们,但逐渐这一切都得到了解决。

如何预订...整个提供商?

目前我们还没有考虑到整个亚马逊瘫痪的情况。 俄罗斯也有类似的情况。 在俄罗斯,我们由一家提供商托管,我们选择从该提供商那里拥有多个站点。 一年前,我们面临一个问题:即使这是两个数据中心,提供商的网络配置层面可能已经存在问题,仍然会影响两个数据中心。 我们最终可能在这两个网站上都无法使用。 当然,这就是发生的事情。 我们最终重新考虑了内部的架构。 它没有太大变化,但对于俄罗斯,我们现在有两个站点,它们不是来自同一提供商,而是来自两个不同的提供商。 如果其中一个失败了,我们可以切换到另一个。

假设,对于亚马逊,我们正在考虑在另一个提供商级别进行预订的可能性; 也许是谷歌,也许是其他人……但到目前为止,我们在实践中观察到,虽然亚马逊在一个可用区级别发生事故,但整个区域级别的事故却相当罕见。 因此,我们理论上有可能会做出“亚马逊不是亚马逊”的预订,但实际上情况并非如此。

关于自动化的几句话

自动化总是必要的吗? 这里有必要回顾一下邓宁-克鲁格效应。 “x”轴是我们获得的知识和经验,“y”轴是对我们行动的信心。 起初我们一无所知,也完全不确定。 然后我们知道一点,变得超级自信——这就是所谓的“愚蠢的顶峰”,“痴呆和勇气”这幅画很好地说明了这一点。 然后我们就学到了一些知识并准备好投入战斗。 然后我们就犯了一些极其严重的错误,发现自己陷入了绝望的深渊,我们似乎知道一些事情,但实际上我们知道的并不多。 然后,当我们积累经验时,我们会变得更加自信。

Bitrix24:“快速上涨的不认为是下跌”

该图很好地描述了我们对某些事故的各种自动切换的逻辑。 我们开始时——我们不知道如何做任何事情,几乎所有的工作都是手工完成的。 然后我们意识到我们可以将自动化附加到一切事物上,就像安稳地睡觉一样。 突然间,我们踩到了一个巨大的耙子:误报被触发,我们在我们不应该这样做的时候来回切换流量。 结果,复制失败或者其他什么——这就是绝望之谷。 然后我们认识到我们必须明智地对待一切。 也就是说,依赖自动化是有意义的,但存在误报的可能性。 但! 如果后果可能是毁灭性的,那么最好将其留给值班人员,值班工程师,他们将确保并监控确实发生了事故,并将手动执行必要的操作......

结论

在七年的时间里,我们从“当东西掉落时会出现恐慌”这一事实,转变为认识到问题并不存在,只有任务,它们必须而且可以被解决。 当你构建一个服务时,从上面看它,评估所有可能发生的风险。 如果您立即看到它们,那么请提前提供冗余以及构建容错基础设施的可能性,因为任何可能发生故障并导致服务无法运行的点都肯定会发生这种情况。 即使您认为基础设施的某些元素肯定不会失败 - 就像同一个 s7,但仍然请记住它们可能会失败。 至少在理论上,要知道如果确实发生了什么事,你将如何处理它们。 制定风险管理计划。 当您考虑自动或手动完成所有操作时,请评估风险:如果自动化开始切换所有操作会发生什么 - 与事故相比,这不会导致更糟糕的情况吗? 也许在某些地方,有必要在自动化的使用和值班工程师的反应之间进行合理的折衷,值班工程师将评估真实情况并了解是否需要当场切换某些内容或“是的,但不是现在”。

完美主义与真正的努力、时间、金钱之间的合理妥协,你可以花在你最终将拥有的计划上。

本文是Alexander Demidov在会议上的报告的更新和扩展版本 正常运行第 4 天.

来源: habr.com

添加评论