amazon-web-services - 尝试在 AWS 上的 lambda 中调用 pycurl 时出错
问题描述
我想使用 pycurl 来获得 TTFB 和 TTLB,但无法在 AWS lambda 中调用 pycurl。
为了专注于这个问题,假设我称这个简单的 lambda 函数为:
import json
import pycurl
import certifi
def lambda_handler(event, context):
client_curl = pycurl.Curl()
client_curl.setopt(pycurl.CAINFO, certifi.where())
client_curl.setopt(pycurl.URL, "https://www.arolla.fr/blog/author/edouard-gomez-vaez/") #set url
client_curl.setopt(pycurl.FOLLOWLOCATION, 1)
client_curl.setopt(pycurl.WRITEFUNCTION, lambda x: None)
content = client_curl.perform()
dns_time = client_curl.getinfo(pycurl.NAMELOOKUP_TIME) #DNS time
conn_time = client_curl.getinfo(pycurl.CONNECT_TIME) #TCP/IP 3-way handshaking time
starttransfer_time = client_curl.getinfo(pycurl.STARTTRANSFER_TIME) #time-to-first-byte time
total_time = client_curl.getinfo(pycurl.TOTAL_TIME) #last requst time
client_curl.close()
data = json.dumps({'dns_time':dns_time,
'conn_time':conn_time,
'starttransfer_time':starttransfer_time,
'total_time':total_time,
})
return {
'statusCode': 200,
'body': data
}
我有以下错误,这是可以理解的:
Unable to import module 'lambda_function': No module named 'pycurl'
我按照教程https://aws.amazon.com/fr/premiumsupport/knowledge-center/lambda-layer-simulated-docker/来创建一个图层,但是在使用 docker生成图层时出现以下错误(我提取了有趣的部分):
Could not run curl-config: [Errno 2] No such file or directory: 'curl-config': 'curl-config'
我什至尝试生成刚刚在我自己的机器上启动的层:
pip install -r requirements.txt -t python/lib/python3.6/site-packages/
zip -r mypythonlibs.zip python > /dev/null
然后将 zip 作为 aws 中的一个层上传,但是在启动 lambda 时出现另一个错误:
Unable to import module 'lambda_function': libssl.so.1.0.0: cannot open shared object file: No such file or directory
似乎该层必须建立在某种扩展的目标环境上。
解决方案
经过几个小时的挠头,我设法解决了这个问题。
TL;DR:使用从 aws 继承的 docker 映像构建层,但使用所需的库,例如libcurl-devel
、openssl-devel
、python36-devel
。看看技巧注3 :)。
详细方法:
- 先决条件:安装 Docker
- 在一个空目录中,复制您
requirements.txt
的内容pycurl
(在我的情况下pycurl~=7.43.0.5
:) - 在同一目录中,创建以下内容
Dockerfile
(参见注释 3):
FROM public.ecr.aws/sam/build-python3.6
RUN yum install libcurl-devel python36-devel -y
RUN yum install openssl-devel -y
ENV PYCURL_SSL_LIBRARY=openssl
RUN ln -s /usr/include /var/lang/include
- 构建 docker 镜像:
docker build -t build-python3.6-pycurl .
- 使用此图像构建层(参见注 2),通过运行:
docker run -v "$PWD":/var/task "build-python3.6-pycurl" /bin/sh -c "pip install -r requirements.txt -t python/lib/python3.6/site-packages/; exit"
- 通过运行压缩层:
zip mylayer.zip python > /dev/null
将文件
mylayer.zip
作为层发送到 aws 并使您的 lambda 指向它(使用控制台,或按照教程https://aws.amazon.com/fr/premiumsupport/knowledge-center/lambda-layer-simulated-docker/)。测试你的 lambda 并庆祝!
注 1.如果要使用 python 3.8,只需将 3.6 或 36 更改为 3.8 和 38。
注意 2.重新生成层时不要忘记删除 python 文件夹,必要时使用管理员权限。
注意 3.注意 DockerFile 最后一行中的符号链接。没有它,gcc
将无法找到一些头文件,例如Python.h
.
注 4.pycurl
用后端编译openssl
,因为它是 lambda 执行环境中使用的 ssl 后端。否则libcurl link-time ssl backend (openssl) is different from compile-time ssl backend
在执行 lambda 时会出错。
推荐阅读
- teradata - where 子句如何用于 teradata 中的日期字段
- jenkins - Jenkins下的SignTool找不到与USB Token匹配的证书
- python - 如何更改句子中字符的位置?
- swift - 传递什么参数来代替 (String) -> void?
- reactjs - 如何使用酶安装找到嵌套的连接组件?
- ckan - 如何将文件上传到 CKAN 扩展包中?
- performance - Julia:有没有办法用离散集合中的条目枚举所有大小为 m × n 的矩阵?
- npm - 在项目的 node_modules 顽固地重新出现 .bin 文件
- select - 选择选项时,显示数据库中的数据 - Woocommerce 自定义字段(结帐)
- javascript - 有效匹配数组,在第二个数组中删除找到的键