gpt4 book ai didi

构建apigateway之openresty中如何使用wasm

转载 作者:我是一只小鸟 更新时间:2023-02-14 22:31:43 24 4
gpt4 key购买 nike

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

  • AssemblyScript SDK
  • C++ SDK
  • Go (TinyGo) SDK
  • Rust SDK
  • Zig SDK

    Servers

  • Envoy
  • Istio Proxy (Envoy-based)
  • MOSN
  • OpenResty (work-in-progress)
  • ATS (proof-of-concept)

Libraries

  • C++ Host
  • Go Host

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'
            }
        }
    }
}
                            
                          

最后此篇关于构建apigateway之openresty中如何使用wasm的文章就讲到这里了,如果你想了解更多关于构建apigateway之openresty中如何使用wasm的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com