用 WasmEdge 和 Rust 在边缘云上构建高性能且安全的微服务

边缘云让开发者能够在靠近用户的地方部署微服务(即细颗粒度的 Web 服务),从而实现更好的用户体验(即非常快的响应时间)、绝佳的安全性以及高可用性。 边缘云利用本地乃至私有的数据中心、CDN 络和电信数据中心(例如 5G MEC)来提供计算服务。 边缘云的成功案例包括 Cloudflare、Fastly、Akamai、fly.io、Vercel、Netlify 等。

但是,与大型公共云相比,边缘云是一个资源受限的环境。 如果边缘微服务本身运行缓慢、臃肿或不安全,将导致在边缘云上部署的全部优势丧失殆尽。

Fly.io[2] 是一个领先的边缘云 VM 服务提供商,它在世界各地都有边缘数据中心。fly.io[3] VM 支持应用程序服务器、数据库以及我们这种微服务的轻量级 runtime。

我将使用 WasmEdge runtime 作为这些微服务的安全沙箱。 WasmEdge 是专门针对云原生服务优化的 WebAssembly runtime。我们将在基于 WasmEdge 的 Docker Images 中打包用 Rust 或 JavaScript 编写的微服务应用程序。这种方法有几种巨大优势。

  • WasmEdge 以接近原生的速度运行沙盒应用。根据一项经过同行评审的研究,WasmEdge 能够以近似 Linux 运行原生机器代码的速度运行 Rust 程序。
  • WasmEdge 是一个高度安全的 runtime。它可以保护你的应用程序免受外部和内部攻击威胁。 WasmEdge runtime 受攻击的脆弱点,相比常规 Linux OS runtime 大大减少。软件供应链攻击的风险大大降低了,因为 WebAssembly 沙箱仅允许明确声明的访问。
  • WasmEdge 在内存足迹上提供了一个完整的可移植应用程序 runtime 环境,仅是标准Linux OS runtime 镜像的1/10。
  • WasmEdge runtime 是跨平台的。这意味着机器的开发和部署不必相同。一旦创建了一个 WasmEdge 应用程序,就可以将其部署到支持 WasmEdge 的任何地方,包括 fly.io[4] 基础设施。
  • 如果是复杂的应用程序,该性能优势会进一步放大。 例如,WasmEdge AI 推理应用程序不需要 Python 安装。WasmEdge node.js 应用程序也无需安装 node.js 和 v8。

  • 异步 HTTP 服务器(Rust)
  • 一个非常快的图片分类 Web 服务(在Rust)和
  • node.js Web服务器
  • 具有数据库连接的有状态的微服务
  • 所有这些都可以在 WasmEdge 中快速且安全地运行,同时只消耗常规 Linux 容器所需资源的1/10。

    前期准备

    首先,请确保在系统上安装了 Docker 工具。如果没有,请按照本教程的第一节[5]安装 Docker。接下来,我们将使用在线安装程序来安装 WasmEdge、Rust 和 fly.io[6]flyctl工具。

    安装 WasmEdge。此处查看详细信息。[7]

    curl -sSf https://raw.githubusercontent.com/WasmEdge/WasmEdge/master/utils/install.sh | bash -s -- -e all

    安装 Rust。此处查看详细信息。[8]

    `curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh`

    fly.io[9] 安装 flyctl 工具。此处查看[10]详细信息[11]

    `curl -L `[`https://fly.io/install.sh`](https://fly.io/install.sh "`https://fly.io/install.sh`")` | sh`

    安装好了 flyctl 之后, 请按照指引在 fly.io[12].上注册免费帐[13]户。现在就可以在边缘云上部署 Web 服务了!

    Rust 写的一个简单的微服务

    我们的第一个示例是用 Rust 编写的简单 HTTP 服务。它演示了一个现代的 Web 应用程序,可以扩展以支持任意复杂的业务逻辑。基于流行的 Tokio 和 Hyper Crate,这个微服务是非常快、异步的(non-blocking),并且对于开发者来说非常容易创建。

    完全静态链接的 WasmEdge 镜像只有 4MB(相比之下基础 Linux 镜像则为 40MB)。这足以运行用 Rust 的 tokio 和 hyper 框架编写的异步 HTTP 服务。

    运行以下两个 CLI 命令,然后从 WasmEdge 的 Slim Docker 镜像创建fly.io[14] 应用。

    $ flyctl launch --image juntaoyuan/flyio-echo$ flyctl deploy

    好了!可以使用 curl 命令测试部署的 Web 服务是否成功。 它回显了你发布的任何数据。

    $ curl https://proud-sunset-3795.fly.dev/echo -d "Hello WasmEdge on fly.io!"Hello WasmEdge on fly.io!

    juntaoyuan/flyio-echo 镜像的 dockerfile 包含 WasmEdge runtime 和自定义的 Web 应用程序 WasmEdge_hyper_server.wasm 的完整包。

    FROM WasmEdge/slim-runtime:0.11.0ADD WasmEdge_hyper_server.wasm /CMD ["WasmEdge", "--dir", ".:/", "/WasmEdge_hyper_server.wasm"]

    构建 WasmEdge_hyper_server.wasm 应用程序的 Rust 源代码项目在这里。[15]它使用 Tokio API 启动 HTTP 服务器。 当服务器收到请求时,它会委派给 echo()函数以异步处理请求。这允许微服务接受和处理多个并发的 HTTP 请求。

    #[tokio::main(flavor = "current_thread")]async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {    let addr = SocketAddr::from(([0, 0, 0, 0], 8080));    let listener = TcpListener::bind(addr).await?;    println!("Listening on http://{}", addr);    loop {        let (stream, _) = listener.accept().await?;        tokio::task::spawn(async move {            if let Err(err) = Http::new().serve_connection(stream, service_fn(echo)).await {                println!("Error serving connection: {:?}", err);            }        });    }}

    异步 echo() 函数如下。它利用 hyper 提供的 HTTP API 来解析请求并生成响应。在这里,响应只是“请求数据正文”。

    async fn echo(req: Request<Body>) -> Result<Response<Body>, hyper::Error> {    match (req.method(), req.uri().path()) {        ... ...        (&Method::POST, "/echo") => Ok(Response::new(req.into_body())),        ... ...        // Return the 404 Not Found for other routes.        _ => {            let mut not_found = Response::default();            *not_found.status_mut() = StatusCode::NOT_FOUND;            Ok(not_found)        }    }}

    现在让我们在基本的微服务中加点料!

    Rust 写的一个 AI 推理微服务

    本例中,我们将创建一个用于图片分类的 Web 服务。它通过 Tensorflow Lite 模型处理上传的图片。我们将使用 WasmEdge 的 Rust API 来访问 Tensorflow,而不是创建一个复杂(且臃肿)的 Python 程序,它以本机机器代码速度运行推理任务(例如,如果有 GPU ,也可以在 GPU 硬件上运行)。通过 WASI-NN 标准,WasmEdge 的 Rust API 可以与 Tensorflow、PyTorch、OpenVINO 和其他 AI 框架中的 AI 模型一起使用。

    对于包含完整 Tensorflow Lite 依赖项的 AI 推理应用程序,WasmEdge 占用空间小于 115MB。 相比之下,标准 Tensorflow Linux 镜像超过 400MB。

    从 WasmEdge + Tensorflow 的 slim Docker 镜像开始,运行以下两个 CLI 命令来创建并部署一个 fly.io[16] 应用程序。

    $ flyctl launch --image juntaoyuan/flyio-classify$ flyctl deploy

    好了!你可以使用 curl 命令来测试部署的 Web 服务是否真的有效。它返回带有可能性等级的图片分类结果。

    $ curl https://silent-glade-6853.fly.dev/classify -X POST --data-binary "@grace_hopper.jpg"military uniform is detected with 206/255 confidence

    juntaoyuan/flyio-classify Docker 镜像的 Dockerfile 包含 WasmEdge runtime 的完整包、整个 Tensorflow 库及其依赖项,以及自定义 Web 应用程序 WasmEdge_hyper_server_tflite.wasm

    FROM WasmEdge/slim-tf:0.11.0ADD WasmEdge_hyper_server_tflite.wasm /CMD ["WasmEdge-tensorflow-lite", "--dir", ".:/", "/WasmEdge_hyper_server_tflite.wasm"]

    用于构建 WasmEdge_hyper_server_tflite.wasm 应用程序的 Rust 源代码项目在这里[17]。 基于 tokio 的异步 HTTP 服务器位于 async main() 函数中,如上一个示例所示。 classify() 函数处理请求中的图片数据,将图片转换为 tensor,运行 Tensorflow 模型,然后将返回值(在一个 tensor 中)转换为文本标签和所识别出内容的概率。

    async fn classify(req: Request<Body>) -> Result<Response<Body>, hyper::Error> {    let model_data: &[u8] = include_bytes!("models/mobilenet_v1_1.0_224/mobilenet_v1_1.0_224_quant.tflite");    let labels = include_str!("models/mobilenet_v1_1.0_224/labels_mobilenet_quant_v1_224.txt");    match (req.method(), req.uri().path()) {        (&Method::POST, "/classify") => {            let buf = hyper::body::to_bytes(req.into_body()).await?;            let flat_img = WasmEdge_tensorflow_interface::load_jpg_image_to_rgb8(&buf, 224, 224);            let mut session = WasmEdge_tensorflow_interface::Session::new(&model_data, WasmEdge_tensorflow_interface::ModelType::TensorFlowLite);            session.add_input("input", &flat_img, &[1, 224, 224, 3])                .run();            let res_vec: Vec<u8> = session.get_output("MobilenetV1/Predictions/Reshape_1");            ... ...                let mut label_lines = labels.lines();            for _i in 0..max_index {              label_lines.next();            }            let class_name = label_lines.next().unwrap().to_string();            Ok(Response::new(Body::from(format!("{} is detected with {}/255 confidence", class_name, max_value))))        }        // Return the 404 Not Found for other routes.        _ => {            let mut not_found = Response::default();            *not_found.status_mut() = StatusCode::NOT_FOUND;            Ok(not_found)        }    }}

    Node.js 中的一个简单的微服务

    虽然基于 Rust 的微服务轻巧快速,但并不是每个人都是 Rust 开发者(目前)。如果更熟悉 JavaScript,你仍然可以充分利用 WasmEdge 在边缘云中的安全性、性能、占用空间小和可移植性!具体来说,可以使用 node.js API 为 WasmEdge 创建微服务!

    对于 Node.js 应用程序,WasmEdge 占用空间小于 15MB。相比之下,标准 Node.js Linux 镜像超过 150MB。

    从 WasmEdge + node.js 的 slim Docker 镜像开始,运行以下两个 CLI 命令,创建并部署一个 fly.io[18] 应用。

    $ flyctl launch --image juntaoyuan/flyio-nodejs-echo$ flyctl deploy

    好了!可以使用 curl 命令来测试部署的 Web 服务是否真的有效。它会回显你发布给它的任何数据。

    $ curl https://solitary-snowflake-1159.fly.dev -d "Hello WasmEdge for Node.js on fly.io!"Hello WasmEdge for Node.js on fly.io!

    juntaoyuan/flyio-nodejs-echo Docker 镜像的 Dockerfile 包含 WasmEdge runtime 、QuickJS runtime WasmEdge_quickjs.wasm、node.js 模块的完整包[19]和 Web 服务应用程序 node_echo.js

    FROM WasmEdge/slim-runtime:0.11.0ADD WasmEdge_quickjs.wasm /ADD node_echo.js /ADD modules /modulesCMD ["WasmEdge", "--dir", ".:/", "/WasmEdge_quickjs.wasm", "node_echo.js"]

    node_echo.js 应用程序的完整 JavaScript 源代码如下。很明显,它仅使用标准 node.js API 来创建一个异步 HTTP 服务器,该服务器回显 HTTP 请求正文。

    import { createServer, request, fetch } from 'http';createServer((req, resp) => {  req.on('data', (body) => {    resp.end(body)  })}).listen(8080, () => {  print('listen 8080 ...n');})

    WasmEdge 的 QuickJS 引擎不仅提供 node.js 支持,还提供 Tensorflow 推理支持。我们将 Rust TensorFlow 和 WASI-NN SDK 封装到 JavaScript API 中,以便 JavaScript 开发者可以轻松创建 AI 推理应用程序[20]

    边缘的状态微服务

    使用 WasmEdge,还可以创建由数据库支持的有状态微服务。此 GitHub 代码库[21]包含 WasmEdge 应用程序中基于 tokio 的 non-blocking 数据库客户端的示例。

  • MySQL client[22] 允许 WasmEdge 应用程序访问大多数云数据库。
  • WasmEdge 应用程序可以使用anna-rs[23] 作为边缘缓存或者数据库。
  • 现在,快快使用 WasmEdge SDK 和 runtime 在边缘云上构建各种 Web 服务吧。已经迫不及待地想看到你的成果了!

    参考资料

    [1]

    fly.io: http://fly.io/

    [2]

    Fly.io: http://fly.io/

    [3]

    fly.io: http://fly.io/

    [4]

    fly.io: http://fly.io/

    [5]

    本教程的第一节: https://www.freecodecamp.org/news/the-docker-handbook/

    [6]

    fly.io: http://fly.io/

    [7]

    此处查看详细信息。: https://wasmedge.org/book/en/start/install.html

    [8]

    此处查看详细信息。: https://www.rust-lang.org/tools/install

    [9]

    fly.io: http://fly.io/

    [10]

    此处查看: https://fly.io/docs/hands-on/install-flyctl/

    [11]

    详细信息: https://www.rust-lang.org/tools/install

    [12]

    fly.io: http://fly.io/

    [13]

    注册免费帐: https://fly.io/docs/hands-on/sign-up/%EF%BC%89

    [14]

    fly.io: http://fly.io/

    [15]

    这里。: https://github.com/wasmedge/wasmedge/wasmedge_hyper_demo/tree/tree/main/main/server%EF%BC%89%E4%B8%8A%E8%8E%B7%E5%BE%97%E3%80%82

    [16]

    fly.io: http://fly.io/

    [17]

    这里: https://github.com/WasmEdge/wasmedge_hyper_demo/tree/main/server-tflite

    [18]

    fly.io: http://fly.io/

    [19]

    完整包: https://wasmedge.org/book/en/dev/js/nodejs.html#the-javascript-modules

    [20]

    轻松创建 AI 推理应用程序: https://wasmedge.org/book/en/dev/js/tensorflow.html

    [21]

    代码库: https://github.com/WasmEdge/wasmedge-db-examples

    [22]

    MySQL client: https://github.com/WasmEdge/wasmedge-db-examples/tree/main/mysql

    [23]

    anna-rs: https://github.com/WasmEdge/wasmedge-db-examples/tree/main/anna

    声明:本站部分文章及图片源自用户投稿,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!

    上一篇 2022年8月17日
    下一篇 2022年8月17日

    相关推荐