无服务器:我现在是大孩子了

2020-08-13 23:20:24

软件工程行业每年都会涌现出几十种新工具和新趋势。现在我已经有一段时间了,我想我开始开发一种像样的雷达,哪些趋势将产生持久的影响,哪些趋势将会失败。可以肯定的是,我做过一些令人尴尬的预测,比如跟我的一个朋友打赌,Git会输给Mercurial,因为Git的用户人体工程学太可怕了。我们都知道结果如何。

但总体而言,我认为我非常清楚哪些技术将成为赢家,哪些技术将成为输家。当谈到无服务器计算时,我不需要使用任何这些专业知识。

是啊,你没看错。不需要预言家就能看出无服务器计算是未来。没有人想要管理服务器。管理服务器是想要执行代码的一个令人讨厌的副作用。我需要一个安全的环境来运行代码,并且由于von Neumann架构,我需要一些内存、一些磁盘空间和一个处理器。这些东西是什么形式并不重要,只要我有足够的就行了。我的代码需要这三个部分,并且我需要一个为我提供它的环境。很简单。

我实现这一目标的愿望并不意味着我想要管理服务器或它运行的环境。在理想的情况下,我会直接去找云提供商说,“这是我的应用程序,帮我运行它。”

在我们开始之前,让我们就无服务器到底是什么达成共识。您将看到一些关于无服务器的定义,这些定义说它按需提供计算资源。虽然这是一个纯粹的定义,但更常用的更广泛的定义是,它是一种以一种不需要您考虑管理服务器的方式提供计算资源的方式。

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

AWS Lambda、Google Cloud Functions或Azure Functions等无服务器功能是提供环境的服务,您可以在其中使用特定接口推送代码块,然后调用该代码。

许多人并不认为无服务器容器是真正的无服务器容器,因为当您构建和推送容器时,您实质上是将整个服务器捆绑在一个漂亮的包中。虽然我倾向于同意它们不是“真正的”无服务器,但它们绝对比运行完整的虚拟机有巨大的好处,并且在某些情况下比无服务器功能有明显的优势。

与传统服务器相比,无服务器容器有很多优势。以下是其中的几个:

服务器管理成本极低-无需管理、修补或故障排除服务器。您仍然在容器中安装了操作系统,但这可能是一个难以置信的最小安装,并且管理的应用表面积要小得多。

通常是无状态的-当构建为容器设计的应用程序时,您通常是在构建一个12个因素的应用程序,或者遵循类似的模式。你的集装箱是牛,不是宠物。如果您的容器崩溃,则会自动启动一个新的容器。

轻松的水平可伸缩性-虚拟机没有任何可伸缩性方面的固有限制,但容器会将您推向允许无服务器容器服务根据需要轻松扩展软件的方向。根据负载、计时和请求计数等因素,您的无服务器容器服务可以运行容器的一个实例或所有实例的10,000个实例,同时透明地处理存储分配、负载平衡、路由等。

安全性-安装在容器中的操作系统通常是短暂的、非常小的,有时是只读的。因此,它提供的受攻击面比典型的通用且寿命长的服务器环境小得多。

源代码控制环境-您的容器定义在一个可以放入源代码管理的文件中进行描述。虽然这是目前几乎任何情况下的最佳实践,但与传统的服务器环境相比,这仍然是一个明显的优势。在传统的服务器环境中,有人可以进入并更改使您的服务器配置漂移的东西。

应用程序和环境捆绑-您将应用程序与其运行环境相结合,并将其部署为单个单元。这样,如果您的软件的新版本使用更新库、操作系统版本或新语言版本,则可以将其作为一个单元进行部署和回滚。

成本低廉-您可以轻松地上下扩展工作负载。虽然运行无服务器容器可能有点贵,但是使用某些提供程序,您可以灵活地弥补这一点。与传统的虚拟机选项相比,无服务器容器通常为您提供了更大的灵活性,可以将资源分割成更小的单元。例如,EC2T3 Nano实例提供2个vCPU,但是您可以请求一个只有0.25个vCPU的容器。

无服务器函数具有无服务器容器的所有优点,但将其提升到了另一个层次。

几乎为零管理-在大多数情况下,您根本不需要考虑操作系统。您可以将代码向上推,然后运行它。在操作系统级别没有什么需要修补的,也没有什么需要维护的--只需推动它,然后忘掉它。

缺省情况下是无状态的,因为您不能依赖在两次调用之间留下的任何东西,所以无服务器函数迫使您以无状态的方式编写代码。这使得它们可以很容易地进行扩展,因为您的函数可以在任何服务器上启动,而不依赖于本地状态。

近乎完美的水平可伸缩性--如果某个东西调用了您的函数,它就会运行。如果它被调用一次,那么它就运行一次。如果它被调用100,000次,那么它就会运行100,000次。当然,有一些平台限制可能会起作用,但这些通常是防止您意外花费10,000美元的保障措施,而不是平台的限制。

成本成本-无服务器函数在执行时只需要成本。因此,如果您的函数只有很少执行,或者非常突发性,您可以节省大量成本。

轻松迁移-如果您有一个现有的应用程序,可能需要一些工作,但您可以让它在容器内运行。

对于稳定的工作负载来说更便宜-如果您有一致的工作负载,那么无服务器容器很可能比等效的无服务器函数调用更便宜。

灵活性-您的操作系统、二进制文件、语言、版本等没有任何限制,您可以直接控制整个容器。无服务器功能服务会将您限制到特定的运行时和版本。一些无服务器功能服务允许自定义运行时,但您仍将被锁定在操作系统中。

故障排除-容器使您可以轻松地参与并解决您的生活环境中正在发生的问题。它们还允许您在本地运行环境的一部分,这使得调试正在发生的事情变得更容易。

长时间运行的任务--无服务器容器一直在运行,最适合长时间运行的任务。大多数无服务器函数对于函数可以执行的时间都有限制。例如,在撰写本文时,AWS Lambda有15分钟的限制。

突发性工作负载的较低成本-无服务器函数是按调用付费的,这意味着您只在代码实际执行时付费。这意味着对于不经常运行的工作负载,它们可能比典型的服务器或容器便宜得多。

快速扩展-无服务器函数服务可以创建函数的新实例,并在几秒钟内准备好为流量提供服务(有时只需几分之一秒)。这有一定的限制,您可以在下面的“扩展无服务器功能”一节中看到关于这些限制的更多讨论。

细粒度可伸缩性-假设您有一个由几十个不同的无服务器函数组成的应用程序,其中一个函数的调用次数是其他函数的1000倍。这一个函数将独立于您的其他函数进行缩放,您甚至不必考虑它。。

更繁重的部署--无服务器容器通常需要一个很大的构建步骤,然后您必须将一个几百兆字节的容器推送到您的存储库。然后,您必须跨集群部署您的容器,如果您有大型部署,这可能需要一段时间。这种周转时间明显长于推送单个云函数,并在几秒内将其接收并开始服务请求。

粗略可伸缩性-当您部署无服务器功能时,您实际上只是部署了单个功能。该函数可以执行多个任务,但通常您部署的是一个单一用途的函数,该函数可以独立于所有其他函数进行扩展。当您部署无服务器容器时,通常是在部署整个应用程序或微服务。该应用程序或微服务中的所有功能都将部署到单个容器中,因此为了对其进行扩展,您必须启动该容器的更多实例。这意味着整个事情可以作为一个单一的单元来衡量。如果您的应用程序中有一块被大量访问,您将不得不扩展整个应用程序以增加您可以服务的通信量。

缺乏控制-有人正在管理您的代码在其上运行的服务器。您的代码运行在操作系统中,只是不是您可以控制的系统。

即使在获得AWS支持将您的并发调用限制提高到20,000次之后,AWS Lambda仍会将您的并发调用限制为每分钟500次,这意味着如果您从零流量开始,将需要近40分钟才能将并发调用扩展到20,000次。同时,所有命中您的服务的、无法路由到活动函数的请求都将收到429个错误。

如果您知道您的流量需要突发更多,您可以购买亚马逊所称的“预配置并发”。这将使一定数量的Lambda函数保持温暖并随时可用,但随后您将放弃无服务器函数的一些好处,因为您要花钱让它们始终运行。但是,在某些情况下,这是值得权衡的。

还有一个问题是,单个函数会耗尽特定区域的所有可用并发性。您可以为特定函数配置“保留并发”,以确保它们的并发性不会完全被其他函数消耗。但是,假设您的并发总量为5000,并且您将一个函数的保留并发设置为1000,那么该区域中的其余函数将只剩下4000个并发。

虽然这些设置中的许多设置对于提供既安全又可用的环境是必要的,但对于刚开始使用无服务器功能的人来说,它可能会带来很多惊喜。

几乎所有的云平台都会抓住一切机会锁定你,Serverless也不例外。然而,与无服务器容器相比,供应商锁定对无服务器功能的影响更大。调用、部署、编排和分配函数的方式都取决于您使用的云提供商。

像Kative这样的项目在创建公司可以用来部署无服务器工作负载的标准环境方面正在取得进展,但通常情况下,你必须部署和管理平台本身才能获得好处。这可以消除以无服务器方式运行代码的许多好处。我们的目标是避免运行基础设施,对吗?值得一提的是,您可以通过Google Cloud Run获得对Kative的本地支持,并且只需付出一些努力,您就可以在AWS Fargate上运行Kative。

听起来我们可能不喜欢无服务器功能,但事实并非如此。我们只是认为它们的用途比无服务器容器更有限。在某些情况下,无服务器功能是完美的解决方案。令人惊讶的是,这通常是在您需要与底层云平台进行强集成的时候。假设您想要将图像上传到S3,并让它自动触发云函数,以某种方式对其进行处理;或者,您有来自Cloudwatch等日志记录服务的日志,并且您希望有一段代码来轻松分析日志流。这才是无服务器功能真正显示其价值的时候。如果您有几个热点端点,希望以不同于应用程序其余部分的方式进行扩展,则它们也可以很好地工作。

正如您所看到的,在大多数情况下,我们仍然推荐无服务器容器。但是你不会看到我们欢呼雀跃,因为无服务器容器并没有提供无服务器计算的真正圣杯。无服务器计算的圣杯是什么?我很高兴你这么问。

无服务器计算的圣杯是真正的效用计算。让我所有的资源在我需要的时候随时可用。能够上传代码块(无论是单个函数还是整个应用程序)和一些元数据,并以允许其无限扩展(具有一些安全限制)的方式运行。它根本不必考虑它需要多少内存、存储或计算,只需自动计算出来即可。无服务器函数实际上比无服务器容器更接近这一点,但是由于上面提到的原因,它们仍然没有达到目标。

请不要将这篇文章解读为我认为无服务器函数或容器还没有准备好在现实世界中采用。对于大多数组织来说,运行服务器对他们来说应该与生成自己的电力一样重要(而一些大型组织需要两者都做!)。使用无服务器计算,您的代码仍然在某个服务器上运行,只不过不是您必须关心的服务器。这真的应该是大多数组织的长期目标,能够只将一大块代码推入服务并让其运行。无服务器计算并不完全能够实现“将代码推上来,然后忘掉它”的梦想,但我们正在接近这一目标。

无服务器计算已经存在,而且还将继续存在。我们将继续看到无服务器服务越来越接近这里描述的理想。但是,虽然Serverless肯定已经长大了,但我们还有很长的路要走。为了真正实现无服务器计算的理想,我们需要对当前的计算和安全模型进行重大反思。虽然挑战是巨大的,但回报甚至更大,所以我们可能会比我们想象的更快地到达那里。