首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何正确加载AWS Lambda中的gem扩展

如何正确加载AWS Lambda中的gem扩展
EN

Stack Overflow用户
提问于 2019-01-23 15:38:35
回答 4查看 3K关注 0票数 7

我在AWS Lambda上处理一个gem加载错误时遇到了问题。

代码语言:javascript
复制
{
  "errorMessage": "LoadError: libpq.so.5: cannot open shared object file: No such file or directory - /var/task/vendor/bundle/ruby/2.5.0/gems/pg-1.1.4/lib/pg_ext.so",
  "errorType": "Function<Sequel::AdapterNotFound>",
  "stackTrace": [
    "/var/lang/lib/ruby/2.5.0/rubygems/core_ext/kernel_require.rb:59:in `require'",
    "/var/lang/lib/ruby/2.5.0/rubygems/core_ext/kernel_require.rb:59:in `require'",
    "/var/task/vendor/bundle/ruby/2.5.0/gems/pg-1.1.4/lib/pg.rb:4:in `<top (required)>'",
    "/var/lang/lib/ruby/2.5.0/rubygems/core_ext/kernel_require.rb:59:in `require'",
    "/var/lang/lib/ruby/2.5.0/rubygems/core_ext/kernel_require.rb:59:in `require'",
    "/var/task/vendor/bundle/ruby/2.5.0/gems/sequel-5.16.0/lib/sequel/adapters/postgres.rb:6:in `<top (required)>'",
    "/var/lang/lib/ruby/2.5.0/rubygems/core_ext/kernel_require.rb:59:in `require'",
    "/var/lang/lib/ruby/2.5.0/rubygems/core_ext/kernel_require.rb:59:in `require'",
    "/var/task/vendor/bundle/ruby/2.5.0/gems/sequel-5.16.0/lib/sequel/database/connecting.rb:88:in `load_adapter'",
    "/var/task/vendor/bundle/ruby/2.5.0/gems/sequel-5.16.0/lib/sequel/database/connecting.rb:17:in `adapter_class'",
    "/var/task/vendor/bundle/ruby/2.5.0/gems/sequel-5.16.0/lib/sequel/database/connecting.rb:45:in `connect'",
    "/var/task/vendor/bundle/ruby/2.5.0/gems/sequel-5.16.0/lib/sequel/core.rb:121:in `connect'",
    "/var/task/vendor/bundle/ruby/2.5.0/gems/sequel-5.16.0/lib/sequel/core.rb:399:in `adapter_method'",
    "/var/task/vendor/bundle/ruby/2.5.0/gems/sequel-5.16.0/lib/sequel/core.rb:406:in `block (2 levels) in def_adapter_method'",
    "/var/task/lib/warehouse/loader.rb:5:in `connection'",
    "/var/task/lib/warehouse/loader.rb:24:in `initialize'",
    "/var/task/lib/warehouse/update.rb:43:in `new'",
    "/var/task/lib/warehouse/update.rb:43:in `block in handle'",
    "/var/task/lib/warehouse/update.rb:42:in `each'",
    "/var/task/lib/warehouse/update.rb:42:in `handle'",
    "/var/task/lambda.rb:11:in `handler'"
  ]
}

我正在使用Sequel库从AWS建立一个PSQL连接,但是函数似乎找不到so文件。我在vendor/bundle (构建于CodeBuild上的Ubuntu中)中打包了依赖项,并验证了.so文件是否存在于上传到lambda的最终工件中。我还编辑了$LOAD_PATH,但这似乎没有帮助。

还有其他人遇到这种困难吗?有关于解决或调试的更多提示吗?

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2019-03-06 18:22:56

您的libpq.so.5文件夹中有lib吗?

您的错误是说没有在libpq.so.5上找到$PATH,在AWS中,文件夹lib会自动加载到路径上,因此,您只需要有这个文件就可以了。

在Lambda世界之外创建的可执行文件不会在lambda上运行,而且您需要在Lambda映像上自己编译可执行文件。这是如何做到这一点的一个例子:

Gemfile

代码语言:javascript
复制
source "https://rubygems.org"

gem "pg"
gem "mysql2"

handler.rb

代码语言:javascript
复制
require 'pg'
require 'mysql2'

def run(event:, context:)
  {
    postgres_client_version: PG.library_version,
    mysql_client_version: Mysql2::VERSION
  }
end

Dockerfile

代码语言:javascript
复制
FROM lambci/lambda:build-ruby2.5

RUN yum install -y postgresql postgresql-devel mysql mysql-devel
RUN gem update bundler

ADD Gemfile /var/task/Gemfile
ADD Gemfile.lock /var/task/Gemfile.lock

RUN bundle install --path /var/task/vendor/bundle --clean

这将构建您的映像,然后运行它生成PG和MYSQL可执行文件,然后将其复制到lib文件夹中。

build.sh

代码语言:javascript
复制
#!/bin/bash -x
set -e

rm -rf lib && rm -rf vendor && mkdir lib && mkdir vendor

docker build -t pg_mysql_layer -f Dockerfile .

CONTAINER=$(docker run -d pg_mysql_layer false)

docker cp \
    $CONTAINER:/var/task/vendor/ \
    ./

docker cp \
    $CONTAINER:/usr/lib64/libpq.so.5.5 \
    lib/libpq.so.5

docker cp \
    $CONTAINER:/usr/lib64/mysql/. \
    lib/

docker rm $CONTAINER

在运行./build.sh之后,它将生成libvendor文件夹,并满足您的需要,现在只需要部署您的lambda函数。

要在本地测试,可以运行:docker run --rm -it -v $PWD:/var/task -w /var/task lambci/lambda:ruby2.5 handler.run

它将返回类似以下内容的内容:

参考文献:https://www.stevenringo.com/ruby-in-aws-lambda-with-postgresql-nokogiri/

参考文献:红宝石/

票数 15
EN

Stack Overflow用户

发布于 2020-12-23 16:40:37

很少有好的插件可以管理AWS的依赖关系。无锯齿红宝石层用于ruby,无服务器-python-要求用于python。

对于您的红宝石情况,您可以使用服务器-红宝石层,只需添加插件相关的配置到您的serverless.yml。

代码语言:javascript
复制
service: using-docker-yums

plugins:
  - serverless-ruby-layer

custom:
  rubyLayer:
    use_docker: true
    docker_yums:
      - postgresql-devel
    native_libs:
      - /usr/lib64/libpq.so.5

provider:
  name: aws
  runtime: ruby2.5

functions:
  hello:
    handler: handler.hello

您需要在您的无服务器项目文件夹中安装下面的命令插件,

代码语言:javascript
复制
sls plugin install -n serverless-ruby-layer

现在,运行sls deploy将自动将gems和libs部署到该层。

查看文档中的示例这里

票数 2
EN

Stack Overflow用户

发布于 2021-10-11 15:31:47

这里有一个类似于“ruan-carlos”的解决方案,但只需一步一步就可以理解。

代码语言:javascript
复制
#!/bin/bash

set -e

cat >Dockerfile <<EOF
FROM public.ecr.aws/lambda/ruby:2.7
RUN yum install -y postgresql-libs
EOF

rm -rf lib

docker build -t pg-layer-source  .

mkdir lib

docker create -ti --name dummy pg-layer-source bash

docker cp dummy:/usr/lib64/libpq.so.5.5 lib/libpq.so.5
docker cp dummy:/usr/lib64/libldap_r-2.4.so.2.10.7 lib/libldap_r-2.4.so.2
docker cp dummy:/usr/lib64/liblber-2.4.so.2.10.7 lib/liblber-2.4.so.2
docker cp dummy:/usr/lib64/libsasl2.so.3.0.0 lib/libsasl2.so.3
docker cp dummy:/usr/lib64/libssl3.so lib
docker cp dummy:/usr/lib64/libsmime3.so lib
docker cp dummy:/usr/lib64/libnss3.so lib

docker rm -f dummy

zip -r $(date +%Y-%m-%d-%s)-lib-pg-layer.zip lib
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/54330779

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档