推荐阅读!GITC主题演讲:微信小程序云解决方案探索之路
在刚刚结束的全球互联网技术大会(GITC)上,我在前端与大家分享了“微信小程序云解决方案的探索之路”,介绍了我们之前对小程序云解决方案的探索过程。
小程序特性思考
小程序刚推出的时候,很多人以为是H5,因为开发小程序的三种语言和HTML、CSS、JS是一条线上的,即使改了扩展,本质也是改不了的。
那么小程序的本质是H5吗?经过我们的论证和分析,我们认为这个小程序不是H5应用程序。主要原因如下:
小程序中不能使用DOM接口,所以HTML5生态中所有基于DOM的库都不能使用(比如jQuery)。小程序不使用URL访问,所以没有域名的概念。这个功能有两个影响,不存在跨域的问题,所以访问控制就是直接在微信MP上配置域名白名单,不支持Cookie存储,这将导致我们后面重点关注会话管理的实现。从以上两个角度来看,我们认为小程序更倾向于传统的CS架构。
那么,小程序和传统CS架构有什么区别呢?主要包括以下两点:
而网络环境会更加复杂。频繁的网络连接可能会导致资源过度消耗,导致电池寿命下降。因此,小程序对网络和资源的优化提出了要求。可伸缩小程序被钉在微信平台上。作为十亿级的社交平台,商业可能面临爆发式增长。如果小程序不能在爆发点快速扩展,就会失去这么重要的机会。因此,小程序对其后台架构的可扩展性提出了更高的要求。
门槛和挑战
基于以上结论,我们做了一些尝试,包括上传下载、会话管理、WebSocket、VOD等。这一次,我们将重点关注共享会话管理和WebSocket,因为我们面临的挑战主要集中在这两种情况下。
会话管理
我们首先开发了一次性案例来实现会话管理。案例需要根据用户保存用户的作品。每次用户登录,都能看到自己的画作。
但是因为小程序不支持Cookie传输,所以会话服务需要自己实现。
我们会话管理的实现目标是:
完成微信所需的认证流程,生成一个用户会话,并使用该会话来确定每个请求的哪些微信用户安全性和可扩展性符合要求。我们的案例根据以下流程建立会话:
其中,在小程序和服务器端,我们提供了JS和Node SDK来提供会话支持。该案例完成了会话服务的功能目标,可以提供会话建立和验证的能力。但是缺点是这种能力只能被Node开发人员使用,不能被其他语言的开发人员使用。同时,由于小程序的appId和appSecret存储在外部网络可以访问的服务器上,因此存在一些安全问题。会话服务与我们的业务相耦合,也给后续的横向拓展带来了麻烦。
因此,我们提出了改进的手段:
会话管理服务器独立提供多种语言的SDKappId和appSecret,并存储在数据库中。由于会话管理服务器的独立性,可以快速开发多种语言的SDK。
优化后,会话建立过程如下图所示:
会话的验证过程如下图所示:
我们会话服务改进的效果仍然很明显:
并且流程和安全性完全满足微信的认证要求。独立的会话服务器可以方便地独立升级和扩展,也为多语言SDK的开发打开了方便之门。
信道服务
我们面临的另一个挑战是WebSocket。正在进行的案件
分析之前,先跟大家分析一下微信支持 WebSocket 的原因。传统的 HTTPS 连接请求,每个请求都需要建立一次连接,耗费比较多的资源。同时微信有最大连接数的限制(5个),所以实时通信的需求不好做,长连接的方案也只能串行传输,这种方案耗电高体验差。
当我们把目光转向 WebSocket 之后,会发现 WebSocket 通信全程只需要建立一次连接,就可以实现双向的实时通信,更省电的情况下获得更好的体验。
这就是小程序支持 WebSocket 的一个重要原因,可以提高业务的体验并增加续航。
鉴于很多同学可能对 WebSocket 还不了解,这里简单介绍一下。
我们的 HTTP 连接是在 TCP 的基础上建立的,当服务器支持 WebSocket 的时候,可以相应一个头部,告知客户端进行协议升级。升级协议后,会复用之前的 TCP 连接,在上面实现 WebSocket 协议实现双向通信。更加详细的资料可以参考MDN上的说明。
回到我们的案例上来,我们当时使用小程序提供的 WebSocket 做了一个实时的剪刀石头布游戏。
我们使用 Socket.IO 实现其后端后,发现在小程序无法使用 Socket.IO 的客户端代码支持。我们只能自己去啃了一下 Socket.IO 的上层协议,实现了一个简版的客户端,从而实现剪刀石头布这个游戏逻辑。
这个案例验证了在小程序上面 WebSocket 的可行性,但是由于客户端的实现是自行实现,和 Socket.IO 的后端配合可能会出现不可控的情况。同时,我们发现 WebSocket 的后端实现门槛比较高,并且进行横向扩展的话会更加困难。
作为云服务厂商,我们首先想到的方案是使用 PaaS 提供服务来支持 WebSocket 连接。这是怎么一个思路呢?
上图很好地解释了 PaaS 形式和传统 WebSocket 形式的不同之处,PaaS 实际上是要实现一个三方通信。
我们看一下使用 PaaS 服务来建立 WebSocket 连接的过程:
建立连接后,小程序和业务服务器之间可以通过下面的形式进行通信:
经过 PaaS 的改造,我们得到了一个新的 WebSocket 方案。该方案的优劣在哪里?
首先,优势比较明显,由平台来提供的服务,由平台自己完成扩展能力的支持以及稳定性和性能的保障,业务无需担心。同时,业务也无需关心 WebSocket 协议的实现,因为业务服务器和信道服务之前的通信都是传统的 HTTP,这样也可以节约业务服务器的长连接资源。
但是这种方案也有它的局限之处。业务服务器和信道服务器之间采取公网通信,处于对信息安全的考虑,最好还是走 HTTPS 通信,这个过程的通信延迟比较客观。其次,三方通信的调试便利性也不如传统的连接方式。
对于上面两个问题,其实我们也有对应方案。如果业务服务器在腾讯云机房运行,那么可以让业务服务器和信道服务器之间通过内网 HTTP 传输,延迟大大降低。信道服务后续也会提供调试日志供大家分析发现问题。
总体来说,PaaS 方案会帮助更多开发者解决掉了门槛较高的部分。
整合
我们上面对于会话服务和信道服务都进行了一个有益的实践,那么这两个服务是否可以整合,信道服务里面是否可以支持会话识别?
事实上我们可以做这个事情。下面的表格描述了会话服务和信道服务与服务模块之间的关系。
我们可以把客户端的部分整合为客户端 SDK,把业务服务器的部分整合为服务器 SDK,并且提供会话服务器的源码开源。
那么上面三个部分加起来,就是目前腾讯云的开源项目 -Wafer。
Wafer 包含了会话服务和信道服务的支持,从全栈模块来提供开源的资源,并且提供了丰富的文档。有兴趣的开发者可以使用上面的连接来查看 Wafer 项目。
产品化实践
Wafer 帮开发者解决了小程序开发过程中信道服务和会话服务的门槛问题,但是作为小程序开发者,还要关心后台架构、资源采供、资源部署、扩展能力、安全性、域名申请等等与业务开发无关的部分。这部分,我们提出了一个一站式部署的方案。
这个方案,会帮你分配好资源并自动部署下面的架构,让开发者可以专注于业务开发。
自动部署的过程其实挺复杂的,有兴趣的同学可以参考下图了解。
上面就是 Wafer 的产品化实践 -腾讯云小程序一站式解决方案。