4.Rust+Axum Tower 中间件实战:从集成到自定义
摘要
深入探讨 Rust 中 Axum Tower 中间件生态系统,包含实用集成与自定义示例。
一、引言
在 Rust 的 Web 开发领域,Axum 是一个轻量级且功能强大的 Web 框架,而 Tower 中间件生态系统为 Axum 提供了丰富的扩展能力。中间件在 Web 应用中扮演着重要的角色,它可以在请求处理前后执行各种操作,如日志记录、数据压缩、限流等。本文将通过实战的方式,详细介绍如何在 Axum 中集成 tower - http 实现常见的中间件功能,同时讲解如何自定义中间件,并探讨中间件的执行顺序与生命周期管理。
二、集成 tower - http 实现日志、压缩、限流
2.1 日志中间件
日志记录是 Web 应用中非常重要的功能,它可以帮助开发者监控应用的运行状态、排查问题。tower - http 提供了 Trace 中间件来实现日志记录。以下是一个简单的示例:
use axum::{routing::get,Router,
};
use tower_http::trace::TraceLayer;
use std::net::SocketAddr;async fn hello() -> &'static str {"Hello, World!"
}#[tokio::main]
async fn main() {let app = Router::new().route("/", get(hello)).layer(TraceLayer::new_for_http());let addr = SocketAddr::from(([127, 0, 0, 1], 3000));axum::Server::bind(&addr).serve(app.into_make_service()).await.unwrap();
}
在这个示例中,我们使用 TraceLayer::new_for_http() 创建了一个日志中间件,并将其添加到路由层中。当有请求到来时,中间件会记录请求的详细信息,包括请求方法、路径、状态码等。
2.2 压缩中间件
数据压缩可以减少网络传输的数据量,提高应用的性能。tower - http 提供了 CompressionLayer 中间件来实现数据压缩。以下是一个示例:
use axum::{routing::get,Router,
};
use tower_http::compression::CompressionLayer;
use std::net::SocketAddr;async fn large_data() -> &'static str {"This is a large amount of data..."
}#[tokio::main]
async fn main() {let app = Router::new().route("/large_data", get(large_data)).layer(CompressionLayer::new());let addr = SocketAddr::from(([127, 0, 0, 1], 3000));axum::Server::bind(&addr).serve(app.into_make_service()).await.unwrap();
}
在这个示例中,我们使用 CompressionLayer::new() 创建了一个压缩中间件,并将其添加到路由层中。当客户端请求 /large_data 时,服务器会对响应数据进行压缩后再发送给客户端。
2.3 限流中间件
限流是一种保护机制,它可以防止应用被过多的请求压垮。tower - http 提供了 RateLimitLayer 中间件来实现限流。以下是一个示例:
use axum::{routing::get,Router,
};
use tower_http::limit::RateLimitLayer;
use std::net::SocketAddr;
use std::time::Duration;async fn limited() -> &'static str {"This is a limited route."
}#[tokio::main]
async fn main() {let app = Router::new().route("/limited", get(limited)).layer(RateLimitLayer::new(10, Duration::from_secs(1)));let addr = SocketAddr::from(([127, 0, 0, 1], 3000));axum::Server::bind(&addr).serve(app.into_make_service()).await.unwrap();
}
在这个示例中,我们使用 RateLimitLayer::new(10, Duration::from_secs(1)) 创建了一个限流中间件,它允许每秒最多处理 10 个请求。当请求超过这个限制时,服务器会返回一个限流响应。
三、自定义中间件开发(身份验证、请求耗时统计)
3.1 身份验证中间件
身份验证是保护应用安全的重要手段。我们可以自定义一个身份验证中间件来验证请求的合法性。以下是一个简单的示例:
use axum::{http::{Request, StatusCode},middleware::Next,response::Response,
};
use std::future::Future;async fn auth_middleware<B>(req: Request<B>, next: Next<B>) -> Result<Response, StatusCode> {let auth_header = req.headers().get("Authorization");if let Some(token) = auth_header {if token == "Bearer valid_token" {return Ok(next.run(req).await);}}Err(StatusCode::UNAUTHORIZED)
}// 在路由中使用
let app = Router::new().route("/protected", get(protected_handler)).layer(axum::middleware::from_fn(auth_middleware));
在这个示例中,auth_middleware 函数会检查请求头中的 Authorization 字段,如果令牌有效,则继续处理请求;否则,返回 401 Unauthorized 错误。
3.2 请求耗时统计中间件
请求耗时统计可以帮助我们分析应用的性能瓶颈。以下是一个自定义的请求耗时统计中间件示例:
use axum::{http::{Request, Response},middleware::Next,
};
use std::time::Instant;async fn timing_middleware<B>(req: Request<B>, next: Next<B>) -> Response {let start = Instant::now();let response = next.run(req).await;let elapsed = start.elapsed();println!("Request took {:?}", elapsed);response
}// 在路由中使用
let app = Router::new().route("/timed", get(timed_handler)).layer(axum::middleware::from_fn(timing_middleware));
在这个示例中,timing_middleware 函数会记录请求开始的时间,在请求处理完成后计算耗时并打印出来。
四、中间件执行顺序与生命周期管理
4.1 中间件执行顺序
中间件的执行顺序是按照它们添加到路由层的顺序来的。在请求处理过程中,请求会依次经过每个中间件,然后到达最终的处理函数;在响应返回过程中,响应会按照相反的顺序经过每个中间件。例如:
let app = Router::new().route("/", get(handler)).layer(middleware1).layer(middleware2).layer(middleware3);
在这个示例中,请求会先经过 middleware1,然后是 middleware2,最后是 middleware3,再到达 handler;响应返回时,会先经过 middleware3,然后是 middleware2,最后是 middleware1。
4.2 生命周期管理
中间件的生命周期管理主要涉及到中间件的初始化和资源释放。在 Rust 中,中间件通常是实现了特定 trait 的结构体。在初始化时,中间件可以进行一些必要的设置,如创建数据库连接、初始化缓存等;在应用关闭时,中间件可以进行资源释放操作,如关闭数据库连接、清理缓存等。例如,一个使用数据库连接池的中间件可以在初始化时创建连接池,在应用关闭时关闭连接池。
五、总结
通过集成 tower - http 中间件和自定义中间件,我们可以为 Axum 应用添加丰富的功能。同时,了解中间件的执行顺序和生命周期管理可以帮助我们更好地组织和优化应用的架构。在实际开发中,合理运用中间件可以提高应用的性能、安全性和可维护性。
相关文章:
4.Rust+Axum Tower 中间件实战:从集成到自定义
摘要 深入探讨 Rust 中 Axum Tower 中间件生态系统,包含实用集成与自定义示例。 一、引言 在 Rust 的 Web 开发领域,Axum 是一个轻量级且功能强大的 Web 框架,而 Tower 中间件生态系统为 Axum 提供了丰富的扩展能力。中间件在 Web 应用中扮…...
51单片机实验一:点亮led灯
目录 一、实验环境与实验器材 二、实验内容及实验步骤 1.用keil 软件创建工程,C文件编写程序,编译生成hex文件编辑 2.用STC烧写hex文件,点亮第一个LED灯 3.使用法2,点除第一个以外的LED灯 一、实验环境与实验器材 环境&am…...
PyCharm 开发工具 修改字体大小及使用滚轮没有反应
PyCharm 开发工具 修改字体大小及使用滚轮没有反应 提示:帮帮志会陆续更新非常多的IT技术知识,希望分享的内容对您有用。本章分享的是PyCharm 开发工具。前后每一小节的内容是有学习/理解关联性,希望对您有用~ PyCharm 开发工具 修改字体大小…...
AndroidStudio编译报错 Duplicate class kotlin
具体的编译报错信息如下: Duplicate class kotlin.collections.jdk8.CollectionsJDK8Kt found in modules kotlin-stdlib-1.8.10 (org.jetbrains.kotlin:kotlin-stdlib:1.8.10) and kotlin-stdlib-jdk8-1.6.21 (org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.6.21) D…...
zookeeper启动报错have small server identifier
解决方案: 1、查看myid是否有重复 2、查看server.X 与myid的X是否一致 3、启动顺序为myid从小到大的服务器顺序...
1.Framer Motion 中 motion/react 和 motion/react-client 的用法和区别
背景知识:服务器端渲染 (SSR) 和客户端渲染 (CSR) 在最新的 Motion for React(原 Framer Motion)12.x 及更高版本中,官方提供了两个入口模块:motion/react 和 motion/react-client。二者对外 API 完全一致,…...
Django 结合 Vue 实现简单管理系统的详解
以下是一个 Django 结合 Vue 实现简单管理系统的详细步骤及示例代码: 项目整体架构思路 后端:使用 Django 搭建 RESTful API,负责数据的存储和处理。前端:使用 Vue 构建用户界面,通过调用后端 API 实现数据的展示、添加、修改和删除等操作。步骤 1:创建 Django 项目和应…...
简易 Python 爬虫实现,10min可完成带效果源码
目录 准备工作 编写爬虫代码 运行爬虫 查看结果 遇到的问题及解决 总结 前言和效果 本文记录了使用 Python 实现一个简单网页爬虫的过程,目标是爬取 quotes.toscrape.com 的名言和作者,并将结果保存到文本文件。以下是完整步骤,包含环境…...
ArcPy工具箱制作(下)
在上一篇博客中,我们已经初步了解了如何制作ArcPy工具箱,包括工具箱的基本概念、准备工作、脚本编写以及将脚本转换为工具箱的步骤。今天,我们将继续深入探讨ArcPy工具箱的制作,重点介绍一些进阶技巧和优化方法. 一、优化工具箱的…...
492Q 型气缸盖双端面铣削组合铣床总体设计
一、引言 492Q 型气缸盖是发动机的重要组成部分,其双端面的加工精度对发动机的性能和可靠性有着重要影响。设计一款适用于 492Q 型气缸盖双端面铣削的组合铣床,能够提高加工效率和质量,满足发动机生产的需求。 二、总体设计要求 加工精度&…...
YOLO学习笔记 | YOLOv11的改进方向与应用领域
YOLOv11作为目标检测领域的前沿模型,其改进方向和应用领域在多个研究中得到了广泛探索。以下从改进策略和应用场景两个维度进行综合总结: 一、YOLOv11的改进方向 1. 骨干网络(Backbone)优化 Swin Transformer替换:通过引入层次化特征表示和移位窗口自注意力机制,解决了视…...
【学习笔记】Py网络爬虫学习记录(更新中)
目录 一、入门实践——爬取百度网页 二、网络基础知识 1、两种渲染方式 2、HTTP解析 三、Request入门 1、get方式 - 百度搜索/豆瓣电影排行 2、post方式 - 百度翻译 四、数据解析提取三种方式 1、re正则表达式解析 (1)常用元字符 ࿰…...
Python + Playwright:编写自动化测试的避坑策略
Python + Playwright:编写自动化测试的避坑策略 前言一、告别 `time.sleep()`,拥抱 Playwright 的智能等待二、选择健壮、面向用户的选择器,优先使用 `data-testid`三、严格管理环境与依赖,确保一致性四、分离测试数据与逻辑,灵活管理数据五、采用 POM 等设计模式,构建可…...
电脑开机启动慢的原因
硬件老化或故障 机械硬盘老化:电脑使用时间较长,机械硬盘的读写速度会逐渐下降。这是因为机械硬盘内部的盘片和磁头在长期使用后,可能会出现磨损、坏道等问题,导致数据读取速度变慢,从而影响开机时系统文件的加载速度&…...
旅游资源网站登录(jsp+ssm+mysql5.x)
旅游资源网站登录(jspssmmysql5.x) 旅游资源网站是一个为旅游爱好者提供全面服务的平台。网站登录界面简洁明了,用户可以选择以管理员或普通用户身份登录。成功登录后,用户可以访问个人中心,进行修改密码和个人信息管理。用户管理模块允许管…...
C语言链接数据库
目录 使用 yum 配置 mysqld 环境 查看 mysqld 服务的版本 创建 mysql 句柄 链接数据库 使用数据库 增加数据 修改数据 查询数据 获取查询结果的行数 获取查询结果的列数 获取查询结果的列名 获取查询结果所有数据 断开链接 C语言访问mysql数据库整体源码 通过…...
WiFi“管家”------hostapd的工作流程
目录 1. 启动与初始化 1.1 解析命令行参数 1.2 读取配置文件 1.3 创建接口和 BSS 数据结构 1.4 初始化驱动程序 2. 认证和关联处理 2.1 监听认证请求 2.2 处理认证请求 2.3 处理关联请求 3. 数据转发 3.1 接收客户端数据 3.2 转发数据 4. 断开连接处理 4.1 处理客…...
中间件--ClickHouse-9--MPP架构(分布式计算架构)
1、MPP 架构基础概念 MPP(Massively Parallel Processing 大规模并行处理) 是一种分布式计算架构,专门设计用来高效处理大规模数据集。在这种架构下*,数据库被分割成多个部分,每个部分可以在不同的服务器节点上并行处理*。这意味着ÿ…...
分布式计算领域的前沿工具:Ray、Kubeflow与Spark的对比与协同
在当今机器学习和大数据领域,分布式计算已成为解决大规模计算问题的关键技术。本文将深入探讨三种主流分布式计算框架——Ray、Kubeflow和Spark,分析它们各自的特点、应用场景以及如何结合它们的优势创建更强大的计算平台。 Spark批量清洗快,…...
每天学一个 Linux 命令(20):find
可访问网站查看,视觉品味拉满: http://www.616vip.cn/20/index.html find 是 Linux 系统中最强大的文件搜索工具之一,支持按名称、类型、时间、大小、权限等多种条件查找文件,并支持对搜索结果执行操作(如删除、复制、执行命令等)。掌握 find 可大幅提升文件管理效率…...
使用Service发布应用程序
使用Service发布应用程序 文章目录 使用Service发布应用程序[toc]一、什么是Service二、通过Endpoints理解Service的工作机制1.什么是Endpoints2.创建Service以验证Endpoints 三、Service的负载均衡机制四、Service的服务发现机制五、定义Service六、Service类型七、无头Servic…...
Winform发展历程
Windows Forms (WinForms) 发展历程 起源与背景(1998-2002) Windows Forms(简称WinForms)是微软公司推出的基于.NET Framework的GUI(图形用户界面)开发框架,于2002年随着.NET Framework 1.0的…...
【Hadoop入门】Hadoop生态之Flume简介
1 什么是Flume? Flume是Hadoop生态系统中的一个高可靠、高性能的日志收集、聚合和传输系统。它支持在系统中定制各类数据发送方(Source)、接收方(Sink)和数据收集器(Channel),从而能…...
npx 的作用以及延伸知识(.bin目录,npm run xx 执行)
文章目录 前言原理解析1. npx 的作用2. 为什么会有 node_modules/.bin/lerna3. npx 的查找顺序4. 执行流程总结1: 1. .bin 机制什么是 node_modules/.bin?例子 2. npx 的底层实现npx 是如何工作的?为什么推荐用 npx?npx 的特殊能力…...
本地部署DeepSeek-R1(Dify升级最新版本、新增插件功能、过滤推理思考过程)
下载最新版本Dify Dify1.0版本之前不支持插件功能,先升级DIfy 下载最新版本,目前1.0.1 Git地址:https://github.com/langgenius/dify/releases/tag/1.0.1 我这里下载到老版本同一个目录并解压 拷贝老数据 需先停用老版本Dify PS D:\D…...
【ubuntu】在Linux Yocto的基础上去适配Ubuntu的wifi模块
一、修改wifi的节点名 1.找到wifi模块的PID和VID ifconfig查看wifi模块网络节点的名字,发现是wlx44876393bb3a(wlxmac地址) 通过udevadm info -a /sys/class/net/wlx44876393bba路径的命令去查看wlx44876393bba的总线号,端口号…...
25软考新版系统分析师怎么备考?重点考哪些?(附新版备考资源)
软考系统分析师(高级资格)考试涉及知识面广、难度较大,需要系统化的复习策略。以下是结合考试大纲和历年真题整理的复习重点及方法: 一、明确考试结构与分值分布 1.综合知识(选择题,75分) 2…...
PyTorch入门------卷积神经网络
前言 参考:神经网络 — PyTorch Tutorials 2.6.0cu124 文档 - PyTorch 深度学习库 一个典型的神经网络训练过程如下: 定义一个包含可学习参数(或权重)的神经网络 遍历输入数据集 将输入通过神经网络处理 计算损失(即…...
Edge浏览器安卓版流畅度与广告拦截功能评测【不卡还净】
安卓设备上使用浏览器的体验,很大程度取决于两个方面。一个是滑动和页面切换时的反应速度,另一个是广告干扰的多少。Edge浏览器的安卓版本在这两方面的表现比较稳定,适合日常使用和内容浏览。 先看流畅度。Edge在中端和高端机型上启动速度快&…...
Docker 和 Docker Compose 使用指南
Docker 和 Docker Compose 使用指南 一、Docker 核心概念 镜像(Image) :应用的静态模板(如 nginx:latest)。容器(Container) :镜像的运行实例。仓库(Registry…...
