使用 Docker 和 Golang 快速上手 WebAssembly

本文介绍了如何使用Docker和Golang快速上手WebAssembly,探讨了WebAssembly的适用场景和优势,并通过实例展示了在浏览器、Node.js和Go中运行WASI标准的WebAssembly程序。从环境准备、创建WebAssembly程序到在不同环境中运行,逐步引导读者掌握WebAssembly的使用。
摘要由CSDN通过智能技术生成

本文将聊聊,如何使用 Docker 和 Golang 快速上手 WebAssembly。我会分别从浏览器场景和“通用应用”场景来进行叙述,如果你还徘徊在 WebAssembly 的门前,或许这篇文章会对你所有帮助。

写在前面

如果从 2017 年浏览器纷纷开始以实验性的方式,支持 Web WebAssembly 功能来看,在浏览器使用非 JavaScript 来完成计算的风已经吹了五年了。不过,感受到 Wasm 生态真正发力的是近三年。

大环境的变化,让行业生态中音视频、云计算、物联网有了更广阔的市场,以及在降本提效上更高的追求,此为天时。如果说 Wasm 生态中的 C 位是 Mozilla,那么去年在 Mozilla 裁员事件出现后,他们迅速成立 Rust 的基金会,以保障 Rust 开发团队能够独立、稳定地运行,保护 Rust 以及周边项目的持续发展,为生态提供土壤,此可谓地利。

天时地利,只待人和。

国内外经济环境均有了前所未有的变化,在少了不少外部资本诱惑之后,能够感受到这几年来,基础技术设施的蓬勃发展,这里面少不了各种优秀的工程师正在将注意力从“业务”,逐步转移到“技术”上。目前 Wasm 王国在它的一等公民 Rust 高速发展和推动下,已经吸引了不少其他语言生态、知名商业公司的注意力。至于何时爆发,我个人认为,只是时间问题。

不过需要注意的是,没有技术会是银弹,只有把技术放在适用的场景下才能达到事半功倍的效果。那么哪些场景适合 WebAssembly 呢?

为了行文方便,接下来 WebAssembly 会简称为 Wasm。

适用场景 & 优势

先来看看,近三年业界公开表明已使用它的场景:

  • 做在线设计工具的业务场景,比如 Figma:早在 2017 年,Figma 就借助这项技术进行了产品优化,《WebAssembly cut Figma’s load time by 3x》,他们的工程师 Rasmus Andersson 也从比较底层的角度分析了 wasm。
  • 复杂的在线 IDE 产品,比如 vim.wasm:在 2019 开始正式进行开发的 基于 wasm 的 VIM 完整移植版。使用 Web Worker 和 SharedArrayBuffer 解决了在浏览器端 JS 和 wasm 进行数据交互时的延迟问题。
  • 云计算场景的边缘计算,比如 Cloudflare、fastly :《WebAssembly on Cloudflare Workers》、《Compute@Edge》
  • 云计算场景网关能力扩展,比如 Envoy & istio、蚂蚁金服、MegaEase、ApiSix:《Istio1.5 & Envoy 数据面 WASM 实践》、《WebAssembly 在 MOSN 中的实践 - 基础框架篇》 、《用 Easegress + WebAssembly 做秒杀》、《云原生网关 APISIX 核心流程源码分析与进化方向思考》
  • 在线音视频处理,比如 Zoom、声网 agora、字节跳动:《Zoom on Web: WebAssembly SIMD, WebTransport, and WebCodecs》、《How WebRTC & WASM are opening new opportunities for web apps》、《如何通过 WebAssembly 在 Web 进行实时视频人像分割》、《Bilibili - WebAssembly在多媒体场景的实践与思考》
  • 高性能的复杂在线数据可视化,比如 perspective:github.com/finos/perspe
  • 浏览器端的前端加密场景,比如coupang :《WebAssembly 在性能及加密场景的深度探索》

如果将上面的场景进行归纳,我们可以看到,在浏览器端、云计算、嵌入式方向,WebAssembly 的优势还是比较大的:

  • 用比较低的代码量来扩展现有业务能力(云端、浏览器端)
  • 充分使用客户端的计算能力,节约云服务器带宽和计算资源成本(浏览器端)
  • 利用 wasm 高性能计算方面带来的优势,解决复杂的计算的执行效率问题(可视化、通用计算场景)
  • 快速复用其他语言技术栈道能力,借助容器化的思路快速迭代产品(云端、浏览器端、嵌入式)
  • 使用更流行、易于开发维护,或者贴合自己团队的语言来进行产品迭代(嵌入式)
  • 前端敏感内容的加密处理(浏览器端)

简单起步:浏览器中的 WebAssembly

循序渐进,我们先从最简单的场景开始:浏览器。

环境准备

如果你不想折腾 golang 的本地开发环境,我们可以使用 Docker 来快速创建一个运行环境:

docker run --rm -it -v `pwd`/code:/app -p 8012:8012 golang:1.17.3-buster bash

这里,我们将本地的 code 目录,映射到容器内的 /app 目录中,并将本地和容器中的 8012 端口打通,以备后续使用。

接着,在命令执行完毕后的容器的终端控制台中进行项目的初始化:

cd /app
go mod init soulteary.com/wasm-demo/v2

然后,使用你喜欢的方式(在容器内或者在本地 IDE中),创建一个 golang 的程序文件,比如 main.go:

package main

import "fmt"

func main() {
	fmt.Println("一切都将从这里开始")
}

完成之后,在容器控制台内执行 go run main.go,不出意外,将看到 “一切都将从这里开始”的文本输出结果。

因为我们要演示的场景包含前端,所以还需要有一个简单的 Web 服务器,继续使用 golang 写一个简单的 Web 服务器吧。

package main

import (
	"log"
	"net/http"
)

func main() {
	log.Fatal(http.ListenAndServe(":8012", http.FileServer(http.Dir("."))))
}

将上面的内存保存为 server.go,当我们执行它的时候,它会将本地作为服务器根目录,对访问者提供 Web 服务。

在这个场景下,工程师们一般会有几个问题:

  • 如何得到一个 Wasm 程序
  • 如何将这个程序放在浏览器中运行;
  • 如何让浏览器中的 JavaScript 能够调用 WASM 的导出函数。( Golang 程序中的函数)
  • 以及如何针对整个程序进行进一步性能优化

在 “Show You The Code” 的过程中,我们将依次解答上面的问题。

从 Golang 创建 WebAssembly 程序

将 Golang 程序“变成” WebAssembly 一般会采取两种方案:

  • 使用 Golang 原生编译器进行编译。
  • 使用 TinyGo 编译器进行编译。

Golang “原生编译器方案”适用性非常好,适合项目初期开发、或者不太介意编译产物尺寸、程序首次分发时间的 B 端产品使用,如果你愿意投入时间做产物体积裁剪,也能够获得不错的结果。构建命令一般会类似 GOOS=js GOARCH=wasm go build -o YOUR_MODULE_NAME.wasm .,构建产物需要

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值