函数计算如何帮助语雀构建稳定且安全的业务架构?

简介:语雀是一个专业的云端知识库,用于团队的文档协做。如今已经是阿里员工进行文档编写和知识沉淀的标配,并于 2018 年开始对外提供服务。

客户介绍

语雀是一个专业的云端知识库,用于团队的文档协做。如今已经是阿里员工进行文档编写和知识沉淀的标配,并于 2018 年开始对外提供服务。数据库

客户痛点

语雀是一个复杂的 Web 应用,也是一个典型的数据密集型应用(Data-Intensive Application),背后依赖了大量的数据库等云服务。语雀服务端是 Node.js 技术栈。当提到 Node 的时候,可能马上就会有几个词浮如今咱们脑海之中:单线程(single-threaded)、非阻塞(non-blocking)、异步(asynchronously programming),这些特性一方面很是的适合于构建可扩展的网络应用,用来实现 Web 服务这类 I/O 密集型的应用,另外一方面它也是你们一直对 Node 诟病的地方,对 CPU 密集型的场景不够友好,一旦有任何阻塞进程的方法被执行,整个进程就被阻塞。浏览器

像语雀这样用 Node 实现整个服务端逻辑的应用,很难保证不会出现一些场景可能会消耗大量 CPU 甚至是死循环阻塞进程的,以 markdown 转换举例,因为用户的输入没法穷举,总有各类可能让转换代码进入到一个低效甚至是死循环的场景之中。在 Node 刚出世的年代,很难给这些问题找到完美的解决办法,而即使是 Java 等基于线程并发模型的语言,在遇到这样的场景也很头痛,毕竟 CPU 对于 Web 应用来讲都是很是重要的资源。而随着基础设置愈来愈完善,当函数计算出现时,Node 最大的短板看起来有了一个比较完美的解决方案。安全

解决方案

“把函数计算引入以后,咱们能够将那些 CPU 密集型、存在不稳定因素的操做通通放到函数计算服务中去执行,而咱们的主服务再次回归到了 I/O 密集型应用模型,又能够愉快的享受 Node 给咱们带来的高效研发福利了!”语雀产品技术负责人不四表示。服务器

“以语雀中遇到的一个实际场景来举例,用户传入了一些 HTML 或者 Markdown 格式的文档内容,咱们须要将其转换成为语雀本身的文档格式。在绝大部分状况下,解析用户输入的内容都很快,然而依然存在某些没法预料到的场景会触发解析器的 bug 而致使死循环的出现,甚至咱们不太敢升级 Markdown 解析库和相关插件以避免引入更多的问题。可是随着函数计算的引入,咱们将这个消耗 CPU 的转换逻辑放到函数计算上,语雀的主服务稳定性不会再被影响。”
yq1.pngmarkdown

除了帮助 Web 系统分担一些 CPU 密集型操做之外,函数计算还能作什么呢?网络

语雀支持使用各类代码形式来绘图,包括 Plantuml、公式、Mermaid,还有一些将文档导出成 PDF、图片等功能。这些场景有两个特色:
一、他们依赖于一些复杂的应用软件,例如 Puppeteer、Graphviz 等;
二、可能须要执行用户输入的内容;架构

支持这类场景看似简单,经过 process.exec 子进程调用一下就搞定了。可是当咱们想把它作成一个稳定的对外服务时,问题就出现了。这些复杂的应用软件可能从设计上并无考虑要长期运行,长期运行时的内存占用、稳定性可能会有一些问题,同时在被大并发调用时,对 CPU 的压力很是大。再加上有些场景须要运行用户输入的代码,攻击者经过构建恶意输入,能够在服务器上运行攻击代码,很是危险。并发

在没有引入函数计算以前,语雀为了支持这些功能,尽管单独分配了一个任务集群,在上面运行这些三方服务,接受主服务的请求来避免影响主服务的稳定性。可是为了解决上面提到的一系列问题还须要付出很大的成本:
一、须要维持一个不小的任务集群,尽管可能大部分时间都用不上那么多资源。
二、须要定时对三方应用软件进行重启,避免长时间运行带来的内存泄露,即使如此有些特殊请求也会形成第三方软件的不稳定。
三、对用户的输入进行检测和过滤,防止黑客恶意攻击,而黑客的攻击代码很难彻底防住,安全风险依旧很大。
yq2.pngless

最后语雀将全部的第三方服务都分别打包在函数中,将这个任务集群上的功能都拆分红了一系列的函数放到了函数计算上。经过函数计算的特色一下解决了上面的全部问题:
一、函数计算的计费模式是按照代码实际运行的 CPU 时间计费,不须要长期维护一个任务集群了。
二、函数计算上的函数运行时尽管会有一些常驻函数的优化,可是基本不用考虑长期运行带来的一系列问题,且每次调用之间都相互独立,不会互相影响。
三、用户的输入代码是运行在一个沙箱容器中,即使不对用户输入作任何过滤,恶意攻击者也拿不到任何敏感信息,同时也没法进入内部网络执行代码,更加安全。
yq3.png异步

除了上面提到的这些功能以外,语雀最近还使用 OSS + 函数计算替换了以前使用的阿里云视频点播服务来进行视频和音频的转码。

因为浏览器能够直接支持播放的音视频格式并很少,大量用户上传的视频想要可以直接在语雀上进行播放须要对它们进行转码,业界通常都是经过 FFmpeg 来对音视频进行转码的。转码服务也是一个典型的 CPU 密集型场景,若是要本身搭建视频转码集群会面临大量的资源浪费,而使用阿里云视频点播服务,成本也比较高,并且可以控制的东西也不够多。函数计算直接集成了 FFmpeg 提供音视频处理能力,并集成到应用中心,配合 SLS 完善了监控和数据分析。语雀将音视频处理从视频点播服务迁移到函数计算以后,经过优化压缩率、减小没必要要的转码等优化,将费用下降至以前的 1/5。
yq4.png

使用效果

语雀产品技术负责人不四表示:从语雀的实践来看,语雀并无像 SFF 同样将 Web 服务迁移到函数计算之上(SFF 模式并非如今的函数计算架构所擅长的),可是函数计算在语雀总体的架构中对稳定性、安全性和成本控制起到了很是重要的做用。总结下来函数计算很是适合下面几种场景:

一、对于时效性要求不算很是高的 CPU 密集型操做,分担主服务 CPU 压力。
二、当作沙箱环境执行用户提交的代码。
三、运行不稳定的三方应用软件服务。
四、须要很强动态伸缩能力的服务。

在引入函数计算以后,语雀现阶段的架构变成了以一个 Monolith Application 为核心,并将一些独立的功能模块根据使用场景和对能力的要求分别拆分红了 Microservices 和 Serverless 架构。应用架构与团队成员组成、业务形态息息相关,可是随着各类云服务与基础设施的完善,咱们能够更自如的选择更合适的架构。

因为 Serverless 的出现,咱们能够将这些存在安全风险的,消耗大量 CPU 计算的任务都迁移到函数计算上。它运行在沙箱环境中,不用担忧用户的恶意代码形成安全风险,同时将这些 CPU 密集型的任务从主服务中剥离,避免出现并发时阻塞主服务。按需付费的方式也能够大大节约成本,不须要为低频功能场景部署一个常驻服务。因此咱们会尽可能的把这类服务都迁移到 Serverless 上。

本文内容由阿里云实名注册用户自发贡献,版权归原做者全部,阿里云开发者社区不拥有其著做权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。若是您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将马上删除涉嫌侵权内容。