网站首页 > 基础教程 正文
本文为英文译文,原文首发在 FreeCodeCamp 原文链接:https://www.freecodecamp.org/news/edge-cloud-microservices-with-wasmedge-and-rust/
边缘云让开发者能够在靠近用户的地方部署微服务(即细颗粒度的 Web 服务),从而实现更好的用户体验(即非常快的响应时间)、绝佳的安全性以及高可用性。 边缘云利用本地乃至私有的数据中心、CDN 网络和电信数据中心(例如 5G MEC)来提供计算服务。 边缘云的成功案例包括 Cloudflare、Fastly、Akamai、fly.io、Vercel、Netlify 等。
但是,与大型公共云相比,边缘云是一个资源受限的环境。 如果边缘微服务本身运行缓慢、臃肿或不安全,将导致在边缘云上部署的全部优势丧失殆尽。
本文将展示如何创建轻量级和高性能的 Web 服务,然后将其免费部署到边缘云提供商 fly.io[1] 上。
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.0
ADD 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.0
ADD 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)
}
}
}
在本文的最后,我们将讨论如何向 Rust 微服务添加更多功能,例如数据库客户端和 Web 服务客户端。
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.0
ADD WasmEdge_quickjs.wasm /
ADD node_echo.js /
ADD modules /modules
CMD ["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
- 上一篇: 通过浏览器工作台启动本地项目
- 下一篇: Deno 1.30 正式发布
猜你喜欢
- 2024-11-25 Deno 1.30 正式发布
- 2024-11-25 通过浏览器工作台启动本地项目
- 2024-11-25 r2frida:基于Frida的远程进程安全检测和通信工具
- 2024-11-25 NPM 使用介绍
- 2024-11-25 使用Hexo在github上搭建静态博客
- 2024-11-25 Android动态调试(1)-Radare2和lldb
- 2024-11-25 Metasploit渗透测试之MSFvenom
- 2024-11-25 浅析CTF中的Node.js原型链污染
- 2024-11-25 首个SSRF漏洞开篇学习
- 2024-11-25 github webhook自动化部署
- 最近发表
- 标签列表
-
- gitpush (61)
- pythonif (68)
- location.href (57)
- tail-f (57)
- pythonifelse (59)
- deletesql (62)
- c++模板 (62)
- css3动画 (57)
- c#event (59)
- linuxgzip (68)
- 字符串连接 (73)
- nginx配置文件详解 (61)
- html标签 (69)
- c++初始化列表 (64)
- exec命令 (59)
- canvasfilltext (58)
- mysqlinnodbmyisam区别 (63)
- arraylistadd (66)
- node教程 (59)
- console.table (62)
- c++time_t (58)
- phpcookie (58)
- mysqldatesub函数 (63)
- window10java环境变量设置 (66)
- c++虚函数和纯虚函数的区别 (66)