语言中拟合函数 计算aic_在函数计算FunctionCompute中使用WebAssembly

稿件来源:阿里云开发者社区(点击下面“了解更多”查看原文)

dd87136ed9b34cdef99e944603f54745.png

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)已经完成。

39b4c49ce2d26e91da75098bec7220bd.png

相比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一起使用。

85e2f4543874adebe640849f6406c31d.png

本节参考了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集成交互。

b9a2346e4d855c8b9d43a2d56d1966f5.png
$ 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
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值