尝试在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中的一层,但我在lanching 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-developenssl-develpython36-devel。请看一下这个技巧(注3:(。

详细方式:

  1. 先决条件:安装Docker
  2. 在一个空目录中,复制包含pycurlrequirements.txt(在我的例子中是:pycurl~=7.43.0.5(
  3. 在同一目录中,创建以下Dockerfile(cf备注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
  1. 构建docker镜像:
docker build -t build-python3.6-pycurl .
  1. 使用此图像构建图层(cf Note 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"
  1. 通过运行压缩层:
zip mylayer.zip python > /dev/null
  1. 将文件mylayer.zip作为一个层发送到aws,并使lambda指向它(使用控制台或按照tutohttps://aws.amazon.com/fr/premiumsupport/knowledge-center/lambda-layer-simulated-docker/)。

  2. 测试你的lambda并庆祝!

注意1.如果您想使用python 3.8,只需将3.6或36更改为3.8和38即可。

注意2.重新生成层时不要忘记删除python文件夹,必要时使用管理员权限。

注意3.注意DockerFile最后一行的符号链接。如果没有它,gcc将无法找到一些头文件,例如Python.h

注意4.使用openssl后端编译pycurl,因为它是lambda执行环境中使用的ssl后端。否则,在执行lambda时会出现libcurl link-time ssl backend (openssl) is different from compile-time ssl backend错误。

最新更新