专栏首页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)

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

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

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

我来说两句

0 条评论
登录 后参与评论

相关文章

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

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

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

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

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

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

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

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

    数据科学实战
  • 一文读懂云函数 SCF 如何进行依赖安装

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

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

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

    腾讯云serverless团队
  • 为Python云函数打包依赖

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

    None-xiaomi
  • 云函数Python依赖包安装,应用启动超时问题排查

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

    worker
  • 函数依赖总结

    SuperHeroes
  • 安装gcc及其依赖

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

    一见
  • 安装VIM所依赖包

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

    三杯水Plus
  • python及其依赖安装

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

    py3study
  • python安装mysql-python依赖包

    新公司,对换工作了!接口自动化使用的是python的behave框架,因此需要折腾python了,而公司配的笔记本是windows的,因此要在windows下折...

    千往
  • 安装GCC-8.3.0及其依赖

    为体验C++17和C++20特性,需安装更新版本的GCC编译器。GCC官网为:https://gcc.gnu.org/,从这里可以下载最新版本的GCC。

    一见
  • ubuntu忽略安装一些依赖

    下载了deep-wine的非官方版,安装了微信,结果每次apt install都会报这个依赖错误,建议我删除这个微信:

    超级大猪
  • Windows下pip安装依赖报错

    windows 下执行 pip install 来安装pip的有些包经常会出错, 最常见的就是 lxml 和 mysqlclient 这类包。

    文渊同学
  • Guice依赖注入(构造函数)

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

    程序猿梦工厂
  • Serverless实践系列(二):为Python云函数打包依赖

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

    腾讯云serverless团队
  • Python一键安装全部依赖包

    requirements.txt用来记录项目所有的依赖包和版本号,只需要一个简单的pip命令就能完成。

    py3study

扫码关注云+社区

领取腾讯云代金券