# 构建全球分布式，关键任务应用程序：Trenches 第 2 部分的经验教训

> 原文： [http://highscalability.com/blog/2015/9/2/building-globally-distributed-mission-critical-applications.html](http://highscalability.com/blog/2015/9/2/building-globally-distributed-mission-critical-applications.html)

![](img/0ba113465fbde4f3efaadcbbdac4299c.png)

*这是 [Kris Beevers](https://www.linkedin.com/pub/kris-beevers/4/a5/113) 的创始人和首席执行官， [NSONE](https://nsone.net/) 的来宾帖子的第二部分，下一代智能 DNS 和流量管理平台的提供者。 这是[第 1 部分](http://highscalability.com/blog/2015/8/31/building-globally-distributed-mission-critical-applications.html)。*

## 集成和功能测试至关重要

在每一个现代软件开发课程中，单元测试都受到重创。 这是一个好习惯。 无论您是进行测试驱动的开发，还是只是敲出代码，如果没有单元测试，您都无法确保一段代码能够达到预期的效果，除非您仔细进行测试，并确保这些测试随着代码的发展而不断通过 。

在分布式应用程序中，即使您拥有世界上最好的单元测试范围，您的系统也会崩溃。 **单元测试还不够**。

您需要**测试子系统**之间的交互。 如果特定的配置数据发生变化，该怎么办–对子系统 A 与子系统 B 的通信有何影响？ 如果您更改了消息格式该怎么办–生成和处理这些消息的所有子系统是否继续互相通信？ 在最新代码更改之后，依赖于四个不同后端子系统的结果的特定类型的请求是否仍会导致正确的响应？

单元测试不能回答这些问题，而集成测试却可以。 **在集成测试套件**中投入时间和精力，并在开发和部署过程的所有阶段都建立了用于集成测试的过程。 理想情况下，始终在您的生产系统上运行集成测试。

## 没有服务中断维护

如果您要构建一个真正的关键任务应用程序，那么您的客户将依靠它来经营自己的业务，那么就没有关闭开关了。 它永远不会停止工作。 您永远不会有服务中断维护。 **即使最复杂的后端体系结构更改也必须毫不夸张地进行**。

这是您应该**认真思考架构**的原因之一。 数小时的白板可以节省数月的工作量。

一个例子：在 NSONE，我们很幸运地从一开始就掌握了大部分架构。 **一开始我们没有做对的事情：我们接受平台中的高频数据输入，这会影响我们如何使用复杂的流量管理配置来回答对 DNS 记录的查询。** 数据馈送可以应用于多个 DNS 记录，因此，服务器负载遥测的馈送可以通知与服务器上托管的多个网站有关的流量路由决策。 我们假设您只会将单个数据 Feed 真正连接到一些 DNS 记录。 因此，我们通过将进入系统的数据馈送扩展为多条消息（每个连接的 DNS 记录一条消息）并将其推送到我们的边缘位置，从而节省了一些时间和精力。 我们错误地假设了，一些我们最喜欢的客户将数据源连接到了数千个 DNS 记录！ 我们早期的懒惰使我们不得不内部进行 DoS，我们知道随着我们的不断发展，这种情况只会变得越来越糟。

问题：我们不能仅仅通过发送更少的控制消息来回溯并解决问题。 我们需要更改数据模型和消息传递模型，以及 4-5 个交互的始终在线系统。 在**初期需要花费 2-3 个小时的额外思考和精力才能变成为期六周的**马拉松：集思广益，深度复杂的重构，大量的正确性测试工作以及一系列精心协调的部署和迁移， 所有人都可以在不中断服务的情况下解决该问题。

虽然这是极端情况，但**新基础架构或代码的每个部署都必须无缝**：精心计划，滚动重启，持续集成测试。 为客户提供服务后，就不会关闭。

## 极其小心地自动化部署和配置管理

现代化的 devops 生态系统充斥着用于部署自动化和配置管理的工具：Chef，Puppet，Ansible，SaltStack，Terraform，以及似乎更多的东西。 您所使用的工具并不像您想的那么重要–阅读并确定哪种模型对您有意义。 但是**重要的是您正在使用这些工具**。 即使在公司的早期阶段，即使看起来更快或更容易，也不要手工管理您的配置或部署：您会犯错误，限制扩展能力，并且将很难进行扩展 以中等规模将自动化改造为移动目标。

但！ 注意：强大的力量带来巨大的责任。 **部署自动化工具使您可以像其他任何东西一样**在头脑中射击平台。

使用 Chef 管理所有主机的 iptables 规则？ **一个疲惫的 devops 工程师和一个按钮操作都可以全局禁用您的平台**。 推出一个新功能，您保证您在登台环境中上下左右测试过吗？ 当您遇到现实流量与模拟流量之间的细微差别时，端到端的自动化部署将使您的产品死光。 明智地使用自动化。

我们使用 **Ansible 管理 NSONE 的配置和部署。 这是一个很棒的工具，具有很多怪癖。** 我们可以自动完成所有操作，并且只需按一下按钮就可以将新的 DNS 传递代码推送到我们的所有边缘位置，但是我们绝对不会这样做。 **我们从最低流量到最高流量按设施推出部署设施。 在一个设施内，我们逐台服务器甚至逐个核心部署，在此过程的每一步都运行全面的功能测试套件。** 在我们研究指标时，有时可能会影响性能，有时甚至是数小时或数天，然后才转移到更关键的设施上。 在开始部署之前，我们就签署了全面的代码审查，不仅是针对我们的应用程序代码，还包括我们的 Ansible 手册和配置。

建立适合您的团队和应用程序的流程，但不要忘记，尽管自动化可以使您快速成长，但也可能使您快速死亡。

## 进行消防演习

坏事发生了。 每个科技公司都会使服务器发生故障。 自从我们启动 NSONE **以来，我们已经经历了各种可以想象到的服务器故障**：磁盘故障，NIC 故障，RAM 损坏，内核崩溃，虚拟环境中嘈杂的邻居副作用以及两者之间的一切。 服务器故障很容易发生。

电源将熄灭。 还记得桑迪飓风吗？ 在 NSONE 目前在曼哈顿下城的办公室的对面，技术人员正在用柴油在桶中爬楼梯，以保持基础设施在线。

光纤将被切断。 BGP 将被劫持。 您将获得 DoSed，其复杂程度各不相同：从脚本小子从其父母的地下室发送 64k ICMP 数据包到全面的 DNS 和 NTP 反射放大攻击，每秒可以以数百万或数亿个数据包的速率对您的基础设施进行 DDoS 处理。

你会怎么做？

**正确的唯一方法是练习。 在坏事情发生之前进行模拟。** Netflix 的 Chaos Monkey 是一个著名的例子。 您不一定总能直接模拟各种事件，但会尽力模拟响应。 这是确保时机成熟时唯一的方法，您可以保持镇定，使用已安装的工具并在困难的情况下有效地做出反应。

## 最小化表面积

随着您的应用程序分布范围越来越广，除非采取谨慎的预防措施，否则遭受恶意攻击的表面积将急剧增加。 **锁定您的系统，并最小化暴露给 Internet 的攻击面。**

**体系结构中的每个角色应仅将其提供的服务公开给需要访问这些服务的系统集。** 您的面向 Internet 的系统应该向您的用户公开您提供的服务，而别无其他。 在后端，您的系统应尽可能在私有 IP 空间上相互交互，并且在不可行的情况下（例如，跨远程设施进行通信），数据应流经加密通道。 无论是通过 AWS 安全组之类的提供程序工具，通过 iptables 规则的自动管理，使用路由器 ACL 或硬件防火墙，还是其他某种机制，都可以积极使用防火墙。 **首先拒绝，然后按角色允许特定流量。**

**切勿允许操作员通过 ssh 等直接访问生产系统。** 人们应该通过高度锁定的堡垒主机进入您的基础架构，并使用多因素身份验证，端口敲门，IP 白名单以及其他相当严苛的安全策略。 确保您的堡垒主机分布在不同的网络和地理位置。 进入其余生产基础架构的操作应仅限于从堡垒主机发起的会话。

有上百万种策略用于锁定系统。 我已经介绍了一些我们发现有效的做法，但绝非详尽无遗。 阅读并从一开始就考虑安全性：它是体系结构的一部分。 随着系统扩展，不要浪费时间以节省时间。

## 了解提供商的情况

几乎每个现代科技公司都在 AWS，DigitalOcean 或其他一些合理的低成本，低障碍的云基础架构提供商上构建其产品的第一个版本。 互联网在 AWS 之前就已经存在，并且基础设施提供商的多样性在过去十年中已经扩大。

**大多数公司在扩展规模时都不会急于放弃 AWS。 但是每个公司都应尽可能保留可选性**。

您可能会发现，应用程序中的特定工作负载最好由裸机处理，或者您需要在澳大利亚拥有高吞吐量的 CDN，或者您在没有 AWS 的情况下在市场上拥有关键的一组用户。 花一些时间来熟悉基础架构生态系统的各个方面：IaaS 提供程序，托管，DNS，CDN，监视等等。 在早期考虑架构时，有个想法，可能随着流量的增长和平台的扩展而需要在哪里寻找。 **准备快速移动**。

在 NSONE，我们运营着一个复杂的全球任播 DNS 交付网络。 在进行原型设计时，AWS 很有意义，但是在启动平台之前，由于网络需求，我们不得不搬到其他地方。 建立一个具有竞争优势的任播 DNS 网络（针对世界一流的可靠性和性能进行调整），很大程度上取决于我们在复杂的托管和运营商环境中的导航能力，推动基础架构和网络提供商支持我们所需的控制深度的能力。 在许多情况下，我们对提供者进行了教育，并帮助他们建立了我们需要利用的功能。

**不要忘记：基础架构运营商也是极客，他们经常对新想法和挑战持开放态度。** 了解生态系统并参与其中。

## 总结

我经历了很多课程，我们学习了构建和扩展分布式，关键任务系统的经验。 从一开始，您将永远不会把所有事情都做好，但是您可以让自己处于一个良好的位置，以便随着公司的发展而优雅而有效地做出反应。

受众是全球性的。 应用程序交付也紧随其后，任何建立在线资源的新公司都应考虑如何以分布式方式进行架构和扩展，以向其用户提供最高质量的服务，从而最大限度地提高性能，可靠性和安全性。

*如果您错过了这篇文章的第一部分，那么[这是第 1 部分](http://highscalability.com/blog/2015/8/31/building-globally-distributed-mission-critical-applications.html)。*