原文链接
分布式系统:何时构建它们以及如何扩展,分步指南。
当我开始创建产品时,有多少初级开发人员患有冒名顶替综合症,这总是让我感到震惊。
我明白了,有很多令人兴奋的例子顶尖公司与可以解决极其复杂的分布式系统数十亿请求,优雅地提升数以百计的应用程序没有任何停机时间,从灾难秒恢复,释放每60分钟,并有光速来自世界任何地方的响应时间。
当您开始项目时,这些期望可能会让人不知所措。但正如你们中许多人已经知道的那样,这些公司中的大多数都是从最小的可行系统和非常差的技术堆栈开始的。这有一个简单的原因:他们在开始时就不需要它。实际上,花更多的时间设计系统而不是编码可能会导致失败。
本文是一步一步的指导。我将向您展示在Visage,我们是如何从有史以来最小的系统开始的,并构建了基本的高可用性可扩展分布式系统。这是一个真实的案例研究,以删除您的配合,如果你从未有过的机会,自己做。
当我刚到达Visage担任首席技术官时,我是唯一的工程师。我对技术堆栈一无所知,但我加入了,因为我真的很喜欢没有内部招聘人员或人力资源服务就能招聘 的想法。这是落后面貌的核心理念:众包通过的协助您的角色一起工作了很多无形的招聘的动力人工情报它去寻找最合适的人才,为你在几天之内。然后,您直接与他们接触,没有中间人。
在“ 人群 ”,在众包立刻触发了我的大脑工程:有会是很多人,工作的同时,期待着良好的表现,从任何地方在世界上。我喜欢挑战。
但是从系统的角度来看,事情很糟糕,实际上很 糟糕。这是我到达时发现的:
- 一个运行数百个过时的有缺陷的插件的受感染的Wordpress实例,在共享服务器上的VM中运行
- 受损的邮箱
- 大量的Google文档和电子表格。
而这是完全正常的。再次,团队中没有技术人员,而我一直期待这样的事情。依然是球队把重点放在商业机会,并取得了各项产品看起来像它 的工作神奇而手动所做的一切!(假装直到完成)。那真是太神奇了。
我们的第一个系统(是的,它很烂,但它确实完成了任务)!
毫不奇怪,我的首要任务是重新创建VM,重新安装更新的Wordpress版本,确保每个人都更改其密码,建立密码策略并删除公司计算机上的数十种恶意软件……但是让我们继续进行系统注意事项。
从Wordpress到Web应用程序
开始构建产品时的首要重点是数据。数据是驱动公司价值的动力。这将是您每天用来做决定的东西,以及您向投资者展示来证明进展的东西。
您需要理清数据,从不同来源以不同格式恢复数据将浪费大量时间。在许多情况下,通过节省大量的工程时间,Wordpress可能是一个很好的选择,但是Visage团队为了满足他们的需求,不得不安装不再需要维护的高级插件。结果,我们无法控制所生成的数据模型,并且无法适应该模型的数据分散在数十个文档和电子表格中。
因此,除非那里已经有一款产品已经满足您90%的需求,否则请考虑理想的数据模型并设计并实施一个最低可行的产品(MVP),该产品将能够保存您的所有数据。
然后考虑API。您的应用程序必须具有API,当您最终出售该API时将至关重要。不要立即扩大规模,但要考虑可伸缩性。使您的API 无状态且尽可能地具有RESTful,因为每个人都希望能够使用标准HTTP方法对其进行查询。
在我们的案例中,我们选择NodeJS,因为我们的大多数代码都只是在处理输入和输出。NodeJS是非阻塞的,并带有一个方便设计API的库:ExpressJS。
如果您需要面向客户的网站,则有多种选择。首先,您可以在应用程序服务器中创建一个将生成页面的层,或者可以构建将由静态Web托管服务器提供服务的Single Page Javascript应用程序。
在Visage,我们选择了第二个选项,并决定为用户创建一个应用程序,为管理员创建一个应用程序。这仅仅是因为我们对用户的期望比对管理员的期望高得多,并且希望使两个代码库保持简单(也出于以后的CORS考虑)。这是我们的系统的样子:
所有数据集中在一个地方
尽早委托敏感数据存储
除非对您的业务至关重要,否则没有充分的理由在系统中存储敏感的个人数据。安全是一件复杂的事情,如果您每天修改代码,直到找到适合您的产品的市场,它就会崩溃。假设任何不想要的人如果真的愿意,都可能违反您的申请。
这里的关键是不要保存任何对黑客来说是快速的胜利的数据。没有人抢劫没有钱的银行。如果要设计SaaS产品,则可能需要身份验证和在线付款。您可以与许多第三方集成,以比您可能更好的方式处理该第三方。
例如,Auth0是处理身份验证的最著名的第三方。条纹也是在线支付的不错选择。他们将奉献所有资源和最好的安全工程团队在这个星球上,让您的数据安全 -或者他们没有一个企业。
云服务是您最好的朋友
因此,在这一点上,我们已经有一种方法来存储我们所有的数据,身份验证,在线支付和供客户使用的Web应用程序,以及可以针对不同用例出售给合作伙伴的API。我们的用户群在不断增长,很明显,他们希望能够随时访问该应用程序。因此,该考虑扩展性和可用性了。
我们依靠一台服务器,但是它只能处理这么多请求,更改服务器或发布新版本将意味着在发布期间关闭应用程序。我们的下一个优先事项是:负载平衡,自动扩展,日志记录,复制和自动备份。当然,如果您是公司中唯一的工程师,那么尝试自己解决所有这些问题将完全是疯狂的。
幸运的是,我们生活在一个只有全面的工程师才能在几天之内使用Amazon Web Services,Google Cloud Services或Azure之类的云服务轻松构建这样的系统的时代。我们决定将系统迁移到AWS,因为当时它是最完整的解决方案,并且我们拥有2年的免费积分。
这就是为什么我在这篇文章中主要谈论AWS解决方案,但是其他平台上也有等效的服务。这也是我们选择开始在Docker 容器中运行模块的时候,原因有很多其他不同的原因,本文将不再涉及(您可以查看本文了解更多信息:https : //medium.freecodecamp.org / amazon-fargate-goodbye-infrastructure-3b66c7e3e413)。
你如何决定来运行你的应用程序实际上取决于你的使用情况,如灵活性,你需要与时间,你可以花你的管理基础设施。
没有好的或坏的答案。
您可以选择对所有模块进行容器化,并使用容器 管理 系统,例如AWS中的ECS / EKS或GCP中的Kubernetes引擎。如果不是这样,并且您不想自己处理自动缩放和负载平衡之类的事情,则可以使用Elastic Beanstalk或App Engine。
如果要完全使用无服务器,还可以结合使用Lambda函数和API网关。我们决定去ECS。我们在3个可用区中部署了3个实例,一个负载平衡器,根据CPU使用情况设置自动缩放,将所有容器的日志与Cloudwatch集成,并设置了Metrics来监视错误,外部调用和API响应时间。
对于我们的数据库,我们使用MongoDB,因为我们的模型非常适合NoSQL数据库及其高度一致性。我们决定利用MongoDB Atlas的优势,并部署了3个副本以实现高可用性。Atlas除其他服务外,还提供自动缩放,自动备份功能,并允许您在发生灾难时无缝地回到过去。
我们还决定将所有静态Web文件托管在S3中,并将Cloudfront用作CDN,以便我们的JS应用可以在世界任何地方快速加载,并可以按要求提供多次服务。Cloudflare也是一个不错的选择,并提供了开箱即用的DDOS保护。
为简单起见,我们决定通过对所有域使用它们的名称服务器来将Route 53用作DNS。这是我在AWS上最喜欢的服务之一。它使您的生活变得更加轻松。每当您想通过域名提供服务时,无论是EC2实例,弹性IP,负载均衡器,Cloudfront 发行版还是任何私有或公开的真实内容,都需要花费您几分钟的时间,因为它与所有其他服务。
将其与证书管理器结合使用,可让您在几分钟之内免费获取SSL证书(包括通配符)并通过勾选一个框将其部署在所有服务器上,您将以最快,最可靠的方式在所有模块上启用HTTPS。再见,“我加密” SSL证书,我必须每3个月左右更新并安装在服务器上??。
开始看起来不错
确定缓存策略
每个人都讨厌缓存管理,缓存可能发生在许多不同的层,并且与缓存相关的问题很难重现,并且是调试的噩梦。
不幸的是,分布式系统的性能严重依赖于良好的缓存策略。关于好的缓存策略,有很多好的文章,所以我不会赘述。只是知道,如果您的静态Web 资源很繁重,您可能想通过巧妙地使用cache-control标头来利用用户的浏览器缓存。
如果您的用户面对的页面是在应用服务器上一遍又一遍地生成的,请使用诸如Squid之类的缓存代理。但最重要的是,您很有可能会一遍又一遍地向数据库发出相同的请求。为了降低数据库负载并节省数据传输时间,请使用内存对象缓存系统(例如memcached)来处理频繁使用且很少更新的对象。
我们开始考虑使用memcached,因为我们经常一再要求相同的候选人资料和工作机会。当我们平均一天中所有请求的响应时间时,在内存优化的机器上实现它可使我们的API 性能提高30%以上。Memcached也是分布式的,因此它可以在不同的服务器上运行,但仍然像是存储对象的一大内存空间。
缓存,到处缓存
地点!
现在,我们有了一个没有单点故障的分布式系统(如果考虑使用AWS ELB和分布式 memcached),并且可以自动伸缩。我们还使用缓存来最大程度地减少网络数据传输。看起来还不错 那时,您可能想审核第三方,看它们是否会像您一样承担负载。
但是,仍然有一些用户抱怨说,该应用程序对他们来说有些慢,尤其是当他们上传文件时。实际上,即使我们的静态Web文件被缓存在世界各地(由CDN提供),我们所有的应用程序服务器也仅部署在美国西部。来自东亚的用户经历了更多的延迟,尤其是在大数据传输方面。
解决方案很容易:将完全相同的ECS集群与新的负载均衡器一起部署在亚洲的新区域,并依靠Route 53 Geoproximity Routing将用户路由到“最近的”负载均衡器。MongoDB Atlas还允许您跨 区域部署副本,因此不需要其他工作。
我们到了!我们的分布式系统已准备就绪。
结论
尽管本文简化了您在此处看到的分布式系统,但我们检查了许多现代Web应用程序中最有可能看到的部分。其他但不涉及的主题包括微服务体系结构,文件存储和加密,数据库分片,计划任务,异步并行计算……也许在下一篇文章中!
我的主要观点是:启动产品时不要尝试构建完美的系统。您的大多数设计选择将取决于产品的用途和使用人员。您将只知道,当您适应产品市场并开始对用户群有了一个很好的了解时,甚至可能要花费数月甚至数年。
即使有很多手动步骤,也要专注于弄清楚人们的需求,并尝试提出解决问题的方法。然后考虑自动化的方法,花费时间进行编码和销毁,并在有意义的地方使用第三方。
不扩展,但始终思考,编码并计划扩展。逐步构建系统,不要基于尚未成熟的功能解决系统设计问题,最后总是尝试在花费的时间与性能,金钱和降低的收益之间找到最佳的平衡点风险。
原文地址:https://www.cnblogs.com/CherryTab/p/12076129.html