天天看点

Serverless Devs 介绍

开篇

2020年11月份,阿里云智能开源了Serverless 社区的开发者工具Serverless Devs(后简称S) 弥补了国内在Serverless 开发者工具的一个空白。通过高度灵活的配置设定,实现了无厂商锁定的支持;直观易懂的可视化配套也带来了极致的开发者使用体验。

通过S你可以体验Serverless hello world 以及 构建生产级Serverless 应用 。你也可以尽情发挥自己的创意,在S 这个平台上为更多的开发者贡献自己的 应用和组件。本篇将会从整个技术架构视角为你揭开S的神秘面纱,希望通过本篇文章可以帮助你了解S的核心设计理念和实现的基本原理,在类似的可扩展应用设计中带来一些解题思路。

S外貌 - 功能结构全景展示

为了更方便的讲解,我们可以先看看S的全景图

Serverless Devs 介绍

如上图所示S 核心构成大致分成了5部分,他们分别是

1 - 核心启动器 ;

2 - GUI 图形界面 ;

3 - 核心组件库s/core和 实现fc部署的 s-framework ;

4 - 应用中心;

5 - 以FC 为基础的Serverless 服务接口。

其中 1,2,3是完全开源开放的,4,5则目前由阿里云云原生团队提供经费负责维护。

值的一提的是,S工具侧服务端应用以及S的社区接口服务都是依赖阿里云函数计算产品,稳定性,可靠性,安全,可观测等能力皆由其保障。

S整个服务侧的开发都专注在业务域,服务端的开发模式基本就是在线撸码,在线构建,在线发布,在线版本管理。 这样的模式为我们的快速迭代发布提供了有力的保障(从开始到第一个版本的研发结束时间至少缩短一周)

接下来的重点介绍会集中在1,2,3部分。在这之前,为了方便更好的理解S的执行过程,我们就先说一说S的灵魂-- 配置约定部分

S灵魂-配置约定

S的配置文件包括 应用/组件 , 秘钥信息,缓存信息。其中应用/组件 是最核心的部分,也是构成整个生态体系最主要的部分。

我们先看一个hexo博客应用的配置文件

HexoComponent:  # 主体(唯一键)
  Component: hexo  # 组件名
  Provider: alibaba # 供应商
  Extends: # 扩展能力
    deploy: # 针对deploy 的扩展
      - Hook: npm install --production
        Path: ./src
        Pre: true
      - Hook: npm run build
        Path: ./src
        Pre: true
  Properties: # 属性配置
    Region: cn-hangzhou
    CodeUri: ./src
    Detail:
      Service:
        Name: hanxiedemo
  Access: hanxie  #访问秘钥           

S启动器可以解读这个配置然后把一个hexo 的博客系统部署到 函数计算上。这个配置本身没有任何处理逻辑,仅是资源和配置描述,他表达的是这样一件事:

主体HexoComponent ,利用 阿里云提供的 hexo 组件以及客户自身在阿里云的秘钥 解锁了部署本地博客应用FC产品的操作。此外,解锁这个部署操作需要的配套参数 Properties以及执行部署前的指令集也可以被描述进去完善部署操作本身。

在这样的范式定义下,配合真正执行逻辑的组件,即可完成各种复杂的操作。当然,软件应用的真实场景会比这个hexo应用要更复杂,可能会由多个具备独立业务逻辑的步骤而成,并且可能有前后的依赖,针对这种情况,我们来看一下如何配置:

Global: # 全局变量
  Access: release
  Region: cn-beijing
  AccessKeyId: '${Env(AccessKeyId)}'
  AccessKeySecret: '${Env(AccessKeySecret)}'
  OSSConfBucketSourceName: serverlessbook-image-source
  OSSConfBucketTargetName: serverlessbook-image-target
  OSSConfObjectSignUrlTimeOut: 1200
SourceBucket: # 存储源主体
  Component: oss
  Provider: alibaba
  Access: hanxie
  Properties:
    Region: '${Global.Region}'
    Bucket: '${Global.OSSConfBucketSourceName}'
    CodeUri: ./test
TargetBucket: # 存储目标主体
  Component: oss
  Provider: alibaba
  Access: hanxie
  Properties:
    Region: '${Global.Region}'
    Bucket: '${Global.OSSConfBucketTargetName}'
    Acl: public-read
ServerlessBookImageDemo: # 执行转化逻辑主体
  Component: fc   # 执行转化逻辑详情
  Provider: alibaba
  Access: hanxie
  Extends:
    deploy:
      - Hook: s ServerlessBookImageDemo install docker
        Src: ./src
        Pre: true
  Properties:
    Region: '${Global.Region}'
    Service:
      Name: ServerlessBook
      Description: Serverless图书案例
      Log:
        Project: aliyun-fc-cn-beijing-9bd4a65b-c9d1-529d-9ce0-c91adfb823ab
        LogStore: function-log
    Function:
      Name: serverless_image
      Description: 图片压缩、水印
      CodeUri: ./src
      Handler: index.handler
      MemorySize: 128
      Runtime: python3
      Timeout: 5
      Environment:
        - Key: AccessKeyId
          Value: '${Global.AccessKeyId}'
        - Key: AccessKeySecret
          Value: '${Global.AccessKeySecret}'
        - Key: OSSConfBucketSourceName
          Value: '${SourceBucket.Output.Bucket}'
        - Key: OSSConfBucketTargetName
          Value: '${TargetBucket.Output.Bucket}'
        - Key: OSSConfEndPoint
          Value: '${SourceBucket.Output.Endpoint.Publish}'
        - Key: OSSConfObjectSignUrlTimeOut
          Value: '1200'
      Triggers:
        - Name: OSSTrigger
          Type: OSS
          Parameters:
            Bucket: '${SourceBucket.Output.Bucket}'
            Events:
              - 'oss:ObjectCreated:*'
            Filter:
              Prefix: ''
              Suffix: ''
           

这是一个图片Ai处理的应用,基本逻辑就是ServerlessBookImageDemo主体,从已有的OSS存储上拿到源图片文件,经过一系列步骤流程操作,转存到目标OSS。为了配合完成这些操作,提前设定好了各种授权配置。并把他们作为全局变量供给3个主体去调用,可以看到,这个复杂配置描述了独立的执行逻辑之间如何协同调用。配置文件通过 “${}”的语法糖描述动态变量,S可以自动解析装配,除此之外 S可以根据调用关系自动识别配置文件中主体的先后执行顺序 ,意味着你只需要关注每一个主体的输入和输出,而不用为他们各自的执行先后去做特殊编排。

讲到这里你或许还是很迷惑,因为配置看起来很复杂,这是因为入参部分也就是Properties 完全属于自定义范畴,所以可以延展的非常复杂(实际上我们有针对这类配置的可视化解决方案,稍后会介绍),但是除了这个,配置文件还是有自己的固定范式(划重点)

首先 最外层的Key (我称为主体),只有2类,一类Global,另一类就是唯一的键名,比如上面的SourceBucket,TargetBucket,ServerlessBookImageDemo;

其次非Global 主体 的范式也是固定的:

  • Component - 核心执行逻辑组件;
  • Provider - 服务商 ;
  • Access-访问秘钥配置;
  • Extends - 主体执行指令的扩展,它包括对应指令执行前后的要做什么操作;
  • Properties - 输入参数,注意这个输入参数是给 Component 使用的。

所以你只要掌握上面划线部分的内容,这些配置文件再复杂也能快速识别出他的主体逻辑。

为了解决复杂配置的问题社区还提供了配套的可视化方案,简化开发者和使用者的配置使用

Serverless Devs 介绍

① 启动器

S 启动器是 serverless devs 最核心的部分,我们经常比喻说Serverless Devs 可以让开发者像使用手机一样玩转Serverless,这个手机的OS 就是说的S 启动器本器,他负责完成配置文件解析,组件加载,任务调度,日志输出,发布管控,国际化等能力。

灵活的指令集

我们说S启动器也是一个灵活的“瘦子”,是因为虽然他支持各种指令自定义,但实际上内置指令只有

init, config, platform, search, set, gui 这六个,通过将配置文件的主体和指令动态加载到内核实现这个骚操作。就举上面水印处理的例子,如果我们在项目外敲 S 这个指令,

输出的只有上面提到的6个指令

Serverless Devs 介绍

但是如果在水印项目的目录下则会有9个

Serverless Devs 介绍

如果再进一步的展开 s ServerlessBookImageDemo 则会继续把ServerlessBookImageDemo主体下的指令全部列举出来,这样的好处就是可以针对单个主体做功能调用,这里面列出来的指令实际上是主体下组件包含的真实方法。当然也有坏处,就是不利于做规范约束,那么针对目前的配置问题社区也正在讨论新的

规范

,欢迎大家一起加入

Serverless Devs 介绍

开发者可以通过开发自己的组件并将它的方法执行通过s 指令的方式触发。

动态的执行解析

当我们使用s deploy 指令的时候,启动器会先把 deploy 指令预加载到系统指令里,

接下来会自动触发 deploy的执行,可以简述为:

预先对配置文件进行解析,分离出变量元素,并进行对应的填充,如果遇到两个主体有先后依赖则进行顺序排序,最后生成待执行主体序列。

接下来按照序列遍历每一个主体 然后去检索主体下包含的组件,

执行donwload-》前置钩子检查执行-》具体组件方法执行的动作。

Serverless Devs 介绍
Serverless Devs 介绍

可以看到,S启动器的核心逻辑是解析相应的配置,组织执行顺序,调度执行任务, 真正的执行逻辑实际上是交给了具体的组件。执行逻辑部分下放到组件,使得S具备了支持不同云厂商的能力。

③ S framework

组件是核心的逻辑,我们就先来看看 组件的基类 核心库 s/core | s/framework

首先要说明的是 s/core 是 完全无厂商场依赖的基础库。

s/framework 继承了 s/core 的基础能力但却依赖 阿里云fc组件,它可以帮助开发者快速构建依托于阿里云fc 的应用场景,但是本身是锁定了云商的,这点需要大家知晓。

基本关系

Serverless Devs 介绍

怎么用

s/core

import { Component, Log } from '@serverless-devs/s-core';

class YourComponent extends Component {
  
  async test(inputs ) {
    
    const fc = await this.load('fc', 'Component'); // 通过load 方法加载已经存在于app store上的组件
    const logger = new Log()  
    logger.log('test core logger ...');
  }
}
           

s/framework

const FrameWork = require('@serverless-devs/s-framework');
class YourComponent extends FrameWork {
      async deploy(inputs) {
          const frameworkInputs = inputs;
        const customerProperty = inputs.Properties.YourCustomerProperty;
            if (customerProperty) {
              // 做自己的逻辑处理,比如整合目录,发布等
            // 可以重新修改入参值 frameworkInputs.Properties.CodeUri = new value;
          }
          return await super.deploy(frameworkInputs);
    }
}           

② S 可视化工具

如果说S 启动器 + S/framework 及所衍生的组件让S实现了支持无厂商锁定的能力,那么S Gui 则是帮助S在使用体验上更进一步。

应用/组件/插件

这三个概念在讲解s gui 之前想先简单说明一下,或许这边会有一些同学的困惑,通常你从app store 搜索项目的时候会发现一个hexo 的博客会出现好几个结果。有些是组件,有些是应用,那么组件和应用是什么关系呢?

Serverless Devs 介绍

应用本身不具备具体的执行逻辑细节,是一个项目的完整描述。它包含全局配置设置部分,项目约定配置,每一个项目又由组件,服务商,秘钥信息,组件入参组成。 应用的配置解析,执行步骤是由核心启动器来把控

组件才是执行逻辑的核心部分,hexo的部署逻辑,图片Ai的转换逻辑都是在组件里完成的,开发者通过将动态的参数剥离给使用的人,做到多场景的支持。而且大部分的应用业务场景都可以依赖我们提供的framework基础能力完成,比如前端框架托管,多语言的framework 托管等,当然如果你想构建更复杂的场景以及跟云商关联,那就需要花一些功夫打通云商服务的sdk了。

插件是更小的执行逻辑单元,通常会放到 应用配置的extends选项中,用来抽离多个不同场景组件的公共逻辑单元。这部分因重要性较低,暂不做过多介绍。

发布的可视化和解析的可视化

S 的组件从生产发布 到真正展现给社区的同学使用,主要涉及2个可视化配置部分

第一个是作为组件作者要把自己的组件文档,组件参数配置描述清楚

Serverless Devs 介绍

如上,组件作者需要将组件的入参说明一一配置成 类似下面Region,Detail的数据结构,一旦入参很多,并且是复合类型的,比如Detail,手写起来会非常麻烦,现在提供了gui 的支持,组件开发者就可以很轻松的构建复杂的配置项。

Region:
    Description: 地域
    Required: true
    Example: ''
    Default: ''
    Type:
      - String
 Detail:
    Description: 详细
    Required: true
    Example: ''
    Default: ''
    Type:
      - Struct:
          Service:
            Description: 服务
            Required: true
            Example: ''
            Default: ''
            Type:
              - Struct:
                  Name:
                    Description: 服务名
                    Required: true
                    Example: ''
                    Default: ''
                    Type:
                      - String           

当然我们给使用者使用的时候也会简化成可视化的方案,比如基于上面的realworld-web-static 组件构建的静态托管应用最终呈现给使用者的配置

Serverless Devs 介绍

我们看到同样是 Region 和 Detail 这两个属性,在开发者描述的时候用的数据结构会比较麻烦,但是给用户这边用的时候就非常简单。

总结下来,S Gui 把简单留给了开发者,同时帮开发者把简单留给了使用者。

极简工程架构

S Gui 是完全基于开源项目构建, 桌面部分是用的electron 官方的demo,Browser 的页面则是 create react 初始化的标准 React项目,没有掺杂过多的依赖。所以如果你比较熟悉React 技术栈,并且希望构建一个结构清爽的桌面项目,也可以直接把S Gui 当成初始化模板使用

Serverless Devs 介绍

此外,我们提供了全套的桌面打包构建脚本,只需执行npm run build 就可以完成Browser 前端打包构建-> electron 多平台资源整合 -> 压缩桌面包 -> 发布OSS 一系列流程。 这大约帮助可以节省 20min 的构建发布时间。

开源开放极具美感的新一代UI库

Serverless Devs 介绍
Serverless Devs 介绍
Serverless Devs 介绍
Serverless Devs 介绍

Gui 的视觉部分使用的是 阿里云智能自研的 Ui库

b-design

,最初是为我们的合作伙伴提供更具现代感的设计体验服务,现在则完全开放给Serverless 社区使用

@b-design/ui
import { Button } from "@b-design/ui";
import "@b-design/ui/dist/index.css";
           

写在最后

因为篇幅的问题,对S的介绍还是相对笼统,如有说明不清楚的还请见谅,另外因为S 本身也是新生的一款Serverless 开发者工具,本身还有很多的不足。我们希望能够有更多的小伙伴加入讨论共建,尤其最近我们决定

对S 的“灵魂”做进一步的“美化”(

讨论链接

),这里面可能涉及大量的核心逻辑改动,也需要拿到更多开发者的宝贵意见,以下是我们的学习群二维码,如果有兴趣的话欢迎你的加入。

Serverless Devs 介绍

如果您对我们的S工具感兴趣,就麻烦帮忙动动手指给我们的项目加个Star吧

S 命令行git地址

https://github.com/Serverless-Devs/Serverless-Devs

S Gui git 地址

https://github.com/Serverless-Devs/Serverless-Devs-App-Store

继续阅读