专栏首页Serverless+云函数安装依赖
原创

云函数安装依赖

使用 Python, Node.js 等开发云函数时, 可能遇到的一个问题就是依赖安装. 由于操作系统版本, 系统库版本及语言版本不一致, 有时在本地环境可以运行良好的程序在部署到 SCF 后可能会出现错误.

本文以为 Node.js 8.9 安装 nodejieba 及为 Python 3.6 安装 pandas 为例, 介绍使用 Docker 为函数安装依赖.

安装 Docker

安装 Docker 超出了本文的范畴, 请参阅文档.

安装 nodejieba

下面是一个简单的例子

'use strict';

const jieba = require('nodejieba');

exports.main_handler = async (event, context, callback) => {
    return jieba.cut('你好世界');
};

WindowsmacOS 上, 你可以正确地运行这个例子, 但是部署到 SCF 上, 会出现如下错误:

{"errorCode":1,"errorMessage":"user code exception caught","stackTrace":"/var/user/node_modules/nodejieba/build/Release/nodejieba.node: invalid ELF header"}

使用 Docker 来安装依赖, 可以解决这个问题, 命令如下:

$ docker run -it --network=host -v /path/to/your-project:/tmp/your-project node:8.9 /bin/bash -c 'cd /tmp/your-project && npm install nodejieba --save'

这里 /path/to/your-project 是你的项目路径, 对应于 Docker 容器里的 /tmp/your-project 目录, 我们在容器里的 /tmp/your-project 目录下安装了 nodejieba, 即相当于在你的项目路径底下安装了 nodejieba.

安装完依赖后, 重新部署到 SCF 上, 现在, 你的函数应该能如期运行了.

安装 pandas

先写一个简单的例子

import pandas as pd

def main_handler(event, context):
    s = pd.Series([1, 3, 5, 6, 8])
    print(s)
    return len(s)

Python 3.6 安装 pandas, 操作与上面的流程类似

$ docker run -it --network=host -v /path/to/your-project:/tmp/your-project python:3.6.1 /bin/bash -c 'cd /tmp/your-project && pip install pandas -t .'

部署到 SCF 上并运行, 我们可以看到如下日志

/var/user/pandas/compat/__init__.py:84: UserWarning: Could not import the lzma module. Your installed Python is incomplete. Attempting to use lzma compression will result in a RuntimeError.
  warnings.warn(msg)
0    1
1    3
2    5
3    6
4    8
dtype: int64

函数可以运行, 但是有一个警告, 提示无法加载 lzma 模块, 试图使用 lzma 压缩会导致运行时错误, 这还得了, 让我们来解决它

直接进入容器内部

$ docker run -it --network=host -v /tmp/foo:/tmp/bar python:3.6.1 /bin/bash

安装 pandas 并运行上面的程序

$ cd /tmp/bar
$ pip install pandas -t .
echo <<EOF >> index.py
> import pandas as pd
>
> def main_handler(event, context):
>     s = pd.Series([1, 3, 5, 6, 8])
>     print(s)
>     return len(s)
>
> main_handler({}, {})
> EOF
$ python -v index.py > run.log 2>&1

让我们看看日志

$ grep lzma run.log
# /usr/local/lib/python3.6/__pycache__/lzma.cpython-36.pyc matches /usr/local/lib/python3.6/lzma.py
# code object from '/usr/local/lib/python3.6/__pycache__/lzma.cpython-36.pyc'
# extension module '_lzma' loaded from '/usr/local/lib/python3.6/lib-dynload/_lzma.cpython-36m-x86_64-linux-gnu.so'
# extension module '_lzma' executed from '/usr/local/lib/python3.6/lib-dynload/_lzma.cpython-36m-x86_64-linux-gnu.so'
import '_lzma' # <_frozen_importlib_external.ExtensionFileLoader object at 0x7f446c40db70>
import 'lzma' # <_frozen_importlib_external.SourceFileLoader object at 0x7f446c40d160>
# cleanup[2] removing lzma
# cleanup[2] removing _lzma
# cleanup[3] wiping lzma
# cleanup[3] wiping _lzma
# destroy _lzma
# destroy lzma

从上面的日志可以看到, 函数运行时确实会加载 lzma, 所以我们至少需要以下两个文件

  • /usr/local/lib/python3.6/lzma.py
  • /usr/local/lib/python3.6/lib-dynload/_lzma.cpython-36m-x86_64-linux-gnu.so

进一步地, 我们看看这个 so 文件有哪些依赖

$ ldd /usr/local/lib/python3.6/lib-dynload/_lzma.cpython-36m-x86_64-linux-gnu.so
	linux-vdso.so.1 (0x00007fff75bb1000)
	liblzma.so.5 => /lib/x86_64-linux-gnu/liblzma.so.5 (0x00007fc743370000)
	libpython3.6m.so.1.0 => /usr/local/lib/libpython3.6m.so.1.0 (0x00007fc742e36000)
	libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007fc742c19000)
	libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fc74286e000)
	libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007fc74266a000)
	libutil.so.1 => /lib/x86_64-linux-gnu/libutil.so.1 (0x00007fc742467000)
	libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007fc742166000)
	/lib64/ld-linux-x86-64.so.2 (0x00007fc74379c000)

除去部分系统库, 看起来还需要这两个文件

  • /lib/x86_64-linux-gnu/liblzma.so.5
  • /usr/local/lib/libpython3.6m.so.1.0

把这四个文件拷贝至项目路径下, 并修改代码, 如下:

import os

os.environ['LD_LIBRARY_PATH'] = os.path.dirname(
    os.path.realpath(__file__)) + ':' + os.environ['LD_LIBRARY_PATH']

import pandas as pd

def main_handler(event, context):
    s = pd.Series([1, 3, 5, 6, 8])
    print(s)
    return len(s)

重新部署, 现在函数可以正常运行并且没有警告了 :)

原创声明,本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

登录 后参与评论
0 条评论

相关文章

  • 【玩转云函数】腾讯云函数 Python 依赖安装

    以下内容来自「玩转腾讯云」用户原创文章,已获得授权。 本次作者主要是想利用腾讯云的 Serverless 云函数服务,由于腾讯云函数 Python 的环境只配...

    腾讯云serverless团队
  • 【玩转腾讯云】腾讯云函数的 Python 依赖安装及测试示例

    本次作者主要是想利用腾讯云的 Serverless 云函数服务,由于腾讯云函数 Python 的环境只配置了基础的 Python 库,

    数据科学实战
  • 云函数Python依赖包安装,应用启动超时问题排查

    腾讯云云函数(Serverless Cloud Function,SCF)是腾讯云为企业和开发者们提供的无服务器执行环境,帮助您在无需购买和管理服务器的情况下运...

    worker
  • 小程序云开发实战二:小程序云开发云函数安装依赖步骤

    1:安装nodejs,准备好环境,这一步就不细说了,没有安装的可以自行百度,不知道有没有安装的可以输入 node -v 查看一下。

    王小婷
  • 小程序云开发实战二:小程序云开发云函数安装依赖步骤

    1:安装nodejs,准备好环境,这一步就不细说了,没有安装的可以自行百度,不知道有没有安装的可以输入 node -v 查看一下。

    王小婷
  • 为Python云函数打包依赖

    在使用无服务器云函数(SCF)的时候通常会遇到导入第三方库的时候,这个时候很多小伙伴就比较头疼:我如何打包进去呢?其实这里有几个方法可以尝试。

    None-xiaomi
  • 一文读懂云函数 SCF 如何进行依赖安装

    云函数 SCF 各个运行时已内置部分常用依赖库,您可前往各运行时代码开发中查询:Node.js、Python 、PHP。但仅有内置依赖库是不足以满足用户的代码...

    腾讯云serverless团队
  • 一文读懂云函数 SCF 如何进行依赖安装(下)

    在《一文读懂云函数 SCF 如何进行依赖安装》一文中为大家介绍了对 Node.js 和 Python 运行时的依赖安装方法,本文将继续为大家讲解 PHP、Ja...

    腾讯云serverless团队
  • 函数依赖总结

    SuperHeroes
  • Serverless实践系列(二):为Python云函数打包依赖

    在使用无服务器云函数SCF时通常会遇到导入第三方库的问题,很多小伙伴比较头疼是:应该如何打包进去?这里,推荐几个不错的方法。

    腾讯云serverless团队
  • Guice依赖注入(构造函数)

    本教程主要详细讲解Guice的构造函数注入. 我们将通过详细的代码以及步骤进行讲解.

    程序猿梦工厂
  • 安装gcc及其依赖

    在gcc-4.8.2和gcc-4.1.2基础上编译gcc-5.2.0,有可能会遇到一些问题。 要想成功编译gcc,则在编译之前需要安装好它的至少以下三...

    一见
  • python及其依赖安装

    Download Miniconda 2.7 64-bit Windows installer from Miniconda website. Install...

    py3study
  • 开普勒云平台:9个示例解析如何安装依赖

    kplcloud是一个基于Kubernetes的轻量级PaaS平台,通过可视化的界面对应用进行管理,降低应用容器化的对度,从而减少应用容器化的时间成本。

    宜信技术学院
  • 安装VIM所依赖包

    CentOS6.3 x86_64 最小化安装版安装vim yum -y install vim 通过这个命令可得出安装vim所得依赖包如下 T...

    三杯水Plus
  • 数据库 部分函数依赖 完全函数依赖 传递函数依赖 第一范式、第二范式、第三范式、BCNF范式区别

    数据库 部分函数依赖 完全函数依赖 传递函数依赖 第一范式、第二范式、第三范式、BCNF范式区别

    全栈程序员站长
  • yarn 安装依赖(ubuntu16.04安装教程)

    Yarn 是由Facebook开发的开源的JavaScript包管理工具,它在现在流行的npm基础上进行了升级改进。Facebook 开发团队创造yarn来克服...

    全栈程序员站长

扫码关注腾讯云开发者

领取腾讯云代金券