我还有一个小项目:给黑客的数字礼品卡。它使用Shopify处理所有与商店相关的东西:前台、付款、退款、报告等。
但与普通的数字产品(电子书、视频)不同,我希望用户从商店购买的每一张卡都是独一无二的。因此,我制作了一个脚本来生成个性化图像,并为每个订单手动运行它。
下一个合乎逻辑的步骤是自动化这个过程。我从无服务器AWS Lambda开始。当时,这是一项热门的新技术,我想了解更多。它似乎非常适合我的用例:可以随时运行且不需要服务器维护的单一职责功能。
这是非常容易开始的。我构建了一个JavaScript函数,并将其部署到AWS Lambda,添加了Shopify web挂钩,一切都成功了!
实际上,编写简单的Lambda函数只占工作的10%。
随着时间的推移,我的后台开始变得越来越复杂:我需要为每个拼图存储一些状态,发送确认电子邮件,显示订单详细信息页面。最初只是一个简单的函数,后来发展成一堆无服务器函数、SNS主题、S3存储桶、DynamoDB表。所有这些都与大量的YAML粘合、传递的无模式JSON对象以及AWS控制台中的随机硬编码配置捆绑在一起。
我认为这只是一个典型的软件开发生命周期:事物以有机方式增长,变得一团糟,需要一些重构。让它先运行(发现市场契合度),然后再修正(重构以整合新发现)。
但这一次情况有所不同。我不能像在传统的单一应用程序中那样轻松地重构东西。原因如下:
当构建块过于简单时,复杂性就会转移到块之间的交互上。
并且无服务器块之间的交互发生在我的应用程序之外。一个lambda将一条消息发布到sns,另一个获取该消息并将其写入DynamoDB,第三个获取新记录并发送电子邮件…。
我可以测试流程中的每一个块,但我对整个过程没有信心。如果发布失败了,我怎么知道呢?系统将如何恢复?我可以回滚并重试吗?原木放到哪里去了?
另一大堆问题隐藏在我的配置中:糟糕的路由53记录,SNS主题中的打字错误,错误的S3存储桶区域。跟踪错误是一项挑战,我无法查看任何单一的日志输出。
在无服务器的情况下,我不再处理我的项目的域,而是处理分布式系统的域。
我来这里是为了寻找一种简单的方式来部署代码,而不是考虑服务器,但最终我不得不围绕平台的限制来设计我的系统。
我显然不喜欢无服务器的生活。所以我决定重写一遍。毕竟,这是我为了好玩而做的一个副业。首选的技术堆栈-Ruby on Rails。
我自2013年以来就没有使用过Rails,在Facebook的过去8年里,我主要是在做JavaScript。
捡起钢轨的经历真的很棒,但是…。平淡无奇。没有什么能真正改变那么多。几乎没有添加什么东西,只有几个小东西在移动。
当然,我确实遇到了一些神奇的Ruby问题。但与我使用JavaScript的典型体验不同,我很快就找到了解决方案。
Rails提供了如此多的内置和配置功能。在没有Rails的这些年里,我习惯于将随机的JavaScript库粘合在一起,以滚动我自己的路由、文件存储包装器、电子邮件预览管道、管理机密、使用装置测试设置、数据库迁移、日志记录、性能报告、部署脚本。使用Rails时,我不必考虑所有这些细节,只需专注于进行产品可见的更改即可。
这就像是在我自己制造了几年的破旧汽车之后,开着一辆特斯拉(Tesla)。相似的组件,但所有组件都经过配置和调整,以便很好地协同工作。
无服务器就像一个黑洞。它承诺了激动人心的冒险,但重力吸引了我,我把大部分精力都花在了处理它的复杂性上,而不是专注于我的产品。
嗨!。我叫亚历克斯。我是Facebook的一名软件工程师,在那里我从事Reaction、Native、Oculus和Messenger的工作。我喜欢思考发展经历。