【问题标题】:Errors when trying to call pycurl in a lambda on AWS尝试在 AWS 上的 lambda 中调用 pycurl 时出错
【发布时间】:2021-05-27 20:46:46
【问题描述】:

我想使用 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'

我按照 tuto 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

然后在 aws 中将 zip 作为图层上传,但是在启动 lambda 时出现另一个错误:

    Unable to import module 'lambda_function': libssl.so.1.0.0: cannot open shared object file: No such file or directory

似乎该层必须建立在某种扩展目标环境上。

【问题讨论】:

  • 为什么不直接使用urllib。这不需要任何层或依赖项,因为它是 Python 标准库的一部分。即使您不想使用urllib,也可以使用requests,这可能是比您的Lambda 中的curl 更好的选择。
  • 谢谢@Jens,这可能是一种解决方法。然而,据我所知,只有pycurl 能够提供诸如 TTLB、TTFB 和 DNS 查找时间等指标。
  • 好的。从您提供的代码中并不清楚。在这种情况下,urllibrequests 可能没有帮助。
  • 你说得对,我把代码改成明确的。

标签: amazon-web-services aws-lambda layer pycurl


【解决方案1】:

在摸索了几个小时后,我设法解决了这个问题。

TL;DR: 使用从 aws 继承的 docker 映像构建层,但使用所需的库,例如 libcurl-developenssl-develpython36-devel。看看技巧注 3 :)。

详细方式:

  1. 先决条件:已安装 Docker
  2. 在一个空目录中,复制包含pycurlrequirements.txt(在我的例子中:pycurl~=7.43.0.5
  3. 在同一目录中,创建以下 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
  1. 构建 docker 镜像:
docker build -t build-python3.6-pycurl .
  1. 使用此映像构建层(参见注 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 指向它(使用控制台,或跟随教程 https://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. 编译 pycurlopenssl 后端,因为它是 lambda 执行环境中使用的 ssl 后端。否则在执行 lambda 时会出现 libcurl link-time ssl backend (openssl) is different from compile-time ssl backend 错误。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-10-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-05
    • 2020-03-09
    相关资源
    最近更新 更多