微信小程序云端解决方案探索之路 - GITC 主题演讲

时间:2022-09-17 16:06:33

转自:https://github.com/tencentyun/blog/issues/1

在刚结束的全球互联网技术大会(GITC)里面,我在前端专场给大家分享了「微信小程序云端解决方案探索之路」,介绍到了我们之前对小程序云端解决方案的探索过程。

小程序特性思考

小程序刚推出的时候,很多人都觉得它就是 H5,因为开发小程序的三大语言和 HTML、CSS、JS 是一脉相承的,即使改变了扩展名也改不了其实质。

那么小程序的实质到底是不是 H5 呢?经过我们的论证分析,我们认为小程序并不是 H5 应用。主要原因如下:

  1. 在小程序里面无法使用 DOM 接口,所以 HTML5 生态中一切基于 DOM 的库都无法使用(如 jQuery)
  2. 小程序并非使用 URL 访问,所以没有域名的概念。这个特性有两个影响
    • 不存在跨域问题,所以访问控制是直接在微信 MP 上配置域名白名单
    • 不支持 Cookie 存储,这将导致后面我们重点研究了会话管理的实现

从上面两个角度来考虑,我们认为小程序更偏向于传统的 CS 架构。

那么,小程序和传统 CS 架构的区别在哪儿?主要包括下面两点:

  1. 网络和续航
    小程序在移动端运行,网络环境会比较复杂,频繁的网络连接可能会过度消耗资源导致续航下降,所以小程序对网络和资源的优化都提出了要求。
  2. 伸缩能力
    小程序寄托在微信平台上运行,作为一个十亿级的社交平台,业务可能会面临爆炸式的增长。如果在爆点小程序不能快速伸缩应对,那么将失去这样一个重要的机会。所以小程序对其后台架构的伸缩能力提出了比较高的要求。

门槛和挑战

在上面一些结论下,我们进行了一些尝试,包括上传下载、会话管理、WebSocket、视频点播等等。这次重点来分享会话管理和 WebSocket,因为我们面临的挑战主要集中在这两个案例上。

会话管理

我们最早开发了一个一笔到底的案例来实现会话管理,案例需要根据用户保存用户的作品,每次用户登录,都可以看到用户自己的绘画。

但是,因为小程序不支持 Cookie 传输,所以会话服务需要自行实现。

我们会话管理的实现目标是:

  1. 完成微信要求的鉴权流程,生成用户会话
  2. 利用会话确定每个请求对应哪个微信用户
  3. 安全性和扩展性满足要求

我们案例按照这个流程进行会话建立:

微信小程序云端解决方案探索之路 - GITC 主题演讲

其中在小程序和服务器我们分别提供 JS 和 Node SDK 来提供会话支持。这个案例完成了会话服务的功能性目标,可以提供会话建立和验证的能力。但是弊端在于,该能力只能被 Node 开发者使用,其他语言的开发者无法使用。同时,因为小程序的 appId 和 appSecret 存放在外网可以访问的服务器上,也有一定安全性问题。会话服务和我们的业务耦合在一起,也给后续的横向扩展带来了麻烦。

于是,我们提出了改进的手段:

  1. 会话管理服务器独立提供
  2. 提供多语言的 SDK
  3. appId 和 appSecret 存放到数据库中

其中多语言的 SDK 正式因为会话管理服务器的独立而可以快速开发到。

优化后,会话的建立流程如下图所示:

微信小程序云端解决方案探索之路 - GITC 主题演讲

而会话的验证流程如下图所示:

微信小程序云端解决方案探索之路 - GITC 主题演讲

我们的会话服务改进取得的效果还是很明显的:

  1. 流程和安全性上完全符合了微信的鉴权要求
  2. 独立会话服务器,可以方便进行独立的升级和扩展,也为多语言 SDK 的开发打开了方便的大门

信道服务

我们面临的另外一个挑战就是 WebSocket。在进行案例分析之前,先跟大家分析一下微信支持 WebSocket 的原因。

传统的 HTTPS 连接请求,每个请求都需要建立一次连接,耗费比较多的资源。同时微信有最大连接数的限制(5个),所以实时通信的需求不好做,长连接的方案也只能串行传输,这种方案耗电高体验差。

当我们把目光转向 WebSocket 之后,会发现 WebSocket 通信全程只需要建立一次连接,就可以实现双向的实时通信,更省电的情况下获得更好的体验。

这就是小程序支持 WebSocket 的一个重要原因,可以提高业务的体验并增加续航。

鉴于很多同学可能对 WebSocket 还不了解,这里简单介绍一下。

微信小程序云端解决方案探索之路 - GITC 主题演讲

我们的 HTTP 连接是在 TCP 的基础上建立的,当服务器支持 WebSocket 的时候,可以相应一个头部,告知客户端进行协议升级。升级协议后,会复用之前的 TCP 连接,在上面实现 WebSocket 协议实现双向通信。更加详细的资料可以参考 MDN 上的说明。

回到我们的案例上来,我们当时使用小程序提供的 WebSocket 做了一个实时的剪刀石头布游戏。

微信小程序云端解决方案探索之路 - GITC 主题演讲

我们使用 Socket.IO 实现其后端后,发现在小程序无法使用 Socket.IO 的客户端代码支持。我们只能自己去啃了一下 Socket.IO 的上层协议,实现了一个简版的客户端,从而实现剪刀石头布这个游戏逻辑。

这个案例验证了在小程序上面 WebSocket 的可行性,但是由于客户端的实现是自行实现,和 Socket.IO 的后端配合可能会出现不可控的情况。同时,我们发现 WebSocket 的后端实现门槛比较高,并且进行横向扩展的话会更加困难。

作为云服务厂商,我们首先想到的方案是使用 PaaS 提供服务来支持 WebSocket 连接。这是怎么一个思路呢?

微信小程序云端解决方案探索之路 - GITC 主题演讲

上图很好地解释了 PaaS 形式和传统 WebSocket 形式的不同之处,PaaS 实际上是要实现一个三方通信。

我们看一下使用 PaaS 服务来建立 WebSocket 连接的过程:

微信小程序云端解决方案探索之路 - GITC 主题演讲

建立连接后,小程序和业务服务器之间可以通过下面的形式进行通信:

微信小程序云端解决方案探索之路 - GITC 主题演讲

经过 PaaS 的改造,我们得到了一个新的 WebSocket 方案。该方案的优劣在哪里?

首先,优势比较明显,由平台来提供的服务,由平台自己完成扩展能力的支持以及稳定性和性能的保障,业务无需担心。同时,业务也无需关心 WebSocket 协议的实现,因为业务服务器和信道服务之前的通信都是传统的 HTTP,这样也可以节约业务服务器的长连接资源。

但是这种方案也有它的局限之处。业务服务器和信道服务器之间采取公网通信,处于对信息安全的考虑,最好还是走 HTTPS 通信,这个过程的通信延迟比较客观。其次,三方通信的调试便利性也不如传统的连接方式。

对于上面两个问题,其实我们也有对应方案。如果业务服务器在腾讯云机房运行,那么可以让业务服务器和信道服务器之间通过内网 HTTP 传输,延迟大大降低。信道服务后续也会提供调试日志供大家分析发现问题。

总体来说,PaaS 方案会帮助更多开发者解决掉了门槛较高的部分。

整合

我们上面对于会话服务和信道服务都进行了一个有益的实践,那么这两个服务是否可以整合,信道服务里面是否可以支持会话识别?

事实上我们可以做这个事情。下面的表格描述了会话服务和信道服务与服务模块之间的关系。

微信小程序云端解决方案探索之路 - GITC 主题演讲

我们可以把客户端的部分整合为客户端 SDK,把业务服务器的部分整合为服务器 SDK,并且提供会话服务器的源码开源。

那么上面三个部分加起来,就是目前腾讯云的开源项目 - Wafer

Wafer 包含了会话服务和信道服务的支持,从全栈模块来提供开源的资源,并且提供了丰富的文档。有兴趣的开发者可以使用上面的连接来查看 Wafer 项目。

产品化实践

微信小程序云端解决方案探索之路 - GITC 主题演讲

Wafer 帮开发者解决了小程序开发过程中信道服务和会话服务的门槛问题,但是作为小程序开发者,还要关心后台架构、资源采供、资源部署、扩展能力、安全性、域名申请等等与业务开发无关的部分。这部分,我们提出了一个一站式部署的方案。

微信小程序云端解决方案探索之路 - GITC 主题演讲

这个方案,会帮你分配好资源并自动部署下面的架构,让开发者可以专注于业务开发。

微信小程序云端解决方案探索之路 - GITC 主题演讲

自动部署的过程其实挺复杂的,有兴趣的同学可以参考下图了解。

微信小程序云端解决方案探索之路 - GITC 主题演讲

上面就是 Wafer 的产品化实践 - 腾讯云小程序一站式解决方案