一、背景说明

先说明一下背景。Serverless 云函数: 云计算发展过程中出现的一种计算资源的抽象,它以云计算平台为基础,为开发者提供业务程序的运行环境,开发者无需关注底层资源分配、扩容部署,代码执行所必要的全部服务由平台提供。

SSR 服务端渲染: 指在服务端将 HTML 渲染到前端,早期常用 "php jsp" 技术来在服务端生成 HTML,近年来 js 同构化趋势演进下,逐步出现了在服务端上运行前端 js 代码进行渲染的方案,如 React、Vue 等主流框架的同构渲染。

若能将 Serverless 技术落地到 SSR 场景,将会有如下优点

  • 云服务资源理论上无限扩容,前端不必考虑业务量对 SSR 机器性能的影响

  • 前端同学无需关注 SSR 机器的运维、申请、扩容

目前 NOW 直播 IVWEB 团队正逐步将 SSR 业务迁移到腾讯云云函数平台上,精简部署运维成本,响应公司自研上云。

二、Serverless 的演进

阿 J 是一个前端开发仔,某天产品跟他说页面白屏加载接口的时间太长了,体验差,这对于优秀的前端开发仔的他并不是难事,他有 99 种让页面加载变快的办法,因此他立马将利用项目中的团队直出架构半天接入了直出,接下来要将直出服务部署到现网,这时他犯难了:

  1. 部署直出服务需要申请机器,申请多少台,申请几核的?

  2. 这个业务量怎么样,有没有突发请求,机器有没有扩容机制?

  3. Nginx 配置怎么改,直出失败的话要怎么接入兜底的静态页面?

恍惚间,他看见腾讯云的同事关于 Serverless 架构演进的 ppt ….

从 IaaS 到 FaaS

在介绍 SCF 云函数之前,我们先来 diff 一下传统 IaaS 业务架构和云函数 FaaS 业务架构:

基于虚拟机的业务架构 (IaaS)

而云函数架构是这样的:

基于云函数的业务架构 (FaaS)

阿 J 对比两者得出,在基于云函数的业务架构下,开发者无需再关注业务基础层的相关配置,可以集中精力处理业务逻辑的开发,基础层由平台负责维护迭代,只要将我们的直出服务部署上云就可以解决部署直出业务中的运维痛点了。

Serverless 的演进

FaaS 的出现使得服务上云变得容易起来,但是 FaaS 并没有解决「公共基础服务」的问题,而所谓公共基础服务,就是形如对象存储、KV存储、消息推送这样的基础服务,这个问题最终落到了云服务提供商这里,因此市面上的云服务无一例外的都提供了上面的「公共基础服务」,这样的服务模式叫做 BaaS(Backend as a Service)。
Serverless 直译过来叫无服务器,这里并不是说不需要服务器,而是说开发者不需要关注服务器,这部分由平台维护提供,开发者仅需关注业务逻辑的开发即可。

Serverless 架构下的 App

用户无须关注支撑应用服务运行的底层资源,以「函数」的形式承载业务逻辑,以「BaaS 服务」的形式支撑公共服务。


考虑到直出服务的特性,阿 J 认为直出业务十分适合上 Serverless,因此他立马开始了前端上云的预研,做 Serveless SSR 服务,免去运维部署烦恼,减少直出接入成本!

三、SCF 云函数开发

阿 J 认真研究了腾讯云的云函数(Serverless Cloud Function,SCF)发现云函数它可以将我们的业务拆成更细的粒度「函数」,而函数的执行环境开发者不需要关注,由平台负责,以下是阿 J 对云函数执行的理解。

云函数执行过程

云平台在执行这些「云函数」的过程其实就是在对外提供服务,通常情况下,Serverless 函数会用于「响应 HTTP 请求」,即通过 HTTP 访问事件来触发云函数的执行,如下图所示:

云函数用户请求链路

而函数的执行不外乎:入参、上下文、返回值、副作用,如图所示:

云函数执行过程

「入参」:云函数的入参即 HTTP 请求中的请求头、请求体
「上下文」:包含此次函数请求的 id、函数执行的环境变量等等
「副作用」:云函数执行可能调用外部服务,如数据库、对象存储、数据监控
「返回值」:即 http 响应如 { retcode: 0, msg: "success" }

阿 J 还了解到根据一定配置部署完云函数之后,云平台会给你一个 URL,通过访问这个 URL 就可以触发对应云函数执行,得到结果。

四、NGW Serverless 同构直出方案

正当阿 J 着手进行 Serverless 直出开发的时候,他猛然发现,Serverless 环境下跟原有的直出环境有较大出入,原有的直出环境是这样的:

  1. 原方案直出是使用 TSW 执行 Koa App 的方式进行直出的,这意味着原方案需要监听端口而不是作为函数来运行,这个要怎么处理?

  2. 云函数怎么做到工程化打包发布,接入到团队现有的 CI 流程中?

  3. 原方案可以做本地调试,而云函数直出怎么做本地调试?

  4. 云函数发布后,会得到一个 URL,那么这个 URL 要怎么接入我们的业务域名下?

  5. 老业务能不能做到无缝迁移到云函数?能不能做到新直出方案兼容老直出方案?

工程化打包

除去前端 webpack 打包之外,对于 Serverless 云函数平台,我们还得在原来的打包产物基础上再做一些操作,其核心在于「打包为 zip 上传到云函数」,如下图所示:

云函数打包

在这里需要引入一个 CLI 工具来打包 zip 和上传云函数,原因是如果需要接入 CI 流程,就要提供命令式的部署来进行 CI 流程。

Serverless 下的同构环境

阿 J 考虑到原先业务的直出方案采用 TSW (https://github.com/tencent/tsw) 来做,但是在 Serverless 下,我们不能把 TSW 搬进云函数里执行,而是抽取了其中我们需要的组件出来,如 tsw ajax http、监控上报、tsw logger 等常用组件,因为:

  1. 方便老业务无缝迁移到云函数直出,解决直出业务的运维痛点

  2. TSW 很大,压缩后近 20 MB,解压出来大很多,不利于云函数的性能

除此之外,还要自己去实现 window.REQUEST plug 类似这样的 TSW 全局注入的对象,因为旧有方案也有依赖这些。

「流式」和「块式」

原来的方案需要 Koa 监听本地端口才能提供服务,而云函数的出入参是块式的,Koa 的出入参是流式的,因此这里需要处理一下云函数的入参。阿 J 的做法是根据云函数入参来动态构造 http 的 IncomingMessage 和 ServerResponse 然后透传给 Koa App 进行直出渲染,最后从 ServerResponse 里取得渲染结果构造为云函数返回值返回。

NGW 作网关转发

阿 J 考虑到业务的可用性以及之前链路接入的痛苦,决定接入 NGW(Node Gateway):

NGW 下的 Serverless 直出链路

通过 NGW 可以做到:

  1. 实现兜底逻辑:云函数可能会 crash,这时候走静态页面接入机

  2. 灰度逻辑:直出上现网的过程中可以通过 NGW 的配置进行部分灰度测试

  3. 链路日志收归:长期以来,前端不好查具体的链路信息,现在有了 NGW 一切皆有可能

云函数本地调试

云函数的无状态模型使得其非常易于进行本地调试,我们只需要在本地构造函数的入参、上下文即可直接进行直出调试了,阿 J 在实际实现中是通过本地起一个 Koa 服务监听端口,利用这个端口的请求来构造入参、上下文,最后传入函数执行结果,返回到前端显示。

同构直出过程

在最后,阿 J 完成了 Serverless 直出方案,其直出过程如下图所示:

同构直出过程

其中有三个核心步骤:「Init」:初始化云函数环境、接受并处理云函数的入参「Koa」:React 同构业务逻辑以 Koa App 的形式体现「Clear」:清理云函数环境、处理 Koa Response 返回直出结果

云函数的性能瓶颈和优化

阿 J 在完成了新直出方案之后马上进行了压测,发现随着压测压力的增加,收包率会出现断崖式下跌,而且还发现部分函数执行耗费时间非常长,联系了云函数的同事看了下发现是「冷启动问题」,那什么是冷启动?
从云函数的架构中可以看到,云函数触发后并不是马上执行,它需要一个环境初始化的过程,这种启动叫做冷启动;还有种情况是,这次请求的函数执行之后马上接到下一次请求,这时候就不用重新初始化云函数环境,而是直接启动,这种称谓热启动。


云函数执行时间分布图

收包率优化前(左)优化后(右)

冷启动问题在压力低的情况下不明显,但是在高并发的情况下就会额外影响回包了,这里SCF 的同事进行了优化:提高最小实例数,减少冷启动,最小实例越多就越能扛住瞬时并发。
此外我们还发现了内存的问题,这里联系了 SCF 的同事进行了 Node 内存模型的相关优化,优化后,已基本不存在 4xx 的问题。

内存超限会报 4xx 的问题,压力越大越容易出现

内存模型优化后表现

到这一步,阿 J 终于初步完成了 Serverless 直出方案设计开发,并逐步在业务中使用推广。

现状和下一步计划


目前 NGW + Serverless SSR 已经应用到 NOW 直播、手 Q 附近、浏览器直播和手 Q 群送礼等多个项目中,实际业务开发中,Node 业务的部署和运维工作量降低了 80% 以上。

阿 J 下一步的计划:

  1. 完善的云函数版本管理

  2. 配合 webpack 进一步优化本地直出调试体验

  3. 配合腾讯云同事进一步优化云函数性能

  4. 完善 React Chunked 流式渲染方案,进一步提升首屏加载速度;

  5. 完善 Node 服务云函数,计划做前端 BFF 方案

  6. 完善直出和链路日志收归,增强服务监控能力

前端入职后很痛苦_NGW前端新技术赛场:Serverless SSR 技术内幕相关推荐

  1. 前端和后端哪个累,前端入职之后真的很痛苦吗

    前端VS后端" 哪个更好? 前端和后端哪个累,前端入职之后真的很痛苦吗 web前端开发和后端开发哪个好,这是许多程序员新手一定会问的问题,毕竟,男怕入错行,那么前端和后端哪个是更好的选择,小 ...

  2. 前端实习生入职后都做什么?

    入职第一天: 入职后会收到项目的git信息(包括git地址,个人账号和密码),会有一个公司邮箱,登录企业微信,钉钉关联手机号,用来每日上下班打卡. 熟悉项目: 了解公司项目开发使用的编辑器,熟悉编辑器 ...

  3. web前端入职配置_我如何从全职妈妈变成前端Web开发人员

    web前端入职配置 I thought about writing about my personal coding journey many times, but never had the cou ...

  4. 程序员入职后千万不要沾沾自喜,不注意这一点,将来很可能后悔!

    程序员入职后千万不要沾沾自喜,不注意这一点,将来很可能后悔! 没错!那就是职业规划,作为一个技术领域的程序员,如果你每天只是为了完成基本的工作的话,那么你肯定会在不久的将来被淘汰的,所以你如果不重视这 ...

  5. 前端入职第一天,应该做什么

    前端入职第一天,应该做什么 1.安装Node 2 .安装前端开发工具及扩展插件 3.安装npm 4.安装yarn 5.安装谷歌浏览器 6.下载git 7.下载postman 1.安装Node Node ...

  6. 入职开发很少写代码_如何简化开发人员入职:将开发环境作为代码

    入职开发很少写代码 Imagine that only a decade ago system administrators deployed, configured, and maintained ...

  7. 入职后发现公司是外包全职_我如何通过全职工作,伴侣和3岁的双胞胎男孩打造产品...

    入职后发现公司是外包全职 by Courtney 通过考特尼 我如何通过全职工作,伴侣和3岁的双胞胎男孩打造产品 (How I built my product with a full-time jo ...

  8. 信仰的力量—海归毕业季的选择与入职后的蜕变记

    叮!又到了校招story时间!今天的主人公是8年海归硕士小钱同学. 别人看到的是他一路名校,披光归来,可疫情期能否留美?回国后选择哪座城市?未来的职业道路如何规划?他的毕业季同样充满了刷题.尝试.失败 ...

  9. 面试官答应给8000工资,新员工入职后变4千,签合同时愣了

    现如今,很多公司在招聘时,往往会打出高工资的幌子来吸引求职者.等员工入职后才发现实际不是这么一回事,工资缩水,待遇也不如说的那么好,只能选择不入职.但求职者已经浪费的时间却没能得到任何补偿,现实往往很 ...

  10. 程序员入职后如何尽快适应新岗位?

    在顺利入职后,如何尽快适应新岗位呢?下面,千锋就为大家支几招,希望大家能够顺利开启职场生涯. 首先,尽快熟悉团队里的规则.有的规则是显性的,有些是隐性的,通常隐性规则比显性规则多.显性规则主要有:公司 ...

最新文章

  1. mysql 写binlog 原理_MySQL binlog原理及应用
  2. linux C语言如何获取进程号和线程号?getpid()、syscall(__NR_gettid)
  3. html切换选择项,HTML选择选项元素
  4. brand.php dnfire.cn_能美火灾报警_能美西科姆消防报警主机如何屏蔽故障点_滁州气象...
  5. ASSERT: “QGLFunctions::isInitialized(d_ptr)“ - Runtime Exception
  6. c#进阶(2)—— ASP.NET MVC 常用路由总结
  7. druid mysql配置详解_druid 参数配置详解
  8. paper reading: roi 区域对人脸测试心率有用
  9. PyTorch入门(二)从零开始搭建一个神经网络
  10. 简单java游戏代码_Java经典小游戏——贪吃蛇简单实现(附源码)
  11. C# 注册dll的两种方式
  12. Tango学习笔记(1)
  13. 中国最美的100首古代情诗
  14. 蚂蚁金服区块链+公益又有新动作,助力相互保险爱心救助账户
  15. LED阵列PCB灯板绘制
  16. 恢复快速启动栏显示桌面按钮
  17. 2021吉林省建筑类职称评审代理评审
  18. 淘宝卖家过劳死VS富士康跳楼死
  19. linux ps 0 1 console,linux终端-console
  20. Java封装类和基本类型的区分

热门文章

  1. 基于中颖SH79F168单片机的航模无刷电调方案
  2. 7.数据结构 --- 图
  3. 10.数据管理(内存,文件锁)
  4. 53. 使 Ajax 可缓存(14)
  5. 42. 添加 Expires 头(3)
  6. 2. Magento2 --- (2) theme --- structure
  7. java 读取clob字段的几种方法
  8. 【问题】ajax两种传递id值方式的区别
  9. 6个基本screen命令
  10. SD2.0大会第1天心得