Rust中如何使用Spin框架构建微服务?


Rust 提供了一种强大而高效的应用程序开发方法。借助 Spin,为分布式应用程序构建强大的微服务变得更加容易。Rust 的性能优势以及 Spin 的易用性和可扩展性使它们成为寻求构建可靠和可扩展系统的开发人员的宝贵选择。

Spin 是一个用于开发、运行和部署微服务和 Web 应用程序的开源框架。您可以使用任何与 wasi 兼容的语言(例如 Go、Rust、Java 和 JavaScript)在 Spin 中开发任何微服务应用程序。

Spin 将您的微服务应用程序转换为无服务器云平台的 WebAssembly 组件,例如 AWS lambda(系统上的自托管服务器)或 WebAssembly 云平台(例如Fermyon Cloud)。在构建和运行微服务时,WebAssembly 提供安全性、可移植性和速度。

微服务是独立的软件组件,在较大的分布式应用程序中执行特定功能。它们被设计为在分布式系统中协同工作,每个服务负责一项任务,同时与其他服务通信以执行复杂的操作。

微服务被构建为小型、轻量级、模块化且可独立部署。您可以将它们部署在容器(例如 Docker)中,并使用容器编排工具(例如 Kubernetes)来管理它们。您还可以使用无服务器计算平台(例如 Google Cloud 函数和 AWS lambda)来实现它们。

安装
现在您已经熟悉了 Spin 和微服务,是时候将spin二进制文件安装到您的系统中了。本节将引导您完成二进制文件的安装。
该二进制文件允许您设置项目并托管本地服务器,并在所有主要操作系统上运行,包括 Windows、Linux 和 MacOS。您还可以选择从源代码构建二进制文件,或使用cargo.

1、在 Windows 上安装
要在 Windows 上安装二进制文件,请下载Windows 二进制版本,解压缩文件,然后将spin.exe文件放置在系统路径中。
要验证安装,请在命令提示符中运行以下命令:

>spin --help

如果出现错误,请尝试重新打开命令提示符,或重新启动系统。如果您没有收到错误,那么恭喜您!您刚刚在系统上安装了二进制文件,并且可以开始设置项目文件夹

2、在 MacOS(Intel 和 Apple 芯片)上安装
要spin在 MacOS 上安装二进制文件,请使用以下命令下载文件:

curl -fsSL https://developer.fermyon.com/downloads/install.sh | bash

上面的命令会下载适合您的系统的兼容二进制文件。为了允许从系统上的任何目录轻松访问二进制文件,请使用以下命令将spin文件移动到/usr/local/bin文件夹:
sudo mv spin /usr/local/bin/

该/usr/local/bin文件夹是一个系统路径,其中包含可以从系统中的所有目录访问的可执行文件。

3、在 Linux 上安装
要安装二进制文件,请使用以下命令下载文件:

curl -fsSL https://developer.fermyon.com/downloads/install.sh | bash

然后,使用以下命令将spin文件移动到/usr/local/bin文件夹:
sudo mv spin /usr/local/bin/

要验证安装,请运行以下命令:
spin --help

4、安装时使用cargo
要使用 来安装二进制文件cargo,请按照下列步骤操作:
克隆 Spin 存储库:
git clone https://github.com/fermyon/spin -b v0.9.0

打开spin目录:
cd spin

安装wasm32-wasiRust 目标:
rustup target add wasm32-wasi

编译项目并将其安装到您的系统中:
cargo install --locked --path .

验证安装是否成功:
spin --help

设置项目文件夹
在系统上安装后spin,让我们设置一个项目文件夹来构建微服务。在本节结束时,您将拥有一个用于构建微服务的初始化项目文件夹。

Spin 提供了用于构建多种不同类型的应用程序的模板。要检查系统上安装的模板,请运行以下命令:

spin templates list

如果您的系统上没有安装模板,请运行以下命令:

spin templates install --git https://github.com/fermyon/spin --update

上面的命令会安装Spin GitHub 存储库中的所有可用模板。安装模板后,您可以重新检查列表以查看已安装的模板。

安装模板后,运行以下命令开始设置项目:

$ spin new
Pick a template to start your application with:
> http-c (HTTP request handler using C and the Zig toolchain)
  http-empty (HTTP application with no components)
  http-go (HTTP request handler using (Tiny)Go)
  http-grain (HTTP request handler using Grain)
  http-php (HTTP request handler using PHP)
  http-rust (HTTP request handler using Rust)
  http-swift (HTTP request handler using SwiftWasm)
  http-zig (HTTP request handler using Zig)
  redirect (Redirects a HTTP route)
  redis-go (Redis message handler using (Tiny)Go)
  redis-rust (Redis message handler using Rust)
  static-fileserver (Serves static files from an asset directory)

该命令会提示您输入要使用的模板、项目名称、项目描述、HTTP 路径和 HTTP 基。对于模板,选择http-rust。对于项目名称,请编写您想要的任何名称。对于描述、HTTP 路径和 HTTP 基础,您可以点击Enter使用它们的默认值。

运行项目
设置项目后,您可能想查看应用程序如何运行。本节向您展示如何构建、运行和测试项目。在本节结束时,您将在系统上运行该项目。

构建项目后,Spin 从源代码生成一个 WebAssembly 组件。要构建应用程序,您需要安装wasm32-wasi目标。您可以wasm32-wasi使用以下两个命令安装目标并将项目编译为 WebAssembly 组件:

rustup target add wasm32-wasi    # Install the WebAssembly target
spin build                       # Build the project

命令完成后,生成的 WebAssembly 组件位于该target/wasm32-wasi/release文件夹中。spin允许您使用以下命令在系统上托管 WebAssembly 组件:

spin up

它在http://localhost:3000/中托管微服务应用程序。项目运行后,您可以使用以下curl命令对其进行测试:

$ curl -i localhost:3000
HTTP/1.1 200 OK
foo: bar
content-length: 14
date: Wed, 01 Mar 2023 11:11:57 GMT

Hello, Fermyon

现在您已经看到了该项目的实际运行,很高兴了解它是如何运作的。在以下部分中,我们将逐步介绍 的关键组件spin.toml以及lib.rs项目中的文件。

Spin.toml:清单文件
spin.toml是一个清单文件。它包含您的项目的配置。看一下项目的spin.toml文件:

spin_version = "1"
authors = [
"Username <youremail@example.com>"]
description =
""
name =
"project-name"
trigger = { type =
"http", base = "/" }
version =
"0.1.0"

[[component]]
id =
"project-name"
source =
"target/wasm32-wasi/release/spin_test.wasm"
allowed_http_hosts = []
[component.trigger]
route =
"/..."
[component.build]
command =
"cargo build --target wasm32-wasi --release"

通过查看该文件,您会注意到一些关键事项:

  • 第 5 行的变量trigger,配置微服务的性质。该微服务提供HTTP接口供外部应用程序与微服务交互
  • 第10行的变量source,它指向编译器放置编译后的WebAssembly组件的位置
  • 第13行变量route,配置微服务所在的路由。/…是一个通配符,它​​使微服务可以从任何路径访问

Lib.rs:微服务的主库
lib.rs是您的微服务的主要库。编译器将此文件编译为 WebAssembly 组件。看看该项目的lib.rs:

use anyhow::Result;
use spin_sdk::{
    http::{Request, Response},
    http_component,
};

/// A simple Spin HTTP component.
#[http_component]
fn handle_spin_test(req: Request) -> Result<Response> {
    println!(
"{:?}", req.headers());
    Ok(http::Response::builder()
        .status(200)
        .header(
"foo", "bar")
        .body(Some(
"Hello, Fermyon".into()))?)
}

  • http_component宏表示该handle_spin_test函数是一个 HTTP 组件。
  • handle_spin_test每当您向微服务发送 HTTP 请求时,Spin 都会运行该函数。handle_spin_test微服务在请求结束时返回结果。

构建函数性微服务
初始化的项目仅处理 Spin 微服务的基础知识。在本节中,我们将构建一个功能更强大的微服务。您将在本文末尾构建的微服务是一个猫事实生成器。微服务使用猫事实忍者 API生成随机猫事实。
首先,初始化一个项目,并将此代码写入您的lib.rs:

use anyhow::Result;
use spin_sdk::{
    http::{Request, Response},
    http_component,
};

#[http_component]
fn cat_facts(_req: Request) -> Result<Response> {
    // fetch fact from the API
    let mut res = spin_sdk::http::send(
        http::Request::builder()
            .method(
"GET")
            .uri(
"https://catfact.ninja/fact")
            .body(None)?,
    )?;
   
// Add "Server" key into the header
    res.headers_mut()
        .insert(http::header::SERVER,
"spin/0.1.0".try_into()?);
   
// Send response to the client
    Ok(res)
}

该spin库提供了发送 HTTP 请求的方法。在此微服务中,我们使用该方法从猫事实忍者 API 获取猫事实。该方法生成一个响应,cat_facts函数可以将其作为微服务的响应对象返回。

要完成该项目,请添加catfact.ninja到allowed_http_hosts文件第 11 行的变量spin.toml:
allowed_http_hosts = ["catfact.ninja"]

如果不这样做,HttpError::DestinationNotAllowed运行项目时就会出现错误。

结论
微服务是分布式应用程序的基础。它们是相互交互的独立部分,形成更大的分布式应用程序。本文将引导您完成微服务的构建。

使用本文中的知识,您可以构建更复杂的微服务,例如执行数据库交互或身份验证的微服务。

要了解有关 Spin 框架的更多信息,请务必查看Spin 文档