现在,Serverless 真的已经成熟了吗?

2020-09-23 15:27:11 浏览数 (1)

作者 | Justin Etheredge

译者 | 张健欣

策划 | Tina

无服务器计算成熟了吗?

每年,软件工程行业都会冒出各种新工具和新趋势。由于我已经研究一段时间了,我想是时候开始开发一个像样的雷达工具,来发现哪些趋势将产生持久的影响,而哪些趋势将虎头蛇尾。可以肯定的是,我曾做过一些令人尴尬的预测,例如和我的一个朋友打赌 Git 会输给 Mercurial,因为 Git 的用户功效学太差了。但我们都知道结果如何。

但总的来说,对于什么样的技术会成为赢家,而什么样的技术会成为败者,我认为我自己有着很好的认识。而谈到无服务器计算时,我还不需要使用任何专业知识。

等等,什么?不需要任何专业知识?

是的,你没看错。根本不需要一个预言家就可以看到,无服务器计算就是未来。没人想要管理服务器。管理服务器是执行代码的一个令人讨厌的副作用。我需要一个安全的环境来运行代码,而根据冯诺依曼架构,我需要一些内存、一些硬盘空间和一个处理器。我其实并不关心这些东西是什么形式,只需要数量足够就可以了。我的代码需要以上三种资源,而我需要一个环境为我提供这些资源。就是这么简单。

我想要运行代码并不意味着我 想要 管理一个服务器或者代码运行的环境。在理想情况下,我会去找一个云服务商,然后告诉他“这是我的应用程序,帮我让它运行吧。”

什么是 Serverless?

在开始之前,让我们先来了解下 Serverless 到底是什么。你会看到一些 Serverless 的定义,说它根据需要提供计算资源。而这只是一个纯粹的定义,更常用的定义是,这是一种可以向你提供计算资源而不需要你自己关心服务器管理的方法。

Serverless 有以下几种形式

无服务器容器

无服务器容器服务,例如 Heroku、Netlify、AWS ECS/EKS Fargate、Google Kubernetes Engine 和 Azure Kubernetes Service 为你提供一个环境,你可以在其中构建一个容器并将其推送到一个管理容器部署和运行的服务中。你不必担心托管控制服务器、节点服务器等集群的运行,你只需要向上推一个包含一些元数据的容器,其余的由这个服务处理。

无服务器函数

无服务器函数,例如 AWS Lambda、Google Cloud Functions 或者 Azure Functions 等服务提供了一个环境,你能在那个环境中使用特定的接口上传一段代码,然后调用这段代码。

Serverless vs 虚拟机

许多人并不认为无服务器容器是真正的 Serverless,因为当你构建和推送一个容器时,你实际上是把整个服务器打到一个包中。虽然我倾向于同意它们并不是真正的Serverless,但它们绝对比运行完整的虚拟机有巨大的好处,而且在某些场景比无服务器函数有明显优势。

无服务器容器的优点

无服务器容器比传统服务器有巨大优势。下面是其中一些优势:

  1. 服务器管理事项很少——不用管理、修补或故障排除服务器。容器内仍然有一个操作系统,但那可以是一个非常极简的安装版,而且要管理的东西会非常少。
  2. 通常是无状态的——当构建针对容器的应用程序时,你通常是在构建一个 12 因子应用程序 或者遵循类似的模式。你的容器 是牲畜,而不是宠物。如果你的容器崩溃了,一个新的容器会自动激活。
  3. 容易横向扩展——虚拟机在扩展性方面本质上没有任何限制,但是容器将你推往一个可以允许无服务器容器服务按需扩展你的软件的方向。基于负载、请求时长和请求数量,你的无服务器容器服务可以运行一个或 10000 个容器实例,同时透明地处理存储分配、负载均衡、路由等。
  4. 安全——在容器中安装的操作系统通常是短暂的、简小的而且有时是只读的。因此,它提供的攻击面比典型的通用和长期服务器环境要小得多。
  5. 源码可控的环境——你的容器定义是在一个可以放入源码控制的文件中描述的。虽然这是当前几乎任何环境下的最佳实践,但与传统服务器环境相对还是有明显的优势。在传统服务器环境,有人可以接入服务器并篡改服务器配置。
  6. 应用程序和环境打包——将应用程序与其所运行的环境结合起来,并将其作为一个单独的单元部署。这样的话,如果你的软件的新版本使用了更新了的库、操作系统版本或者语言版本,它可以作为一个单独的单元部署和回滚。
  7. 成本——你可以轻松上下调整你的工作负载。虽然运行一个无服务器容器可能会稍微贵一点,但你可以灵活地在几个服务商之间做取舍。与传统的虚拟机选项相比,无服务器容器通常为你提供了更大的灵活性,可以将资源分割成更小的单元。例如,一个 EC2 T3 实例提供 2 个 vCPU,但是你能只用 0.25 个 vCPU 请求一个容器。

无服务器函数的优点

无服务器函数拥有无服务器容器的所有优点,但是将其提升到了另外一个级别。

  1. 几乎零管理——在大部分情况下,你不需要考虑操作系统。你只需要推送你的代码,然后运行它们。在操作系统级别没有什么需要修补,也没有什么需要维护——只要推送代码,然后忘了这回事就可以了。
  2. 默认无状态——无服务器函数强制你用一种无状态的方式编写代码,因此你不能依赖于调用之间的任何内容。这使得无服务器函数很容易扩展,因为你的函数可以在任何服务器上激活而不依赖本地状态。
  3. 几乎完美的水平扩展——某些东西调用了你的函数,然后它运行了。调用一次,就运行一次。调用 10000 次,就运行 10000 次。当然,运行中可能会有一些平台限制,但这些通常是为了防止意外花费 10000 美元的保障措施,而不是平台的限制。
  4. 成本——无服务器函数只在执行时花钱。因此,如果你只有一些不常执行的函数,或者偶尔大量执行的函数,你可以节省很多成本。

无服务器容器 vs 无服务器函数

无服务器容器的优势

  1. 容易迁移——如果你有一个现成的应用程序,可能需要一点儿工作,但是你可以让它在容器中运行。
  2. 对于稳定的工作负载来说更便宜——如果你的工作负载稳定,那么无服务器容器会比同等调用量的无服务器函数更便宜。
  3. 灵活性——对于操作系统、二进制文件、语言、版本等没有限制。你完全控制整个容器。无服务器函数服务会限制你使用特定的运行时和版本。一些无服务器函数服务允许自定义运行时,但你还是会被锁定在操作系统中。
  4. 故障排除——容器使得你可以轻松介入并诊断你的线上环境正在发生的故障情况。它们还允许你在本地环境运行部分系统,这使得调试发生了什么更容易。
  5. 长期运行的任务——无服务器容器一直运行,这最适合长期运行的任务。大部分无服务器函数对于一个函数会执行多上时间都会有限制。例如,在本文撰写的当下,AWS Lambda 有一个 15 分钟的限制。

无服务器函数的优势

  1. 对于突增的工作负载的成本更低——无服务器函数是根据调用量付费的,这意味着你只需要在代码实际运行时付费。这意味着,对于那些不经常运行的工作负载,它们会比传统服务器或容器更便宜。
  2. 快速扩展——无服务器函数服务可以在几秒(有时甚至不到一秒)内创建一个你的函数实例并让它响应流量请求。对此会有一些特定的限制,你可以在下面的“扩展无服务器函数”章节看到关于这些限制的更多讨论。
  3. 细粒度的可扩展性——假设你有一个应用程序,它由许多不同的无服务器函数组成,而其中一个函数的调用次数比其他函数的调用次数多了 1000 倍。那么这个调用次数特别大的函数将独立于其它函数进行扩展,你甚至不需要考虑它。

无服务器容器的劣势

  1. 部署方式比较重——无服务器容器通常需要一个大型的构建步骤,然后你需要将一个几百兆字节的容器推到你的仓库。然后你需要在你的集群中部署你的容器,而如果你的部署很大的话可能会需要一点儿时间。
  2. 粗粒度扩展——当你部署一个无服务器函数时,你只是部署了一个单独的函数。那个函数可能会执行多个任务,但是通常你都会部署一个单一目的的函数,这个函数可以独立于其它函数扩展。当你部署一个无服务器容器时,你通常会部署整个应用程序或微服务。那个应用程序或微服务的所有功能都会被部署到一个单独的容器,因此想要扩展它的话就要准备那个容器的更多实例。这意味着整个事情作为一个单独的单元扩展。如果你的应用程序的一部分被大量点击,那么你需要扩展整个应用程序来增加可以响应的流量。

无服务器函数的劣势

  1. 缺乏控制——某个人在管理运行代码的服务器。你的代码运行在一个操作系统中,而你对此没有任何控制。
  2. 专有性——围绕无服务器函数没有任何真正的标准。因此,你通常是使用特定供应商的工具和接口来编写你的无服务器应用程序。使用诸如 AWS step 函数之类的工具会与供应商强关联,因为目前跨无服务器函数的编排还没有一点儿标准。这会使得你深度陷入特定供应商的生态系统,而让切换供应商变得比较困难。
  3. 重写——拿到一个现有的应用程序,让它用无服务器函数来工作通常来说是不可能的。你基本上通常不得不从零开始编写你的应用程序来利用无服务器函数的优势。
  4. 可追溯性——无服务器函数拥有和微服务一样的挑战,但更极端。跟踪贯穿你系统的单个请求会涉及很多无服务器函数。你需要确保你使用了诸如 AWS X-ray、Google Cloud Trace 或者 Distributed Tracing in Azure 之类的工具。
  5. 调试 / 测试——你可以使用 Serverless、Google Function Framework 或者 AWS SAM 等工具在本地机器上轻松运行一个云函数,但得到实际的调用会比较困难,因为云函数通常和云生态系统以自动化的专有的方式集成在一起。另外,诸如 AWS step 函数之类的服务在不同 lambda 之间引入了编排层,会使得调试线上环境正在发生什么更加困难。
  6. 部署——无服务器函数的部署会是一个挑战,但大部分是因为他们提供的工具(例如一个 集成开发环境)鼓励不良行为。使用 无服务器框架 会使得你的部署更自动化和可管理,但是你需要努力去设置并管理它,不然版本控制和维护成百上千个函数将会非常痛苦。

扩展无服务器函数

扩展无服务器函数需要一点儿额外的注意,因为人们通常认为像 AWS Lambda 或 GCP 云函数之类的工具是针对扩展能力的万能之计。它们假定你只需要推送你的云函数,几乎马上就会获得可扩展性。但这与事实相差太远。这些无服务器函数服务使得扩展变得异常简单,但是平台的局限性会影响函数扩展的速度和高度。

例如,AWS Lambda 有个初始的每个区域 1000 函数并发调用量的限制(这是指这个区域的所有函数)。这个限制是作为一个安全措施来防止意外的资源使用,而且可以通过联系 AWS 客户支持来增加。

基于此,你可能认为你能够呼叫 AWS 客户支持并请求将并发调用量增加到 20000,然后你就可以推大量请求到你的 Lambda 函数并使它快速扩展到对应的级别来应对你的服务需求。不幸的是,事实并非如此。

即使你让 AWS 客户支持将你的限制增加到 20000 并发调用量,AWS Lambda 仍然会限制你每分钟只能增加 500 并发调用量,这意味着如果你是从 0 开始的话需要 40 分钟才能增加到 20000 并发调用量。同时,所有访问你的服务但不能被路由到激活的函数的请求都会收到 429 错误。

如果你知道你的流量会比当前突增,你可以购买 Amazon 的“预配置并发”功能。该功能将保持特定数目的 Lambda 函数待命,但是你将放弃无服务器函数的一些优势,因为你需要支付来保持这些函数一直运行。但是,在某些场景中,这种权衡是值得的。

还有一个担忧是,单独某个函数会占用特定区域的所有可用的并发量。你可以为特定的函数配置“保留并发”,来保证它们的并发量不会被其它函数完全消耗。但是假如你总共有 5000 并发量并将某个函数的保留并发量设为 1000,那么你在那个区域的所有其它函数就只剩下 4000 并发量。

虽然这些设置中的许多设置都是提供一个安全又可用的环境所必需的,但它能够为刚开始使用无服务器函数的新手带来许多惊喜。

供应商锁定

几乎所有的云平台都会抓住每一个机会来让你锁定,Serverless 也不例外。然而与无服务器容器相比,无服务器函数更关心供应商锁定问题。调用、部署、编排和分配函数的方式都取决于你所使用的云供应商。

像 Knative 这样的项目正在努力创建一个企业可以用来部署无服务器工作负载的标准环境,但是,一般来说,你必须部署和管理平台本身才能获得好处。这会抵消用无服务器方式运行代码的许多优点。目标是避免运行基础设施,对吗?我要提到的是,你可以通过 Google Cloud Run 获得对 Knative 的本地支持,并且通过一些努力,可以在 AWS Fargate 上运行 Knative。

对无服务器函数有什么反对意见?

可能听起来我们不喜欢无服务器函数,但事实并非如此。我们只是认为它们的用途比无服务器容器更有限。在某些特定场景下,无服务器函数是完美的解决方案。令人惊讶的是,通常你需要与底层云平台强集成。假设你想要上传一张图片到 S3,并让它自动触发一个云函数以某种方式处理这张图片;或者你有一些 Cloudwatch 这样的日志服务生产的日志,并且想要有一段代码来轻松地分析日志流。这时,无服务器函数才真正展现出它们的价值。当你有一些需要扩展的应用程序的热点端点,而你想要用与其它端点不同的扩展方式扩展它们时,无服务器函数也非常适合。

正如所知,在大多数情况下,我们仍然推荐无服务器容器。但是你不会看到我们为此欣喜若狂,因为无服务器容器并不能提供无服务器计算的圣杯。无服务器计算的圣杯是什么?我很高兴你问到这一点。

无服务器计算的圣杯

无服务器计算的圣杯是效用计算。当我需要的时候,让我所有的资源都按我需要的样子可用。能够上传一段代码(无论是单个函数还是整个应用程序)以及一点儿元数据,并允许其无限扩展(附带一些安全限制)。为了不必考虑它需要多少内存、存储或计算资源,它只需要自动计算出来。无服务器函数实际上比无服务器容器更接近于此,但是由于上面提到的原因,它们仍然没有达到目标。

Serverless 都长大了

请不要把这篇文章解释为我不认为无服务器函数或容器已经准备好在现实世界采用。对于大多数组织来说,运行服务器应该和产生他们自己的能力一样重要(一些大型组织需要同时做到这两个!)。使用无服务器计算,你的代码仍然运行在某个地方的一台服务器上,只是你不需要再关心这台服务器。对于大部分组织来说,这确实是一个长期的目标,使得能够将一段代码推送到某个服务中并让它运行。无服务器计算并不能实现“上传代码,然后忘掉它”的梦想,但是我们已经接近了。

无服务器计算在这里,并将继续存在。我们将看到无服务器服务越来越接近这里描述的理想化的情景。但是,虽然 Serverless 已经成熟了,但我们还有一段路要走。为了真正实现无服务器计算的理想,我们需要审慎地重新思考当前的计算和安全模型。虽然挑战是巨大的,但回报更大,因此我们可能比我们想象的更快实现这个理想。

作者简介

Justin Etheredge 一位专注于云计算、Serverless 的博主。

参考阅读

Serverless: I’m a big kid now(https://www.simplethread.com/serverless-im-a-big-kid-now/)


0 人点赞