背景简述
之前对serverless做了一些简单了解,一直在考虑怎么应用到项目中,恰好最近有个小项目,就尝试接入了midway-faas做初步实战
项目功能很简单,基于electron 开发一个跨平台的客户端,提供OCR功能,支持截图和第三方软件截图,支持文件上传
设计
client提供两种方式进行图文识别,一种是使用用户自己的百度token,直接调用百度api,另一种是通过http触发faas接口,在faas中通过我的token调用百度api,默认使用faas,用户可配置为使用自己的token直连
ps: 虚线部分待实现
研发
通过设计也可以看出,研发主要分client和faas,以下分别介绍
electron
- 简介 基于electron开发跨平台的客户端, 支持截图,api调用配置,客户端管理,文件拖拽等,electron详细开发见官方文档
- 设计
-
功能及ui
- 配置管理
- 截图
- 图片拖拽
- 截图复制
- 客户端退出或重启
-
处理问题记录
- net 模块封装
electron 提供了net模块,该模块是对nodejs http/https的封装,但相对来说还是比较原生,在封装post请求时,总提示
net::ERR_INVALID_ARGUMENT
,刚开始查的文档相关性不高,最后在官方的issue中找到,net中会自动补上content-length
- 页面布局 前端本来写的就菜,之前基于框架写功能还凑合,这次项目功能简单,想着少引入点依赖,减小client体积,就通过原生js,css,html来写了,结果各种坑鸭,想到的功能和布局,但不知道要用哪个css属性,大部分时间都花在了看文档和搜索上,磕磕绊绊算完成了
- 打包 基于electron/nwjs这种框架开发客户端,客户端真的是太大了,起步50M,在缩减体积上花了不少时间,但并没有减少多少,通过webpack打包压缩了源码,在electron-builder中使用了双package.json,分离了devDependencies,但打包后依然48M,想搜索了一些裁剪electron的方式,但没找到合适的方案,有处理方案的大佬,麻烦提供下
- net 模块封装
electron 提供了net模块,该模块是对nodejs http/https的封装,但相对来说还是比较原生,在封装post请求时,总提示
midway-faas
serverless从提出到现在,经历了概念火热(炒作)-冷静-探索合理场景-稳步实践和发展的过程,当前认可的serverless 架构是faas+baas,可参考上篇(serverless初探),和server mesh一样,新概念,新技术,总有待推广和验证,在合适的场景中发挥作用,提升产能,节约成本等。
当前serverless的生产实战,主要还是集中在大前端,以及一些非核心工具应用的实验,所以本次的工具应用,选择采用faas来实战serverless
- 简介
midway-faas是阿里开源的node faas框架,基于阿里开源的midway框架,它提供了跨云平台,云端一体化,传统node项目迁移到faas,以及快速开发和部署的功能
- 项目结构 midway-faas提供了 f 脚手架,可以快速生成选定的项目结构,最终项目结构如下
├── f.yml faas配置
├── package.json 依赖
├── src
│ └── index.ts 函数入口
| |── baiduOcr.ts 服务调用
└── tsconfig.json
- faas配置 项目配置如下,具体文档见f.yml,这里选择阿里云平台,触发器选择http
service: serverless-ocr # 应用名
provider:
name: aliyun ## 云平台
functions:
index: # 函数
handler: index.test # 函数入口
events: # 触发器
- http:
method: get # method
path: /test # path
accurate:
handler: index.accurate
events:
- http:
method: post
path: /accurate
package:
artifact: code.zip
-
功能 完成百度token获取和图文识别
-
处理问题记录
- request参数
之前已经走过一次midway-faas开发部署的流程,所以流程上坑不多,本地开发测试完成后,部署在云平台后,调用接口一直提示参数格式问题,在平台看日志要开通日志服务,要收费😅,我就没开,所以不好查问题,就麻烦midway开发者[@Harry Chen](https://github.com/czy88840616) 看了下,问题比较简单,代码中通过
const body = this.ctx.req.body
获取body参数,但云平台实际上会对参数做一些处理,处理结果放在 request对象上,所以在云平台上需要通过this.ctx.request.body
才能获取到,修改即可
- request参数
之前已经走过一次midway-faas开发部署的流程,所以流程上坑不多,本地开发测试完成后,部署在云平台后,调用接口一直提示参数格式问题,在平台看日志要开通日志服务,要收费😅,我就没开,所以不好查问题,就麻烦midway开发者[@Harry Chen](https://github.com/czy88840616) 看了下,问题比较简单,代码中通过
项目成品
- 截图
- 配置
- 系统管理
- ocr
性能和安全
-
性能测试 作了下,对faas接口进行了压测,结果没来得及付费(流量费用),欠费停服了,还好充完值立马恢复了,数据也还在
- 云平台faas配置 选择128M,单实例5并发的配置
- 函数计算的伸缩策略:
- 函数是在实例中执行的,正常情况下一个实例并发只执行一个请求,当并发有新请求来的时候就会自动扩容,执行完成后自动缩容。当然如果有刚才执行过请求的空闲实例,那这个实例是会被复用的。
- 支持单实例多请求,就是一个实例里可以并发执行多个请求,需要用户自己设置单实例多请求个数,比如 10 个,那就是这个实例中有 10 个请求的时候就会扩容。扩缩容都是函数计算自动处理的,用户是无感知的。
-
梯度测试 ab(s)模拟并发,进行接口性能测试
- 预期:随着并发量的增加,faas 自动扩容,支持越来越大的请求量,伴随压测结束,faas自动缩容,由于百度api调用总数和qps的限制,错误率越来越高
- 结果:
-
2c 1000n
-
5c 1000n
-
10c 1000n
-
50c 1000n
-
100c 1000n
-
300c 1000n
-
500c 1000n 500并发时,客户端报错退出,没有有效数据
-
-
函数指标
-
百度指标
以上可以看到,平台最低配置下,总请求量不变,随着并发量的增加
- 接口处理的平均耗时在增加;
- 总耗时,先降后升
- 错误率上升
- 所有错误均来自Length指标,结合百度api监控指标和阿里fc监控指标,可以推断,错误来自百度api限制,云函数实际上抗住了压力
ps: 上述测试方案的设计说服力有点不足,后期将百度api换成ocr开源的库后,再对比测试
综合以上测试,监控数据,可以看出,faas可靠性满足日常需求么的问题,关键是
按量付费,省钱啊
(见下图),总体部署,测试完成,仅用1元不到
,这对一些实验性项目,工具型,测试型的项目来说,实在是太划算了,这也是serverless的竞争优势
-
流控,安防 faas是依赖平台的,fass部署完成后,平台默认会提供一个可访问接口的域名,也可选择自定义域名,这里使用默认域名,这样接口就暴露在公网上,只要知道接口url(如果选择接口在外网可访问),就可以进行dos攻击,这样即使平台可以支撑攻击的流量,也是白白浪费资源,所以需要通过云平台提供的网关进行流控和安防,阿里云提供了公用api网关,可根据需要配置相应的网关策略
-
日志,监控 阿里云提供了faas对应的日志,通过开通日志服务(sls)即可查看应用日志,监控也一样,可以开通默认监控项之外的监控数据,具体看官网文档,以下是默认监控项
总结
待优化
- electron 当前设计的流程中,请求是由main进程发送,再将结果通过ipc发送给render进程,这不符合electron最优实践,main进程应该主要负责render进程的调度和管理,请求发送应该让render进程自行处理,eletron也支持配置跨域请求。
electron的体积大的问题,没能得到很好的解决,搞不了后面换Qt算了😅
-
ocr服务 当前ocr服务使用的是百度开放的api,免费版限制在50-50000次每天,QPS限制为2,个人使用肯定是够了,如果作为公用的工具型产品,可能会不够用,所以可以考虑通过开源的OCR库(如tesseract)在faas端处理图文,或者使用多个ocr平台的接口,依次使用
-
网关和监控策略完善 通过网关过滤恶意攻击,监控配置告警策略
项目地址
参考资料
大佬们多指教