我们的AWS账单不到收入的2%。我们是这样做的

2020-06-28 15:33:32

对于大多数资助的初创公司来说,服务器成本通常不是一个问题,但对于像我们这样的自给自足的SaaS产品来说,重要的是有一个口袋里很容易负担的AWS账单,而且与MRR的比例更高。

为此,当我们创建superlemon.xyz时,我做的第一件事就是想办法消耗最少的云资源。我们目前使用我们的AWS设置为每秒约250个请求提供流量服务。

我现在将逐一查看这些资源,并讨论实现它们的昂贵方式和廉价方式。

谈到计算实例,大多数人选择AWS EC2实例。EC2实例是运行服务器应用程序的最安全选择,因为它们高度可配置、可伸缩,并且您可以根据需要按需更改配置。但是,有时您并不真正需要对计算实例进行这种级别的控制,这就将我们带到了AWS LightSail。

顾名思义,LightSail是EC2的轻量级版本。在幕后,LightSail实例实际上是EC2实例,但这对用户来说并不明显,而且与高度可配置的EC2不同,LightSail附带了一个固定的配置,一旦您进行配置,该配置就不能更改。计费也是每月固定金额,而不是EC2,按小时计费。

为了让您了解LightSail有多简单,请看一下这些EC2仪表板和LightSail仪表板的屏幕截图。

但我们在这里不是要讨论EC2与LightSail的复杂性,所以让我们来谈谈成本吧。

具有2个虚拟内核、4 GB RAM和80 GB存储的EC2实例每月的价格约为37美元,而配置完全相同的LightSail实例的价格为每月20美元,几乎是成本的一半!

如前所述,这里唯一的缺点是实例是固定的,存储和计算能力都不能在以后根据流量和使用量的峰值进行调整。

在我们的案例中,我们不需要计算实例上太多的存储,至于计算能力,我们可以很容易地在流量增加时提供另一个LightSail实例,并将其设置在负载均衡器之后。这样,我们的系统仍然是可伸缩的。

为您的应用程序选择数据库提供程序可能是一个棘手的决定,但在较高级别上,只有一件事是任何数据库提供程序都绝对需要的-自动执行数据库的定期备份的能力,以及从其中一个备份还原数据库的能力。

所有这些功能都由AWS RDS以及一系列其他功能(如存储的自动扩展、多可用区等)提供。但是,对于我们简单的SaaS产品,我们并不真正需要这种级别的数据库控制,更不用说使用最低可接受配置的RDS每月最低200美元的费用。

我们的救星又一次是LightSail,它以非常便宜的价格为托管数据库提供固定存储。不过,只有MySQL和PostgreSQL可用,这对我们来说很好,因为我对MySQL相当满意。我们目前为一个MySQL数据库配置了2个vCPU、4 GB RAM和120 GB SSD,每月收费60美元。

这里的缺点是数据库不会自动伸缩,因此您必须确保您的应用程序使用的存储空间不会超过您选择的实例中可用的存储空间。我们通过定期清除数据库中超过X天的数据和属于X天前从我们的应用程序中删除且此后再也没有回来的用户的数据来做到这一点。

对于我们的应用程序,我们需要一个缓存层以及对可以异步执行的作业进行排队的能力。这里经验丰富的人可能已经意识到,最好的工具是Redis,而AWS有一项名为ElastiCache的服务,它在引擎盖下是Redis。

再说一次,这将是一个非常安全的选择,因为它是完全托管和可伸缩的。我们需要的是一个至少有6 GB内存和2vCPU的Redis实例,如果我们使用ElastiCache,我们的成本大约是每月112美元,更不用说在其他地方运行异步工作程序的额外成本了。

在这一点上,我可能听起来像是一张破唱片,但我们最终做的是为LightSail实例提供2vCPU和8 GB内存,每月花费40美元,并在该实例上安装了一个开源版本的Redis。我们还使用相同的实例来运行异步工作程序,这些工作程序读取Redis队列并执行作业。

那么它的缺点是什么呢?因为它不是托管服务,所以您必须自己监控Redis服务器。有很多工具可以帮助您做到这一点,我推荐的工具是prometheus.io。

这意味着您必须做一些额外的工作来设置Redis实例中的指标集合,并使用grafana仪表板来查看这些指标,但是从长远来看,这项额外的工作节省了大量资金,而且您可以看到像这样一个超级酷的仪表板。

我们的应用程序需要一个javascript文件加载到我们客户的网站中。此JS文件获得大量流量,因为此流量会根据我们的客户获得的访问量进行调整。这可能很可怕,因为这意味着我们真的不知道JS文件最终可能会收到多少请求,所以我们犹豫了是否使用CloudFront,这是AWS上CDN的GoTo解决方案。

因此,我们最终采取了一种完全不同的方法。我们的应用程序是Shopify应用程序,在构建应用程序的过程中,我们创建了一个Shopify商店。每家Shopify商店都有自己的个人CDN,你可以在那里手动上传任何东西,它将通过Shopify CDN提供服务。因此,我们将JS文件缩小并上传到Shopify商店的CDN,现在我们使用这种方法零成本地为20000家Shopify商店提供服务。

这种方法有一个明显的缺点。Shopify商店CDN不提供可用于以编程方式上传文件API,必须手动完成。此外,与CloudFront不同的是,文件上传后没有使其无效的选项。因此,如果您必须对文件进行更新,则必须上载一个新文件并将所有现有用户迁移到此新文件。

这听起来可能是一个很大的缺点,但实际上我花了一个小时来创建一个脚本,将所有现有20000家商店的JS文件更新为我提供的更新后的JS文件。因此,每当我对此JS文件进行新的发布时,我只需手动将一个新文件上传到CDN,然后将该文件作为输入并运行此脚本,我们就可以上线了!这种方法对我们是有效的,因为我们一开始就没有对JS文件进行太多的发布。

每个应用程序都需要能够将进入其域或子域的请求路由到在幕后运行的各种应用程序。实现这一点的最佳方式是使用AWS ELB,它可用于跨多个目标(如Amazon EC2实例、容器、IP地址和Lambda函数)自动分发传入应用程序流量。

在N个相同的LightSail实例之间,负载平衡来自我们的Merchants Shopify商店的流量。

所有这些都可以使用Nginx来完成,Nginx是一款很棒的软件,即使使用它附带的默认设置,它也相当健壮。

因此,我们只是在一个现有的LightSail实例上安装了一个稳定版本的Nginx,该实例已经用于托管我们的一个服务器应用程序。我们还使用Amplify.nginx.com进行监控。此设置相当于零成本使用托管服务。

在计算实例(40$)上使用自托管Redis服务器,而不是使用ElastiCache(112$)。

使用自托管Nginx服务器(固定成本为20美元),而不是ELB(成本取决于流量和使用情况)。

我想强调的是,我们是一款微型SaaS产品,解决了一个小而具体的用例,因此这种AWS设置对我们很有效。这可能不适用于交通不稳定的大型组织或产品。

这种设置也不适用于那些已经有大量工作要做的人,他们更愿意使用托管服务,而不是承担定期监视、维护和调配硬件资源的额外麻烦,因为这需要时间成本。

我们是一个由2个人组成的团队,拥有一个计算量不大、云需求非常简单的产品。我们使用此AWS设置运行此产品已有一年多的时间,到目前为止还没有遇到任何问题。