发布于 2026-01-06 1 阅读
0

使用 Python 和 AWS Lambda 创建无服务器函数

使用 Python 和 AWS Lambda 创建无服务器函数

入门指南

正如大多数对这个主题有所了解的人都知道的那样,“无服务器函数”这个名称其实并不准确。服务器仍然参与整个过程,只不过,正如Web开发领域长期以来的趋势一样,开发者对服务器的控制权越来越少。

虽然这听起来很糟糕,但对于只想把酷炫的产品推向酷炫用户(任何使用你产品的人都很酷,这是商业的第一法则😁)的开发者来说,部署和运维生产环境应用的大部分工作都是繁琐且永无止境的。云托管和托管软件的发展历程表明,放弃对这些环节的控制权通常会降低许多开发者的入门门槛。“无服务器”函数,或者更准确地说是“函数即服务”,正是这一趋势的必然发展;我们领域的许多 杰出 人士对此都感到非常兴奋。

主要好处在于,当以服务形式运行这些函数时,云托管的“按需付费”理念实际上得到了扩展,因为你无需在项目中添加任何额外开销。你无需运行虚拟服务器(该服务器在空闲时会占用资源,并按分钟计费)。你运行的函数仅在被触发时才使用资源,这意味着你只需在用户实际使用你的代码时付费。是不是很棒?

虽然我个人对将越来越多的生产资料(明白我的意思吗?😁)拱手让给那些号称仁慈的企业巨头感到不安,但我还是觉得,为了自己的技术发展,我应该尝试一下无服务器函数,尤其是有那么多文章都在盛赞这些工具的巨大成本节约优势。所以我试了。

基本设置

如果您之前已经创建过 Serverless 函数,则可以跳到第 3 部分。

1. 安装

首先,你需要安装Serverless框架。虽然不用这个框架也能编写无服务器函数,但据我所知,Serverless 框架能让整个过程变得简单得多。你可以使用以下命令安装它:

npm install -g serverless
Enter fullscreen mode Exit fullscreen mode

请注意,无论您使用哪种语言编写函数,Serverless都是一个 node 模块,必须使用npm.

2. 设置管理员服务帐户

接下来,您需要设置一个可以附加代码的服务。对于Serverless支持的任何提供商,设置过程都应该类似,目前支持的提供商包括:

本文仅介绍如何在 AWS 中实现。如果您使用的是其他服务,我建议您查阅Serverless 的文档;它非常出色

首先,前往 AWS 并导航至 IAM 服务。

IAMLoad

接下来,导航至“添加用户”Users并点击。进入后,为您的服务账户添加一个描述性名称。由于这是一个管理账户,供您的Serverless CLI(为避免混淆,下文简称SLS)安装使用,用于更改您的 AWS 账户,因此您可以为其指定一个通用名称,并在您编写的所有服务中使用同一个服务账户。您也可以使用单独的账户,我最初设置时,因为不太了解相关知识,所以给它取了一个项目特定的名称。使用项目特定的账户有助于确保您创建的所有内容保持清晰和独立,但这并非绝对必要。

请务必勾选“程序化访问”复选框,以便 CLI 自动将更改应用到您的帐户。

添加用户

在下一页中,授予您的服务帐户AdministratorAccess权限。

管理员访问权限

准备就绪后,点击“创建用户” ,然后复制您的访问密钥 ID私钥(或将其下载为 CSV 文件)。如果您已经操作到这里,我假设您知道这些密钥非常重要,应该妥善保管。

CopyKeys

你快完成了!你是不是很喜欢这种没完没了的配置过程,明明只是想把什么东西组装起来?

TYBG

现在您只需运行以下命令,即可授予SLS访问您凭据的权限:

serverless config credentials --provider aws --key <ACCESS KEY ID> --secret <SECRET KEY>
Enter fullscreen mode Exit fullscreen mode

好了,现在你可以开始创建项目了。嘿,谁也没说过这不会有点繁琐。不过你应该庆幸SLS会帮你处理很多事情。

3. 创建您的服务项目

现在您已准备好创建项目,请导航至要创建服务的文件夹并执行以下操作:

serverless create --template aws-python3 --path <PATH>
Enter fullscreen mode Exit fullscreen mode

现在你应该看到一个文件夹,里面装满了 Serverless 相关的东西。在这个文件夹里,你应该能看到一个名为 ` .config` 的serverless.yml文件。这是你新项目的主要配置文件。打开它,你应该会看到类似这样的内容(以及我删除的一些注释):

service: my-service

provider:
  name: aws
  runtime: python3.6
package:
  exclude:
    - secrets.yaml

functions:
  hello:
    handler: handler.hello
Enter fullscreen mode Exit fullscreen mode

你还应该有一个handler.py包含hello()函数的文件。如果你看一下上面的内容,你会发现它已经在服务中注册了(就在最底部),名称是 `<service_name>` hello。这意味着你可以将服务的各个部分拆分到不同的文件中,同时handler.py仍然直接将它们注册到你的服务中。真是太方便了!

我讨厌有些作者在攻略里故意让你尝试一些行不通的方法,只是为了证明自己的观点,我觉得这很烦人,所以我就直接告诉你吧:

虽然您已经定义了一个名为 `function` 的函数,hello并且它链接到了一个函数处理程序,但您目前没有办法触发该函数。这就是为什么我们需要event在 `function` 中定义的函数中添加一个 `get_function` 语句serverless.yml。请按如下方式更新它:

functions:
  hello:
    handler: handler.hello
    events:
      - http:
          path: hello
          method: get
Enter fullscreen mode Exit fullscreen mode

events集合包含各种类型的触发器,可用于触发您的函数。这些触发器包括定时任务、Alexa 技能、物联网触发器等等。现在,您将使用一个简单的 HTTP 触发器,当您向端点发送GET请求时,它将做出响应/hello

从这里开始,你可以像处理普通的 Python 项目一样处理它,只有一个例外,我会在最后提到。要安装依赖项,只需env像往常一样创建目录,或者使用 Pipenv。你可能希望serverless-python-requirements这个仓库在你的服务目录中安装依赖项,这将自动将你的依赖项打包,并通过requirements.txt.PipfilePYTHONPATH

关于 PipEnv 的说明
PipEnv 是一个相对较新的工具,用于替代全局安装模块或之前的默认方案——虚拟环境。它由 Kenneth Reitz 编写并推荐,Kenneth Reitz 也是requests《Python 编程指南》等热门工具的作者。PipEnv 极大地简化了我的开发流程,然而,在使用 PipEnv 时,我遇到了一些模块问题google-client-api,不得不重新设计我的项目venv。如果您依赖此模块并且正在编写无服务器函数,我建议您不要使用 PipEnv。

4. 部署和测试

最后,您需要部署您的函数:

serverless deploy
Enter fullscreen mode Exit fullscreen mode

获取输出中列出的端点,其格式应类似于:

GET - https://xxxxxxxxxx.execute-api.us-east-1.amazonaws.com/dev/hello
Enter fullscreen mode Exit fullscreen mode

如果您需要在不执行部署的情况下获取有关服务的信息,只需运行命令sls info即可注销端点、函数等。

如果您在浏览器中访问该网址,应该会收到以下响应:

Go Serverless!

您还可以通过以下命令调用您的服务:

sls invoke -f hello
Enter fullscreen mode Exit fullscreen mode

如果由于某种原因您没有收到该响应,您可以运行:

sls logs -f <function_name> —tail
Enter fullscreen mode Exit fullscreen mode

查看服务器上特定函数的连续日志。

耶!我们完成了!对吧?嗯……算是吧……

不太像

问题在于,部署到你的服务需要相当长的时间,而且这样的测试过程会变得非常繁琐。此外,如果你有生产服务,那么部署到测试环境……是不可取的。

那么,我们该如何测试我们新开发的函数呢?

有几种不同的方法,包括一些高级库,但就目前而言,我发现只需添加local关键字(如下所示)即可完美解决问题:

sls invoke local --function <FUNCTION> --log
Enter fullscreen mode Exit fullscreen mode

您无需访问远程函数实例,而是访问托管在您自己的机器上的函数实例,这意味着您可以保存文件并进行测试,而无需重新部署。

好了,这些是基础知识,但总有更多东西需要学习。

5. 后续步骤

我在使用无服务器函数时遇到的第一个问题是,对于如何管理密钥值缺乏清晰的说明。我发现这篇指南非常实用且易于理解,建议你也看看。

如果你对无服务器解决方案的理念和架构更感兴趣,我推荐你阅读这篇文章,并建议你了解一下 FaaS 方法和传统 Web 后端在架构方面的差异。

我的用例

那么,我究竟想用这一切建造什么呢?

过去十个月或十一个月里,我一直坚持更频繁地去健身房,幸运的是,我做到了。我每周去健身房三天,从一月到八月底,最多也就错过一天。九月份和几个好朋友进行了一次精彩的旅行,让我有点疲惫,所以休息了两周。有一件事我始终坚持,那就是每次在健身房锻炼后,我都会用谷歌表格记录我做了多少组、多少次,有时还会记录一下我的感受。这一切或许看起来有点多余或毫无意义,但我发现,追踪和回顾这些数据确实能帮助我保持动力,取得进步。

现在我已经有了所有这些数据,我想处理它们(目前有46个电子表格),并以交互式图表的形式在我的网站上展示。既然有了数据,为什么不利用它们呢?

为了实现这个目标,我编写了一个函数,它可以从我的工作表中获取数据,将每个工作表转换为一个对象,然后将该对象提供给一个静态前端,前端再将这些数据导入到 D3 图表中。目前它还在开发中,但我希望很快就能发布。

无服务器函数确实让我的路由配置运行速度比搭建服务器快得多。

局限性

我欢迎对以下任何陈述(以及之前的任何陈述)进行纠正。

无服务器功能看起来很棒,因为从理念上看,它们似乎是云托管理念的最终演进。然而,它们也存在一些缺点。

如果你是自托管,这种架构似乎并非明智之选,因为底层服务器依然存在,处于空闲状态,并且可能为了协调每次函数调用的启动和关闭而消耗更多资源。只有当亚马逊或谷歌承担费用时,这种模式才有意义。此外,如果你有长时间运行的进程或后台任务(不包括可设置为函数触发器的定时任务),这种架构可能并非最佳选择。持久层也带来了挑战,因为它们必须托管在外部服务器上,或者使用 DynamoDB、GCD 等数据存储服务。最后,对于那些将空闲时间视为总体成本中占比极小的项目而言,这种架构带来的收益可能有限。这意味着,如果你的服务经常受到访问且访问量较大,那么 FaaS 可能是一个值得等待的趋势。

结论

无服务器函数似乎能为我提供相当长一段时间的深入学习机会,因为它们既消除了传统开发流程带来的现有问题,也给习惯于搭建服务器的开发者带来了新的挑战。下次当你进行原型设计或创建访问量较低的路由时,我强烈建议你首先了解一下无服务器架构。

致谢
本文中的大部分知识都来自这篇入门指南,我根据我的 Python 用例对其进行了调整,以及优秀的文档
特别感谢我的好朋友Malik Browne的剪辑!
文章来源:https://dev.to/dangolant/creating-serverless-functions-with-python-and-aws-lambda-dli