HarmonyOS开发者限时福利来啦!最高10w+现金激励等你拿~ 了解详情
写点什么

如何定制化开发 Serverless Framework 的 Component ?

  • 2020-08-09
  • 本文字数:2642 字

    阅读完需:约 9 分钟

如何定制化开发Serverless Framework的Component ?

在使用 Serverless Framework 开发者工具时,无论是哪家云计算运营商与社区都会提供很多组件供我们选择。虽然这些组件可以在一定程度上解决绝大部分问题,但是在某些时候,我们还可能存在一些定制化需求,那么这个时候可能就需要我们自己来定制化开发 Component。

开发一个全局变量组件

Serverless Framework Plugin 是可以设置全局变量,在之后的一些引用中可以直接使用全局变量。但是在 Component 中没有全局变量的概念,这就导致一个问题:如果有多个函数,每个函数都有数据库的配置,难道是要把数据库的配置写多次吗?


有人说,不用写多次,我们完全可以使用.env来解决这个问题。例如,在每个函数中通过include引入某个未知的.env,将一些配置信息放到这里,就可以解决这个问题。


但是这会引发新的问题,如果有多个.env文件怎么处理?例如,有一个.env.test,还有一个.evn.dev,那么是要批量替换这个引入的文件,还是修改文件名?所以,在稍微复杂一点的环境中,还是需要一个全局变量来控制一些事情。


通过实现一个 Component 来解决全局变量问题,解决全局变量问题再与.env方案结合,我认为是在生产中获得更大便利的最优解:


  • 首先第一步,需要明确组件具体功能:


实现一个全局组件,用户可以配置全局信息,之后的项目可以以直接引用,如果有修改,直接修改全局变量的配置就好。


  • 接下来明确yaml的结构:


这个结构相对来说就很自由了,我的设想是:


GlobalComponent:  component: 'serverless-global'  inputs:    key: value
复制代码


其中,组件名称是serverless-global,组件的字段可以自定义,主要就是key-value形式。


  • 然后是针对功能和yaml定义动作,主要动作是,在程序执行时,将用户定义的key-value完整输出,这样用户就可以在其他组件中引用,例如:


GlobalComponent:  component: 'serverless-global'  inputs:    region: ap-beijing    ScfComponent_1:  component: '@serverless/tencent-scf'  inputs:    region: ${GlobalComponent.region}    ScfComponent_2:  component: '@serverless/tencent-scf'  inputs:    region: ${GlobalComponent.region}
复制代码


  • 最后就是项目的开发。


一个标准的 Serverless Component 格式是这样的:


// serverless.jsconst { Component } = require('@serverless/core')class MyComponent extends Component {  /*   * default (必须) : 执行命令 `$ serverless` 会运行此函数   */  async default(inputs = {}) {    return {}  }
/* * remove (可选) : 执行命令 `$ serverless remove` 会运行此函数, 如果在default中保存了状态,那么此处也必须要存在,否则会报错 */ async remove(inputs = {}) { return {} }
/* * others (可选):其他功能 */ async others(inputs = {}) { return {} }}module.exports = MyComponent
复制代码


对于 GlobalComponent 而言,是不是只需要把用户的输入内容(input),输出就好?


全局变量组件第一个版本的代码如下:


// serverless.jsconst { Component } = require('@serverless/core')class GlobalComponent extends Component { async default(inputs = {}) {   return inputs }}module.exports = GlobalComponent
复制代码


由于在实际生产中,全局变量组件可能会有一些额外用法,例如是否可以在全局变量组件中直接引入某些 Yaml 等操作?…



这种做法是比较常见的,因为可能存在多套配置,完全可以在这里进行不同配置文件的引入。


我们可以对上面的代码进行进一步完善:


// serverless.jsconst { Component } = require('@serverless/core')const yamljs = require('yamljs')
class GlobalComponent extends Component { async getOutput(inputs = {}, output) { const reg = /\${file\(.*?\)}/g for (const key in inputs) { const regResult = reg.exec(inputs[key]) if (regResult) { const inputPath = inputs[key].slice(7, -2) // const file = inputPath[0] == '/' ? inputPath : path.join(process.cwd(), inputPath) const yaml = yamljs.load(inputPath) const jsonStr = JSON.stringify(yaml) const jsonTemp = JSON.parse(jsonStr, null) if (jsonTemp) { output[key] = await this.getOutput(jsonTemp, {}) } } else { output[key] = inputs[key] } } return output }
async default(inputs = {}) { const output = {} await this.getOutput(inputs, output) return output }}
module.exports = GlobalComponent

复制代码


至此,我们就完成了一个全局变量组件的开发。


  • 当然除了上面说的这种简单组件,在开发过程中,我们还会有一些其它需要注意的点:


  1. Serverless Framework Component 是会生成一个缓存目录.serverless,这个缓存文件怎么来的?


this.state = {}await this.save()
复制代码


可以通过上面的方法,将需要缓存的内容放入{}中,进行缓存。


  • 如何引用其他组件?


const othersComponent = await this.load('@serverless/tencent-scf', 'scf-component');
复制代码


这其中有两个参数,一个是组件的名字:@serverless/tencent-scf,另一个是本次引用的名字:scf-component,本次引用的名字怎么理解?其实就是这样,在缓存目录会生成很多组件,例如:



这是部署一个 express 之后生成的缓存目录,这里面可以看到有文件叫这个名字:Template.express.TencentFramework.apigateway.ap-guangzhou-apigateway


针对这条记录而言,其引用层为:


tencent-express 组件->tencent-framework->tencent-apigateway-mutil-region->tencent-apigateway


那么每段含义:


Template: 此处是一个统一的开头


express: 这个组件在 Yaml 中的名字



TencentFramework: 在 tencent-express 引用了 tencent-framework 时候,给本次引用的名字(可以不填写,不填写会默认)


apigateway: 在 tencent-framework 引用了 tencent-apigateway-mutil-region 时,给它的本次引用的名字(可以不填写,不填写会默认)


ap-guangzhou-apigateway: 在 tencent-apigateway-mutil-region 引用了 tencent-apigateway 时,给它的本次引用的名字(可以不填写,不填写会默认)


这样做的目的是为了让我们在进行移除等操作时,可以更好的找到资源信息。

总结

正如文章开始所说,我们在做一个项目的时候,社区和官方提供给我们的能力基本是通用的,可能无法很好地满足定制化需求,那么这个时候,我们就可以通过文中的方法开发出自己的组件。


当然有些时候,官方或者社区没有提供某种组件,我们也可以开发,成为一个贡献者。


2020-08-09 23:351836

评论

发布
暂无评论
发现更多内容

sqlserver锁表产生的原因

linux大本营

数据库· SQL sever 表锁

c语言把8个char类型的值(char中存放的是16进制值)转换成一个int类型代码

linux大本营

C语言 char int

软件测试/测试开发丨Linux 常用高频命令

测试人

Linux 软件测试 自动化测试 测试开发

从“捐赠”到“接受捐赠”,这背后是openEuler的两次蜕变

Geek_2d6073

在毫秒量级上做到“更快”!DataTester助力飞书提升页面秒开率

字节跳动数据平台

大数据 AB testing实战 用户体验 企业号 4 月 PK 榜 秒开率

c++实现一个tcp高性能网络服务器

linux大本营

TCP 多线程 异步IO epoll 高性能服务器

一个解决tcp粘包问题的c++代码

linux大本营

TCP 网络协议 C++ TCP 粘包

洞见数字时代的创新原力,数云原力大会暨 2023TECH 第五届数字中国技术年会开幕

通明湖

升级企业数智化底座是数智化2.0阶段的“最优解”

用友BIP

用友iuap 用友技术大会 数智化底座 数智化2.0阶段

用友自主研发企业商用版TimensionDB时序数据库重磅发布!

用友BIP

数据库 用友iuap 用友技术大会 升级企业数智化底座

linuxc获取文件内容

linux大本营

Linux

攻防大牛在身边,2023首届阿里云CTF 大赛冠军揭晓

Lily

Springboot之如何纯文本转成.csv格式文件?|超级详细,建议收藏

bug菌

Spring Boot 2 spring-boot 三周年连更

awk常量和标识符

linux大本营

脚本 awk

大连理工大学OpenHarmony技术俱乐部正式揭牌成立

Geek_2d6073

sougou的workflow的10个技术点

linux大本营

workflow 异步框架 C++

5.10版本的linux内核create_boot_cache函数解析

linux大本营

Linux内核

如何系统地学习Spring Boot?

博文视点Broadview

PVP2多屏幕演示投放软件:PVP2 ProVideoPlayer2 中文版

真大的脸盆

Mac Mac 软件 视频播放器 视频播放

招商基金数字化转型下的研发管理|标杆案例

万事ONES

5.10版本的linux内核setup_kmalloc_cache_index_table函数解析

linux大本营

内存管理 内存泄漏 Linux内核

用AI赋能基础教育,小度人工智能青竹公开课现已走进6所知名小学

科技热闻

在 Kubernetes 中实施零信任的七条准则

NGINX开源社区

nginx Kubernetes

Wallys/QSDK/IPQ4019 and IPQ4029 chipsets support 20 km remote transmission

Cindy-wallys

IPQ4019 ipq4029

设计模式天花板,详解23种设计模式+7大设计原则

小小怪下士

Java 程序员 设计模式

用c++写一段快速排序算法

linux大本营

排序算法 数据结构与算法 C++

强强联手:机器学习与运筹学

鼎道智联

算法

5.10版本的linux内核pgtable_init函数解析

linux大本营

Linux内核

c++生成pdf

linux大本营

C++ libHaru

HSM加密机集群&监控方案

白粥

监控 集群 加密机

DataX助力Oracle数据库迁移

白粥

数据迁移 DataX

如何定制化开发Serverless Framework的Component ?_服务革新_刘宇_InfoQ精选文章