我想在本地运行我的lambda函数(我目前正在使用ruby 2.7.1
),但是当我需要一个需要本机依赖项的gem时,它会失败,因为它找不到它们。
我试图使用'pg'
gem来连接到postgresql数据库。然后,我继续运行sam build
和sam local invoke HelloWorldFunction --event events/event.json
,但由于下一个错误而失败:
Invoking app.lambda_handler (ruby2.7)
Failed to download a new amazon/aws-sam-cli-emulation-image-ruby2.7:rapid-1.0.0 image.
Invoking with the already downloaded image.
Mounting /home/user/sam-app/.aws-sam/build/HelloWorldFunction as /var/task:ro,delegated
inside runtime container
Init error when loading handler app.lambda_handler
{
"errorMessage": "libpq.so.5: cannot open shared object file: No such file or directory - /var/task/vendor/bundle/ruby/2.7.0/gems/pg-1.2.3/lib/pg_ext.so",
"errorType": "Init<LoadError>",
"stackTrace": [
"/var/lang/lib/ruby/site_ruby/2.7.0/rubygems/core_ext/kernel_require.rb:92:in `require'",
"/var/lang/lib/ruby/site_ruby/2.7.0/rubygems/core_ext/kernel_require.rb:92:in `require'",
"/var/task/vendor/bundle/ruby/2.7.0/gems/pg-1.2.3/lib/pg.rb:5:in `<top (required)>'",
"/var/lang/lib/ruby/site_ruby/2.7.0/rubygems/core_ext/kernel_require.rb:92:in `require'",
"/var/lang/lib/ruby/site_ruby/2.7.0/rubygems/core_ext/kernel_require.rb:92:in `require'",
"/var/task/app.rb:3:in `<top (required)>'",
"/var/lang/lib/ruby/site_ruby/2.7.0/rubygems/core_ext/kernel_require.rb:92:in `require'",
"/var/lang/lib/ruby/site_ruby/2.7.0/rubygems/core_ext/kernel_require.rb:92:in `require'"
]
}
我接下来要做的是执行sam build --use-container
并得到Gem::Ext::BuildError
和消息ERROR: Failed to build gem native extension.
似乎没有包含gem所需的外部库。
我的问题是:
我读过一些有关使用Layers的知识,但我并不完全理解,因为这是我第一次使用lambda函数。
似乎山姆人解决方案还有一些未解决的问题,但这不会在不久的将来。
任何帮助将不胜感激! 谢谢!
答案 0 :(得分:1)
Lambda中的层基本上为您提供了一种安装与您的函数不直接相关但被其使用的依赖项的方法。这是支持重用并加快构建和部署时间的绝佳方法。这里的想法是,您可以将常见或共享的依赖项(如postgresql库)安装到该层中,然后从您的函数中引用它们。
简而言之,它们为您提供了一种方法,将内容放置在lambda可以在运行时访问的文件系统上。
但是,在这种情况下,存在一些相互关联的问题:
pg
gem要求将软件包安装在操作系统上,并且文件在构建时就可用pg
gem本身不会安装依赖项这意味着使用图层比理想情况要简单一些。
对于您的问题,请尝试以下操作:
pg_layer
的新目录Makefile
的文件(大小写很重要),其内容如下:LIB_DIR = $(ARTIFACTS_DIR)/lib
LIB_FILES = \
/usr/lib64/libpq.so.* \
/usr/lib64/libldap_r-2.4.so.2* \
/usr/lib64/liblber-2.4.so.* \
/usr/lib64/libsasl2.so.* \
/usr/lib64/libssl3.so \
/usr/lib64/libsmime3.so \
/usr/lib64/libnss3.so
build-PGLayer:
yum install -y amazon-linux-extras
yum install -y postgresql-devel postgresql-libs
mkdir -p $(ARTIFACTS_DIR)/vendor/bundle
mkdir -p $(LIB_DIR)
for f in $(LIB_FILES); do cp $$f $(LIB_DIR); done
cp -r . $(ARTIFACTS_DIR)
mkdir -p $(ARTIFACTS_DIR)/ruby/gems
gem install pg --install-dir $(ARTIFACTS_DIR)/ruby/gems/2.7.0
template.yaml
文件,然后将以下内容添加到您的Resources
部分: PGLayer:
Type: AWS::Serverless::LayerVersion
Properties:
CompatibleRuntimes:
- ruby2.7
ContentUri: 'pg_layer'
Metadata:
BuildMethod: makefile
template.yaml
文件中,更改函数定义以将以下内容添加到Properties
: Layers:
- !Ref PGLayer
pg
(由于该层而自动可用,将其保留在该位置将阻止您构建函数)准备好构建时,请使用命令sam build --use-container
。
要在图层上本地运行lambda函数,请使用sam local start-api
。
准备部署sam deploy
时,将推动整个应用程序(包括该层)的运行,并配置要使用该层的功能。