AWS Lambda上无法加载mysql2文件

3
尝试让Lambda连接RDS数据库,但无法加载mysql2 gem。尝试了“pristine”指令,但未解决问题。已将mysql2 gem构建到供应商目录中,并使用“bundle install --deployment”完成操作。可能是由于mysql2使用的编译扩展造成的问题。但不确定如何在AWS Lambda上解决这个问题。您有什么想法吗?以下是日志输出:
START RequestId: 62f35c49-039f-11e9-be04-1fd1111df42b Version: $LATEST
Ignoring mysql2-0.5.2 because its extensions are not built. Try: gem pristine mysql2 --version 0.5.2
Init error when loading handler lambda_function.lambda_handler
{
  "errorMessage": "cannot load such file -- mysql2",
  "errorType": "Init<LoadError>",
  "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/lambda_function.rb:3: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'"
  ]
}
END RequestId: 62f35c49-039f-11e9-be04-1fd1111df42b
REPORT RequestId: 62f35c49-039f-11e9-be04-1fd1111df42b  Duration: 1439.17 ms    Billed Duration: 1500 ms    Memory Size: 128 MB Max Memory Used: 17 MB  
Unknown application error occurred
Init<LoadError>

这是我的Gemfile:

source 'https://rubygems.org'

gem 'mysql2', '~> 0.5.2'
gem 'sequel', '~> 5.15.0'

Gemfile.lock

GEM
remote: https://rubygems.org/
specs:
  mysql2 (0.5.2)
  sequel (5.15.0)

PLATFORMS
  ruby

DEPENDENCIES
  mysql2 (~> 0.5.2)
  sequel (~> 5.15.0)

BUNDLED WITH
  1.17.2

这是我的lambda_function.rb文件的顶部:

require 'json'
require 'logger'
require 'mysql2'
require 'sequel'

还没有完全阅读它,但似乎我可以使用Docker在与Lambda相似的环境中构建gem及其扩展程序。请参阅此处 - James
3个回答

2
Dhanabal的回答是可行的,但是我想进一步阐述,因为对我来说这个答案过于程序化。基本上,带有本地扩展的gem应该在与AWS Lambda相同的环境中构建。因此,我们需要在模拟Lambda环境的 docker镜像中构建本地扩展。此外,我们需要将动态库复制到加载路径中。首先,让我们找出可以放置库的位置。在容器中执行echo $LD_LIBRARY_PATH,您将得到/var/lang/lib:/lib64:/usr/lib64:/var/runtime:/var/runtime/lib:/var/task:/var/task/lib:/opt/lib。所以,我只需将库从/usr/lib64/mysql复制到[function dir]/lib并部署即可。就是这样。

谢谢,Sam。关于给出为什么以及怎么做的优点,你说得真好。 - James
当我进入docker容器的var/task/lib时,我看到了*.so文件。但是当我退出docker容器后,我看到lib目录为空。我需要映射它们吗?当我执行lambda函数时,我会收到libmysqlclient.so.18:无法打开共享对象文件:没有那个文件或目录的错误消息。 - Steven Aguilar
Docker有点复杂。我不能代表你的设置说话,但对于我来说,我在开发中使用docker-compose。我将整个代码目录挂载到开发环境的容器中。我有一个Makefile用于打包zip文件,在那里执行复制操作。这是我的Makefile中的一些观察结果:docker-compose run --rm application cp $(shell docker-compose run --rm application realpath /usr/lib64/libnettle.so.4) ./lib/libnettle.so.4虽然它不是MySQL库,但希望这可以帮助到你。 - Curious Sam

0

Dhanabal的回答有两点需要注意:

1)cp -a /usr/mysql/.so这一步骤缺少一个*号。 2)确保lib目录中没有符号链接,因为符号链接在压缩后会失效,你需要实际的文件。


0

前提条件: * Docker

创建一个如下所示的 Docker 文件

    FROM lambci/lambda:build-ruby2.5
    RUN yum -y install mysql-devel
    RUN gem update bundler
    CMD "/bin/bash"

构建 Docker

    docker build -t lambda-ruby2.5-mysqldep .

使用以下命令在您的源代码文件夹中运行Docker:

Docker run

    docker run --rm -it -v $PWD:/var/task -w /var/task lambda-ruby2.5-mysqldep

这将让你进入bash

  • 将mysql文件夹从/usr/lib64/mysql移动到/usr/mysql
  • mkdir -p /var/task/lib
  • cp -a /usr/mysql/.so. /var/task/lib/
  • bundle config --local build.mysql --with-mysql-config=/usr/local/mysql/bin/mysql_config
  • 使用和不使用部署进行bundle安装

然后退出bash。创建一个lambda部署包并上传到AWS。这对我有用。


像RUN yum -y install mysql-devel这样的命令,是否有适用于PostgreSQL 10的命令? - momwhocode

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接