前言

看见一篇非常通俗易懂且适合新手阅读的Web应用架构文章,我将其手工翻译了出来,分享给大家。

也可以去阅读英文原文,标题为,贴出链接:

https://stephenmann.io/post/whats-in-a-production-web-application

英文标题为:

What's in a Production Web Application?

正文

在我职业生涯的早期,我曾在一家工作内容为构建Web内容管理系统的公司工作。他们的产品帮助营销部门可以自己管理网站的内容,而不是依靠开发人员来管理网站。该产品帮助他们的客户降低了运营成本,并帮助我学习如何构建Web应用程序。

虽然产品本身有一个非常普通的用途,但其客户缺倾向于使用它来解决非常特殊的问题。这些问题以各种眼花缭乱的方式将对产品的要求推到了极限,并且要求该产品必须提供解决方案。在这种环境中工作了十多年,让我对生产环境下的Web应用程序有了全面的了解,其中一些我们将在本文中讨论。

这些年我学到的经验之一是,对于开发Web应用程序,个别工程师倾向于非常深入地了解他们感兴趣的东西,对于不感兴趣但必要的组件缺只学习皮毛,这其实是非常“危险”。这对于具有良好沟通的工程师团队来说非常有效,因为这些组合知识将重叠以填补任何个人的局限。然而,这对于独立工程师或者在这方面经验不足的团队,就显得“危险”。

如果你是在这样的环境中开始,然后开始从头开始构建和部署整个Web应用程序,你可能很快就会理解我说的“危险”的意思。

业界已经提供了许多旨在解决这个问题的解决方案:托管Web应用程序(Beanstalk,AppEngine等),托管容器管理(Kubernetes,ECS等等)以及许多其他解决方案。一旦你启动并运行它们,它们就可以正常工作,我认为它们在解决问题方面做得很好。它们隐藏了启动和运行Web应用程序所需的大量复杂性,并且它们倾向于“刚好能工作”。

不幸的是,当它不是“刚好能工作”,或者当你需要完成一些特殊的业务时,你可能会发现自己会希望更多地了解那个不祥的黑盒子。

在这篇文章中,我将采用一个不可靠的系统,并将其演变为具有合理可靠性的系统。沿途的每一步都将使用现实中会遇到的问题作为进入下一步的目的。我没有讨论一个最终设计的每一部分,而是使用这种增量方法有助于读者了解自己的需求,以及自己目前处于哪一步。我们将从头开始构建托管Web应用程序托管服务所提供的基本结构,并希望能够详细介绍每个部分存在的意义。

让我们开始

让我们假设你有一年500美元的托管预算,因此你决定从Amazon AWS租用一台t2.medium服务器。 在撰写本文时,每年仅花费约400美元。

你事先知道你需要设计登录系统,并且你需要存储用户信息,因此你需要一个数据库。 由于预算有限,让我们在我们唯一的服务器上托管它。 最终得到的结构如下:

看起来足够了,哈哈。 事实上,它可能会稳定工作很长一段时间。因为你网站的体量还很小。 此时,你可能每天最多只能处理10次访问。 一个小实例可能已经足够了,但由于你对公司的发展持乐观态度,因此你使用t2.medium实例做出了不错的选择。

你的业务价值存储在该数据库中,因此非常重要。你应该确保就算该服务器发生故障,不会导致你的数据丢失。所以最好去确保下你没有将数据库内容存储在临时磁盘上,不然的话,如果实例被删除,你将丢失所有数据。这会非常可怕。

此外,你还应确保将备份转到外部存储。AWS S3似乎是一个放置这些的好地方,它相对便宜,所以让我们设置它。而且你肯定应该通过每隔一段时间做一次数据备份来测试它是否正常工作。

你的结构现在应该如下所示:

在这时,你已经提高了数据库的可靠性,接下来,你想通过对服务器运行负载测试来为可能到来的大规模的黑客新闻流量(译者注:原文为Hacker News,一个信息源资讯网站)峰值做好准备。一切似乎进展顺利,直到500错误开始出现,然后是404流,所以你要调查弄清楚发生了什么。

事实证明,你没有任何线索来得知网站崩溃到底是因为什么原因,因为你把日志写到控制台,而没有将控制台输出传递到日志文件中。你还看到该进程未运行,因此你默认了这就是你获得404的原因。你脸上的紧张情绪稍稍缓解了点,并且庆幸还好自己没有直接将你的网站登记到Hacker News上。

你创建了一个运行Web服务器的systemd服务来保证你的服务会在崩溃后自动重启。此外,你最终解决了日志记录问题。然后你运行另一个负载测试,以确保你已经解决了所有问题。

你又看见了500错误(幸好没有404),你检查日志以查看出错的地方。你发现数据库连接池已经饱和,该连接池设置为10。你更新了参数,重新启动数据库,然后再次运行负载测试。一切顺利,所以你决定在Hacker News上推广你的网站。

发布日

卧槽!!!(译者注:Great Scott!!!谚语)你的服务大受欢迎。你进入了Hacker News的头条。你在30分钟内获得5,000次点击,你看到评论涌入了进来。来看看他们怎么说?

我得到了404,所以我必须检查页面的存档版本。如果有人需要,这是链接:...

妈的空白页啊!我禁用了Javascript,为什么网站作者会觉得我会取读取你的2 MB Javascript文件 ...

你的主页需要4秒钟才能加载。我居住在澳大利亚,Traceroute显示服务器托管在德克萨斯州的某个地方。另外,为什么你的网页需要2 MB的Javascript?

在混乱中,你被迫在服务器上设置了Nginx作为应用程序的反向代理,并将其配置为服务器静态404页面。 还将静态文件推送到AWS S3,这样做是为了让CloudFront CDN能够起作用,来减少澳大利亚用户的访问时间。

这时候你已经解决了当前的问题,这之后,你可以随时访问服务器并查看日志。 但你慢慢发现,你的SSH连接非常迟钝。经过检查,你发现你的日志文件已经完全耗尽了你的磁盘空间,这会使你的进程崩溃并阻止它再次启动。你创建一个更大的磁盘并在其上挂载日志。 你还设置了滚动日志来防止日志文件再次变得非常巨大。

性能问题

几个月过去了。你的用户群在慢慢增长。你的网站开始变慢。你在CloudWatch监控中注意到,这似乎只发生在中午和晚上。由于变慢的开始和结束时间每天都相同,你猜测这是由于服务器上的计划任务造成的。你检查了你的crontab,看见了你自己在午夜安排了一份工作:备份数据库。果然,你的备份需要12个小时,并且备份程序使数据库过载了,导致了网站访问极慢。

发现了这个问题后,你决定新建一个从数据库,并在从数据库上运行备份。 所以你创建了一个从数据库。在同一台服务器上运行从数据库没有多大意义,你决定,是时候扩展了!你创建两个新服务器:一个用于master数据库,另一个用于slave数据库。 你将备份更改为在从属数据库中定时运行。

组建团队

一切都运行平稳了一段时间,几个月过去了,你聘请了一个更大的开发团队,其中一位新开发人员发现了一个bug,这个bug会导致生产服务器的崩溃。此位程序员觉得是由于开发环境与生产不同导致的。他说的话有些道理,你听起来觉得很对,所以你决定把这个问题解决。

你构建了更多不同的环境:Staging,QA和生产环境。幸运的是,你从写这个项目第一天开始就搭建了自动基础架构,因此环境的增加很容易。并且从第一天起,你就使用了良好的持续交付机制,因此你可以轻松地从管道构建新分支。

在这之后,营销部门希望推出v2.0版本。你不确定v2.0版本是什么,但无论如何你还是决定做了。是时候准备另一次流量的飙升了。在Web服务器上运行的服务已经接近服务器的峰值利用率,因此你决定开始对流量进行负载平衡。亚马逊ELB能够让你轻松上手。在这个时候,你还发现博客文章中的分层图表应该从上到下而不是从左到右显示图层。

你再次将你的网站发布到Hacker News。 它撑住了巨大的流量,取得了极大的成功!

这一切似乎都很棒,直到有一天,你去检查了你的日志。 这时你才发现,检查一次日志,需要一个小时,因为要检查12台服务器(每个环境中有4台服务器),这显得很麻烦。幸运的是,你的公司现在已经赚了足够的钱来实现ELK堆栈(ElasticSearch,LogStash,Kibana),你构建了一个ELK环境并将它用在了所有环境中。

这样一来,你可以轻松地查看日志了,你发现,有很多奇怪的东西混在了日志里。

GET /wp-login.php HTTP/1.1" 404 169 "-" "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:40.0) Gecko/20100101 Firefox/40.1
GET /wp-login.php HTTP/1.1" 404 169 "-" "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:40.0) Gecko/20100101 Firefox/40.1
GET /wp-login.php HTTP/1.1" 404 169 "-" "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:40.0) Gecko/20100101 Firefox/40.1
GET /wp-login.php HTTP/1.1" 404 169 "-" "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:40.0) Gecko/20100101 Firefox/40.1
GET /wp-login.php HTTP/1.1" 404 169 "-" "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:40.0) Gecko/20100101 Firefox/40.1
GET /wp-login.php HTTP/1.1" 404 169 "-" "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:40.0) Gecko/20100101 Firefox/40.1
GET /wp-login.php HTTP/1.1" 404 169 "-" "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:40.0) Gecko/20100101 Firefox/40.1
GET /wp-login.php HTTP/1.1" 404 169 "-" "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:40.0) Gecko/20100101 Firefox/40.1
GET /wp-login.php HTTP/1.1" 404 169 "-" "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:40.0) Gecko/20100101 Firefox/40.1
GET /wp-login.php HTTP/1.1" 404 169 "-" "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:40.0) Gecko/20100101 Firefox/40.1

你根本没运行过任何PHP有关的服务,这非常令人担忧。 你注意到数据库服务器上也有类似的可疑日志,现在你很想问自己为什么将它们的端口暴露在了外网上,是时候区分公共和私人子网了。

OK,你又开始检查你的日志。黑客还是可以攻击你,但现在它们仅限于负载均衡器上的端口80,因为你的应用程序服务器,数据库服务器和ELK堆栈不再暴露在互联网上,这下你舒坦了。

尽管进行了集中式日志记录,但你还是不得不通过手动检查日志来发现中断。 你可以使用Amazon CloudWatch设置磁盘,CPU和网络警报,以便在达到80%容量时向你发送电子邮件。还能说什么,简直完美。

一帆风顺

开玩笑!没有一帆风顺的事情,总有事情会出错。幸运的是,你有很多工具可以更轻松地处理这些问题。

我们构建了一个可扩展的Web应用程序,包括备份,回滚,集中式日志记录,监控和警报。这是一个很好的总结时刻,因为这里的增长往往取决于特定应用的需求。

业界提供了许多托管选项,可以为你处理大部分内容。你可以依靠Beanstalk,AppEngine,GKE,ECS等,而不是自己构建所有这些服务。大多数这些服务都会自动设置合理的权限,负载均衡器,子网等。他们需要花费很多麻烦才能使应用程序快速启动并运行,这样可以确保你的站点长时间运行所需的可靠性。

无论如何,我认为了解这些平台提供的功能以及提供它们的原因是有用的。它可以根据你自己的需求更轻松地选择平台。一旦你在平台上运行了所有东西,你就已经弄清楚了这个工具的这些重要方面是如何工作的。当出现问题时,有助于了解你拥有解决问题的必要工具。

总结

这篇文章跳过了很多细节问题。它不包括如何自动创建基础结构,如何配置服务器或如何配置服务器。它不包括如何创建开发环境,如何设置连续交付管道,或如何执行部署或回滚。它不包括网络安全,秘密共享或最小特权原则。它不包括不可变基础架构或无状态服务器或迁移的重要性。这些主题中的每一个都需要自己的帖子。

本文的目的主要是提供一个合理的生产Web应用程序应该是什么样子的高级概述。 未来的帖子可以参考这个并扩展它。

感谢你的阅读!

编者注:编辑:不要使用文章中出现过的具体数值作为你服务的参数设置。

通俗易懂的生产环境Web应用架构介绍的更多相关文章

  1. Kubernetes 在生产环境中常用架构

    Kubernetes 在生产环境中常用架构 首先,我们来梳理下Kubernetes生产架构,其设计适用于绝大多数环境.如下图所示 在该架构中,我们可以将其分为四层,如下: Client层:即Kuber ...

  2. 马老师 LNMP生产环境Web架构 笔记

    http协议和缓存原理.多路IO模型: MIME机制,Multipurpose Internet Mail Extensions,多用户互联网邮件扩展.MIME使用一个简单的字符串组成,最初是为了标识 ...

  3. 技术分享 | Appium环境安装与架构介绍

    原文链接 Appium架构 Appium 设计哲学 不需要为了自动化而重新编译或修改被测应用 不应该让移动端自动化测试限定在某种语言或者某个具体的框架 不要为了移动端的自动化测试而重新造轮子 移动端自 ...

  4. [译]MongoDb生产环境注意事项

    译注: 本文是翻译MongoDB Manuel中的MongoDB Production Notes一节内容.这节内容重点关注生产环境中影响性能和可靠性的各种注意事项,值得正在部署MongoDB的工作者 ...

  5. 中小研发团队架构实践之生产环境诊断工具WinDbg 三分钟学会.NET微服务之Polly 使用.Net Core+IView+Vue集成上传图片功能 Fiddler原理~知多少? ABP框架(asp.net core 2.X+Vue)模板项目学习之路(一) C#程序中设置全局代理(Global Proxy) WCF 4.0 使用说明 如何在IIS上发布,并能正常访问

    中小研发团队架构实践之生产环境诊断工具WinDbg 生产环境偶尔会出现一些异常问题,WinDbg或GDB是解决此类问题的利器.调试工具WinDbg如同医生的听诊器,是系统生病时做问题诊断的逆向分析工具 ...

  6. web资源预加载-生产环境实践

    此文记录资源预加载在我们项目的实践,技术难度不算高,重在介绍一套技术方案的诞生与实施,其中都进行了哪些思考,依据什么来做决策,如何进行效果评估,等等.为读者在制定技术方案时提供一定启示. 背景 资源预 ...

  7. 中小研发团队架构实践之生产环境诊断工具WinDbg

    生产环境偶尔会出现一些异常问题,WinDbg或GDB是解决此类问题的利器.调试工具WinDbg如同医生的听诊器,是系统生病时做问题诊断的逆向分析工具,Dump文件类似于飞机的黑匣子,记录着生产环境程序 ...

  8. EF架构~CodeFirst生产环境的Migrations

    回到目录 Migrations即迁移,它是EF的code first模式出现的产物,它意思是说,将代码的变化反映到数据库上,这种反映有两种环境,一是本地开发环境,别一种是服务器的生产环境,本地开发环境 ...

  9. 使用SecureCRTP 连接生产环境的web服务器和数据库服务器

    一.使用SecureCRTP 连接生产环境的web服务器 首先,需要知道以下参数信息: 1.web服务器的ip地址     2.服务器的端口号    3.会话连接的用户名和密码   4.服务器的用户名 ...

  10. web移动端生产环境调试

    如果是开发环境,比较容易: 最笨的方法是手机开QQ电脑开QQ把做好的页面传给手机QQ直接打开.. 参考: http://blog.allenm.me/2014/05/mobile-web-debug- ...

随机推荐

  1. Elasticsearch内核解析 - 数据模型篇【转载】

    原文链接 Elasticsearch是一个实时的分布式搜索和分析引擎,它可以帮助我们用很快的速度去处理大规模数据,可以用于全文检索.结构化检索.推荐.分析以及统计聚合等多种场景. Elasticsea ...

  2. linux学习指令与现有环境解决问题笔记

    linux学习指令与现有环境笔记 注意:我将pytorch和cuda安装在了pytorch这个虚拟环境中 pytorch安装及注意问题 注意版本对应,稳定版2.0.1对应cuda11.7,别按错了 按 ...

  3. SQL优化篇之-如何减少耗时查询的调用次数

    函数调用次数与性能 在查询语句中,如果 Select 子句调用了较为耗时的函数或子查询,需要特别考虑函数调用次数对于SQL整体执行时间的影响. 一.数据准备,SQL 语句 模拟较耗时的用户函数 确保执 ...

  4. 3D Object Detection Essay Reading 2024.04.01

    Swin Transformer paper: https://arxiv.org/abs/2103.14030 (ICCV 2021) code:https://github.com/microso ...

  5. #莫队,bitset#洛谷 3674 小清新人渣的本愿

    题目 分析 只要做到\(O(n\sqrt{n})\)的时间复杂度就可以了 考虑莫队,首先乘号就是枚举\(x\)的约数\(d\), 判断\(d\)和\(\frac{x}{d}\)是否同时出现, 再考虑差 ...

  6. SkipList和java中ConcurrentSkipListMap的实现

    目录 简介 SkipList ConcurrentSkipListMap SkipList的实现 concurrent的实现 总结 SkipList和java中ConcurrentSkipListMa ...

  7. Java break、continue 详解与数组深入解析:单维数组和多维数组详细教程

    Java Break 和 Continue Java Break: break 语句用于跳出循环或 switch 语句. 在循环中使用 break 语句可以立即终止循环,并继续执行循环后面的代码. 在 ...

  8. Go 语言学习:了解 const 关键字及常量声明

    如果一个变量应该有一个固定的.不能改变的值,你可以使用const关键字. const关键字将变量声明为"常量",这意味着它是不可改变和只读的. 语法 const CONSTNAME ...

  9. 华为终端云服务牵手Likee,助力其用户与变现双增长

    如今,社交媒体越来越深入人们的生活,改变了人们沟通方式的同时,也塑造着全新的人际关系和品牌形象.为了迎合用户多样化的需求和提升用户体验, 社交媒体行业的新老企业不断追逐着新技术和新功能.据调查机构Da ...

  10. 知识图谱增强的KG-RAG框架

    昨天我们聊到KG在RAG中如何发挥作用,今天我们来看一个具体的例子. 我们找到一篇论文: https://arxiv.org/abs/2311.17330 ,论文的研究人员开发了一种名为知识图谱增强的 ...