openresty 中如何使用 wasm

WASM 是什么?

WebAssembly是一种运行在现代网络浏览器中的新型代码,并且提供新的性能特性和效果。它设计的目的不是为了手写代码而是为诸如C、C++和Rust等低级源语言提供一个高效的编译目标。

对于网络平台而言,这具有巨大的意义——这为客户端app提供了一种在网络平台以接近本地速度的方式运行多种语言编写的代码的方式;在这之前,客户端app是不可能做到的。

而且,你在不知道如何编写WebAssembly代码的情况下就可以使用它。WebAssembly的模块可以被导入的到一个网络app(或Node.js)中,并且暴露出供JavaScript使用的WebAssembly函数。JavaScript框架不但可以使用WebAssembly获得巨大性能优势和新特性,而且还能使得各种功能保持对网络开发者的易用性。

比如在envoy 中,主要是通过wasm 提供多语言开发扩展envoy功能的目的

openresty如何玩?

那么在openresty 中是否也可以这么集成wasm呢?

当然是可以的,毕竟openresty 本身就是 nginx + lua , 再加一个 wasm vm 进去也是一样可以做到的。

利用nginx模块化系统就可以做到这个事情了

由于模块的代码都是 c, 大家都不太有兴趣,

这里就不细说了, 有兴趣的小伙伴 可以在 api7/wasm-nginx-module 这里了解细节

nginx 模块怎么开发可以看 nginx 模块开发 - Google 搜索

proxy-wasm是什么?

这里重点提 proxy-wasm 这个东西, 它是上述加在nginx 中的wasm 模块中的 api 标准集合

最初出现与 envoy, 现在也是 Istio 1.6 之后扩展选项, 如下图

目前支持如下

SDKs

Libraries

openresty 中使用wasm 的例子

1. 基于 assemblyscript 的示例代码

内容主要为添加 response header

export * from "@solo-io/proxy-runtime/assembly/proxy"; // this exports the required functions for the proxy to interact with us.
import { RootContext, Context, registerRootContext, FilterHeadersStatusValues, stream_context } from "@solo-io/proxy-runtime/assembly"; class AddHeaderRoot extends RootContext {
createContext(context_id: u32): Context {
return new AddHeader(context_id, this);
}
} class AddHeader extends Context {
constructor(context_id: u32, root_context: AddHeaderRoot) {
super(context_id, root_context);
}
onResponseHeaders(a: u32, end_of_stream: bool): FilterHeadersStatusValues {
const root_context = this.root_context;
if (root_context.getConfiguration() == "") {
stream_context.headers.response.add("hello", "world!");
} else {
stream_context.headers.response.add("hello", root_context.getConfiguration()); // 添加 response header
}
return FilterHeadersStatusValues.Continue;
}
} registerRootContext((context_id: u32) => { return new AddHeaderRoot(context_id); }, "add_header");

编译可以得到,我们只需要 release.wasm 文件其实

2. 为 openresty 按照 wasm

重新构建 openresty 并安装 wasm 模块, 如下为对应脚本 build.sh

#!/usr/bin/env bash

# prev_workdir="$PWD"
# repo=$(basename "$prev_workdir")
# workdir=$(mktemp -d)
# cd "$workdir" || exit 1
# echo $workdir or_ver="$1" cc_opt=${cc_opt:-}
ld_opt=${ld_opt:-}
luajit_xcflags=${luajit_xcflags:="-DLUAJIT_NUMMODE=2 -DLUAJIT_ENABLE_LUA52COMPAT"}
OR_PREFIX=${OR_PREFIX:="/usr/local/openresty"}
debug_args=${debug_args:-} wasm_nginx_module_ver="0.6.2" git clone --depth=1 -b $wasm_nginx_module_ver \
https://github.com/api7/wasm-nginx-module.git \
wasm-nginx-module-${wasm_nginx_module_ver} cd wasm-nginx-module-${wasm_nginx_module_ver} || exit 1
./install-wasmtime.sh
cd .. cd openresty-${or_ver} || exit 1
./configure --prefix="$OR_PREFIX" \
--with-cc-opt="$cc_opt" \
--with-ld-opt="-Wl,-rpath,$OR_PREFIX/wasmtime-c-api/lib $ld_opt" \
$debug_args \
--add-module=../wasm-nginx-module-${wasm_nginx_module_ver} \
--with-poll_module \
--with-pcre-jit \
--without-http_rds_json_module \
--without-http_rds_csv_module \
--without-lua_rds_parser \
--with-stream \
--with-stream_ssl_module \
--with-stream_ssl_preread_module \
--with-http_v2_module \
--without-mail_pop3_module \
--without-mail_imap_module \
--without-mail_smtp_module \
--with-http_stub_status_module \
--with-http_addition_module \
--with-http_auth_request_module \
--with-http_secure_link_module \
--with-http_random_index_module \
--with-http_gzip_static_module \
--with-http_sub_module \
--with-http_dav_module \
--with-http_flv_module \
--with-http_mp4_module \
--with-http_gunzip_module \
--with-threads \
--with-compat \
--with-luajit-xcflags="$luajit_xcflags" \
-j`nproc` make -j`nproc`
make install DESTDIR="$PWD"
OPENRESTY_PREFIX="$PWD$OR_PREFIX"
cd .. cd wasm-nginx-module-${wasm_nginx_module_ver} || exit 1
OPENRESTY_PREFIX="$OPENRESTY_PREFIX" make install
cd ..

运行

#!/usr/bin/env bash

or_ver="1.21.4.1"

tempdir=$(mktemp -d)
echo "do at ${tempdir}"
cp -R ./ ${tempdir}
cd ${tempdir}
wget --no-check-certificate https://openresty.org/download/openresty-${or_ver}.tar.gz
tar -zxvpf openresty-${or_ver}.tar.gz > /dev/null
sh build.sh $or_ver

3. 测试

这里就只列举 demo 文件,感兴趣的自己测试

worker_processes 1;
worker_cpu_affinity auto;
worker_rlimit_nofile 65535; events {
use epoll;
worker_connections 65535;
accept_mutex off;
multi_accept on;
} http { lua_package_path "${prefix}deps/share/lua/5.1/?.lua;${prefix}deps/share/lua/5.1/?/init.lua;${prefix}?.lua;${prefix}?/init.lua;;./?.lua;/usr/local/openresty/luajit/share/luajit-2.1.0-beta3/?.lua;/usr/local/share/lua/5.1/?.lua;/usr/local/share/lua/5.1/?/init.lua;/usr/local/openresty/luajit/share/lua/5.1/?.lua;/usr/local/openresty/luajit/share/lua/5.1/?/init.lua;";
lua_package_cpath "${prefix}deps/lib64/lua/5.1/?.so;${prefix}deps/lib/lua/5.1/?.so;;./?.so;/usr/local/lib/lua/5.1/?.so;/usr/local/openresty/luajit/lib/lua/5.1/?.so;/usr/local/lib/lua/5.1/loadall.so;";
lua_socket_log_errors off;
wasm_vm wasmtime; # wasm 运行时设置 init_by_lua_block { # 初始化加载可以复用wasm。避免运行时加载的损耗
wasm = require("resty.proxy-wasm")
plugin = wasm.load("add_header", "/app/wasm/assemblyscript/build/release.wasm")
} server {
listen 80;
server_tokens off; location /t {
return 200;
header_filter_by_lua_block { # 这里设置调用 wasm
local ctx = wasm.on_configure(plugin, 'add_header')
wasm.on_http_response_headers(ctx)
}
} location /d {
return 200;
header_filter_by_lua_block {
ngx.header['test'] = 'add_header'
}
}
}
}

构建api gateway之 openresty 中如何使用 wasm的更多相关文章

  1. 构建api gateway之 动态插件

    动态插件 之前已经拆解细点逐个介绍了 tcp .http 代理相关核心点,现在介绍一个让 api gateway 变得很灵活的功能实现: 动态插件. 由于 lua 的动态语言特点,我们可以比较方便做到 ...

  2. 构建api gateway之 健康检查

    Healthcheck 由于服务无法保证永远不会下线,而且下线时不一定能有人员能及时发现, 所以api gateway 一般会引入一个监工 Healthcheck, 像大家每年体检一样定时确认服务是否 ...

  3. 构建api gateway之 http路由实现

    http路由 路由是指路由器从一个接口上收到数据包,根据数据包的目的地址进行定向并转发到另一个接口的过程. 而这里的http路由其实等同于web开发中,根据http相关参数(比如url.http me ...

  4. 构建api gateway之 负载均衡

    什么是负载均衡 负载均衡,英文名称为Load Balance,其含义就是指将负载(工作任务)进行平衡.分摊到多个操作单元上进行运行 以下为几种负载均衡策略介绍 1.随机(Random) 大家很多时候说 ...

  5. 构建api gateway之 基于etcd实现动态配置同步

    配置中心 在之前 tcp的yaml配置 介绍了如何监听yaml文件变化然后更新配置. 当然假如我们有很多实例,那么yaml改动将是非常痛苦的事情,那么如何做到配置文件统一管理,实时更新呢? 我们可以引 ...

  6. 谈谈微服务中的 API 网关(API Gateway)

    前言 又是很久没写博客了,最近一段时间换了新工作,比较忙,所以没有抽出来太多的时间写给关注我的粉丝写一些干货了,就有人问我怎么最近没有更新博客了,在这里给大家抱歉. 那么,在本篇文章中,我们就一起来探 ...

  7. 微服务中的 API 网关(API Gateway)

    API 网关(API Gateway)提供高性能.高可用的 API 托管服务,帮助用户对外开放其部署在 ECS.容器服务等云产品上的应用,提供完整的 API 发布.管理.维护生命周期管理.用户只需进行 ...

  8. 服务中的 API 网关(API Gateway)

    我们知道在微服务架构风格中,一个大应用被拆分成为了多个小的服务系统提供出来,这些小的系统他们可以自成体系,也就是说这些小系统可以拥有自己的数据库,框架甚至语言等,这些小系统通常以提供 Rest Api ...

  9. [转载] 构建微服务:使用API Gateway

    原文: http://mp.weixin.qq.com/s?__biz=MzA5OTAyNzQ2OA==&mid=206889381&idx=1&sn=478ccb35294c ...

  10. Spring Boot中使用Swagger2构建API文档

    程序员都很希望别人能写技术文档,自己却很不愿意写文档.因为接口数量繁多,并且充满业务细节,写文档需要花大量的时间去处理格式排版,代码修改后还需要同步修改文档,经常因为项目时间紧等原因导致文档滞后于代码 ...

随机推荐

  1. Perl语言中一些内置变量等,$x、qw、cmp、eq、ne等

    转载 Perl语言中一些内置变量等,$x.qw.cmp.eq.ne等 字母 符号 释义 eq  = = equal(等于) ne != not equal(不等于) cmp 比较 qq  " ...

  2. 面试 考察网络请求HTTP相关知识(第六天!)

    01.HTTP 常⻅的状态码有哪些? 1xx 服务器收到请求 2xx 请求成功         ---   200 成功状态码 3xx 重定向            ---  301永久重定向,浏览器 ...

  3. Window使用PowerShell改文件时间戳

    We cross infinity with every step; we meet eternity in every second. 我们每一步都跨过无穷,每一秒都遇见永恒. Window使用Po ...

  4. 原来用 MySQL 也可以做全文检索

    我是风筝,公众号「古时的风筝」,专注于 Java技术 及周边生态. 文章会收录在 JavaNewBee 中,更有 Java 后端知识图谱,从小白到大牛要走的路都在里面. 有朋友聊到他们的系统中要接入全 ...

  5. AWS启示录:创新作帆,云计算的征途是汪洋大海

    全文13100字,预计阅读时间15到20分钟. 开篇:创新是AWS发展的最持久驱动力 云计算,新世纪以来最伟大的技术进步之一,从2006年 Amazon Web Service(以下简称AWS)初创时 ...

  6. 卸载virtualbox中linux虚拟机的增强工具

    报错信息 vboxclient:the virtualbox kernel service is not running 前言 我由virtualbox换到vmware 遇到了这个问题,很烦每次都通知 ...

  7. 2023年 DevOps 七大趋势

    随着时间的推移,很明显 DevOps 已经成为最高效的敏捷框架中的无人不知晓的名字.越来越多的企业(包括各类规模企业)正在采用 DevOps 方法来简化其运营效率.DevOps 的新时代趋势已经见证了 ...

  8. Tkinter根据屏幕分辨率最大化适应屏幕

    还不能够实现所有组件随分辨率自动变化 # 实现的是界面覆盖整个屏幕 from tkinter import * import win32api, win32con # 获取屏幕的分辨率 width = ...

  9. 【zookeeper】Zookeeper相关概念、重难点(myid)、语法、使用、工具

    1234567890 1请按照我是想额度插入fvtgb6yhn7ujm8ik,9ol.

  10. 我今天吃了SHI,请对下联

    最近看到不少好玩的.实用的 Github 项目,就来给大家推荐一把. 1. 跨平台终端 Tabby(前身是 Terminus) 是一个可高度配置的终端模拟器和 SSH 或串口客户端,支持 Window ...