首先介绍下在本文出现的几个比较重要的概念:php
函数计算(Function Compute): 函数计算是一个事件驱动的服务,经过函数计算,用户无需管理服务器等运行状况,只需编写代码并上传。函数计算准备计算资源,并以弹性伸缩的方式运行用户代码,而用户只需根据实际代码运行所消耗的资源进行付费。函数计算更多信息 参考。
Fun: Fun 是一个用于支持 Serverless 应用部署的工具,能帮助您便捷地管理函数计算、API 网关、日志服务等资源。它经过一个资源配置文件(template.yml),协助您进行开发、构建、部署操做。Fun 的更多文档 参考。
fun install: fun install 是 fun 工具的一个子命令,用于安装 pip 和 apt 依赖,提供了命令行接口和 fun.yml 描述文件两种形式。
备注: 本文介绍的技巧须要 Fun 版本大于等于 2.9.3。html
函数计算安装第三方依赖一大痛点,文章 函数计算安装依赖库方法小结 对可能会遇到的问题和解决方法作了细致总结,fun install 是基于以前的经验和成果将最佳实践的方法固化到工具中,方便用户便捷的安装依赖。java
使用 fun install init
在当前目录初始化一个 fun.yml 文件。(这一步不是必须的,若是您打算手写 fun.yml 而后经过 fun install 命令批量执行 task,init 是一个好的开始。)node
在函数计算项目根目录执行 fun install init
命令,选择一个 runtime。python
$ fun install init ? Select runtime (Use arrow keys) python2.7 python3 nodejs6 nodejs8 java8 php7.2
而后会在当前目录生成一个 fun.yml 文件,内容以下:linux
runtime: python2.7 tasks: []
下面的命令安装 python 的 tensorflow 包git
$ fun install --runtime python2.7 --package-type pip tensorflow skip pulling image aliyunfc/runtime-python2.7:build-1.2.0... Task => [UNNAMED] => PYTHONUSERBASE=/code/.fun/python pip install --user tensorflow
说明github
--runtime
指定 runtime,若是已经初始化 fun.yml 文件, 因为 fun.yml 里声明了 runtime ,该选项能够省略。--package-type
指定安装依赖的类型,pip 和 apt 是目前的两个可选值。命令执行在 fc-docker 提供的 container 中,容器内部执行的命令会逐行打印出来,好比上面命令中内部真实执行了 PYTHONUSERBASE=/code/.fun/python pip install --user tensorflow
命令。docker
安装完成之后会在生成一个 .fun 目录, 可执行文件会被放置到 .fun/python/bin
目录下,库文件放置到 .fun/python/lib/python2.7/site-packages
下。shell
.fun └── python ├── bin │ ├── freeze_graph │ ├── markdown_py │ ├── pbr │ ├── saved_model_cli │ ├── tensorboard │ ├── tflite_convert │ ├── toco │ └── toco_from_protos └── lib └── python2.7 └── site-packages ├── tensorboard ├── tensorboard-1.12.2.dist-info ├── tensorflow ├── tensorflow-1.12.0.dist-info ├── termcolor-1.1.0.dist-info ...
相比以前的 pip install -t . <package-name>
方式,fun install 安装文件的存放位置更有组织,依赖文件和代码文件分离开了,便于清理、拆分后借助 OSS 或 NAS 初始化依赖文件。可是组织事后也带来一个新问题,须要用户自定义环境变量库文件才能被程序找到。为了方便用户使用提供了一个 fun install env
打印出必要的环境变量。
$ fun install env LD_LIBRARY_PATH=/code/.fun/root/usr/lib/x86_64-linux-gnu:/code:/code/lib:/usr/local/lib PATH=/code/.fun/root/usr/local/bin:/code/.fun/root/usr/local/sbin:/code/.fun/root/usr/bin:/code/.fun/root/usr/sbin:/code/.fun/root/sbin:/code/.fun/root/bin:/code/.fun/python/bin:/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/sbin:/bin PYTHONUSERBASE=/code/.fun/python
关于若是设定函数计算的环境变量,请参考 https://help.aliyun.com/document_detail/69777.html 。若是您使用 fun local
和 fun deploy
进行调试和部署,您无需关注环境变量问题,已经帮您设定好了。
install 命令加上 --save 参数,会将命令持久化成 task 保存到 fun.yml 文件中。
$ fun install --runtime python2.7 --package-type pip --save tensorflow skip pulling image aliyunfc/runtime-python2.7:build-1.2.0... Task => [UNNAMED] => PYTHONUSERBASE=/code/.fun/python pip install --user tensorflow
上面的命令多加了一行 --save
参数,查看 fun.yml 内容:
runtime: python2.7 tasks: - pip: tensorflow local: true
以后直接执行 fun install
不带参数,就能够依次执行任务。
$ fun install skip pulling image aliyunfc/runtime-python2.7:build-1.2.0... Task => [UNNAMED] => PYTHONUSERBASE=/code/.fun/python pip install --user tensorflow
$ fun install -v skip pulling image aliyunfc/runtime-python3.6:build-1.2.0... Task => [UNNAMED] => apt-get update (if need) Ign http://mirrors.aliyun.com stretch InRelease Get:1 http://mirrors.aliyun.com stretch-updates InRelease [91.0 kB] Get:2 http://mirrors.aliyun.com stretch-backports InRelease [91.8 kB] Get:3 http://mirrors.aliyun.com stretch/updates InRelease [94.3 kB] Hit http://mirrors.aliyun.com stretch Release.gpg Hit http://mirrors.aliyun.com stretch Release Get:4 http://mirrors.aliyun.com stretch-updates/main Sources [3911 B] ....
函数计算使用 apt-get 安装依赖是另外一类常见的安装问题,使用 fun install 也能够方便的安装。
$ fun install --runtime python3 --package-type apt libzbar0 skip pulling image aliyunfc/runtime-python3.6:build-1.2.0... Task => [UNNAMED] => apt-get update (if need) => apt-get install -y -d -o=dir::cache=/code/.fun/tmp libzbar0 => bash -c 'for f in $(ls /code/.fun/tmp/archives/*.deb); do dpkg -x $f /code/.fun/root; done;' => bash -c 'rm -rf /code/.fun/tmp/archives'
使用方法及其参数和 pip 包依赖相似,只须要将 --package-type
设定成 apt
, 包名使用平常 apt-get 能够安装的 deb 包名便可。
fun.yml 由一组 task 组成,执行 fun install 命令时会依次执行 task ,达到批量安装的效果。
fun.yml 的文件格式以下
runtime: python3 tasks: - name: install libzbar0 apt: libzbar0 local: true - name install Pillow by pip pip: Pillow local: true - name: just test shell task shell: echo '111' > 1.txt
runtime
是必填的字段。目前 task 有三种类型:apt, pip 和 shell。fun.yml 文件放置在 template.yml 文件中函数 codeUri 指向的目录,若是 template.yml 里声明了多个函数,而且放置在不一样的 codeUri 目录,须要建立多个 fun.yml 文件。
全部 task 的 name 字段是可选的,没有 name 字段的时候执行的时候会输出为
Task => [UNNAMED]
apt 和 pip 类型的 task 都是 install task 的子类型,描述格式相似
name: install libzbar0 apt: libzbar0 local: true
上面的 task 描述与下面的命令是等价的
fun install --package-type apt libzbar0
在使用 fun install 安装的过程当中,使用 --save
参数能够在当前目录的 fun.yml 文件中生成上面 task 的描述结构。
local
字段默认为 true,表示依赖会被装在当前目录的 .fun 子目录下,打包 zip 的时候回一并打包进去。设定为 false,依赖安装到系统目录,这种状况通常用于编译依赖,好比某个执行文件或者库是编译或者构建期须要的,运行期不要,那能够设定 local: false
,打包的时候会被忽略,不影响最终 zip 包的文件尺寸。
shell 类型的 task 是为基于源码编码的安装场景设计的。
name: install from source shell: ./autogen.sh --disable-report-builder --disable-lpsolve --disable-coinmp
下面是一个 python3 实现简单二维码识别程序部署到函数计算的例子。源码位于 https://github.com/aliyun/fun/tree/master/examples/install/pyzbar_example
本例子使用 pip 的 pyzbar 库进行二维码识别,pyzbar 依赖 apt-get 安装的 libzbar0 库。装载图片须要 pip 的 Pillow 库。因此 fun.yml 的文件描述以下
runtime: python3 tasks: - apt: libzbar0 local: true - pip: Pillow local: true - pip: pyzbar local: true
使用 fun install 安装依赖
$ fun install skip pulling image aliyunfc/runtime-python3.6:build-1.2.0... Task => [UNNAMED] => apt-get update (if need) => apt-get install -y -d -o=dir::cache=/code/.fun/tmp libzbar0 => bash -c 'for f in $(ls /code/.fun/tmp/archives/*.deb); do dpkg -x $f /code/.fun/root; done;' => bash -c 'rm -rf /code/.fun/tmp/archives' Task => [UNNAMED] => PYTHONUSERBASE=/code/.fun/python pip install --user Pillow Task => [UNNAMED] => PYTHONUSERBASE=/code/.fun/python pip install --user pyzbar
template.yml 文件内容以下
ROSTemplateFormatVersion: '2015-09-01' Transform: 'Aliyun::Serverless-2018-04-03' Resources: pyzbar-srv: Type: 'Aliyun::Serverless::Service' pyzbar-fun: Type: 'Aliyun::Serverless::Function' Properties: Handler: index.handler Runtime: python3 Timeout: 60 MemorySize: 128 CodeUri: .
index.py 文件内容以下:
from pyzbar.pyzbar import decode from pyzbar.pyzbar import ZBarSymbol from PIL import Image def handler(event, context): img = Image.open('./qrcode.png') return decode(img, symbols=[ZBarSymbol.QRCODE])[0].data
使用 fun local 在本地执行
fun local invoke pyzbar-fun skip pulling image aliyunfc/runtime-python3.6:1.2.0... Thalassiodracon RequestId: 964980d1-1f1b-4f91-bfd8-eadd26a307b3 Billed Duration: 630 ms Memory Size: 1998 MB Max Memory Used: 32 MB
Thalassiodracon
即为识别后的输出结果。
本文介绍了 fun 工具的一个新特性 fun install ,使用 fun install 能够方便的安装 apt 和 pip 软件包,对于屡次安装的工程化需求能够考虑将安装步骤持久化为 fun.yml 文件. fun.yml 文件提供了比命令行更多的功能,能够编写 shell 类型的 task,以支持源码安装的场景。能够经过设定 local: false
将依赖安装的系统目录,以解决编译依赖而非运行依赖的状况。
本文为云栖社区原创内容,未经容许不得转载。