Serverless Framework Services 服务模型:基于 serverless.yml 组织、部署与管理 AWS 无服务器应用
【免费下载链接】serverless⚡ Serverless Framework – Effortlessly build apps that auto-scale, incur zero costs when idle, and require minimal maintenance using AWS Lambda and other managed cloud services.项目地址: https://gitcode.com/GitHub_Trending/se/serverless
Services(即“项目”)是 Serverless Framework 的组织单元。一个 Service 对应一份serverless.yml配置文件,在其中声明函数、触发事件与需要创建的 AWS 基础设施资源。阅读本文后,你将掌握 Service 的组织与拆分策略、serverless.yml顶层各配置段的职责、基于stages的分阶段配置(参数 / 可观测性 / 变量解析器)、部署与清理命令,以及通过frameworkVersion固定 CLI 版本的工程化实践。
本文以 docs/sf/providers/aws/guide/services.md 为主体,并结合本仓库中 config-schema.js 与 service.js 的源码实现展开说明。
Service:Serverless 应用的最小组织单元
Service 是 Serverless Framework 的组织单位。一个 Service 在概念上可以视为“一个可独立部署的完整应用”——它通过一个serverless.yml文件集中描述三件事:
- 要部署哪些functions(函数);
- 触发这些函数的events(事件);
- 需要一并创建、随栈销毁的AWS resources(基础设施资源)。
一个最简配置如下:
service: users provider: # 云厂商配置 name: aws functions: # 待部署的函数 usersCreate: events: - httpApi: 'POST /users/create' usersDelete: events: - httpApi: 'DELETE /users/delete' plugins: # 需要启用的插件 resources: # 需要部署的额外 AWS 资源这里service声明了 Service 名称,provider声明目标云厂商(AWS),functions下每个键是一个函数,其events定义了触发方式(上述示例是 HTTP API 路由);plugins与resources分别用于扩展框架能力与声明额外基础设施。创建新 Service 最简单的方式是直接运行serverless命令,由 CLI 交互式引导生成脚手架,快速上手可参考 Getting Started 指南。
从配置校验的源码也可以看出这些顶层属性的约束(见 config-schema.js):
service引用serviceName定义,是必需的;provider为对象且必须包含name;- 缺失任一必需属性时,Service 构造会直接抛出错误(错误码如
SERVICE_NAME_MISSING、PROVIDER_NAME_MISSING,见 service.js)。
组织方式:从单体 Service 到多 Service 拆分
项目初期,绝大多数开发者用一个 Service 承载该应用的全部函数、事件与资源——这也是官方推荐的做法:
my-service/ # 包含所有函数与基础设施资源 serverless.yml当应用逐渐长大,可以按业务切分为多个 Service。常见策略是按**工作流(workflow)或数据模型(data model)**组织:把处理同一类业务(如 Users / Posts / Comments 的 CRUD)的函数与其数据库资源放进同一个 Service:
users/ # 包含 4 个做 Users CRUD 的函数和 Users 数据库 serverless.yml posts/ # 包含 4 个做 Posts CRUD 的函数和 Posts 数据库 serverless.yml comments/ # 包含 4 个做 Comments CRUD 的函数和 Comments 数据库 serverless.yml这样做合理的原因在于:相互关联的函数通常共享公共基础设施资源,将它们聚合为一个部署单元,既便于整体部署,也带来更好的组织性与关注点隔离(separation of concerns)。当需要编排、串联部署多个 Service 时(例如共享输出变量、按顺序部署、子 Service 组合),可阅读仓库中的 “Composing services” 组合多服务文档 获取完整方案。
工作目录内容与 serverless.yml 的职责
执行serverless create或初始化后,工作目录中通常会出现两个核心文件:
serverless.yml—— Service 的配置文件;handler.js—— 首个函数默认引用的处理逻辑文件。
serverless.yml承担的主要职责包括(原文列举如下,均为顶层配置):
- 声明一个 Serverless Service;
- 定义 Service 将要部署到的云提供商;
- 定义一个或多个函数;
- 定义触发每个函数的事件(如 HTTP 请求);
- 定义要使用的插件;
- 定义需要创建的一组 AWS 资源;
- 允许
events中列出的事件在部署时自动创建对应资源(如httpApi事件会生成 API Gateway 资源); - 通过 变量系统(如
${env:xxx}、${param:xxx}、${self:xxx})提供灵活配置。
一个较完整、带注释的示例:
# serverless.yml service: users provider: name: aws runtime: nodejs14.x stage: dev # 默认 stage,默认值为 dev region: us-east-1 # 覆盖默认区域,默认值为 us-east-1 profile: production # 该 Service 使用的默认 AWS profile memorySize: 512 # 覆盖默认内存大小,默认值为 1024 functions: usersCreate: # 一个函数 handler: users.create events: # 触发该函数的事件 - httpApi: 'POST /users/create' usersDelete: # 一个函数 handler: users.delete events: # 触发该函数的事件 - httpApi: 'DELETE /users/delete' # 函数所使用的基础设施资源,此处直接书写原生 AWS CloudFormation resources: Resources: usersTable: Type: AWS::DynamoDB::Table Properties: TableName: usersTable AttributeDefinitions: - AttributeName: email AttributeType: S KeySchema: - AttributeName: email KeyType: HASH BillingMode: PAY_PER_REQUEST值得注意的细节:
- 上例中
stage、region、memorySize等provider级默认值,可被函数级配置或命令行选项覆盖。其中stage 的默认回退在源码中明确体现:在 service.js 的reloadServiceFileParam()中,若provider.stage为空会被显式置为'dev'。 functions下的函数名遵循^[a-zA-Z0-9-_]+$模式(见 config-schema.js 第 1 行定义的functionNamePattern)。runtime需设置为 AWS Lambda 当前支持并匹配你所安装框架版本的运行时标识,示例中的nodejs14.x为旧版说明性写法,本仓库最新 schema 示例使用的是nodejs20.x(见 config-schema.js)。resources段直接书写原始 CloudFormation 语法,部署时会被整体并入生成的 CloudFormation 模板,可进一步参考仓库中的 serverless.yml 配置参考 与 resources 指南。
函数、事件与资源的完整字段说明可分别查看仓库内的 functions 指南 及对应事件类型的独立文档。
基于 stages 的分阶段配置
stages段(serverless.yml顶层属性,v4 起作为params等旧属性的现代替代,见 config-schema.js)允许你按阶段声明差异化配置,主要包括三类内容:参数(parameters)、可观测性(observability)与变量解析器(resolvers)声明。每个 stage 名须匹配^[a-zA-Z0-9-]+$模式,default作为任何未显式指定阶段的回退兜底。
为每个 stage 设置参数
可以为不同 stage 设置不同的参数值,并用default阶段作为未列出阶段的回退:
# serverless.yml service: billing stages: prod: params: stripe_api_key: ${env:PROD_STRIPE_API_KEY} default: params: stripe_api_key: ${env:DEV_STRIPE_API_KEY}随后在serverless.yml其它位置通过${param:xxx}引用这些参数:
functions: chargeCustomer: handler: billing.charge environment: STRIPE_API_KEY: ${param:stripe_api_key}框架会根据当前部署的 stage 自动选择正确的参数值:--stage prod部署时使用${env:PROD_STRIPE_API_KEY},其余 stage(例如dev)则回退到default中的取值。参数机制的完整说明参见 parameters 文档。
按 stage 启用或关闭可观测性
可以在stages中为特定阶段开启/关闭 Serverless Dashboard 的可观测性能力:
# serverless.yml service: billing stages: prod: observability: true default: observability: false上例表示:prod阶段启用可观测性,其余阶段默认关闭。若需追踪指标、日志、追踪数据,可进一步参考 Dashboard / 可观测性文档。从本仓库的 schema 可见,observability字段既接受布尔值,也接受枚举值(axiom/dashboard)或带provider与dataset的对象形式(见 config-schema.js),说明该能力同时对接了多个遥测后端实现。
声明变量解析器(resolvers)
stages的另一个典型用途,是在default阶段声明terraform、vault等外部变量的解析器(resolver)。下面的示例声明了一个读取 S3 后端 Terraform state 的terraform解析器:
stages: default: resolvers: terraform: type: terraform backend: s3 bucket: terraform-state key: users-table/terraform.tfstate声明之后,即可在配置中通过${terraform.output.xxx}这类语法引用由 Terraform 输出、或由 Vault 管理的值。关于解析器的字段与使用方式,可分别参考 terraform 变量文档 与 vault 变量文档。schema 层面,stages.*.resolvers被建模为自由对象(见 config-schema.js),由对应 provider 插件动态扩展其校验逻辑。
部署:翻译为单一 CloudFormation 栈
当你执行部署时,serverless.yml中声明的所有函数、事件与资源会被翻译成一个 AWS CloudFormation 模板,并以单个 CloudFormation 栈(stack)完成部署。这就是一个 Service 同时是“组织单元”与“部署单元”的底层原因。
在serverless.yml所在目录执行部署命令:
serverless deploy部署默认使用devstage 与us-east-1区域。可通过 CLI 选项覆盖:
serverless deploy --stage prod --region us-east-1关于部署过程内部机制(打包、上传、变更集应用等)与所有可用选项,可查看仓库内的 部署指南 与deploy命令参考。
移除:一条命令清理云上资源
需要从 AWS 账户中清理该 Service 时,使用:
serverless remove移除过程只会删除provider 基础设施上的资源(即serverless.yml中声明的全部资源,随 CloudFormation 栈一并删除)。本地目录中的 Service 文件会被保留,因此之后你仍然可以修改配置,并将其重新部署到其它 stage、区域或云厂商。
版本固定:用 frameworkVersion 约束 Serverless 版本
Serverless Framework 通常通过npm install -g serverless全局安装,以便所有 Service 都能使用serverlessCLI。全局安装的弊端在于无法在package.json中锁定版本:当你升级了 Serverless 而同事或 CI 系统仍是旧版本时,可能出现在新版本serverless.yml中使用了仅新版本支持的语法,而 CI 却用旧版本部署的隐患。frameworkVersion属性正是为消除这种版本漂移而设计的。
配置方式是在serverless.yml顶层声明frameworkVersion。每当从 CLI 执行任何 Serverless 命令时,框架都会检查当前版本是否满足该约束(CLI 遵循 Semantic Versioning 语义,可写精确版本也可写范围)。官方推荐固定到精确版本,以确保团队成员与 CI 环境行为完全一致。
精确版本示例
# serverless.yml frameworkVersion: '2.1.0' service: users provider: name: aws runtime: nodejs14.x memorySize: 512 …版本范围示例
# serverless.yml frameworkVersion: "^2.1.0" # >=2.1.0 && <3.0.0 service: users provider: name: aws runtime: nodejs14.x memorySize: 512 …说明:上述示例取自官方文档以演示语法;在当前仓库(Serverless Framework v4,见 packages/serverless/package.json)中,应声明与所安装 CLI 主版本匹配的约束,例如'4'或'^4.0.0'(schema 示例即采用'4',见 config-schema.js)。
版本校验的底层实现
版本校验逻辑位于 Service 构造阶段(service.js),核心行为包括:
- 若
frameworkVersion不是合法的 semver range,会根据configValidationMode抛出INVALID_FRAMEWORK_VERSION错误,或在warn模式下仅告警并跳过校验; - 框架使用
semver.coerce将版本归并为主版本号进行比较,若 CLI 实际版本与配置声明主版本(major)不一致,将抛出FRAMEWORK_VERSION_MISMATCH,例如“The Serverless version (4.x) does not satisfy the 'frameworkVersion' (2.1.0)…”; - 该校验还支持通过
configValidationMode: 'warn' | 'error' | 'off'控制严格程度(默认warn,见 config-schema.js),方便在存量项目升级时渐进启用。
小结
围绕serverless.yml,本文覆盖了 Service 的完整生命周期管理:用单一 Service 起步、按业务模型拆分并借助 Compose 编排;在配置文件中组织函数、事件与 CloudFormation 资源;通过stages实现按阶段差异化参数、可观测性与变量解析器;最后用deploy/remove完成部署与清理,并用frameworkVersion消除团队间的版本漂移。Service 既是逻辑上的组织单元,也是物理上的 CloudFormation 部署单元——理解这一点,是掌握 Serverless Framework 进行 AWS 应用交付的起点。
【免费下载链接】serverless⚡ Serverless Framework – Effortlessly build apps that auto-scale, incur zero costs when idle, and require minimal maintenance using AWS Lambda and other managed cloud services.项目地址: https://gitcode.com/GitHub_Trending/se/serverless
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考