你喜欢思考服务器的问题吗?
大多数开发者不喜欢。这就是为什么AWS Lambda等无服务器平台变得如此流行的原因,它让你在云中运行功能而无需考虑服务器。
在本教程中,我们将介绍如何创建和部署一个使用Python的AWS Lambda函数,并连接到CockroachDB无服务器数据库。本教程并不假定你有任何关于CockroachDB Serverless或AWS Lambda的经验,但需要对Python和使用命令行有一定的了解。(如果你有Lambda和/或CockroachDB Serverless的经验,我们的文档中也有本教程的快速版本,以及使用Node.js而非Python的相同版本)。
在开始之前,我们先来看看我们将在AWS Lambda上设置的函数,以了解我们要做什么。
了解我们的Python AWS Lambda函数
为了本教程的目的,我们已经写好了Python函数,可以在Github上访问。它包含几个不同的文件。init_db.py 是在AWS Lambda上实际运行的Python代码,其他文件是支持性文件,如requirements.txt ,这将确保Lambda安装正确的psycopg2驱动版本,我们的函数需要运行。
如果我们看一下代码,我们会发现init_db.py 中有两个函数:create_accounts() 和lambda_handler() 。
第一个,create_accounts() ,连接到CockroachDB无服务器数据库,创建一个有两列的accounts 表,id 和balance 。然后通过为每一行的id 值生成UUID,为balance 值生成一个随机的六位数的整数来创建n 账户。注意,它需要两个参数,p 和n 。p 是连接池和数据库连接,n 是函数将生成的账户数量。
(不用说,没有一个真正的银行应用会随机添加账户并生成余额,但本教程的目的只是为了演示我们如何在AWS Lambda上建立并运行一个与CockroachDB连接的函数)。如果我们想让我们的Lambda函数做一些不同的事情,create_accounts() 是我们要改变或替换的主要函数)。
init_db.py 中的第二个函数,lambda_handler() ,创建一个连接池,帮助Lambda与CockroachDB无服务器数据库连接。它也调用了 create_accounts() ,并提供了两个参数(连接池和5 ,要创建的账户数量),所以如果我们想改变create_accounts() 的功能,就必须确保也要改变lambda_handler() 的这一部分。
现在我们了解了我们的Lambda函数将做什么,让我们开始在AWS Lambda上创建和部署它的过程。
第1步:创建一个AWS账户
第一步是创建一个AWS账户,如果你还没有一个。访问AWS主页面,点击橙色的 "创建AWS账户 "按钮,然后按步骤操作。
请注意,注册AWS将需要信用卡或借记卡。这并不意味着你实际上需要支付任何费用--许多AWS服务有一个免费层,而我们在本教程中所做的事情不需要太多的存储或使用大量的计算,所以它将是免费的。然而,如果你担心潜在的成本,AWS确实允许你在创建账户后设置预算限制。
一旦我们建立了AWS账户,让我们登录并记下亚马逊账户ID,因为我们以后会需要它。这可以通过在AWS控制台的任何页面上点击顶部菜单栏右侧的账户用户名找到。

第2步:创建一个AWS IAM用户
一旦我们创建了一个AWS账户,我们就需要在其中创建一个IAM用户。与我们在第一步创建的账户相关的用户被称为AWS账户根用户,但现在我们需要在AWS的IAM系统中创建一个具有管理员级别权限的普通用户账户。
有几种不同的方法来创建IAM用户,但要通过AWS控制台来做,我们需要导航到IAM仪表板,从左边的菜单中选择 "用户",然后点击 "添加用户"。
从那里,使用你选择的任何用户名创建一个用户,选择 "访问密钥 - 程序化访问 "凭证类型,并附加 "AdministratorAccess "AWS策略。
请确保保存创建用户时提供的访问密钥ID和秘密访问密钥!以后我们在配置AWS CLI时将需要这些来进行认证。
第3步:安装AWS CLI
下一步是下载AWS CLI,以便我们可以使用命令行与AWS合作。要做到这一点,请访问AWS CLI页面,并为您的操作系统下载相关版本。
(技术上来说,创建Lambda函数不需要这一步,因为AWS控制台允许你使用Web UI创建函数。然而,我们将在本教程中使用命令行)。
第四步:创建一个CockroachDB无服务器集群
现在是时候创建一个CockroachDB云账户了(如果你还没有的话),并启动一个新的无服务器集群。我们将在下面提供书面说明,但这里有一段视频,介绍了CockroachDB无服务器的设置过程(为了本教程的目的,在3分钟处停止)。
要创建一个账户,请先注册(不需要信用卡)。一旦我们注册成功,我们就可以登录并选择集群页面上的 "创建集群 "按钮。
在下一个屏幕上,我们将选择 "无服务器 "并选择我们的选项。
- 云提供商。尽管我们要创建一个AWS Lambda函数,但你的CockroachDB无服务器集群并不需要在AWS上,不过如果将CockroachDB和AWS Lambda函数放在同一个AWS区域,你可能会看到最好的性能结果。
- 区域。任何选项都可以,但为了获得最佳性能,我们希望确保你在这里选择的任何选项在地理上接近你的AWS区域。
- 支出限额:保持默认设置为0美元。
- 集群名称:保持默认设置,如果你愿意,也可以调整。
一旦我们做出选择,我们将点击 "创建集群 "按钮。一个新的CockroachDB无服务器集群将在几秒钟内启动,一个名为 "连接信息 "的窗口将打开。
点击 "连接字符串 "标签,将连接字符串复制到安全的地方,因为我们以后会用到它。它将看起来像这样,除了,, 等将被替换成你的集群的特定信息。
postgresql://:@free-tier14..cockroachlabs.cloud:26257/defaultdb?sslmode=verify-full&options=--cluster%3D
一旦我们保存了我们的连接字符串,我们就可以关闭 "连接信息 "窗口。
第5步:克隆Python函数
接下来,打开命令行,克隆我们的样本Python代码的Github repo。
git clone https://github.com/cockroachlabs/examples-aws-lambda
这将在工作目录中创建一个名为examples-aws-lambda 的文件夹,其中包括我们的 Python 和 Node.js 示例的代码。
导航到Python子目录。
cd examples-aws-lambda/python
第6步:创建部署包
从技术上讲,这是一个可选的步骤--如果我们运行ls ,我们将看到这个文件夹已经包含了一个部署包(deployment-package.zip )。然而,让我们通过使用我们的代码创建一个新的部署包的步骤。
首先,我们需要下载并安装psycopg2-binary 。请注意,我们安装的是为Linux编译的版本(这是AWS要求的),并且我们要为文件创建一个名为my-package 的新目录。
python3 -m pip install --only-binary :all: --platform manylinux1_x86_64 --target ./my-package -r requirements.txt
接下来,我们需要将所有的项目文件压缩成一个压缩文件。我们将首先把我们刚刚下载的文件压缩到my-package 。我们将导航到该目录。
cd my-package
然后,我们将使用zip ,将这些文件压缩成一个叫做my-deployment-package.zip 的文件,我们将把这个文件存放在我们刚来的python 目录中。注意这里的命令末尾的. ,它告诉zip压缩工作目录中的所有文件(my-package)。
zip -r ../my-deployment-package.zip .
现在,我们返回到python 目录...
cd ..
...并使用zip's-g (grow)选项,将init_db.py 和root.crt 添加到我们刚刚创建的my-deployment-package.zip 文件。
zip -g my-deployment-package.zip init_db.py root.crt
我们的部署包现在已经准备好了,所以下一步是配置AWS。
第7步:配置AWS
运行以下命令,然后按照提示配置AWS。
aws configure
我们将以我们在步骤2中创建的用户身份进行认证,而不是根用户。我们将被提示提供四个输入。
- 访问密钥ID:插入步骤2中生成的访问密钥ID。
- 秘密访问密钥。插入在第2步中生成的秘密访问密钥。
- 默认区域名称:输入你喜欢的AWS区域,如
us-east-1。(理想情况下,这与你的CockroachDB部署是同一个区域)。 - 默认的输出格式。默认情况下,输出格式为
json,所以如果我们留空,我们会得到JSON格式的输出。其他可用的输出格式在AWS文档中列出,但对于我们的目的来说,JSON就可以了。
接下来,我们需要为我们的Lambda函数创建一个执行角色。这将授予该函数访问AWS资源的权限。
aws iam create-role --role-name lambda-ex --assume-role-policy-document '{"Version": "2012-10-17","Statement": [{ "Effect": "Allow", "Principal": {"Service": "lambda.amazonaws.com"}, "Action": "sts:AssumeRole"}]}'
我们还需要将AWSLambdaBasicExecutionRole 策略附加到该角色。这允许Lambda函数访问它所需要的AWS服务的基本套件。(如果我们的函数依赖于其他AWS资源,如DynamoDB数据库,我们可以附加其他策略,但在这种情况下,我们只需要 "基本 "级别的权限)。
aws iam attach-role-policy --role-name lambda-ex --policy-arn arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
现在,所要做的就是部署我们的函数并进行测试!
第8步:将函数部署到AWS Lambda上
为了将函数部署到lambda,我们将导航到部署包目录并使用create-function 命令进行部署。
aws lambda create-function \
--function-name init-crdb \
--region \
--zip-file fileb://deployment-package.zip \
--handler init_db.lambda_handler \
--runtime python3.9 \
--role arn:aws:iam:::role/lambda-ex \
--environment "Variables={DATABASE_URL=,PGSSLROOTCERT=./root.crt}"
请注意,上述命令中的三个元素必须用你的具体信息替换。
- 必须用你的AWS区域来代替,即 。
us-east-1 - 必须用你的AWS账户ID(就是我们在第1步中保存的那个;在任何AWS控制台页面点击顶部导航栏右侧的账户名称即可找到)。
- 必须用你在第4步中保存的CockroachDB连接字符串代替。
另外,请注意,虽然其他的东西都可以直接输入,但--environment 这个变量必须是一个字符串字面。
当我们运行最后一条命令时,AWS将创建一个新的Lambda函数,名称为init-crdb 。如果我们打开浏览器,查看AWS Lambda控制台,我们可以点击 "Lambda function(s) "下的数字,然后点击下一页的 "init-crdb",可以看到我们所有的代码已经上传到Lambda。
如果我们点击 "配置 "选项卡,查看左侧导航栏中的 "环境变量",我们也可以看到我们的两个环境变量,DATABASE_URL 和PGSSLROOTCERT ,都正确地存储在那里。

第9步:调用函数
现在我们已经把一切都设置好了,让我们来调用这个函数,以确保一切都按预期工作。从我们对函数代码的审查中,我们知道,如果它工作正常,调用我们的函数将在我们的数据库中添加五个带有UUID和随机账户值的账户。
我们可以像这样调用该函数并记录结果。
aws lambda invoke --function-name init-crdb out --log-type Tail \
--query 'LogResult' --output text | base64 -d
运行该代码应该会产生与此类似的输出。
START RequestId: b8126db0-ffeb-4f62-8ac9-f592518c7f8c Version: $LATEST
[INFO] 2022-03-02T21:06:21.311Z b8126db0-ffeb-4f62-8ac9-f592518c7f8c Created new account with balance 421740.
[INFO] 2022-03-02T21:06:21.314Z b8126db0-ffeb-4f62-8ac9-f592518c7f8c Created new account with balance 957949.
[INFO] 2022-03-02T21:06:21.318Z b8126db0-ffeb-4f62-8ac9-f592518c7f8c Created new account with balance 333464.
[INFO] 2022-03-02T21:06:21.322Z b8126db0-ffeb-4f62-8ac9-f592518c7f8c Created new account with balance 879226.
[INFO] 2022-03-02T21:06:21.325Z b8126db0-ffeb-4f62-8ac9-f592518c7f8c Created new account with balance 490512.
[INFO] 2022-03-02T21:06:21.330Z b8126db0-ffeb-4f62-8ac9-f592518c7f8c Database initialized.
END RequestId: b8126db0-ffeb-4f62-8ac9-f592518c7f8c
REPORT RequestId: b8126db0-ffeb-4f62-8ac9-f592518c7f8c Duration: 806.48 ms Billed Duration: 807 ms Memory Size: 128 MB Max Memory Used: 47 MB Init Duration: 163.85 ms
正如我们所看到的,该函数按预期工作:五个具有随机余额的新账户已被创建并添加到数据库中。
如果我们愿意,我们可以通过查找我们的CockroachDB无服务器集群,点击它,点击 "数据库",然后点击 "defaultdb "来进一步确认,在那里我们可以看到账户表确实已经被创建。

(可选)使用CockroachDB的SQL shell来查看结果
虽然我们已经确认了我们的函数创建了 accounts ,但我们也可以使用CockroachDB的SQL shell来检查表的内容。
要做到这一点,我们需要先安装CockroachDB客户端。
curl https://binaries.cockroachdb.com/cockroach-v21.2.5.darwin-10.9-amd64.tgz | tar -xz; sudo cp -i cockroach-v21.2.5.darwin-10.9-amd64/cockroach /usr/local/bin/
一旦安装完毕,我们就可以使用下面的命令进行连接。请注意,你需要将下面代码中--url 后面的连接字符串替换为你的CockroachDB集群的连接弹簧,即我们在步骤4中保存的那个。
cockroach sql --url "postgresql://:@free-tier14..cockroachlabs.cloud:26257/defaultdb?sslmode=verify-full&options=--cluster%3D"
该命令将我们连接到集群并启动SQL shell。在那里,我们可以针对集群上的任何数据库编写和运行SQL查询。默认情况下,它将把我们连接到defaultdb ,这也是我们的函数创建表的数据库,所以我们可以通过运行一个简单的SELECT 语句看到账户表的内容。
id | balance
---------------------------------------+----------
038bcf6a-0d04-44f4-abf2-ebaac4092e60 | 957949
3c71272f-de7c-49d4-b1c1-420248481f3b | 333464
900c78e9-740c-4e50-bd7f-367009a33432 | 421740
a21bda06-9180-4fcc-85e8-2d3f1cedea18 | 879226
ea9ccd45-d12b-44cf-9462-6b65478e7430 | 490512
(5 rows)
Time: 41ms total (execution 3ms / network 38ms)
在这里,我们看到账户确实被添加到了数据库中,而且ID和账户余额值与我们调用Lambda函数时在输出日志中看到的相同。我们已经完全确认了我们的无服务器函数和无服务器数据库都在按预期运行。
接下来的步骤
我们已经在AWS Lambda上启动并运行了我们的函数,当然,这只是冰山一角。在应用方面,我们可能会想改变我们的代码,做一些更有用的事情,而不是简单地生成随机的账户和值。
在AWS Lambda方面,我们想设置一个触发器,自动调用我们的函数(例如,基于一个事件),而不是通过命令行手动完成。关于调用函数的AWS Lambda文档是一个好的开始。