自定义函数与依赖包解耦下发
1、背景描述
在使用边缘函数时,边缘函数常常需要使用import
来引用第三方依赖。本文将介绍如何将依赖包上传至对象存储,以及如何在编写函数代码时直接引用依赖包。本文将以 Python3.6 为例进行说明。
2、本地测试代码开发
在将代码上传到云端前,我们需要先在开发机上开发和测试代码。
2.1、测试用例说明
我们编写的用例是获取 https://cloud.baidu.com/ 的 headers 信息
2.2、用例代码
新建一个代码文件,命名为 index.py
,代码如下:
1#!/usr/bin/env python3
2# -*- coding: utf-8 -*-
3
4import requests
5
6def handler(event, context):
7 """
8 data: {"action": "A"}
9 """
10 if 'action' in event:
11 if event['action'] == 'A':
12 r = requests.get('https://cloud.baidu.com/')
13 if str(r.status_code) == '200':
14 event['info'] = dict(r.headers)
15 else:
16 event['info'] = 'exception found'
17 else: event['info'] = 'action error'
18 else:
19 event['error'] = 'action not found'
20
21 return event
2.3、依赖包整理
在用例代码当中,我们我们看到使用了 requests
库,我们需要把 requests
这个依赖包下载下载。在本地新建一个文件夹python3-request
,进入到文件夹内,执行request下载命令。
1# 进入python3-request文件夹
2cd python3-request
3# 下载request库
4pip3 download requests
执行过程如下图所示:
下载完成之后,我们发现文件夹内有多个 .whl
结尾的压缩包,如下图所示:
解压 .whl
压缩包,得到源码。
1unzip -d . "*.whl"
这样我们就得到了源码,但压缩包和 .dist-info
并不是我们所需要的,为了使文件体积尽量的小,我们可以把这些文件删除,执行以下命令:
1rm -rf *.whl *.dist-info
执行完毕以后,就只剩下request依赖包以及request自身的依赖,如下图所示:
执行压缩命令,得到request依赖包的zip文件
1# 进入python3-request文件夹
2cd python3-request
3# 将当前目录下的所有内容压缩到python3-request.zip文件当中
4zip -r python3-request.zip ./*
2.4、函数本地测试
在上传python3-request.zip依赖包之前,
我们可以先做一个简单的测试,看下 index.py
是否可以正确的输出我们想要的header。
1、将 index.py
copy到python3-request
目录下。
2、在python3-request
目录下新建一个 test.py
文件,代码内容如下:
1import index
2
3event = {}
4event['action'] = "A"
5print(index.handler(event, ""))
3、执行python3 test.py
查看输出结果。可以看到正确输出了我们想要的 handler 内容,如下图所示:
2.5、上传依赖包至对象存储
将 python3-request.zip
上传到云端 对象存储,可点击此处下载。
3、创建配置项
3.1、创建配置项python3-request-package
创建配置项python3-request-package
,该配置项为函数依赖包,配置项信息如下图所示:
- 类型:HTTP
- URL:https://bie-document.gz.bcebos.com/baetyl-function/python3-request.zip
- 文件名称:python3-request.zip
- 是否解压:是
3.2、创建函数python-code-1
创建函数python-code-1,如下图所示:
函数代码是在本地测试代码index.py基础上做的修改,代码如下所示:
1#!/usr/bin/env python3
2# -*- coding: utf-8 -*-
3
4import sys
5sys.path.append("/var/lib/baetyl/python3")
6import requests
7
8def handler(event, context):
9 """
10 data: {"action": "A"}
11 """
12 if 'action' in event:
13 if event['action'] == 'A':
14 r = requests.get('https://cloud.baidu.com/')
15 if str(r.status_code) == '200':
16 event['info'] = dict(r.headers)
17 else:
18 event['info'] = 'exception found'
19 else: event['info'] = 'action error'
20 else:
21 event['error'] = 'action not found'
22
23 return event
可以看到,多了如下两行代码,改代码主要是用于引用依赖包函数。
1import sys
2sys.path.append("/var/lib/baetyl/python3")
4、应用创建
1、创建函数应用bie-python
2、配置函数应用,如下图所示:
基本信息
- 函数配置项:选择前面创建的python-code-1
- 运行时:选择python3
函数列表
- 函数名称:process
- 函数入口:index.handler,因为python-code-1函数的名称是index.py,函数当中定义了handler,所以此处为index.handler
- 容器目录:
.
,使用点号,表示当前目录卷配置
- 前三个是默认配置卷,不用修改
- 添加一个配置项,选择前面创建的
python3-request-package
,卷名称也使用python3-request-package
即可。
5、创建测试边缘节点
1、新建一个边缘节点,开通baetyl-rule和baetyl-function两个系统应用,如下图所示:
2、将bie-python这个函数应用部署到测试节点,部署完毕以后的应用清单如下图所示:
6、配置 baetyl-rule
在节点"应用部署"菜单栏,选择 baetyl-rule 模块,点击查看。
然后点击数据卷,选择第一个配置项进行配置。
baetyl-rule 的配置如下:
1rules:
2 - name: rule1
3 source:
4 topic: broker/topic1
5 target:
6 topic: broker/topic2
7 function:
8 name: bie-python/process
9
10logger:
11 level: debug
12 encoding: console
函数的完整路径是 服务名称/函数入口
,则上述函数的调用路径为bie-python/process
。
7、配置 baetyl-broker
参考 baetyl-rule 应用的配置方法,同步配置 baetyl-broker 应用。
修改broker-conf配置文件,配置内容如下:
1session:
2 sysTopics:
3 - $link
4 - $baetyl
5logger:
6 level: debug
7 encoding: console
8listeners:
9 - address: 'tcp://0.0.0.0:8883'
10principals:
11 - username: test
12 password: test
13 permissions:
14 - action: pub
15 permit:
16 - '#'
17 - action: sub
18 permit:
19 - '#'
为 baetyl-broekr 添加一个8883:8883
的端口映射,将baetyl-broker服务暴露到宿主机上,边缘通过MQTT-BOX进行测试
8、端侧验证
等待上述服务部署到端侧后,我们使用 mqttbox 发送消息到 baetyl-broker 来进行测试。
1、首先我们使用 mqttbox 连接,连接信息如下:
2、连接成功后,可以看到Connected,如下所示:
3、点击Add Subscriber,订阅broker/topic1
和broker/topic2
两个topic。
4、在上图的Payload处,输入 {"action":"A"}
,然后点击Publish。然后可以在broker/topic2
处看到我们请求的
https://cloud.baidu.com/ 的 header 内容。如下图所示: