1. 引言
Serverless 是一种 “无服务器架构”,让用户无需关心程序运行环境、资源及数量,只要将精力 Focus 到业务逻辑上的技术。
现在公司已经实现 DevOps 化,正在向 Serverless 迈进,而为什么前端要关注 Serverless?
对业务前端同学:
1.会改变前后端接口定义规范。
2.一定会改变前后端联调方式,让前端参与服务器逻辑开发,甚至 Node Java 混部。
3.大大降低 Nodejs 服务器维护门槛,只要会写 JS 代码就可以维护 Node 服务,而无需学习 DevOps 相关知识。
对一个自由开发者:
4.未来服务器部署更弹性,更省钱。
5.部署速度更快,更不易出错。
前端框架总是带入后端思维,而 Serverless 则是把前端思维带入了后端运维。
前端开发者其实是最早享受到 “Serverless” 好处的体。他们不需要拥有自己的服务,甚至不需要自己的浏览器,就可以让自己的 JS 代码均匀、负载均衡的运行在每一个用户的电脑中。
而每个用户的浏览器,就像现在最时髦,最成熟的 Serverless 集,从远程加载 JS 代码开始冷启动,甚至在冷启动上也是卓越领先的:利用 JIT 加速让代码实现毫秒级别的冷启动。不仅如此,浏览器还是实现了 BAAS 服务的完美环境,我们可以调用任何函数获取用户的 Cookie、环境信息、本地数据库服务,而无需关心用户用的是什么电脑,连接了怎样的网络,甚至硬盘的大小。
这就是 Serverless 理念。通过 FAAS(函数即服务)与 BAAS(后台即服务)企图在服务端制造前端开发者习以为常的开发环境,所以前端开发者应该更能理解 Serverless 带来的好处。
2. 精读
FAAS(函数即服务) + BAAS(后台即服务) 可以称为一个完整的 Serverless 的实现,除此之外,还有 PASS(平台即服务)的概念。而通常平台环境都通过容器技术实现,最终都为了达到 NoOps(无人运维),或者至少 DevOps(开发&运维)。
简单介绍一下这几个名词,防止大家被绕晕:
FAAS - Function as a service
函数即服务,每一个函数都是一个服务,函数可以由任何语言编写,除此之外不需要关心任何运维细节,比如:计算资源、弹性扩容,而且可以按量计费,且支持事件驱动。业界大云厂商都支持 FAAS,各自都有一套工作台、或者可视化工作流来管理这些函数。
BAAS - Backend as a service
后端及服务,就是集成了许多中间件技术,可以无视环境调用服务,比如数据即服务(数据库服务),缓存服务等。虽然下面还有很多 XAAS,但组成 Serverless 概念的只有 FAAS + BAAS。
PAAS - Platform as a service
平台即服务,用户只要上传源代码就可以自动持续集成并享受高可用服务,如果速度足够快,可以认为是类似 Serverless。但随着以 Docker 为代表的容器技术兴起,以容器为粒度的 PAAS 部署逐渐成为主流,是最常用的应用部署方式。比如中间件、数据库、操作系统等。
DAAS - Data as a service
数据即服务,将数据采集、治理、聚合、服务打包起来提供出去。DAAS 服务可以应用 Serverless 的架构。
IAAS - Infrastructure as a Service
基础设施即服务,比如计算机存储、网络、服务器等基建设施以服务的方式提供。
SAAS - Software as a Service
软件即服务,比如 ERP、CRM、邮箱服务等,以软件为粒度提供服务。
容器
容器就是隔离了物理环境的虚拟程序执行环境,而且环境可被描述、迁移。比较热门的容器技术是 Docker。
随着容器数量增多,就出现了管理容器集的技术,比较有名的容器编排平台是 Kubernetes。容器技术是 Serverless 架构实现的一种选择,也是实现的基础。
NoOps
就是无人运维,比较理想主义,也许要借助 AI 的能力才能实现完全无人运维。
无人运维不代表 Serverless,Serverless 可能也需要人运维(至少现在),只是开发者不再需要关心环境。
DevOps
笔者觉得可以理解为 “开发即运维”,毕竟出了事情,开发要被问责,而一个成熟的 DevOps 体系可以让更多的开发者承担 OP 的职责,或者与 OP 更密切的合作。
回到 Serverless,未来后端开发的体验可能与前端相似:不需要关心代码运行在哪台服务器(浏览器),无需关心服务器环境(浏览器版本)、不用担心负载均衡(前端从未担心过)、中间件服务随时调用(LocalStorage、Service Worker)
前端同学对 Serverless 应该尤为激动。就拿笔者亲身经历举例吧。
从做一款游戏说起
笔者非常迷恋养成类游戏,养成游戏最常见的就是资源建造、收集,或者挂机时计算资源的 读秒规则前端有哪些常用框架。笔者在开发游戏的时候,最初是将客户端代码与服务端代码完全分成两套实现的:
// ... UI 部分,画出一个倒计时伐木场建造进度条
const currentTime = await requestBuildingProcess();
const leftTime = new Date().getTime() - currentTime;
// ... 继续倒计时读条
/
/ 读条完毕后,每小时木头产量 + 100,更新到客户端计时器
store.woodIncrement += 100;
为了游戏体验,用户可以在不刷新浏览器的情况下,看到伐木场建造进度的读条,以及 嘭 一下建造完毕,并且发现每秒钟多获得了 100 点木材!但是当伐木场 建造完成前、完成时、完成后的任意时间点刷新浏览器,都要保持逻辑的统一,而且数据需要在后端离线计算。 此时就要写后端代码了:
// 每次登陆时,校验当前登陆
const currentTime = new Date().getTime()
// 获取伐木场当前状态
if ( /* 建造中 */) {
  // 返回给客户端当前时间
  const leftTime = building.startTime - currentTime
  res.body = leftTime
} else {
  // 建造完毕
  store.woodIncrement += 100
}
很快,建筑的种类多了起来,不同的状态、等级产量都不同,前后端分开维护成本会越来越大,我们需要做配置同步。
配置同步
为了做前后端配置同步,可以将配置单独托管起来前后端共用,比如新建一个配置文件,专门存储游戏信息:
export const buildings = {
  wood: {
    name: "..",
    maxLevel: 100,
    increamentPerLevel: 50,
    initIncreament: 100
  }
  /* .. and so on .. */
};
这虽然复用了配置,但前后端都有一些共同的逻辑可以复用,比如 根据建筑建造时间判断建筑状态,判断 N 秒后建筑的产量等等。 而 Serverless 带来了进一步优化的空间。
在 Serverless 环境下做游戏
试想一下,可以在服务器以函数粒度执行代码,我们可以这样抽象游戏逻辑:
// 根据建筑建造时间判断建筑状态
export const getBuildingStatusByTime = (instanceId: number, time: number) => {
  /**/
};

/
/ 判断建筑生产量
export const getBuildingProduction = (instanceId: number, lastTime: number) => {
  const status = getBuildingStatusByTime(instanceId, new Date().getTime());
  switch (status) {
    case "building":
      return 0;
    case "finished":
      // 根据 (当前时间 - 上次打开时间)* 每秒产量得到总产量
      return; /**/
  }
};

// 前端 UI 层,每隔一秒调用一次 getBuildingProduction 函数,及时更新生产数据
// 前端入口函数
export const frontendMain = () => {
  /**/
};

// 后端 根据每次打开时间,调用一次 getBuildingProduction 函数并入库
// 后端入口函数
export const backendMain = () => {
  /**/
};
利用 PASS 服务,将前后端逻辑写在一起,将 getBuildingProduction 函数片段上传至 FAAS 服务,这样就可以同时共享前后端逻辑了!
在文件夹视图下,可以做如下结构规划:
.
├── client    # 前端入口
├── server    # 后端入口
├── common    # 共享工具函数,可以包含 80% 的通用游戏逻辑
也许有人会问:前后端共享代码不止有 Serverless 才能做到。
的确如此,如果代码抽象足够好,有成熟的工程方案支持,是可以将一份代码分别导出到浏览器与服务器的。但 Serverless 基于函数粒度功能更契合前后端复用代码的理念,它的出现可能会推动更广泛的前后端代码复用,这虽然不是新发明,但足够称为一个伟大的改变。
前后端的视角
对于前端开发者,会发现后台服务变简单了。对于后端开发者,发现服务做厚了,面临的挑战更多了。
更简单的后台服务
传统 ECS 服务器在租赁时,CentOS 与 AliyunOS 的环境选择就足够让人烦恼。对个人开发者而言,我们要搭建一个完整的持续集成服务是很困难的,而且面临的选择很多,让人眼花缭乱:
•可以在服务器安装数据库等服务,本地直联服务器的数据库进行开发。
•可以本地安装 Docker 连接本地数据库服务,将环境打包成镜像整体部署到服务器。
•将前后端代码分离,前端代码在本地开发,服务端代码在服务器开发。
甚至服务器的稳定性,需要 PM2 等工具进行管理。当服务器面临攻击、重启、磁盘故障时,打开复杂的工作台或登陆 Shell 后一通操作才能恢复。这怎么让人专心把精力放在要做的事情上呢?
Serverless 解决了这个问题,因为我们要上传的只是一个代码片段,不再需要面对服务器、系统环境、资源等环境问题,外部服务也有封装好的 BAAS 体系支持。
实际上在 Serverless 出来之前,就有许多后端团队利用 FAAS 理念简化开发流程。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。