简介: 无服务计算本身是一个概念或者理论模型,落地到具体技术上主要有函数即服务(FaaS)以及后端即服务(BaaS)两种形式,阿里云提供函数即服务 FaaS 产品。
作者 | 宋文龙(闻可) 阿里云全球技术服务部高级交付专家
无服务器计算(Serverless Computing)在构建和运行应用时无需管理服务器等基础设施。它描述了一个细粒度的部署模型,在该模型中,应用被拆解为一个或多个细颗粒度的函数,在云端托管环境中被触发运行,然后根据需要执行、扩展容量并且计费。各大云厂商 Amazon、微软、Google、IBM、阿里云、腾讯云、华为云相继推出 Serverless 产品。
无服务计算本身是一个概念或者理论模型,落地到具体技术上主要有函数即服务(FaaS)以及后端即服务(BaaS)两种形式,阿里云提供函数即服务 FaaS 产品。
阿里云对于 FaaS 的定义如下:
函数计算是事件驱动的全托管计算服务。使用函数计算,您无需采购与管理服务器等基础设施,只需编写并上传代码。函数计算为您准备好计算资源,弹性地、可靠地运行任务,并提供日志查询、性能监控和报警等功能。
关于 FaaS 的详细介绍官方文档已经讲的很清楚,本文不再赘述。本文重点讨论无服务计算的应用场景以及应用实践。
无服务计算有很多优点,个人认为其中最主要的有三点:
下图说明了阿里云 FaaS 产品的核心优势:
前面探讨了无服务计算的优势,那么无服务计算都有哪些典型的应用场景呢?
在此分享笔者之前在项目中构建无服务应用的两个案例:
云端视频转码:
物联网设备监控:
基于项目经历以及个人理解,笔者认为无服务计算主要有以下几种典型的应用场景:
前面列举了很多无服务计算的优点以及运用在一些场景中的好处,很多人肯定觉得无服务计算太好用了,太想用了,这个场景能否用无服务计算?那个业务能否用无服务计算代替?
这里笔者可能要先泼一瓢冷水:无服务计算很好用,但不一定处处好用。当然这瓢冷水以及接下来的一些总结只是基于个人理解, 欢迎拍砖。
个人认为无服务计算其实只适合应用在一些逻辑相对简单、外部依赖相对较少、不需要复杂编排治理、没有极致性能要求的业务,主要原因如下:
笔者认为这两者应该不是一个维度的概念,微服务更多的是一种服务构建的架构思想,而无服务更偏重于一种服务部署和运行的技术方案,例如:微服务架构中某一个接口是可以通过无服务方式实现的。
当然,涉及到具体技术层面,通过 SpringCloud 或者 Dubbo 对外提供 RESTful 接口服务,还是将无服务函数挂载到 API 网关下对外提供 RESTful 服务,这两种技术方案确实是可以放到一起比较的。至于选择哪种技术实现,个人认为主要取决于运用场景和业务复杂度,前面总结了无服务计算的优势和不一定那么好用的场景。下面是个人的建议:
前面谈了比较多抽象的概念和看法, 下面结合笔者经历的一个实际案例展示如何使用阿里云 FaaS 产品构建一个无服务应用,尤其是实现 FaaS 应用的自动构建、自动部署。
某外企客户需要将一个为用户提供产品咨询的服务从某友商无服务平台迁移到阿里云 FaaS。这个应用原部署于友商海外平台,基于 Nodejs 开发,通过 API Gateway 暴露 RESTful 接口,数据存储采用友商云原生 NoSQL 数据库。
迁移改造主要涉及以下三部分工作:
其中第三部分构建、部署脚本改造是此次迁移工作的重点,接下来逐一展开说明。
友商的无服务计算及网关在阿里云上均有对应产品,在此不展开比较。
友商云原生 NoSQL 数据库为该平台独有产品,经过和客户讨论认为,完全可以用其他 NoSQL 产品代替,加之现有开发人员更熟悉 MongoDB 技术栈,最后数据存储选型为阿里云云原生 MongoDB。
以下为整体迁移方案示意图:
用户编写无服务应用代码时,原则上只需要关注代码逻辑即可,主体代码逻辑部分大体上差异不大,比较明显的差异主要体现在事件处理入口函数写法上。参考FaaS 代码示例改造针对 API 网关事件的处理函数:
module.exports.handler = function(event, context, callback) {
var response = {};
callback(null, response);
};
客户原来采用第三方工具 Serverless (https://www.serverless.com/) 实现无服务计算应用的构建和部署。Serverless 框架虽然宣称支持几乎所有主流云厂商的无服务产品,但经过调研后发现其对某友商支持是最全面的,有很多代码示例或者工程脚手架,几乎是开箱即用。但该工具对阿里云的支持比较有限,示例也相对较少。经过评估,我们决定采用阿里云自己的工具 Funcraft。
Funcraft 如何安装配置请参考产品文档,此处不展开讨论。接下来主要展示如何通过 Funcraft 脚本实现服务、函数、网关、日志、鉴权等相关资源的部署及配置。
编写脚本前,先看一下目标系统的部署架构以及 Funcraft 要实现的功能蓝图:
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:[email protected]: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 资源中如何配置白名单安全组:
以上脚本资源都准备好后,就可以执行 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 已经部署完成并且可以正常运行了。
接下来可以将以上 Funcraft 命令及脚本可以加入到 Jenkins、Gitlab 等工具流水线中,结合代码版本管理工具实现函数应用的持续集成、持续发布。
随着无服务计算产品和技术的进一步成熟,会有越来越多的用户选择无服务计算技术;随着阿里云的进一步发展壮大,也会有越来越多用户采用阿里云 FaaS 构建无服务应用。
本文探讨了无服务计算的应用场景,并且结合实际应用案例,讲解了如何用 FaaS 构建无服务 Web 后台应用,并实现自动构建、自动部署,希望以上探讨和经验能够帮到大家。
宋文龙,花名闻可,阿里云全球技术服务部高级交付专家,有多年云原生应用开发架构经验以及多年高性能服务器研发经验。目前专注于运用阿里云中间件技术、结合阿里巴巴中台架构经验为客户构建符合行业需要的业务中台解决方案并完成交付。
原文链接
本文为阿里云原创内容,未经允许不得转载。