# huaweicloud-Serverless-FunctionGraph-RedEnvelope-Python-Sample
**Repository Path**: HuaweiCloudDeveloper/huaweicloud-serverless-function-graph-red-envelope-python-sample
## Basic Information
- **Project Name**: huaweicloud-Serverless-FunctionGraph-RedEnvelope-Python-Sample
- **Description**: 华为云-开发者联盟-Serverles-FunctionGraph-RedEnvelope-Python示例代码
- **Primary Language**: Unknown
- **License**: Not specified
- **Default Branch**: master-dev
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 1
- **Forks**: 0
- **Created**: 2023-01-12
- **Last Updated**: 2023-04-14
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
# 华为云 FunctionGraph For Red Envelope项目演示
## 1. 说明
本项目将演示通过华为云FunctionGraph实现抢红包场景,让开发者上手体验FunctionGraph。
### 1.1 环境准备
* python3.9.2
* Pycharm 2022+
### 1.2 必备PyPI包
* influxdb==5.3.1
* kafka-python==2.0.2
* redis==4.3.4
* python-redis-lock==3.7.0
* python-socketio==5.7.2
* aiohttp==3.8.3
* aiokafka==0.8.0
### 1.3 基础云服务能力
* 分布式缓存服务(Distributed Cache Service,简称DCS)
更多详情,请参考 [分布式缓存服务 成长地图](https://support.huaweicloud.com/dcs/index.html)
* 高性能云数据库 GaussDB(for Influx)
更多详情,请参考 [GaussDB(for Influx) 成长地图](https://support.huaweicloud.com/influxug-nosql/nosql_05_0039.html)
* 分布式消息服务Kafka版
更多详情,请参考 [分布式消息服务Kafka版 成长地图](https://support.huaweicloud.com/kafka/index.html)
* 对象存储服务(Object Storage Service,OBS)
更多详情,请参考 [对象存储服务 OBS 成长地图](https://support.huaweicloud.com/obs/index.html)
* 云容器实例(Cloud Container Instance, CCI)
更多详情,请参考 [云容器实例 CCI 成长地图](https://support.huaweicloud.com/cci/index.html)
* API网关(APIG)
更多详情,请参考 [API网关 APIG 成长地图](https://support.huaweicloud.com/apig/index.html)
### 1.4 核心代码介绍
* api_grab/index.py 为抢红包的业务逻辑
* api_send/index.py 为发红包的业务逻辑
* util/config_center.py 为配置中心,负责加载环境变量中的配置信息
* util/influx_connect.py 为对influxdb的连接,可以对influx进行增删改查
* util/kafka_producer_connect.py 为kafka的生产者实现,负责连接kafka发送消息
* util/middleware.py 为中间件实现,通过python装饰器实现分布式锁规避在并发情况下,抢红包金额无法正确划分问题。
* util/redis_connect.py 为对redis的连接,实现对redis进行增查功能
* util/response_format.py 为响应的格式化,FunctionGraph配置APIG触发器响应格式是必须带有个别字段。
* util/aio_kafka_consumer_connect.py 异步kafka消费者实现,负责消费kafka消息。
* util/logger.py 日志模块。
* test_case/base64_param_encode.py 在FunctionGraph配置测试事件时,body需要通过base64加密。
* test_case/common.py 存放测试用的常量值。
* test_case/kafka_client_connect.py kafka主用户实现,负责topic的增删。
* test_case/kafka_consumer_connect.py kafka消费者实现。
* test_case/test_create_terminal_for_user.py 通过打开多终端模拟多个用户抢红包。
* test_case/test_many_user.py 用户运行逻辑。
* test_case/test_prepared.py 测试准备代码。
* websocket_app/app_asyncio.py.py 异步websocket_APP代码。
## 2.项目部署
### 2.1 本地必备程序
1. window10操作系统
2. 下载并安装[python3.9.2](https://www.python.org/downloads/release/python-392/) 。(注意安装后需要确认是否设置了python环境变量)
3. 下载并安装[Pycharm 2022+](https://www.jetbrains.com.cn/en-us/pycharm/)
4. 下载并安装[node.js 16.17.0](https://nodejs.org/dist/v16.17.0/) 。(
注意安装后需要确认是否设置了node.js环境变量)
### 2.2 基础环境搭建
1. 创建虚拟私有云 VPC ([快速入门](https://support.huaweicloud.com/qs-vpc/vpc_qs_0001.html))
2. 购买分布式缓存服务 DCS ([快速入门](https://support.huaweicloud.com/dcs/index.html))
3. 购买云数据库 GaussDB(for Influx) ([快速入门](https://support.huaweicloud.com/influxug-nosql/nosql_05_0039.html))
4. 购买分布式消息服务Kafka版 ([快速入门](https://support.huaweicloud.com/kafka/index.html))
5. 购买API网关专享版([快速入门](https://support.huaweicloud.com/apig/index.html))
### 2.3 部署(两个函数部署方式一致,创建的委托等资源可以复用)
1. 拉取代码
* git拉取代码,示例:
>cd D://
git clone https://gitee.com/HuaweiCloudDeveloper/huaweicloud-serverless-function-graph-red-envelope-python-sample.git
* 进入[代码仓](https://gitee.com/HuaweiCloudDeveloper/huaweicloud-serverless-function-graph-red-envelope-python-sample) ,下载代码zip文件,解压zip文件到任意文件夹。

2. 创建函数
步骤一

步骤二

3. 创建委托
步骤一

步骤二

步骤三 可以根据函数所需云服务定制权限限制的权限,Tenant Administrator为除了iam用户权限所有云服务权限。函数主要用到服务有DIS,DMS以及VPC的访问权限

步骤四 选择已创建的委托,并点击保存

4. 上传函数
步骤一

步骤二

5. 设置VPC
步骤一 建议选择与其他服务实例(Kafka, redis, influxdb)相同的VPC及子网,并点击保存

6. 设置环境变量

注意:环境变量填写完,请点击保存。
KAFKA_CLUSTERS

注1:KAFKA_CLUSTERS的值格式应为["ip:port", "ip:port"], 例["110.110.111.11:9092", "110.110.111.12:9092"]
REDIS_HOST、REDIS_PORT、REDIS_PASSWORD

注1:REDIS_PASSWORD为创建服务实例时设置密码
注2:这里的Redis服务是分布式缓存服务 Redis版
INFLUX_HOST、INFLUX_PORT、INFLUX_USERNAME、INFLUX_PASSWORD

注1:INFLUX_PASSWORD为创建服务实例时设置密码
7. 绑定API网关专享版触发器
步骤一 创建触发器

步骤二 选择APIG专享版

步骤三 创建成功

8. 制作依赖/上传依赖
步骤一 制作依赖(本步骤可以选择跳过,已有制作好的依赖包直接上传,red_envelope_function\dependency.zip)
环境准备:制作函数依赖包推荐在EulerOS环境中进行,原因函数执行的操作系统为EulerOS,使用其他系统打包可能会因为底层依赖库的原因,运行出问题,比如找不到动态链接库。
编写requirements.txt文件。
> vi /tmp/requirements.txt
将所有需要的包写入其中,例:
```
influxdb==5.3.1
kafka-python==2.0.2
redis==4.3.4
python-redis-lock==3.7.0
requests==2.28.1
```
安装第三方依赖包
> pip install -r /tmp/requirements.txt --target=/tmp/dependency -i https://repo.huaweicloud.com/repository/pypi/simple --extra-index-url=https://pypi.tuna.tsinghua.edu.cn/simple --extra-index-url=https://pypi.mirrors.ustc.edu.cn/simple/ --trusted-host pypi.tuna.tsinghua.edu.cn --trusted-host pypi.mirrors.ustc.edu.cn
注意:可能会出现个别包版本不存在的情况,可以尝试更改-i参数后面的镜像源地址
切换到依赖包的安装目录
> cd /tmp/dependency
打包所有依赖到zip文件(zip找不到,下载并安装zip)
> zip -rq dependency.zip *
下载dependency.zip到本地
步骤二 上传依赖




### 2.4 测试
> **测试前准备**
> 步骤一 购买NAT网关,并通过NAT网关开通DNAT规则,让本地PC可以访问Kafka及influxdb。(假设使用的同VPC下的ECS,该步骤可跳过,可使用各服务实例的内网地址)
> 
> Kafka内网IP三选一
> 
> 
> Influxdb内网IP二选一
> 
> 步骤二 添加本地PC环境变量
> 
> KAFKA_CLUSTERS变量值填入"[弹性公网ip:公网端口]",例如"101.0.0.1:9090"(具体值在下一张图)
> 
> 
> INFLUX_HOST
> 
> INFLUX_PORT
> 
> 
> INFLUX_USER,INFLUX_PASSWORD如上操作,为创建influxdb时设置账户密码。
> 步骤三 代码创建influxdb中databases。
> 
> 注意:运行程序时环境变量没生效请重启Pycharm
> 注意:报错找不到相关依赖,请打开Pycharm终端执行命令 pip install -r requirements.txt
> 步骤四 代码创建kafka中topic(如果已设置自动创建topic可以忽略此步骤)。
> 
1. 发红包函数测试
步骤一 配置测试事件
进入send_api函数编辑页面,点击测试及配置测试事件。

运行项目中test_case/base64_param_encode.py,复制base64加密参数。

加密参数粘贴至body部分,修改httpMethod为POST。

步骤二 测试
注意:首次测试时,会因为创建连接的原因,运行时间相对较久,导致函数超时。需要设置执行超时时间。例:

步骤三 验证结果

2. 抢红包函数测试
步骤一 配置测试事件
进入grab_api函数编辑页面,点击测试及配置测试事件。

运行项目中test_case/base64_param_encode.py,修改红包id,复制base64加密参数。

加密参数粘贴至body部分,修改httpMethod为POST。

步骤二 测试
注意:首次测试时,会因为创建连接的原因,运行时间相对较久,导致函数超时。需要设置执行超时时间。例:

步骤三 验证结果

3. 接口测试
步骤一 进入APIG界面,点击进入专享版控制台
[API网关](https://console.huaweicloud.com/apig)

步骤二 创建应用

步骤三 绑定API

步骤四 选定两个已创建API

步骤五 点击调试

步骤六 调试发红包API

步骤七 调试抢红包API

4. 模拟多用户,开始监听消费队列
步骤一 修改 项目根路径/test_case/common.py常量值

API网关公网IP

接口路径(发红包接口同理)


步骤二 允许接口简易认证(两个接口都需要操作)
进入接口页面

点击编辑

开启支持简易认证,点击立即完成

点击发布API

选择环境,点击发布

步骤三 添加应用AppCode
选择自动生成

步骤四 将生成的AppCode及域名host写入访问请求头
域名host



步骤五 多进程模拟用户监听红包消息


5. 模拟用户发送红包
点击运行

成功发送

抢红包场景模拟成功

6. 页面交互测试
* 本地部署
> 前提条件
> 1. 本地已配置KAFKA_CLUSTERS环境变量,并测试连接成功
>
步骤一 运行Websocket APP

步骤二 修改 项目根目录/red_envelope_front/.env.development 文件

注意:VUE_APP_DOMAIN可以使用API分组自动生成的子域名,因子域名没有备案请参考2.5 常见问题 3 进行相关操作
步骤三 新建终端,运行前端代码
> cd red_envelope_front
>
> npm install
>
> npm run dev
>

步骤四 打开Chrome浏览器,访问前端页面

步骤五 测试各功能

* OBS + CCI + DNS + APIG部署
> 项目描述
通过OBS托管静态页面,CCI部署WebSocket APP,APIG统一后端服务入口。因OBS无法通过Nginx作为代理服务器代理转发请求,
所以需要两个域名分别解析前端页面及APIG网关,通过浏览器访问时,会出现跨域问题。
>
> 前提条件
> 1. 拥有已备案通过的公网域名,详见[域名注册](https://support.huaweicloud.com/domain/index.html)
> 2. CCI, APIG, KAFKA, INFLUXDB, REDIS都在同一个VPC内
>
步骤一 制作WebSocket APP镜像及CCI部署WebSocket APP(操作在linux环境下完成)
拉取代码
> cd /tmp
> git clone https://gitee.com/HuaweiCloudDeveloper/huaweicloud-serverless-function-graph-red-envelope-python-sample.git
进入项目根目录
> cd huaweicloud-serverless-function-graph-red-envelope-python-sample
>
登录华为云SWR(可在SWR总览右侧登录指令复制登录命令)
> docker login xxx
>
注意:留意所在Region
> docker build -t red_envelope_websocket:test .
> docker tag red_envelope_websocket:test swr.cn-south-1.myhuaweicloud.com/{组织名}/red_envelope_websocket:test
> docker push swr.cn-south-1.myhuaweicloud.com/{组织名}/red_envelope_websocket:test
>
注意:请根据自定义组织名修改命令行中组织名
CCI页面操作步骤,单击创建无状态负载

注意:因业务逻辑原因,POD数量只需1个。


步骤二 WebSocket APP绑定APIG接口



后端服务地址于websocket工作负载页面-访问配置-内网访问地址,如下图:



步骤三 APIG绑定域名



步骤四 修改 项目根目录/red_envelope_front/.env.production 文件

步骤五 构建前端代码
通过PyCharm新建终端,切换目录
> cd red_envelope_front
>
> npm run build
>
步骤六 上传前端代码至OBS(建议通过[OBS Browser+](https://support.huaweicloud.com/intl/zh-cn/browsertg-obs/obs_03_1003.html) 上传)


步骤七 配置静态页面托管


步骤八 配置自定义域名


步骤九 DNS解析


OBS静态页面域名,如下图:

步骤十 配置跨域预校验OPTION请求





步骤十一 打开Chrome浏览器,访问前端页面

步骤十二 测试各功能

### 2.5 常见问题
1. 实例需要打开对应的端口安全组入方向规则,让各服务之间可以互相访问。
2. 导致各数据库或消息队列实例连接超时原因,一般为安全组入方向规则没有打开或者打开错误。
3. 未备案域名,服务器配置IP映射域名。
> * windows
>> 修改 C:\WINDOWS\system32\drivers\etc\hosts 文件。
>> 
>> 打开cmd,测试域名是否能访问。
>> ```
>> ping 域名
>> ```
>> 
> * linux
>> 修改 /etc/hosts 文件。
>> ```
>> vim /etc/hosts
>> ```
>> 
>> ```
>> ping 域名
>> ```
>> 
>
> 注意:域名是网址的组成部分,例如http://localhost.com/test 中localhost.com为域名