抽象的

抽象的

抽象的

我正在重建我的网站,这一次,我决定使用静态网站生成器(jekyll、sculpin.io 等)。部分作为练习,我希望这个网站托管在全球平衡的主机上以提高速度。(因此美国观众应该从美国服务器访问该网站。)

因此,我的目标是创建尽可能最快的网站。因为我希望可以。

作为一项奖励任务,如果可能的话,我想放置一个重定向器,将某些语言用户引导至网站的英语、德语等版本。

问题是,我该怎么做?以下是我尝试过的:

使用 CDN

我可以找一个随机的静态网站主机,并在整个页面前面放置一个 CDN。虽然这种方法效果不错,但 CDN 会从缓存中删除很少使用的资源,需要时才重新获取它们,这会增加加载时间。

亚马逊 AWS 静态网站托管

使用 Amazon S3 bucket,可以构建静态托管。问题是 bucket 的名称必须与网站名称完全相同,并且 bucket 名称是全局的,因此我无法创建 bucket 的多个实例并直接为网站提供服务。

亚马逊 Route53/EC2

虽然运行自己的操作系统并不是最佳选择(工作量太大,成本高),但这是一个选择。尤其是因为 Puppet 使自动化变得简单。

此设置需要每个区域都有一个 EC2 实例、在其前面配置一个弹性负载均衡器以及 Route53 将流量路由到地理位置本地的 ELB。

自行构建

在每个区域提供 VPS 或根服务器,我可以运行自己的操作系统并安装 nginx。在其他方面,这将与 AWS 设置非常相似。

概括

这些都不能满足我对静态网站托管的需求。如何解决这个问题?这其中隐藏着什么问题?我需要查看哪些服务?

答案1

作者:Cosmocatalano (自己的作品) CC0,通过 Wikimedia Commons;公共领域图像来自 https://upload.wikimedia.org/wikipedia/commons/thumb/f/fc/Project-triangle.svg/256px-Project-triangle.svg.png

我倾向于这样开头“任选两个。”

这个变体铁三角本质上说,你不能同时拥有这三者。如果我们假设你想要好(性能、可靠性)、快(部署简单)和便宜(服务提供商收费和维护)……你最好的情况可能是三者中取其二,而这几乎没有灵丹妙药。

我不太同意 CDN 方法不够快的观点,因为对象不必非常受欢迎才能足够受欢迎,而且在设计良好的页面上,偶尔等待少数对象的短暂等待可能不会被注意到。像 CloudFront 这样的 CDN 具有额外的优势,即您对原始服务器的请求在很大程度上穿越亚马逊自己的网络,而不是公共互联网,从而消除了全球数据传输的一些变量。

但是,有一种混合方法,基本上结合了您提到的所有元素:

前线是 CDN。我们称之为 CloudFront,它使用 DNS 自动将浏览器的请求路由到最优的边缘位置。

CDN 在后端连接的原始服务器实际上是多台服务器,使用 Route 53 进行地理/延迟路由,因此 CDN 边缘连接到附近 AWS 区域中最近的原始服务器。

这些地理/延迟路由目标(CDN 刷新任何非缓存对象的来源)是 EC2 实例,但它们不是功能齐全的 Web 服务器,而是运行代理,每个区域有一个或多个,使用 S3 而不是硬盘作为存储后端。由于代理可以在前往 S3 的途中重写原始主机标头,因此您的存储桶名称不再需要匹配,因此您可以在每个区域放置一个。您可以使用 HAProxy 等代理在非常小的实例上实现相当大的吞吐量(我有 t2.micro 机器每天处理 200 万个请求,同时保持稳定的 CPU 利用率在 3% 左右)。由于代理与存储桶位于同一区域,因此没有数据传输费用。您不需要 ELB,因为 Route 53 运行状况检查可以从 CDN 将从中选择的池中删除不起作用的代理。如果 S3 存储桶因任何原因无法被代理访问,代理将故意未通过其运行状况检查,导致其从选择中被删除。

如果您想要绝对亚毫秒级的速度,您可以使用 Varnish 作为 EC2 机器上的代理,并将来自 S3 的内容缓存在 EC2 内部,这样如果 CDN 需要全新的副本,您可能已经拥有它了。

因此,浏览器选择最近的 CDN 边缘,CDN 选择最近的后端,这是一个代理(每个区域可能有多个代理之一),它对任何尚未被 CDN 保存的内容都有低延迟路径,存储在同一区域的存储桶中。

可用性高、容错性好、全球范围内反应速度极快、由标准组件构建、以略带创意的方式相互连接。(我就是这样做的。)

相关内容