使用S3和CloudFront托管整个Web应用程序

2020-07-12 14:44:50

有几种方法可以在Internet上托管应用程序,但我最熟悉的一种是使用Apache或Nginx这样的Web服务器,在那里您可以托管应用程序的所有静态组件,还可以将其用作反向代理服务器来定向API调用。

但最近我遇到了另一种托管Web应用程序的方式,它更优雅、更具成本效益,而且不需要维护。这种方法利用了AWS S3和AWS CloudFront,结果证明它的设置要容易得多,可以无限扩展,而且比其他方法更便宜。

我构建的产品目前是以这种方式构建的-我们使用Nginx的开源版本,该版本托管在AWS VPS实例上,该实例负责托管我们的Web应用程序的静态文件,并且还充当反向代理服务器,将API调用发送到我们的后端应用程序。

到目前为止,这种设置效果很好,因为我们需要访问应用程序仪表板的用户数量有限,而且也不需要CDN,因为用户,特别是付费计划中的用户,在网站加载之前再等待几秒钟没有任何问题。

当我们的产品中有新的功能要求时,此要求发生了变化。我们的用户是电商,他们大多数在接受订单时接受“货到付款”选项,这就为欺诈留下了很大的空间,因为有人下了订单,选择了“货到付款”的付款方式,而没有实际购买产品的意图。

为了解决这个问题,我们引入了一项功能,在此功能中,下达COD订单的客户会在WhatsApp上收到一条自动消息,以通过链接确认他们的订单。

现在这个网页将被从使用我们应用程序的商家购买的客户访问,所以这个页面的流量可能非常不稳定,更不用说它将来自世界各地,在那里用户的互联网连接也会不稳定,并且根据地区的不同而有所不同。

因此,以托管应用程序其余部分的方式托管此网页是没有意义的。此Web应用程序具有以下要求

事实证明,如果您使用S3和CloudFront(AWS提供的CDN)组合托管应用程序,所有这些事情都可以实现。

AWS文档中有关于如何执行此操作的全面指南-文档链接。

此操作的TL:DR是创建一个S3存储桶,其名称与您想要托管Web应用程序的域/子域同名。

例如,我们的网页必须托管在cod.superlemon.xyz上,所以这就是S3存储桶的名称。在此之后,您必须在存储桶上更改文档中提到的一系列属性和设置。

完成此操作后,您可以根据您所在的地区使用以下任一链接来测试它是否起作用。

虽然AWS文档中的步骤相当全面,但这里有一个问题您必须牢记。如果您的Web应用程序运行在我们正在使用的Reaction这样的框架上,您必须确保在AWS存储桶的“静态网站托管”设置下,将索引文档和错误文档设置为index.html。

这是为了确保如果您在Reaction应用程序中设置了任何URL路由,这些路由都会得到遵守。

上面的步骤只完成了您的应用程序现在驻留在S3中的流程中的一个步骤。但是,只有当应用程序可以作为CDN访问时,该过程才算完成。为此,您必须使用CloudFront并将其配置为使用您的S3存储桶作为源。此处提供了有关此过程的全面文档。

这里也有一些令人费解的地方。第一个问题是,您将需要一个SSL证书才能将您的应用程序作为https://.托管。您可以使用AWS证书管理器轻松获取SSL证书。如果您使用Route53来管理您的域和子域,此过程会变得更加简单。即使你为你的域名使用另一个提供商,如GoPardy或Bigrock,我强烈建议你遵循这些步骤将你的域名插入Route53。

这里的另一个问题再次与reactjs URL路由有关。如果您要在应用程序中使用此功能,则必须遵循另一个步骤。在您的CloudFront发行版下,您必须导航到错误页并创建新的自定义错误响应,如下所示。

这将确保如果CDN找不到您指定的URL路径,它将默认为index.html,在出现reactjs应用时,index.html将处理路由。

完成所有这些步骤后,您将收到一个CloudFront发行版的URL,类似于-dohgltcrfo5nj.cloudfront t.net。您只需将此URL用作别名并将其映射到您的域/子域(在我们的示例中为cod.superlemon.xyz。

就这样,完成了!您现在拥有了一个不需要监视或管理的高可用性应用程序。以这种方式启动应用程序后,它现在位于CDN上,如果您将来必须更新应用程序,则必须使CDN缓存失效才能使更改生效。这可以在“无效”选项卡下完成。

然后提供所有已更新的路径,并且您希望CDN缓存失效。如果要使整个应用程序无效,只需输入";*";即可。

这种方法非常适用于Web应用程序大多是静态的并且可以与后端应用程序完全解耦的用例。

在成本方面,使用这种方法您只会产生CDN成本,因为任何Web应用的S3存储成本都会相当低,并且CDN成本将取决于您有多少流量,因此它会随着使用情况而很好地扩展。

作为参考,我们的网页在6月份有大约10万的点击量,我们的成本大约是0.79美元