无服务计算应用场景探讨及 FaaS 应用实战

头图.jpg

做者 | 宋文龙(闻可)  阿里云全球技术服务部高级交付专家html

什么是无服务计算

无服务器计算(Serverless Computing)在构建和运行应用时无需管理服务器等基础设施。它描述了一个细粒度的部署模型,在该模型中,应用被拆解为一个或多个细颗粒度的函数,在云端托管环境中被触发运行,而后根据须要执行、扩展容量而且计费。各大云厂商 Amazon、微软、Google、IBM、阿里云、腾讯云、华为云相继推出 Serverless 产品。node

无服务计算自己是一个概念或者理论模型,落地到具体技术上主要有函数即服务(FaaS)以及后端即服务(BaaS)两种形式,阿里云提供函数即服务 FaaS 产品。mongodb

阿里云对于 FaaS 的定义以下:docker

函数计算是事件驱动的全托管计算服务。使用函数计算,您无需采购与管理服务器等基础设施,只需编写并上传代码。函数计算为您准备好计算资源,弹性地、可靠地运行任务,并提供日志查询、性能监控和报警等功能。数据库

关于 FaaS 的详细介绍官方文档已经讲的很清楚,本文再也不赘述。本文重点讨论无服务计算的应用场景以及应用实践。json

无服务计算应用场景

1. 无服务计算的优点

无服务计算有不少优势,我的认为其中最主要的有三点:后端

  • 使用无服务计算,用户无需考虑基础设施,能够更加专一于业务逻辑;
  • 无服务计算支持弹性伸缩,按需使用,按量计费,很是适合流量不稳定、有明显波峰波谷的业务;
  • 无服务计算是云原生产品,能够无缝对接各类云上产品,做为黏合剂串联各类云原生产品。

下图说明了阿里云 FaaS 产品的核心优点:api

1.png

2. 无服务计算应用场景

前面探讨了无服务计算的优点,那么无服务计算都有哪些典型的应用场景呢?安全

在此分享笔者以前在项目中构建无服务应用的两个案例:bash

  • 云端视频转码:
    • 技术方案:设备端捕获短视频,上传到云端存储(例如阿里云 OSS),云端存储监测到文件上传后触发无服务计算函数函数,函数中调用 FFmpeg 给视频加水印、加特效,将视频转码后再转存到云端存储上,同时通知业务服务更改视频状态。
    • 方案优点:设备端视频上传频率很不稳定,可能有一段时间全部设备空闲,也有可能某一段时间几千台设备同时上传,而视频转码是比较消耗资源的,若是经过普通服务器提供转码能力并要确保全部视频都能在预期时间内转码完成的话,必须按最高并发量配置服务器资源,这些服务器成本是至关可观的。即便云服务器采用 Auto Scalling 策略,也需常备部分服务器,没法作到不使用时零运行成本,并且云服务 Auto Scalling 触发及启动时间也是分钟级的,很难达到服务能力秒级快速伸缩。
  • 物联网设备监控:
    • 技术方案:设备端经过云原生 IoT 服务上报状态,云原生 IoT 服务收到消息后触发无服务计算函数,函数中对 IoT 原始消息作简单清洗后转发到后端服务作进一步业务处理,例如:发推送消息给设备管理 App,固然也能够经过函数将 IoT 消息转存到 NoSQL 数据库。
    • 方案优点:端侧设备活跃时间不固定,若是想经过其余后端服务监控设备状态, 该服务必须保持 7*24 小时在线,架构和应用都须要确保高可用。并且设备并发量也是不稳定的,要考虑服务伸缩架构。还有一点须要考虑的是,云端资源经过事件或者规则直接唤起无服务计算函数比价方便,只须要简单配置便可,而对接自定义服务则要复杂得多。

基于项目经历以及我的理解,笔者认为无服务计算主要有如下几种典型的应用场景: 

  • 可分解成独立运行单元的 CPU 密集计算型任务;
  • 构建弹性伸缩 Web 后台应用;
  • 无缝粘合调度云上资源;
  • 快速低成本上线敏捷应用。

3. 无服务计算不适合作什么

前面列举了不少无服务计算的优势以及运用在一些场景中的好处,不少人确定以为无服务计算太好用了,太想用了,这个场景可否用无服务计算?那个业务可否用无服务计算代替?

这里笔者可能要先泼一瓢冷水:无服务计算很好用,但不必定到处好用。固然这瓢冷水以及接下来的一些总结只是基于我的理解, 欢迎拍砖。

我的认为无服务计算其实只适合应用在一些逻辑相对简单、外部依赖相对较少、不须要复杂编排治理、没有极致性能要求的业务,主要缘由以下:

  • 无服务计算在服务编排以及服务治理方面是比较弱的,虽然主流云厂商都提供无服务计算的函数编排产品(例如阿里云的 Serverless 工做流,AWS 的 Step Functions 等),但想要实现函数的限流降级、调用链追踪、自动注册发现等比较复杂的编排治理以及可探测性仍是须要作不少额外的工做,弥补这些不足所要作的工做远大于无服务计算自己节省的工做量。这点也是和无服务计算无需运维、配置简单、开箱即用的思想是背道而驰的。
  • 无服务计算应用运行所依托的底层服务器以及运行环境对用户是透明的,用户没法选择,也没法优化。例如在笔者以前的视频转码方案中,有些特效处理若是运行在 GPU 服务器上是能够大幅加速的,可是在无服务计算中只能依靠 CPU 计算。
  • 无服务计算程序运行的环境是高度标准化的,有些依赖于特定运行环境、特定服务器版本、甚至特定硬件资源的依赖是很难确保兼容性的。若是有些应用尤为是原有技术资产受到运行环境制约的话,尽可能仍是回归到传统的云服务器部署方案。
  • 无服务计算的弹性伸缩并不是没有上限,和普通应用同样,无服务应用在实际生产系统中也须要考虑并发达到上限的状况。虽然全部厂商的无服务计算产品都能根据并发量弹性伸缩,但这个弹性自己仍是靠底层硬件资源支撑的,通常来说各厂商的无服务计算产品都会有默认的并发上限设置,虽然经过工单申请能够调整,但也不能调整为无限量。若是帐号下有多个无服务应用,须要对不一样应用作的流量分配或者限制,而且考虑某一应用访问流量达到并发上限的状况。

4. 无服务可否替代微服务

笔者认为这二者应该不是一个维度的概念,微服务更多的是一种服务构建的架构思想,而无服务更偏重于一种服务部署和运行的技术方案,例如:微服务架构中某一个接口是能够经过无服务方式实现的。

固然,涉及到具体技术层面,经过 SpringCloud 或者 Dubbo 对外提供 RESTful 接口服务,仍是将无服务函数挂载到 API 网关下对外提供 RESTful 服务,这两种技术方案确实是能够放到一块儿比较的。至于选择哪一种技术实现,我的认为主要取决于运用场景和业务复杂度,前面总结了无服务计算的优点和不必定那么好用的场景。下面是我的的建议:

  • 若是应用中须要复杂的服务编排、服务治理、调用链追踪、统一的配置管理、自动注册发现等能力,建议仍是采用“传统的”微服务技术方案;
  • 相反,若是只须要构建一个“短平快”的应用,采用无服务计算方案会让你好体验到极大的便利。正如笔者接下来将要分享的案例,就是采用无服务技术构建一个简单的 Web 后台应用。

阿里云 FaaS 实战

前面谈了比较多抽象的概念和见解, 下面结合笔者经历的一个实际案例展现如何使用阿里云 FaaS 产品构建一个无服务应用,尤为是实现 FaaS 应用的自动构建、自动部署。 

1. 项目背景介绍

某外企客户须要将一个为用户提供产品咨询的服务从某友商无服务平台迁移到阿里云 FaaS。这个应用原部署于友商海外平台,基于 Nodejs 开发,经过 API Gateway 暴露 RESTful 接口,数据存储采用友商云原生 NoSQL 数据库。

迁移改造主要涉及如下三部分工做:

  • 阿里云产品适配选型
  • 代码逻辑改造
  • 应用部署工具选择及脚本编写

其中第三部分构建、部署脚本改造是这次迁移工做的重点,接下来逐一展开说明。

2. 阿里云产品适配选型

友商的无服务计算及网关在阿里云上均有对应产品,在此不展开比较。

友商云原生 NoSQL 数据库为该平台独有产品,通过和客户讨论认为,彻底能够用其余 NoSQL 产品代替,加之现有开发人员更熟悉 MongoDB 技术栈,最后数据存储选型为阿里云云原生 MongoDB。

如下为总体迁移方案示意图:

2.png

3. 代码逻辑改造

用户编写无服务应用代码时,原则上只须要关注代码逻辑便可,主体代码逻辑部分大致上差别不大,比较明显的差别主要体如今事件处理入口函数写法上。参考FaaS 代码示例改造针对 API 网关事件的处理函数:

module.exports.handler = function(event, context, callback) {    
    var response = {};
    callback(null, response);
};

4. 应用部署工具选择及脚本编写

  • 应用构建及部署工具选择

客户原来采用第三方工具 Serverless (https://www.serverless.com/) 实现无服务计算应用的构建和部署。Serverless 框架虽然宣称支持几乎全部主流云厂商的无服务产品,但通过调研后发现其对某友商支持是最全面的,有不少代码示例或者工程脚手架,几乎是开箱即用。但该工具对阿里云的支持比较有限,示例也相对较少。通过评估,咱们决定采用阿里云本身的工具 Funcraft。 

Funcraft 如何安装配置请参考产品文档,此处不展开讨论。接下来主要展现如何经过 Funcraft 脚本实现服务、函数、网关、日志、鉴权等相关资源的部署及配置。

  • 编写脚本

编写脚本前,先看一下目标系统的部署架构以及 Funcraft 要实现的功能蓝图:

3.png

Funcraft 脚本及配置说明详见如下代码:

yaml
ROSTemplateFormatVersion: '2015-09-01'
Transform: 'Aliyun::Serverless-2018-04-03'
Resources:
  demoService: #资源名称, 根据须要命名
    Type: 'Aliyun::Serverless::Service'
    Properties: #属性设置
      Description: 'This is a faas demo ' #资源描述
      Policies:  #安全策略,系统自动根据策略为函数建立角色
        - AliyunOSSFullAccess
        - AliyunRAMFullAccess
        - AliyunLogFullAccess
        - AliyunApiGatewayFullAccess
        - AliyunFCFullAccess
        - AliyunMongoDBFullAccess
        - AliyunVPCFullAccess
        - AliyunECSNetworkInterfaceManagementAccess #特别说明,配置此策略才能建立弹性网卡进而打通函数以及VPC内链接
      VpcConfig: #容许函数访问的VPC配置
        VpcId: 'vpc-xxxxxx'
        VSwitchIds: ['vsw-xxxxxx']
        SecurityGroupId: 'sg-xxxxxx'
      LogConfig: #日志服务配置
        Project: sls-demo
        Logstore: logstore-demo
    demoFunction: #函数名称
      Type: 'Aliyun::Serverless::Function' #资源类型为服务,服务内能够挂载多个函数
      Properties:
        Handler: index.handler #事件处理入口
        Runtime: nodejs10   #程序运行环境
        CodeUri: './src'  #程序代码相对于当前脚本的路径
        EnvironmentVariables:   #环境变量设置,
          MONGO_URL: mongodb://userx:pwdx@dds-xxx.mongodb.rds.aliyuncs.com:3717/demoDb #Mongo内网链接地址
          RESULT_TABLE_NAME: demo_table
  demoGroup: # Api Group
    Type: 'Aliyun::Serverless::Api' #资源类型为API,每一个API分组下能够挂载多个API接口
    Properties:
      StageName: RELEASE  #发布环境
      DefinitionBody:
        '/v1/recommendervera/[resultId]': # request path
          get: # http method
            x-aliyun-apigateway-api-name: demo_api # api name
            x-aliyun-apigateway-fc: # 当请求该 api 时,要触发的函数,
              arn: acs:fc:cn-shanghai:xxx:services/demoService.LATEST/functions/demoFunction
              timeout: 3000
            x-aliyun-apigateway-request-parameters: #设置参数类型
                - apiParameterName: 'resultId'
                  location: 'Path'  #传参方式,此处为在URI请求路径中传餐
                  parameterType: 'String'
                  required: 'REQUIRED'  #设置为必选参数
        '/v1/recommendervera/': # request path
          post: # http method
            x-aliyun-apigateway-api-name: demo_api_post # api name
            x-aliyun-apigateway-fc: # 当请求该 api 时,要触发的函数,
              arn: acs:fc:cn-shanghai:xxxx:services/demoService.LATEST/functions/demoFunction
              timeout: 3000
            x-aliyun-apigateway-auth-type: APP  #设置鉴权类型,此处设置为简单的APP code类型鉴权
            x-aliyun-apigateway-app-code-auth-type: HEADER #鉴权加密方式,此处设置为经过Header传递受权后的app
  • 资源准备

服务、函数、API 网关均可以经过以上Funcraft 脚本一站式建立完成,日志、MongoDB、鉴权所需应用等外部资源须要提早建立或者配置好。

这里特别要说明的是:函数经过内网连接 MongoDB 时,须要经过配置容许函数访问 MongoDB 所在 VPC 及交换机,并为函数访问建立一个独立的安全组用于配置弹性网卡,而且将此安全组加入到 MongoDB 的白名单中,进而打通函数计算与 VPC 之间的网络联通。

前面提到的 VPC、交换机以及安全组已经提早建立好并配置在 Funcraft 脚本中了,下面看看在实际的 MongoDB 资源中如何配置白名单安全组:

4.png

5. 构建和部署

以上脚本资源都准备好后,就能够执行 fun build 命令进行构建了。构建时,工具会读取指定代码目录下的 package.json 文件加载相关插件依赖及配置。

构建执行命令示例:

bash
$ fun build
using template: template.yml
start building function dependencies without docker
building demoService/demoFunction
running task: flow NpmTaskFlow
running task: CopySource
running task: NpmInstall
Build Success
Built artifacts: .fun/build/artifacts
Built template: .fun/build/artifacts/template.yml
Tips for next step
======================
* Invoke Event Function: fun local invoke
* Invoke Http Function: fun local start
* Deploy Resources: fun deploy

构建完成后, 执行 fun deploy 命令部署到云端。示例以下:

bash
$ fun deploy
using template: .fun/build/artifacts/template.yml
using region: cn-shanghai
using accountId: ***********3452
using accessKeyId: ***********1fap
using timeout: 60
Collecting your services information, in order to caculate devlopment changes...
Resources Changes(Beta version! Only FC resources changes will be displayed):
┌──────────────┬──────────────────────────────┬────────┬──────────────────────┐
│ Resource     │ ResourceType                 │ Action │ Property             │
├──────────────┼──────────────────────────────┼────────┼──────────────────────┤
│              │                              │        │ Description          │
│              │                              │        ├──────────────────────┤
│              │                              │        │ Policies             │
│ demoService  │ Aliyun::Serverless::Service  │ Add    ├──────────────────────┤
│              │                              │        │ VpcConfig            │
│              │                              │        ├──────────────────────┤
│              │                              │        │ LogConfig            │
├──────────────┼──────────────────────────────┼────────┼──────────────────────┤
│              │                              │        │ Handler              │
│              │                              │        ├──────────────────────┤
│              │                              │        │ Runtime              │
│ demoFunction │ Aliyun::Serverless::Function │ Add    ├──────────────────────┤
│              │                              │        │ CodeUri              │
│              │                              │        ├──────────────────────┤
│              │                              │        │ EnvironmentVariables │
└──────────────┴──────────────────────────────┴────────┴──────────────────────┘
? Please confirm to continue. Yes
Waiting for service demoService to be deployed...
make sure role 'aliyunfcgeneratedrole-cn-shanghai-demoService' is exist
role 'aliyunfcgeneratedrole-cn-shanghai-demoService' is already exist
attaching policies ["AliyunOSSFullAccess","AliyunRAMFullAccess","AliyunLogFullAccess","AliyunApiGatewayFullAccess","AliyunFCFullAccess","AliyunMongoDBFullAccess","AliyunVPCFullAccess","AliyunECSNetworkInterfaceManagementAccess"] to role: aliyunfcgeneratedrole-cn-shanghai-demoService
attached policies ["AliyunOSSFullAccess","AliyunRAMFullAccess","AliyunLogFullAccess","AliyunApiGatewayFullAccess","AliyunFCFullAccess","AliyunMongoDBFullAccess","AliyunVPCFullAccess","AliyunECSNetworkInterfaceManagementAccess"] to role: aliyunfcgeneratedrole-cn-shanghai-demoService
attaching police 'AliyunECSNetworkInterfaceManagementAccess' to role: aliyunfcgeneratedrole-cn-shanghai-demoService
attached police 'AliyunECSNetworkInterfaceManagementAccess' to role: aliyunfcgeneratedrole-cn-shanghai-demoService
Waiting for function demoFunction to be deployed...
Waiting for packaging function demoFunction code...
The function demoFunction has been packaged. A total of 1675 files were compressed and the final size was 2.1 MB
function demoFunction deploy success
service demoService deploy success
Waiting for api gateway demoGroup to be deployed...
    URL: GET http://xxx-cn-shanghai.alicloudapi.com/v1/recommender/[resultId]
      stage: RELEASE, deployed, version: 20200715144450426
      stage: PRE, undeployed
      stage: TEST, undeployed
    URL: POST http://xxx-cn-shanghai.alicloudapi.com/v1/recommender/
      stage: RELEASE, deployed, version: 20200715144453967
      stage: PRE, undeployed
      stage: TEST, undeployed
api gateway demoGroup deploy success

脚本正常执行后,能够在云端看到相关函数及 API 已经部署完成而且能够正常运行了。

5.png

6.png

接下来能够将以上 Funcraft 命令及脚本能够加入到 Jenkins、Gitlab 等工具流水线中,结合代码版本管理工具实现函数应用的持续集成、持续发布。

总结

随着无服务计算产品和技术的进一步成熟,会有愈来愈多的用户选择无服务计算技术;随着阿里云的进一步发展壮大,也会有愈来愈多用户采用阿里云 FaaS 构建无服务应用。

本文探讨了无服务计算的应用场景,而且结合实际应用案例,讲解了如何用 FaaS 构建无服务 Web 后台应用,并实现自动构建、自动部署,但愿以上探讨和经验可以帮到你们。

做者简介

宋文龙,花名闻可,阿里云全球技术服务部高级交付专家,有多年云原生应用开发架构经验以及多年高性能服务器研发经验。目前专一于运用阿里云中间件技术、结合阿里巴巴中台架构经验为客户构建符合行业须要的业务中台解决方案并完成交付。

课程推荐

为了更多开发者可以享受到 Serverless 带来的红利,这一次,咱们集结了 10+ 位阿里巴巴 Serverless 领域技术专家,打造出最适合开发者入门的 Serverless 公开课,让你即学即用,轻松拥抱云计算的新范式——Serverless。

点击便可免费观看课程:https://developer.aliyun.com/learning/roadmap/serverless

Serverless 公众号,发布 Serverless 技术最新资讯,聚集 Serverless 技术最全内容,关注 Serverless 趋势,更关注你落地实践中的遇到的困惑和问题。

相关文章
相关标签/搜索