亚马逊无服务器计算 lambda 的初体验
共计 4477 个字符,预计需要花费 12 分钟才能阅读完成。
1. 简介
Amazon Lambda
是亚马逊云科技提供的一种无服务器计算服务,它的特点如下:
-
无服务器(Serverless)
- 开发者无需管理底层服务器。
Amazon Lambda
会自动为代码提供执行环境,包括计算资源、内存、存储等。 - 计费基于实际执行时间和资源消耗,避免了闲置资源浪费。
- 开发者无需管理底层服务器。
-
事件驱动
代码的执行通常由某些事件触发。常见触发器包括:- 文件上传到 Amazon S3。
- 数据库更新(如 DynamoDB)。
- API Gateway 请求。
- 定时任务(通过 Amazon EventBridge)。
- 消息队列(如 Amazon SQS 或 Kafka)。
- 函数即服务(Function as a Service, FaaS)
此外,对于 Amazon Lambda
提供了非常高的永久免费额度,关于其他更多免费产品可以点击这里
/>
2. 账号注册
如果还没有注册需要先注册,当然注册也非常简单,但是需要一张信用卡。首先点击注册账户,与其他的注册方式不同,这里需要先输入邮箱和用户名。
/>
点击验证电子邮箱会收到验证码,输入进行验证即可。
/>
然后当然就是要创建密码了,这里需要输入复杂一点的密码,否则不能通过验证。
/>
接下来需要填写联系人信息,这里按自己情况进行填写即可。需要注意的是 州/省/自治区/直辖市或地区
这里必须使用英文,所以就索性全部用英文了。
/>
然后就是关键了,需要填写信用卡信息,因为申请亚马逊云科技必须持有一张信用,比如万事达、运通卡、VISA卡、银联信用卡支付方式
/>
然后就是验证手机号码了,这个也简单,收个验证码就行。
/>
然后就到了最后一步,选择支持计划,这里选择免费的基本支持就好了。
/>
3. 简单使用
登陆后就可以进入 lambda 控制台,然后点击创建函数。
/>
这里有多种运行时环境可以选择,比如 Python、Node,甚至还支持 Java 环境。
/>
这里选择 Python,因为待会用到的案例也是 Python 环境。填写好函数名称,点击创建即可。
/>
创建后的页面如下。
/>
提示我们已经创建好了函数,可以在该页面修改代码和进行测试。
/>
这里的代码就是重头戏了,因为这里是处理事件关键代码。入口函数一般都命名为 lambda_handler
,可以看见案例里面是直接返回一个 Hello from Lambda!
字符串。
那么如何看写的代码是否有问题呢?总不能每次都发布再看结果有没有问题吧。这个也简单,只需要点击 Test
创建一个测试事件。
/>
然后定义测试事件名称创建。
/>
点击运行后可以看见返回没问题。
/>
4. 自定义函数
上面的官方案例仅仅只能作为学习,我们基本用不到,所以我们需要自定义函数内容来满足我们自己的需求。
比如说我想定义一个函数,当触发这个函数时可以给特定邮箱发送邮件。这里只是一个简单的案例,还可以有其他的更多玩法,就像 cf 的 workers 那样,也是可以将 workers 的内容改造成 lambda 的格式的。
import json
import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from email.header import Header
import logging
import os
# 设置日志
logger = logging.getLogger()
logger.setLevel(logging.INFO)
def sendmail():
# 从环境变量或 Secrets Manager 获取凭证
from_addr = os.getenv('FROM_ADDR', 'xxx@qq.com') # 使用环境变量存储邮箱地址
password = os.getenv('EMAIL_PASSWORD', 'xxx') # 使用环境变量存储邮箱密码
to_addr = "xxx@qq.com"
smtp_server = "smtp.qq.com"
smtp_port = 465
html_msg = """
<h1>测试内容</h1>
"""
# 创建邮件对象
msg = MIMEMultipart()
msg['From'] = from_addr # 发件人
msg['To'] = to_addr # 收件人
subject = '来自 Amazon lambda'
msg['Subject'] = Header(subject, 'utf-8') # 邮件主题
msg.attach(MIMEText(html_msg, 'html', 'utf-8')) # 邮件正文内容
try:
smtpobj = smtplib.SMTP_SSL(smtp_server, smtp_port)
smtpobj.login(from_addr, password) # 登录邮箱
smtpobj.sendmail(from_addr, to_addr, msg.as_string()) # 发送邮件
logger.info("邮件发送成功")
except smtplib.SMTPException as e:
logger.error("发送邮件时出错: %s", str(e))
finally:
smtpobj.quit() # 退出 SMTP 会话
def lambda_handler(event, context):
try:
sendmail()
return {
'statusCode': 200,
'body': json.dumps('邮件发送成功')
}
except Exception as e:
return {
'statusCode': 500,
'body': json.dumps(f"邮件发送失败: {str(e)}")
}
只需要将上面的内容替换掉之前 lambda_function.py
的内容,并填写好 smtp 相关账户密码。
然后这里可能还需要在配置里面配置一下超时事件,比如将超时改为 10 秒。
/>
再创建一个函数 url,目的是为了方便通过访问 url 触发。
/>
这里为了简单选择不需要授权。
/>
此时也可以通过测试事件查看是否能够发送邮件,由于上面讲过了这里就不提了。这里多了一种触发的方式,就是访问刚刚创建的 url。另外,可以看见下图还能添加其他很多类型的触发器。
/>
效果如下:
/>
5. 使用容器映像
有些时候像之前那样创建,编写的函数代码需要的环境并不能满足需求。此时一个比较好的方式是使用容器,基于它提供的容器打造成自己需要的容器环境,再将函数代码放入容器内。构建好镜像以后,将镜像上传到 容器注册表 ECR,然后在创建函数时选择该镜像。
5.1 创建仓库
既然需要用到容器注册表,就需要先创建一个仓库,点击创建存储库,输入仓库名,点击创建。
/>
创建好以后点击右上角可以查看推送命令。
/>
5.2 安装命令行工具
参考文档,安装命令如下:
# 1. 下载
curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
# 2. 解压
unzip awscliv2.zip
# 3. 安装
sudo ./aws/install
查看版本:
aws --version
5.3 配置
由于命令行需要配置凭据才能进行相关操作,所以先需要创建访问密钥,访问 安全凭证,点击创建访问密钥。
/>
如果是根用户会提示建议使用 IAM 角色创建,但这里为了方便还是勾选根用户继续创建,如果有需要可以创建对应角色。
/>
创建好密钥后记得保存,因为以后不能查看了。
/>
创建好以后就可以在服务器创建 ~/.aws/credentials
文件,并填写好对应的内容。
[default]
aws_access_key_id=xxx
aws_secret_access_key=xxx
5.4 构建镜像并上传
上面的准备工作做完以后,接下来就是创建镜像了。首先创建一个 app.py,内容还是和上面一样。
import json
import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from email.header import Header
import logging
import os
# 设置日志
logger = logging.getLogger()
logger.setLevel(logging.INFO)
def sendmail():
# 从环境变量或 Secrets Manager 获取凭证
from_addr = os.getenv('FROM_ADDR', 'xxx@qq.com') # 使用环境变量存储邮箱地址
password = os.getenv('EMAIL_PASSWORD', 'xxx') # 使用环境变量存储邮箱密码
to_addr = "xxx@qq.com"
smtp_server = "smtp.qq.com"
smtp_port = 465
html_msg = """
<h1>测试内容</h1>
"""
# 创建邮件对象
msg = MIMEMultipart()
msg['From'] = from_addr # 发件人
msg['To'] = to_addr # 收件人
subject = '来自 Amazon lambda'
msg['Subject'] = Header(subject, 'utf-8') # 邮件主题
msg.attach(MIMEText(html_msg, 'html', 'utf-8')) # 邮件正文内容
try:
smtpobj = smtplib.SMTP_SSL(smtp_server, smtp_port)
smtpobj.login(from_addr, password) # 登录邮箱
smtpobj.sendmail(from_addr, to_addr, msg.as_string()) # 发送邮件
logger.info("邮件发送成功")
except smtplib.SMTPException as e:
logger.error("发送邮件时出错: %s", str(e))
finally:
smtpobj.quit() # 退出 SMTP 会话
def lambda_handler(event, context):
try:
sendmail()
return {
'statusCode': 200,
'body': json.dumps('邮件发送成功')
}
except Exception as e:
return {
'statusCode': 500,
'body': json.dumps(f"邮件发送失败: {str(e)}")
}
然后编写 dockerfile:
FROM public.ecr.aws/lambda/python:3.8
# Copy function code
COPY app.py ${LAMBDA_TASK_ROOT}
# Set the CMD to your handler (could also be done as a parameter override outside of the Dockerfile)
CMD [ "app.lambda_handler" ]
接下来推送命令就派上用场了,按提示操作即可。
/>
5.5 创建函数
相比较于之前的创建函数,这里需要选择容器映像,不出意外可以看见刚刚上传的镜像。
/>
选择好以后点击创建。
/>
由于是容器,不能直接编辑代码,但是可以在界面上进行测试,效果也是一样的。
/>
Tips:清朝云网络工作室