WebAssembly 是一种新的W3C规范,无需插件可以在所有现代浏览器中实现近乎原生代码的性能。同时由于 WebAssembly 运行在轻量级的沙箱虚拟机上,在安全、可移植性上比原生进程更加具备优势。同时资源消耗小、启动速度快的特点也非常适合Serverless的场景。开发者们开始探索WebAssembly在Serverless的应用场景。

WebAssembly 101

WebAssembly (WASM) 是一种可以在Web浏览器上运行的编译语言(如C/C++, Rust, Go)的技术方案。WebAssembly采用二进制字节码格式,运行在基于堆栈的虚拟机上。2017年2月28日,四大主流浏览器Chrome, Firefox, Safari和IE共同宣布 WebAssembly 的最小可行产品(MVP)已经完成。

相比JavaScript, 使用WebAssembly可以更高效地在Web浏览器中运行代码逻辑。

  1. 下载更快:相比类似功能的JavaScript代码,WebAssembly文件体积更小
  2. 解析更快:由于WebAssembly采用二进制的中间表示(Intermediate Representation),可以类比JVM的byte code。无需代码解析过程,可以实现毫秒级解码加载。
  3. 执行更快:由于 JavaScript 使用动态类型,编译器很难对代码实现深度优化;而WebAssembly采用静态类型,编译器可以高效优化;同时JavaScript采用垃圾回收机制,而WebAssembly指令更接近机器码,需要程序自己控制垃圾回收策略,相比自动垃圾回收效率可以更高。通常而言,WASM与JavaScript相比,可以实现30%性能提升,在复杂的计算逻辑中,会有更高的性能提升。同时由于减少了语言的动态性和采用静态内存处理,WebAssembly也更加适合要求可预测性能的计算场景。

WebAssembly作为社区标准,具有良好的可移植性。WebAssembly代码逻辑可以一致地运行在不同浏览器实现中,并与JavaScript或浏览器对象进行交互调用。WebAssembly也可以运行在非浏览器环境下。此外WebAssembly运行在一个沙箱化的执行环境中,严格遵守浏览器安全策略,具有良好的安全性。

函数计算 + WebAssembly 模块

Function as a Service(FaaS)是Serverless Computing的重要计算形态,它提供了事件驱动的编程模型,开发者只需编写和上传事件响应代码,而平台则会负责计算资源的弹性伸缩。

FaaS主要支持了 Node.js, Python, PHP等解释型语言,也支持Java, C#等编译型语言。由于在Node.js 8.0版本以后已经内置了WebAssembly运行时,在主流的FaaS环境可以通过Node.js实现调用WebAssembly模块的能力,比如在AWS Lambda和Cloudflare Worker。

在FaaS中利用Node.js调用WebAssembly 模块,有以下优点

  1. 更好的性能 - 尤其是计算密集型任务
  2. 可移植性 - 为NPM编译原生代码是一个大坑,在FaaS中运行的原生代码则需要针对目标执行环境进行构建来保障兼容性。比如AWS Lambda中的原生代码需要依赖Amazon Linux构建;阿里云函数计算要求二进制代码基于Linux 4.4构建。而WebAssembly代码可以保证在不同的目标环境运行有一致的结果。
  3. 多语言支持 - 类似C/C++, Rust, Golang这样的已有业务代码可以通过编译成WebAssembly进行复用,比如可以直接将C编写的图像处理应用运行在函数计算中,而不受函数计算支持的现有运行时的限制。

我们也将做一个小实验,结合Rust和AssemblyScript两种语言在阿里云函数计算(FunctionCompute, FC)场景中体验WebAssembly。

环境准备

  • 安装并配置阿里云函数计算的 Serverless 应用部署的工具 Fun
  • 下载示例代码,git clone https://github.com/denverdino/fun-wasm
  • (可选) Rust环境需要安装 wasm-pack

利用Rust构建Serverless WebAssembly应用

Rust是Mozilla的一个新的系统级编程语言。Mozilla同时也是WebAssembly技术最重要的推动者,它基于WebAssembly发布了wasm-bindgen,目的提升 JavaScript 和 Rust 之间的互操作性,可以让 Rust代码能够与JavaScript一起使用。

本节参考了Scott Logic的文章,我们将利用wasm-bindgen,在FunctionCompute的Node.js运行时中运行基于Rust编译的WebAssembly代码。

$ cd rust-wasm# 一个简单的Rust Hello World应用,利用wasm_bindgen声明与JavaScript代码的绑定$ cat src/lib.rsuse wasm_bindgen::prelude::*;#[wasm_bindgen]pub fn hello_world() -> String { let mut string = String::new(); string.push_str("Hello, rust-wasm!"); return string;}# 编译生成WebAssembly和NodeJS绑定$ wasm-pack build --target nodejs# 简单的函数计算事件响应代码,在NodeJS中调用WebAssembly逻辑$ cat index.jsconst wasm = require("./pkg/rust_wasm");var getRawBody = require('raw-body')module.exports.handler = function (request, response, context) { // get request body getRawBody(request, function (err, body) { response.setStatusCode(200); response.send(wasm.hello_world()); });}# Serverless应用部署模板,利用HTTP Trigger进行访问$ cat template.ymlROSTemplateFormatVersion: '2015-09-01'Transform: 'Aliyun::Serverless-2018-04-03'Resources: fun: Type: 'Aliyun::Serverless::Service' rust-wasm: Type: 'Aliyun::Serverless::Function' Properties: Handler: index.handler CodeUri: ./ Description: 'http trigger demo!' Runtime: nodejs8 Events: http-test: Type: HTTP Properties: AuthType: ANONYMOUS Methods: ['GET', 'POST', 'PUT']

部署并测试

$ fun deploy...Waiting for service fun to be deployed... Waiting for function rust-wasm to be deployed... Waiting for packaging function rust-wasm code... package function rust-wasm code done, the number of files you have packaged is:11 Waiting for HTTP trigger http-test to be deployed... methods: [ 'GET', 'POST', 'PUT' ] url: https://xxxxxxx.cn-shanghai.fc.aliyuncs.com/2016-08-15/proxy/fun/rust-wasm/ function http-test deploy success function rust-wasm deploy successservice fun deploy success$ curl https://xxxxxxx.cn-shanghai.fc.aliyuncs.com/2016-08-15/proxy/fun/rust-wasm/Hello, rust-wasm!

利用AssemblyScript构建Serverless WebAssembly应用

AssemblyScript可以将一个 TypeScript 严格的子集编译成 WebAssembly。AssemblyScript 使用与 TypeScript 相同的语法,但使用了自己的标准库来支撑 WebAssembly 的功能,这意味着开发者不必为了编写 WebAssembly 而去学习新的编程语言,这是一个巨大的优点。而且AssemblyScript是针对WebAssembly设计的语言,它可以生成更加简练的WebAssembly代码,并更加简单地与JavaScript集成交互。

$ cd assemblyscript# 下面是一个简单的Fibonacci数列的递归实现$ cat assembly/index.ts// The entry file of your WebAssembly module.export function fib(n: i32): i32 { let t: i32; let a: i32 = 0; let b: i32 = 1; for (let i: i32 = 0; i < n; i++) { t = a + b; a = b; b = t; } return b;}# 生成WebAsssembly目标代码$ npm run asbuild# 如下是AssemblyScript自己生成的胶水代码,用于加载WebAssembly模块$ cat wasm.jsconst fs = require("fs");const compiled = new WebAssembly.Module(fs.readFileSync(__dirname + "/build/optimized.wasm"));const imports = { env: { abort(_msg, _file, line, column) { console.error("abort called at index.ts:" + line + ":" + column); } }};Object.defineProperty(module, "exports

中计算散度的函数_荷畔微风 - 在函数计算FunctionCompute中使用WebAssembly相关推荐

  1. sql中聚合函数和分组函数_学习SQL:聚合函数

    sql中聚合函数和分组函数 SQL has many cool features and aggregate functions are definitely one of these feature ...

  2. python3中map函数_解决Python3下map函数的显示问题

    map函数是Python里面比较重要的函数,设计灵感来自于函数式编程.Python官方文档中是这样解释map函数的: map(function, iterable, ...) Return an it ...

  3. scala 函数中嵌套函数_如何在Scala中将函数转换为部分函数?

    scala 函数中嵌套函数 First, let's see what is a function and a partial function, and then we will see their ...

  4. python中的func函数_如何解释python func函数中的n?

    Func函数第一次了解知道是学习闭包章节中的,而后,因为函数本身存在的意义涵盖很多知识点,所以经常使用,在调用的时候,看到一个问题,就是关于python func函数中的n是什么?大家有没有考虑过呢? ...

  5. hive substr函数_数据分析工具篇——HQL函数及逻辑

    本篇文章我们梳理一下hive常用的函数,对于hive而言,常用的函数并不是特别多,往往记住关键几个,就可以解决80%的问题,这也是大家喜欢hive的原因,那么,常用的函数有哪些呢? 时间函数 1)时间 ...

  6. python四大高阶函数_详谈Python高阶函数与函数装饰器(推荐)

    一.上节回顾 Python2与Python3字符编码问题,不管你是初学者还是已经对Python的项目了如指掌了,都会犯一些编码上面的错误.我在这里简单归纳Python3和Python2各自的区别. 首 ...

  7. c++将小写转换为大写函数_必须掌握的基础函数组合应用技巧,提高效率,准时下班...

    点击上方"Excel函数公式"免费订阅 货币,生活中必不可少的东西,是物品价值等的直接体现,在实际的工作中也经常遇到,如果给定的数据中,要对其进行格式的设置,你会怎么做? 一.Do ...

  8. decode函数_「实践」云函数 + API,你也可以做个天气信息系统

    为什么要把云函数 SCF 与 API 网关进行结合?本文告诉你答案! 通常,我们用云函数 SCF 写一个函数应用,这个应用可能多种多样.例如之前介绍过的 OJ 系统判题功能,通过 NLP 实现文本摘要 ...

  9. php求平均值的函数_最全计算机二级函数关键知识点汇总整理!

    小编在校大学生,一年自学通过六个证,现开办自己的软件图书专营部.以学生价专业提供各省 初级会计.中级会计.注册会计师.管会.全国计算机二级.英语四六级.银行从业.证券从业.基金从业.期货从业.税务师. ...

最新文章

  1. C 语言编程 — 编程实践
  2. python 命令-python解析命令行参数的三种方法详解
  3. ACM入门之【分块】
  4. linux wine运行效率,Wine 3.0让Windows应用在Linux上流畅运行!
  5. Mac OS X终端的常用操作命令(UNIX指令)
  6. JDBC中使用preparedStatement防止SQL注入
  7. mysql join buffer_MySQL cache之join buffer的优化
  8. idea报错Cannot resolve jdk.tools:jdk.tools:1.7
  9. 1、pandas使用sort_values排序
  10. mac 向mysql输入 数据_(mac系统下)mysql 入门
  11. 单变量微积分笔记—— 积分方法之换元法总结(简单换元和三角换元)
  12. build lavas 失败_基础教程 - 快速开始 PWA 工程 - 《Lavas 指导教程文档》 - 书栈网 · BookStack...
  13. 软件分享 AirPlayer
  14. ffmpeg ts与mp4互相转换
  15. ZooKeeper客户端源码(二)——向服务端发起请求(顺序响应+同步阻塞+异步回调)
  16. 计算机智能科学与技术高校排名,2021年全国智能科学与技术专业大学排名(原创)...
  17. 电脑主机没有网卡,使用外置无线网卡实现无线投屏/多屏协同
  18. 手机银行消息服务器,服务与功能_手机银行_服务介绍_个人电子银行_电子银行频道_建设银行...
  19. 【COGS2652】秘术「天文密葬法」(长链剖分,分数规划)
  20. DeepKE发布新版本:支持低资源、长篇章、多任务的图谱抽取开源框架,开源开放

热门文章

  1. HTML: 字體設置
  2. FPGA大数据之我认为的明天
  3. PMCAFF推荐 | YC主席:75%的创业团队走出孵化器就忘了本,开始干虚假工作
  4. redis持久化方案比较
  5. LTP--linux稳定性测试 linux性能测试 ltp压力测试
  6. 腾讯 Web UI 解决方案 QMUI Web —— 探索与沉淀
  7. 块状元素的text-align对齐属性
  8. 个人作业-Week2:案例分析
  9. virtualbox奇葩的问题-unable to load r3 module
  10. 【转】mysql-status和variables区别