Shopify如何在浏览器之外使用WebAssemblyShopify如何在浏览器外使用WebAssemblyShopify致力于让大多数商家需要的功能变得简单易用,通过接口在Shopify平台上进行查询、扩展和更改,从而为商家提供更多的可能性。有了这些接口,我们丰富的合作伙伴生态系统可以解决许多问题。这个生态系统主要......
Shopify致力于让大多数商家需要的功能变得简单易用,通过接口在Shopify平台上进行查询、扩展和更改,从而为商家提供更多的可能性。有了这些接口,我们丰富的合作伙伴生态系统可以解决许多问题。这个生态系统主要由“App”(独立托管的Web服务)来运营。该应用程序通过网络与Shopify进行通信。这种模式虽然功能强大,但是会带来一系列的技术问题。我们的合作伙伴需要建立可以随着Shopify的规模而扩展的Web服务,这使得一些资源有限的合作伙伴更加捉襟见肘。即使合作伙伴拥有无限的资源,但与Shopify的通信所带来的网络延迟,也足以让我们的App在要求高时效性的用例中失败。
我们希望我们的合作伙伴可以专注于使用他们的专业知识来解决问题,而不是花费时间来管理可伸缩的Web服务。为了实现这个目标,我们保持了不受信任的伙伴代码的灵活性,并在我们的基础设施上运行它。为了保证这些代码的性能、安全性和灵活性,我们选择了WebAssembly作为通用格式。
web程序集
什么是WebAssemblyWebAssembly.org给出了如下定义:
WebAssembly (Wasm)是一种基于栈虚拟机的二进制指令格式。Wasm是一个为编程语言设计的可移植编译目标,它使客户机和服务器应用程序能够部署在Web上。"
要了解更多关于WebAssembly及其历史的信息,您可以浏览这篇由Mozilla的Lin Clark撰写的图文并茂的文章。本文在此不再赘述。
Wasm通常与JavaScript一起运行在浏览器中,但Shopify采取了不同的方式,在浏览器外运行Wasm,不使用JavaScript。作为一种高性能语言,Wasm绝不是JavaScript的简单替代品:它是为Web和非Web嵌入而设计的,解决了浏览器和代码执行引擎中广泛存在的一个难题,即如何在不可信环境中高效执行程序。Wasm满足我们的三个主要技术要求:安全性、性能和灵活性。
安全
运行不受信任的代码非常危险。本质上,这些代码不仅难以预测,而且很可能对整个Shopify平台造成损害。虽然市面上没有100%安全可靠的应用程序,但我们仍然要防范安全漏洞,并在问题发生后采取措施减轻其影响。
Wasm将代码执行放在基于堆栈的沙盒环境中,依靠显式导入与主机通信。因此,我们不能在Wasm中编写任何恶意代码。我们只能使用提供的输入端口来操作虚拟环境。Wasm在这方面不同于字节码,因为字节码直接引用它们想要运行的计算机或操作系统。
Wasm还有许多不同的功能来保护用户免受错误代码的影响,包括受保护的调用堆栈和运行时类型检查。关于Wasm安全模型的更多细节在WebAssembly.org上提供。
表演
在电子商务领域,更快的运行速度是商家推动业绩增长的必要武器。如果Shopify提供的功能不能平衡加载时间和定制价值,那么这个功能就根本没有价值。
Wasm自己的设计充分利用了常见的硬件功能,在各种平台上发挥最接近的原生性能。面向追求最高性能,优化浏览器执行的开发者群体。因此,无论是现在还是未来,Wasm及其外围工具在设计上都将侧重于性能优化。
灵活性
能够帮助开发者提高开发效率的代码执行服务才是真正有用的服务。Wasm作为一种字节码格式,兼容各种编译器,为代码开发者提供支持多种编程语言的一流开发体验。这也使我们能够在不改变底层执行模型的情况下提供多语言支持。
基于社区
Shopyify基本保持了相同的开发目标和设计,这为我们选择Wasm提供了一个技术上的理由,但事实并不仅限于此:我们选择Wasm不仅关乎技术,更关乎人。如果Wasm生态系统被忽视了,或者只是奄奄一息,那么我们不会选择它。集结号社区充满活力和创新,潜力无穷。自从加入这个热情的社区后,Shopify受益匪浅。
同样,我们也在为社区贡献自己的力量。通过收集用户反馈,探索功能缺陷,并为我们使用的开源工具提交代码贡献。我们相信这为与WebAssembly社区建立良好的互利合作关系奠定了坚实的基础基础,我们也期待在未来继续为这个充满活力的社区贡献我们的力量。
代码执行服务的架构
在简单介绍了WebAssembly以及我们选择它的原因之后,接下来就是深入探讨我们的运行方案了。
我们使用Lucet,一个最初由Fastly开发的开源工具。Fastly,一家公司,为大量短命的、不可信的模块提供了可编程的边缘云平台,使得它们可以在尽可能接近其发起地的地方执行请求。这和我们的合作伙伴提供的代码是一个问题,所以我们很自然的选择了Lucet。
朗讯
Lucet是Wasm的运行时和编译器。Wasm中的模块保证了系统的安全性。因为我们不能在Wasm中编写恶意代码,所以Lucet利用Wasm模块的验证来检查安全性。验证后,模块会被编译成可执行文件,性能可以达到原生状态。此外,Wasm还支持预编译,可以避免运行时编译带来的延迟。Lucet container在启动时不需要做任何事情,这使得它的启动时间达到了惊人的35μs。如果你对Lucet及其工作原理感兴趣,可以查看Fastly的CTO泰勒·麦克马伦的视频。
Shopify Wasm发动机工作原理流程图
我们将Lucet包装在一个管理I/O和模块存储的Rust Web服务中,并称之为Wasm engine。运行时,Shopify通过Web请求调用Wasm引擎来处理一些功能。之后,引擎在站点的上下文中调用应用程序输出,其中上下文可能涉及创建折扣、执行约束或同步任何商家希望在平台中进行个性化定制的服务。
行驶性能
下图显示了从我们最新的性能测试中提取的一些指标。我们选择了一个小函数和逆行测试:让模块限制添加到购物车的商品数量。测试过程中,每分钟执行10万个模块,时长约5分钟。
模块执行所需的时间
此图表显示了执行模块所需时间的详细信息,包括容器的I/O和模块的执行。y轴代表时间(单位:ms),x轴代表测试运行的具体时间。
图中浅紫色的图例表示在Lucet中执行模块所需的时间,其宽度徘徊在100μs左右,其余图标是I/O处理和引擎的细节。可以看出,总执行时间约为4 ms。所有时间显示都是第99个百分比(99p)。为了更好的理解图中时间的含义,我们来对比一下Shopify中优秀的在线商店渲染服务Storefront Renderer的测试请求时间。
店面渲染器响应时间
此图表显示了一段时间内店面呈现器的请求时间。y轴表示请求时间(单位:秒),x轴表示返回值的具体时间。浅蓝色线代表大约700毫秒的第99个百分比。
如果粗略估计模块处理时间在5毫秒以内,可以说Lucet执行时间的性能影响几乎可以忽略不计。
生成WebAssembly
为了让我们优秀的执行引擎发挥作用,我们还需要授权开发者创建兼容的Wasm模块。Wasm的作用不是让用户自己写代码(如果他们愿意,当然可以写),而是作为编译目标存在。这让我们思考以下问题:我们支持哪些编程语言,支持到什么程度。
理论上,Wasm支持的任何开发语言都是可能的。然而,我们更希望开发者能够专注于为企业解决问题,而不是研究如何符合我们的API。这就是为什么我们选择单一语言Ruby支持,并为开发人员提供快速入门工具。但是,由于Ruby动态语言的特性,我们不能直接将其编译成Wasm,涉及编译解释器的解决方案会有严重的性能损失。正因为如此,我们最终决定采用静态编译的语言,并把动态语言编译的可能性留给了未来。
通过我们的研究发现,Shopify生态系统中的大多数开发者都能熟练应用JavaScript。不幸的是,JavaScript和Ruby一样,是一种动态语言,所以不得不排除。最后,我们选择了一种语法类似于TypeScript的开发语言:AssemblyScript。
使用汇编脚本
尽管WebAssembly支持大量的开发语言,但有两种主要类型的编译器我们不能使用:
生成环境或开发语言的特定产品的编译器,即节点或浏览器。(例如Asterius、Blazor)
仅适用于特定运行时的编译器。这些编译器生成的模块依赖于特定语言的特定导入,通常是为了支持某些特定语言的标准库而存在的,这样它们就可以在系统调用或运行时拥有可用的函数。因为我们不想被锁定在某个特定的语言中,所以这种编译器不在我们的考虑范围之内。(例如流明)
这些强大的编译器在其他情况下可能会创造奇迹,但不幸的是它们不能被我们使用。我们需要可以生成WebAssembly的工具,而不是WebAssembly支持的工具。脚本是我们选择的工具。
与WebAssembly中的其他工具一样,AssemblyScript仍在开发中。它缺少一些关键功能,比如闭包支持,在边缘情况下仍然会报告错误。这时,社区的重要性就显现出来了。
开发语言AssemblyScript及其外围工具拥有活跃用户的爱好者和维护者社区,他们自2019年Shopify首次使用AssemblyScript以来一直支持我们。而且我们还通过OpenCollective长期贡献代码支持社区。我们已经编写了一个语言服务器,在实现闭包方面取得了一些进展,并为编译器和外围工具提供了错误修复。
我们还将AssemblyScript整合到我们的早期工具中。在Shopify CLI中,我们允许开发人员通过命令行集成AssemblyScript来创建、测试和部署模块。为了提高开发效率,我们提供了一个SDK,可以处理Shopify定义对象(比如“钱”)的底层实现。除了这些工具之外,我们还建立了一个允许合作伙伴监控模块的系统,以便他们可以在模块出现故障时收到警报。我们的最终目标是让合作伙伴能够将他们的代码迁移到我们的平台上,而不会失去代码在原始平台上的灵活性和可观察性。
特别声明:以上文章内容仅代表作者本人观点,不代表ESG跨境电商观点或立场。如有关于作品内容、版权或其它问题请于作品发表后的30日内与ESG跨境电商联系。
二维码加载中...
使用微信扫一扫登录
使用账号密码登录
平台顾问
微信扫一扫
马上联系在线顾问
小程序
ESG跨境小程序
手机入驻更便捷
返回顶部