如何为Ruby的mysql2库配置AWS Lambda Layer?
解决Ruby Lambda Layer中mysql2库的libmariadb依赖问题
核心问题分析
你遇到的错误是因为mysql2的原生扩展依赖libmariadb.so.3,但Lambda运行时无法找到这个库。Lambda的Ruby环境默认不会扫描/opt/ruby/libs路径的动态库,且本地编译的mysql2依赖库和Lambda的Amazon Linux 2运行环境不兼容,直接复制单个so文件也可能遗漏依赖。
正确的Layer构建步骤
1. 使用Lambda兼容环境编译mysql2
Lambda的Ruby运行时基于Amazon Linux 2,必须在该环境下编译mysql2才能保证兼容性。用Docker启动兼容容器:
docker run --rm -v "$PWD":/var/task public.ecr.aws/sam/build-ruby3.3:latest bash
2. 在容器内安装依赖并编译mysql2
进入容器后,执行以下命令:
# 安装mariadb开发库(用于编译mysql2的原生扩展) yum install -y mariadb-devel # 创建Layer目录结构 mkdir -p ruby/gems/3.3.0 ruby/specifications/3.3.0 lib # 安装mysql2到指定目录,指定mariadb的库和头文件路径 gem install mysql2 -v 0.5.6 --install-dir ./ruby/gems/3.3.0 -- --with-mysql-lib=/usr/lib64/mysql --with-mysql-include=/usr/include/mysql # 复制mysql2的spec文件到specifications目录 cp ./ruby/gems/3.3.0/specifications/mysql2-0.5.6.gemspec ./ruby/specifications/3.3.0/ # 复制所需的动态库到lib目录(包括libmariadb.so.3及其依赖) cp /usr/lib64/mysql/libmariadb.so.3 ./lib/ # 可选:用ldd检查libmariadb.so.3的依赖,复制Lambda环境缺失的库 # ldd /usr/lib64/mysql/libmariadb.so.3
3. 打包Layer
退出容器后,将ruby和lib目录打包为zip(注意zip根目录是这两个文件夹,不能包含外层父目录):
zip -r mysql2-layer.zip ruby lib
Lambda函数配置
- 将打包好的zip上传为Lambda Layer,并附加到你的Ruby函数。
- 在Lambda函数的环境变量中添加:
这会告诉系统动态库加载器优先从LD_LIBRARY_PATH=/opt/lib:$LD_LIBRARY_PATH/opt/lib查找依赖。
验证代码示例
使用以下测试代码验证RDS连接:
require 'mysql2' def handler(event:, context:) client = Mysql2::Client.new( host: ENV['RDS_HOST'], username: ENV['RDS_USER'], password: ENV['RDS_PASSWORD'], database: ENV['RDS_DB_NAME'] ) query_result = client.query('SELECT VERSION() as mysql_version') { statusCode: 200, body: query_result.first.to_json } end
关键注意事项
- 绝对不能在本地(如Mac/Windows)编译
mysql2,否则依赖库与Lambda环境不兼容。 - 动态库必须放在
/opt/lib目录(对应Layer的lib文件夹),而非/opt/ruby/libs,因为Lambda默认的LD_LIBRARY_PATH包含/opt/lib。 - 确保Layer的目录结构严格符合Lambda要求:
/opt/ruby/gems/3.3.0/gems/mysql2-x.x.x和/opt/lib/libmariadb.so.3。
内容的提问来源于stack exchange,提问作者digopp22
相关产品推荐
相关产品推荐

