译:用了serverless的六个月里,我学到的六件事

504 阅读10分钟

英文原文 | 译文原文

一旦你找到了合适的工具,serverless 的世界真的相当爽,连中间层都被彻底取消。

在十月份的 ServerlessConf 的精彩安利后,我决定将公司整个架构都转入 serverless。最初我花了好几个月转换思维,摸索着将基于 Python Flask 的程序转成 Lambda,这些尝试帮我找到一些不错的方法。

六个月后,我们基于 serverless 部署了第四个大型项目。下面的经验教训,是我们在过程中总结出来的。

第一课 - 放弃 Python

对于传统的请求-相应式架构,Flask 是不错的轻量级框架。会话通过服务器管理。但是这在响应式开发的时代里,相当的古朴,就好像在用橡皮筋和刮刀盖房子。

传统方式: Python Flask 程序运行在 EB,数据存储在 RDS 上

当你开始将更多工作转移到客户端以支持交互,你一定会使用 JavaScript。这些工作之前会内嵌到 Python 模板,导致积累更多的技术包袱。。

基于 Flask 的方案到最后往往会混合多种语言。我很快就得出结论,这种方式很糟糕。我开始怀疑我为什么还在使用 Python。

在转换到 Node 之后,一切都变得更加可维护也合乎逻辑,并且不需要同时使用多种语言。通过在 Webpack 上的 Node/Express 配置,你还可以使用 ES6 避免一些 Python 开发者讨厌的 JavaScript 结构。

在 Zappa/Flask 上做同样的事情简直比报税还麻烦。但是只需要 5 分钟,你就能狗酱一个成熟的基于 Lambda 的 Node/Express 应用,就像填写 1040EZ 表单一样(译者:外国人报税梗是过不去了嘛?),没什么大不了的。所以,我们放弃了 Python 加入了酷小伙专属的 JavaScript 阵营。

Lambda 函数作为单体应用

那我们放弃了什么? Python 主义者会说一堆很厉害的语言特性,但与 JavaScript 实实在在的异步魅力相比,这些仅仅是玩具。现在我们不用在担心 Python 2/3 的版本问题(这玩意还在升级?)。至少对于我们项目而言,切换非常容易。

当然,Ben Kehoe 用他的观点和对使用 Python 与 Node 进行无服务器的见解提供了一个引人注目的替代者陷阱。

第二课 - 放弃中间层

可能是因为我们一直在开发 Web 应用,或者可能是我太老了,我们花了好长时间才发现无服务器的一个明显好处。

我们首批 Web 应用还包含了 Node Express 层,用来记录会话状态。(1)期待用户能够反复命中同一个 Lambda 容器。(2)因为设计失误,我们大量使用 DynamoDB 来存储会话 ID。这种实践非常糟糕。

在“过渡”的第一阶段,我们的中间层就像运行在 Lambda 上的 Web 服务器,错的离谱。之后,我们结束了充满 JavaScript 调用 REST API 的 html 页面。这种方式十分粗糙,让项目很快就变得难以维护。在 Serverless 中,中间层必须取消。

状态移至客户端、逻辑移至 Lambda

第三课 - 拥抱 Vue

把所有内容都放在前端真的非常不错,不过很快就会变得一团糟。最终因为你羞于让别人检查你的代码,因为写的都是一堆然并卵 的代码。不让别人检查你的代码,对于程序员来说,并不是一个好的习惯。

接触单页面程序(SPA)后,我开始了解 React。它是目前最流行的前端框架。React 很不错,但是学习曲线陡峭,需要很多 Webpack/Babel 上的设置,而且引入了 JSX。虽然最终可能会使用它,但是对目前我们的需求来说,它过于复杂,所以我们寻找了其他方案。

幸运的是,我很快发现了 Vue.js,我的 serverless 开发立马变得非常轻松。简单来说:一天之内你就能学会 Vue。

Vue 的设计方法非常契合我们的设计模式,一切都是组件,它们自我管理内容、设计和代码。这使得我们对多个客户项目和分散团队的管理非常容易,并且在 serverless 中表现的也非常不错。

开源 JavaScript 框架给你提供了功能强大的 Debug 工具、出色的组织能力和开箱即用的 Webpack 构建,能节省很多时间。只需要安装路由和 store 管理插件,你就可以像 Facebook 的工程师一样开发出优秀的程序。谁能想到单页应用程序会如此简单?

从 serverless 角度来看,Vue 将你所有的代码都编译到 index.html 和 bundle.js 文件中,十分容易就可以上传到 S3。npm run 是新的编译命令。

好好想想,过去我们需要通过 Elastic Beanstalk 部署程序并监视利用率,在必要时自动扩展还得管理基础架构。

SPA 真正的魅力在于,当你部署应用程序时,只需要简单的将 index.html、budle.js 和少量文件依赖项复制到 S3 并通过 CloudFront 加速。这使得你可以稳定的分发和加载速度,还可以实现多版本管理和任何你喜欢的部署方式,因为它只需要管理文本文件。

这样,我们实际上拥有的无限扩展的能力,并且按需付费。不需要为程序基础架构管理支付任何费用。

Vue 实际上允许你在浏览器中构建桌面应用程序,这意味着你可以极大的改善用户体验。所有用户状态都可以在用户端管理,而不需要反复的发送请求。你可以使用过渡效果等一系列标准 UI 技巧隐藏演示,并且整个程序都能运转的相当棒。

第四课 - 学会爱上 DynamoDB

在某些方面,转到 serverless 最困难的一部分是 DynamoDB。在最开始几轮迭代中,你肯定会一些错误,会有放弃这些回到熟悉有舒服的 RDS 的念头。

很长一段时间,SQL 都是我的拐杖,我必须承认我放了很多业务逻辑在数据库理。但是 RDMS 系统只是另外一个单体应用,不能很好的扩展,它们不支持动态的扩展的敏捷系统思想。

DynamoDB 是一种完全不一样的生物。如果操作正确,NoSQL 可以提供出色的性能,大规模扩展,并且几乎没有管理上的开销。但是你必须花时间来研究它的工作原理,这些在初始阶段会有很多坑。

Dynamo 表字段不能包含空白字符串。备份的时间点也不是自动的。如果弄错了分区和排序,你就必须从头开始创建表。如果过度的尝试模拟 SQL 查询,你会经历表单的爆炸。这些都和 RDS 想去甚远。

在看过不少教程,经历过尝试、失败和最终的成功,我明白…

  • 你需要了解 DynamoDB 的工作方式,花一些时间来了解索引策略,如何查询数据。很容易就在不了解的情况下,很容易就跳进这些坑,很多人都被坑过,然后在错误的时候选择回到 RDMS。犯了错误就该克服错误。
  • DynamoDB 很容易被忽视的一点就是,你可以通过流的方式将代码添加到表事件上,就像 SQL 触发器一样可以做任何事情。这些功能非常强大,我们使用一种非常简单的模式,就是将表变更推送到 SNS 主题队列中。这样变更都能被其他的 serverless 代码吸收,甚至你可以都还没写。
  • 别忘了 DynamoDB 可以为其他存储系统(RDMS, Readshift 或纯文本文件)供流,并可以有效的缓解流量高峰或保护其他数据库免受海量数据的冲击。DynamoDB 具有 TTL 特性,这对于暂存要推送到其他位置的数据非常有用。

第五课 - serverless 框架棒呆!

我的 lambda 早期体验非常繁琐,直接在 AWS 控制台里编写代码带来的大量工作和琐碎事情带来的错误信息,让人十分沮丧。缺少一个桥梁连接 IDE 和生产环境。

好在最终我发现了 serverless 框架。这是我这些年来发现的最令人兴奋的东西。

一个简单的 sls deploy 命令有着巨大能量,将你的代码打包在一起,并发送到 Amazon。而且,如果需要检查因为代码错误导致的日志,只需键入 sls logs -f functionname -t 你就能像 pro 一样检查 CloudWatch 日志,甚至都不需要打开浏览器。

这种改变,翻天覆地!使用 serverless 的人应该赞扬每个云服务商从一开始就应该提供的服务。优秀的一塌糊涂。

第六课-全新的授权方式

在传统应用中,你需要对用户进行一次身份验证,然后通过追踪会话 ID 来追踪用户。之所以喜欢它,是因为你只需麻烦一次,之后在整个生命周期就可以肆无忌惮使用 ID,无论你希望登录多长时间。

在过去,会话 ID 控制访问

但是这种方法有问题的,它仅当你有一台服务器处于中间层才能正常工作。而我们刚刚把服务器给取消掉了。它还可能会让你遭受一些讨厌的攻击,例如跨站请求伪造(CSRF),并且无法让你轻松的将身份认证传递到其他服务。因此,这种方法基本上只支持单体应用(爆炸!)。

我们讨厌单体应用和跨站请求伪造攻击。不过我们有新方法-JWT,JWT 着实让人欢喜。当我了解到它的工作原理,我有一种禅意般的欣悦,但我需要一个图来表示它。

第一步,获得一个 JWT;第二步,使用它和你编写的任何服务进行通信;

第一步看起来很熟悉:授权程序获得 JWT 令牌

第二步很神奇:任何 lambda 函数都可以接受并验证令牌

简单来说每个请求都经过身份验证,并且客户端可以与多个 serverless 进行通信,具有反单体功能,而且跨站请求伪造攻击在 JWT 下甚至都不存在。你的 serverless 代码所需要的就是使用自定义授权起来检查 JWT 是否有效(使用模板代码),然后就完事了。

JWT 使得其他所有认证方式都看起来太过复杂。我们将所有项目切换到 Auth0(有些地方是 Cognito),并且再也没有转会回来。Serverless 认证即疯狂又简单。所以,加入我们吧。

这是个勇敢的新世界

我在 AWS 上工作了很长时间,但从来没有像这样摸索着进行开发。即使在 EC2 的时候,也有很多帮助文档,因为我加入的时间很晚。在离开 A Cloud Guru 的 serverless 会议后,这感觉像是一块未开发的领域,并且在黑暗中还有更多的发现。

在最初的几次实验中,我们尝试使用现有工具和技术是有些失败,结果并不理想。经过几个月的部署,我们已经正式开始以 100% serverless 的方式交付项目。我想想,我们的迁移困难和早期探索非常值得。

我们正在构架精巧的实时 SPA 程序,这些程序尽使用 serverless 架构,可以轻松地扩展,并且降低 70%-90%地成本。回报令我既高兴又震惊。我从来没有像现在这样坚信 serverless 技术将彻底改变基于云的应用交付。

结果是变革性的。