- 后端
- 微服务
- 云原生
【免费下载链接】midway
🍔 A Node.js Serverless Framework for front-end/full-stack developers. Build the application for next decade. Works on AWS, Alibaba Cloud, Tencent Cloud and traditional VM/Container. Super easy integrate with React and Vue. 🌈
Midway Serverless 是 Midway 面向 Serverless 云平台输出的一套 Node.js 云函数开发方案,帮助前端与全栈开发者以熟悉的 Midway 编程模型构建 FaaS 函数,并部署到阿里云 FC、腾讯云 SCF、AWS Lambda 等平台。本文以 site/versioned_docs/version-3.0.0/serverless/serverless_intro.md 为主体,结合仓库内@midwayjs/faas函数框架、FC 启动器、事件类型定义等源码,系统讲解 Midway Serverless 能做什么、函数的适用与不适用的场景,以及函数、函数组、触发器、运行时、发布平台、Layer 等核心术语,读完即可对 Serverless 化改造的边界与落地方式建立完整认知。
Midway Serverless 能做什么
Midway Serverless 是用于构建 Node.js 云函数的 Serverless 框架。它的核心价值在于:帮助开发者在云原生时代大幅降低服务器与运维的维护成本,把精力从"如何部署、如何扩容、如何保证可用性"中解放出来,更专注于产品研发本身。
在 Midway Serverless 的场景下,开发者不再编写一个完整的、常驻监听端口的 Web 应用,而是编写一个个独立的函数逻辑,交给云平台去调度、伸缩和计费。平台负责实例的创建、销毁与扩容,开发者只需关心"输入长什么样、输出怎么处理"。
Midway Serverless 和 Midway 的关系
Midway Serverless 是 Midway 产出的一套面向 Serverless 云平台的开发方案,其内容主要包括两部分:
- 函数框架
@midwayjs/faas:提供函数场景下的框架运行时、装饰器与上下文封装; - 与平台配套的工具链、启动器等:例如
@midwayjs/serverless-fc-starter(阿里云 FC 启动器)、@midwayjs/serverless-http-parser(HTTP 事件解析器)等。
在 Midway Serverless 2.0 之后,Midway Serverless 和 Midway 的能力开始复用:两者共享同一套 CLI 工具链、编译器、装饰器等基础设施。也就是说,在传统 Web 应用中掌握的依赖注入、生命周期、配置加载、路由与中间件等能力,在函数场景下依然成立。
当前,Midway Serverless 主要面向的是函数(FaaS)场景。从源码结构可以清晰看到这一分工:@midwayjs/faas包在 packages/faas/src/index.ts 中导出了MidwayFaaSFramework(框架主体)、FaaSConfiguration(配置与初始化)、AbstractBootstrapStarter(启动器抽象基类)以及事件装饰器,而@midwayjs/core的容器、装饰器、配置服务等能力则通过依赖复用。
函数(FaaS)能做什么
很多人对函数还不太清楚,或者不知道它能做什么。当前函数可以理解为一个小容器:原来要写一个完整的应用来承载能力,现在只需要写中间的"逻辑部分",并考虑输入和输出的数据即可,其余都由平台承载。
具体来说,函数可以承担以下几类工作:
- 承载 HTTP 等流量:通过绑定平台的触发器(Trigger/Event),函数可以承接 HTTP、Socket 等流量。传统应用需要自己启动服务并监听端口,而函数通过事件机制被平台调用;
- 调用 BaaS 服务:通过平台提供的 BaaS SDK,函数可以对外调用数据库、Redis 等托管服务;
- 提供传统 HTTP API 服务:结合现有的前端框架(React、Vue 等)渲染页面,形成完整的前后端交付;
- 作为独立的数据模块被触发:例如文件上传变更后的处理、解压任务等;
- 作为定时任务的逻辑部分:到了指定的时间或时间间隔被执行,无需常驻进程。
从源码看,@midwayjs/faas的函数框架 packages/faas/src/framework.ts 将函数分为两类调用路径:invokeTriggerFunction会判断isHttpFunction,为 true 时走httpMiddlewareManager(HTTP 中间件链),否则走eventMiddlewareManager(事件中间件链)。HTTP 函数的返回值会写入ctx.body,最终由formatHttpResponse统一格式化为{ isBase64Encoded, statusCode, headers, body }结构(见 packages/faas/src/framework.ts#L412-L475);而事件函数则直接把处理器返回值作为结果返回,例如阿里云 OSS 上传事件、MNS 消息等,其事件结构在 packages-serverless/faas-typings/typings/fc.ts 中有完整类型定义(如SingleOSSEvent、SingleCDNEvent、MNSStreamEvent)。
另外,@midwayjs/faas还提供了Event参数装饰器(见 packages/faas/src/decorator.ts),在事件函数中可以直接注入原始事件对象:ctx.originEvent && ctx.originContext ? ctx.originEvent : ctx,这样处理器就能以声明式方式拿到平台原始事件数据。
函数不能做什么
函数的架构决定了,有些需求是函数无法支持的;同时函数和应用在能力上仍有一定区别。文档明确列出了函数不适用的场景:
- 执行时间超过函数配置下限制的(最好不超过 5s);
- 有状态、需要在本地存储数据的;
- 长连接场景,例如 WebSocket 等;
- 后台任务、有大数据量执行的;
- 依赖多进程通信的;
- 大文件上传(例如网关限制 2M 以上);
- 自定义环境的,例如 nginx 配置、C++ 库(C++ addon 动态链接库等)、Python 版本依赖等;
- 大量服务端缓存的;
- 需要固定 IP 的情况。
这些限制来自函数"单一链路、无状态、由平台调度"的本质:函数实例生命周期短、可被平台随时回收重建,本地磁盘数据与常驻内存状态无法保证可靠;执行时长受平台超时配额约束;网络出口 IP 与底层运行时环境由平台统一管控,无法像传统 VM 一样自定义。
从实现上也能印证这一设计取向:AbstractBootstrapStarter(见 packages/faas/src/starter.ts)中,getBaseDir在 TypeScript 环境下指向appDir/src、编译后环境指向appDir/dist,函数代码以入口文件的形式被平台"包裹执行",并不像应用那样自带完整的服务生命周期管理。
术语描述
函数
逻辑意义上的一段代码片段,通过常见的入口文件包裹起来执行。函数是单一链路并且无状态的。现在很多人认为 Serverless = FaaS + BaaS:FaaS 是无状态的函数,BaaS 解决带状态的服务。
在@midwayjs/faas中,函数通过MidwayFaaSFramework注册并调度:框架维护了一个funMappingStore: Map<string, RouterInfo>,在loadFunction()阶段通过MidwayServerlessFunctionService.getFunctionList()拿到全部函数清单并建立"处理器名 → 路由信息"的映射(见 packages/faas/src/framework.ts#L165-L191),调用时再通过invokeTriggerFunction根据handlerMapping定位到对应处理器执行。
函数组
多个函数聚合到一起的逻辑分组名,对应原有的"应用"概念。一个函数组相当于传统应用的一次部署单元,组内可以包含多个函数。
源码中,IMidwayFaaSApplication提供了getFunctionName()与getFunctionServiceName()两个方法(见 packages/faas/src/interface.ts#L424-L465):getFunctionName优先读取环境变量MIDWAY_SERVERLESS_FUNCTION_NAME,其次读取平台适配器(applicationAdapter)提供的信息;getFunctionServiceName同理对应MIDWAY_SERVERLESS_SERVICE_NAME。这里的 "Service" 即对应文档所说的"函数组"(服务/分组),在阿里云 FC 上即"服务"概念,在 packages-serverless/midway-fc-starter/src/index.ts 的onInit中可以看到,它正是从初始化上下文context.service.name与context.function.name中取得这两个值。
触发器
触发器,也叫 Event(事件)、Trigger,特指触发函数的方式。与传统的开发理念不同,函数不需要自己启动一个服务去监听数据,而是通过绑定一个(或者多个)触发器,数据通过类似事件触发的机制调用到函数。
在@midwayjs/faas中,HandlerOptions通过isHttpFunction区分触发类型(见 packages/faas/src/interface.ts#L419-L422),框架据此选择不同的中间件链与参数注入方式。FC 启动器在onRequest中通过事件特征判断触发方式(见 packages-serverless/midway-fc-starter/src/index.ts#L86-L96):event是IncomingMessage/EventEmitter时为 HTTP 触发,事件含headers、queryParameters、httpMethod时为 API 网关触发,否则按事件触发器处理(Buffer 入参会先转为 UTF-8 字符串再尝试 JSON 解析)。
函数运行时
英文叫 Runtime,具体指执行函数的环境。在各个平台可能是镜像,也可能是 Node.js 代码包,例如社区常见的 kubeless 运行时。该代码包会实现对接平台的各种接口、处理异常、转发日志等能力。
仓库中的@midwayjs/serverless-fc-starter正是"运行时/启动器"这一角色的实例。它的 README(见 packages-serverless/midway-fc-starter/README.md)说明了其用途:用于包裹无法定制运行时的 FaaS 平台(比如阿里云 FC)。启动器暴露exports.init(initializer 初始化入口)与exports.handler(函数入口),内部通过AbstractBootstrapStarter初始化 Midway 容器与框架,再调用framework.invokeTriggerFunction完成函数分发。onStart()中还会针对 FC 环境做特殊处理(见 packages-serverless/midway-fc-starter/src/index.ts#L23-L55):设置MIDWAY_SERVERLESS_REPLACE_LOGGER替换默认上下文日志、设置MIDWAY_LOGGER_DISABLE_COLORS禁用控制台颜色(FC 控制台无法探测颜色支持,日志采集必须禁用),并支持initializeMethodName、handlerName、aggregationHandlerName等入口配置。
发布平台
函数最后承载的平台。现在社区最常见的有阿里云 FC、腾讯云 SCF、AWS 的 Lambda 等。
仓库通过packages-serverless/faas-typings为不同平台提供了事件类型定义:packages-serverless/faas-typings/typings/fc.ts 定义了阿里云 FC 的 OSS、CDN、MNS 等事件结构,packages-serverless/faas-typings/typings/scf.ts 则对应腾讯云 SCF 的事件模型。同时,@midwayjs/faas的IFaaSConfigurationOptions提供了applicationAdapter(平台适配器)抽象(见 packages/faas/src/interface.ts#L472-L485),允许各平台通过getFunctionName、getFunctionServiceName、runAppHook、runContextHook等钩子接入统一的函数框架,从而屏蔽平台差异。
Layer
由于运行时的代码比较简单,且需要保证稳定性、无法经常性地更新,Layer 被设计出来用于扩展运行时的能力,同时可以精简本地的函数代码量(因为有一些平台限制了上传压缩包的大小)。
Layer 是平台侧提供的共享依赖层能力:把常见的公共依赖(如 node_modules、ffmpeg 等二进制、公共配置)打包成层,函数在运行时挂载即可使用,既避免重复上传大体积代码包,也让运行时本身的更新可以独立于业务函数进行。这一设计正好呼应了上文"函数代码包应当精简"的约束,以及"函数不能做的事"里对自定义环境(如 C++ 动态链接库)的限制——在平台不支持自定义运行时的情况下,Layer 提供了一条补充运行时能力的路径。
小结:从应用到函数,先评估边界再动手
通过上面的梳理可以看出,Midway Serverless 的定位非常清晰:复用 Midway 的依赖注入、配置、装饰器与工具链,把应用改造成"函数组 + 函数 + 触发器"的结构,部署到各云平台。改造前应优先对照"函数不能做什么"的清单做边界评估——执行时长、有状态存储、长连接、大文件、自定义环境、固定 IP 等场景都不适合直接函数化。
如果决定走函数化路线,可以从本文提到的三个仓库模块入手继续深入:函数框架与中间件调度看 packages/faas/src/framework.ts 和 packages/faas/src/configuration.ts;平台启动器与入口封装看 packages-serverless/midway-fc-starter/src/index.ts;HTTP 事件到 Koa 风格上下文的转换看 packages-serverless/serverless-http-parser/src。本文所属的 Serverless 系列文档还包含平台部署(aliyun_faas.md、aws_lambda.md)、上下文与开发调试(serverless_context.md、serverless_dev.md)等专题,可作为下一步阅读的入口。
- 后端
- 微服务
- 云原生
【免费下载链接】midway
🍔 A Node.js Serverless Framework for front-end/full-stack developers. Build the application for next decade. Works on AWS, Alibaba Cloud, Tencent Cloud and traditional VM/Container. Super easy integrate with React and Vue. 🌈
相关推荐
Midway Serverless 入门指南:Node.js 云函数框架的能力边界与核心术语全解析
Midway Serverless 入门指南:Node.js 云函数框架的能力边界与核心术语全解析 Midway Serverless 是 Midway 体系下
后端微服务云原生Midway Serverless 框架入门:函数即服务(FaaS)能力边界与术语体系全解析
Midway Serverless 框架入门:函数即服务(FaaS)能力边界与术语体系全解析 本文基于 Midway 开源仓库 site/versioned_d
后端微服务云原生Midway Serverless 入门指南:基于 @midwayjs/faas 的 Node.js 云函数开发全解析
Midway Serverless 入门指南:基于 @midwayjs/faas 的 Node.js 云函数开发全解析 导读 Midway Serverless
后端微服务云原生
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考