先说明一下背景。php
Serverless 云函数: 云计算发展过程当中出现的一种计算资源的抽象,它以云计算平台为基础,为开发者提供业务程序的运行环境,开发者无需关注底层资源分配、扩容部署,代码执行所必要的所有服务由平台提供。 SSR 服务端渲染: 指在服务端将 HTML 渲染到前端,早期经常使用 php jsp 技术来在服务端生成 HTML,近年来 js 同构化趋势演进下,逐步出现了在服务端上运行前端 js 代码进行渲染的方案,如 React、Vue 等主流框架的同构渲染。前端
若能将 Serverless 技术落地到 SSR 业务场景,将会有以下优势webpack
目前 NOW 直播 IVWEB 团队正逐步将 SSR 业务迁移到腾讯云云函数平台上,精简部署运维成本,响应公司自研上云号召。nginx
阿 J 是一个前端开发仔,某天产品跟他说页面白屏加载接口的时间太长了,体验差,这对于优秀的前端开发仔的他并非难事,他有 99 种让页面加载变快的办法,所以他立马将利用项目中的团队直出架构半天接入了直出,接下来要将直出服务部署到现网,这时他犯难了:git
- 部署直出服务须要申请机器,申请多少台,申请几核的?
- 这个业务量怎么样,有没有突发请求,机器有没有扩容机制?
- nginx 配置怎么改,直出失败的话要怎么接入兜底的静态页面?
恍惚间,他看见腾讯云的同事关于 Serverless 架构演进的 ppt ....github
在介绍 SCF 云函数以前,咱们先来 diff 一下 传统 IaaS 业务架构
和 云函数 FaaS 业务架构
:web
而云函数架构是这样的:ajax
阿 J 对比二者得出,在基于云函数的业务架构下,开发者无需再关注业务基础层的相关配置,能够集中精力处理业务逻辑的开发,基础层由平台负责维护迭代,只要将咱们的直出服务部署上云就能够解决部署直出业务中的运维痛点了。数据库
FaaS 的出现使得服务上云变得容易起来,可是 FaaS 并无解决 「公共基础服务」 的问题,而所谓公共基础服务,就是形如对象存储、KV存储、消息推送这样的基础服务,这个问题最终落到了云服务提供商这里,所以市面上的云服务无一例外的都提供了上面的「公共基础服务」,这样的服务模式叫作 BaaS(Backend as a Service)。浏览器
Serverless 直译过来叫无服务器,这里并非说不须要服务器,而是说开发者不须要关注服务器,这部分由平台维护提供,开发者仅需关注业务逻辑的开发便可。
用户无须关注支撑应用服务运行的底层资源,以「函数」的形式承载业务逻辑,以「BaaS 服务」的形式支撑公共服务。
考虑到直出服务的特性,阿 J 认为直出业务十分适合上 Serverless,所以他立马开始了前端上云的预研,作 Serveless SSR 服务,免去运维部署烦恼,减小直出接入成本!
阿 J 认真研究了腾讯云的云函数(Serverless Cloud Function,SCF)发现云函数它能够将咱们的业务拆成更细的粒度「函数」,而函数的执行环境开发者不须要关注,由平台负责,如下是阿 J 对云函数执行的理解。
云平台在执行这些「云函数」的过程其实就是在对外提供服务,一般状况下,Serverless 函数会用于「响应 HTTP 请求」,即经过 HTTP 访问事件来触发云函数的执行,以下图所示:
而函数的执行不外乎:入参、上下文、返回值、反作用,如图所示:
阿 J 还了解到根据必定配置部署完云函数以后,云平台会给你一个**「Invoke URL」**,经过访问这个 URL 就能够触发对应云函数执行,获得结果。
正当阿 J 着手进行 Serverless 直出开发的时候,他猛然发现,Serverless 环境下跟原有的直出环境有较大出入,原有的直出环境是这样的:
除去前端 webpack 打包以外,对于 Serverless 云函数平台,咱们还得在原来的打包产物基础上再作一些操做,其核心在于「打包为 zip 上传到云函数」,以下图所示:
在这里须要引入一个 CLI 工具来打包 zip 和上传云函数,缘由是若是须要接入 CI 流程,就要提供命令式的部署来进行 CI 流程。
阿 J 考虑到原先业务的直出方案采用 TSW (github.com/tencent/tsw) 来作,可是在 Serverless 下,咱们不能把 TSW 搬进云函数里执行,而是抽取了其中咱们须要的组件出来,如 tsw ajax http、监控上报、tsw logger 等经常使用组件,由于:
除此以外,还要本身去实现 window.REQUEST plug 相似这样的 TSW 全局注入的对象,由于旧有方案也有依赖这些。
原来的方案须要 Koa 监听本地端口才能提供服务,而云函数的出入参是块式的,Koa 的出入参是流式的,所以这里须要处理一下云函数的入参。阿 J 的作法是根据云函数入参来动态构造 http 的 IncomingMessage 和 ServerResponse 而后透传给 Koa App 进行直出渲染,最后从 ServerResponse 里取得渲染结果构造为云函数返回值返回。
阿 J 考虑到业务的可用性以及以前链路接入的痛苦,决定接入 NGW(Node Gateway):
经过 NGW 能够作到:
云函数的无状态模型使得其很是易于进行本地调试,咱们只须要在本地构造函数的入参、上下文便可直接进行直出调试了,阿 J 在实际实现中是经过本地起一个 Koa 服务监听端口,利用这个端口的请求来构造入参、上下文,最后传入函数执行结果,返回到前端显示。
在最后,阿 J 完成了 Serverless 直出方案,其直出过程以下图所示:
其中有三个核心步骤:
阿 J 在完成了新直出方案以后立刻进行了压测,发现随着压测压力的增长,收包率会出现断崖式下跌,并且还发现部分函数执行耗费时间很是长,联系了云函数的同事看了下发现是「冷启动问题」,那什么是冷启动? 从云函数的架构中能够看到,云函数触发后并非立刻执行,它须要一个环境初始化的过程,这种启动叫作冷启动;还有种状况是,此次请求的函数执行以后立刻接到下一次请求,这时候就不用从新初始化云函数环境,而是直接启动,这种称谓热启动。
冷启动问题在压力低的状况下不明显,可是在高并发的状况下就会额外影响回包了,这里SCF 的同事进行了优化:提升最小实例数,减小冷启动,最小实例越多就越能扛住瞬时并发。 此外咱们还发现了内存的问题,这里联系了 SCF 的同事进行了 Node 内存模型的相关优化,优化后,已基本不存在 4xx 的问题。
到这一步,阿 J 终于初步完成了 Serverless 直出方案设计开发,并逐步在业务中使用推广。
目前 NGW + Serverless SSR 已经应用到 NOW 直播、手 Q 附近、浏览器直播和手 Q 群送礼等多个项目中,实际业务开发中,Node 业务的部署和运维工做量下降了 80% 以上。
阿 J 下一步的计划:
关注【IVWEB社区】公众号获取每周最新文章,通往人生之巅!