当前位置: 首页 > news >正文

【从零开始的rust web开发之路 四】rust语言tokio异步使用redis教程

文章目录

前言

使用rust写web,自然是离不开redis缓存的。rust也有现成redis连接库,并且支持阻塞和异步两种模式。下面教程我我以tokio异步操作redis方式为主,同步的操作可以参考异步,区别不大

一、首先引入依赖

redis = { version = "0.24.0",features = [ "r2d2" , "tokio-comp" ] }

我这里feature开启了r2d2连接池,以及开启了tokio异步支持特性。
全部特性列表如下
可选功能
定义了一些可以启用其他功能的功能 如果需要的话。其中一些是默认打开的。

  • acl:启用 ACL 支持(默认启用)
  • aio:启用异步 IO 支持(默认启用)
  • geospatial:启用地理空间支持(默认启用)
  • script:启用脚本支持(默认启用)
  • r2d2:启用 R2D2 连接池支持(可选)
  • ahash:启用AHASH地图/设置支持并在内部使用AHASH(+7-10%性能)- (可选)
  • cluster:启用 Redis集群支持(可选)
  • cluster-async:启用异步 Redis 集群支持(可选)
  • tokio-comp:启用对 Tokio的支持(可选)
  • connection-manager:启用对自动重新连接的支持(可选)
  • keep-alive:通过板启用保持活动选项(可选)socket2

二、创建redis客户端

    let client = redis::Client::open("redis://127.0.0.1:6379/").unwrap();//获取连接let con = client.get_async_connection().await.expect("连接redis失败");

此处url的格式为redis://[][:@][:port][/]
db是redis数据库索引。可根据业务自行修改

三、相关操作

设置值

#[tokio::main]
async  fn main() {let client = redis::Client::open("redis://127.0.0.1:6379/10").unwrap();let mut con = client.get_async_connection().await.expect("连接redis失败");con.set::<&str,u32,()>("my_key", 12).await.expect("操作失败");
}

此处<&str,u32,()>前两个泛型指定key,value。第三个泛型是实现了FromRedisValue Trait的返回,set方法可以不指定

mset设置多个key值

#[tokio::main]
async  fn main() {let client = redis::Client::open("redis://127.0.0.1:6379/10").unwrap();let mut con = client.get_async_connection().await.expect("连接redis失败");con.mset::<&str,u32,()>(&[("my_key1", 100), ("my_key2", 200)]).await.expect("操作失败");
}

设置含有过期时间的值

#[tokio::main]
async  fn main() {let client = redis::Client::open("redis://127.0.0.1:6379/10").unwrap();let mut con = client.get_async_connection().await.expect("连接redis失败");//设置60秒过期,第三个参数是过期时间con.pset_ex::<&str,u32,()>("my_key", 12,60*1000).await.expect("操作失败");
}

pset_ex是毫秒单位,set_ex是秒

如果key不存在才设置

#[tokio::main]
async  fn main() {let client = redis::Client::open("redis://127.0.0.1:6379/10").unwrap();let mut con = client.get_async_connection().await.expect("连接redis失败");con.set_nx::<&str,u32,()>("key3",30).await.expect("操作失败");
}

获取基本类型值

#[tokio::main]
async  fn main() {let client = redis::Client::open("redis://127.0.0.1:6379/10").unwrap();let mut con = client.get_async_connection().await.expect("连接redis失败");let value : u32 = con.get("my_key").await.expect("获取值失败");println!("my_key = {}", value);
}

删除一个键

#[tokio::main]
async  fn main() {let client = redis::Client::open("redis://127.0.0.1:6379/10").unwrap();let mut con = client.get_async_connection().await.expect("连接redis失败");con.del::<&str, ()>("key3") .await.expect("删除redis key失败");
}

删除多个键

#[tokio::main]
async  fn main() {let client = redis::Client::open("redis://127.0.0.1:6379/10").unwrap();let mut con = client.get_async_connection().await.expect("连接redis失败");// 多个键删除let keys_to_delete = vec!["my_key1", "my_key2"];let result = con.del::<&Vec<&str>, i32>(&keys_to_delete).await;match result {Ok(count) => println!("Deleted {} keys", count),Err(e) => println!("Error: {}", e),}
}

判断键是否存在

#[tokio::main]
async  fn main() {let client = redis::Client::open("redis://127.0.0.1:6379/10").unwrap();let mut con = client.get_async_connection().await.expect("连接redis失败");// 判断键是否存在let exists : bool = con.exists("my_key").await.expect("执行redis命令失败");println!("exists: {}", exists);
}

更多详细的接口文档可以看官网AsyncCommands接口https://docs.rs/redis/0.24.0/redis/trait.AsyncCommands.html

如何使用json序列化

 可以通过自定义方法添加泛型约束实现功能。使用serde_json库来进行序列化

导入相关依赖

[dependencies]
tokio = { version = "1.35.1", features = ["full"] }
redis = { version = "0.24.0",features = [ "r2d2" , "tokio-comp","json" ] }
serde_json = "1.0.111"
serde = { version = "1.0.195", features = ["derive"] }

代码相关实例

use redis::{aio, AsyncCommands, RedisError, RedisResult, ToRedisArgs};
use serde::{Deserialize, Serialize};
use serde::de::DeserializeOwned;#[derive(Debug, Clone,Deserialize, Serialize)]
struct User{name: String,age: u8,email: String,
}#[tokio::main]
async  fn main() {let client = redis::Client::open("redis://127.0.0.1:6379/10").unwrap();let mut con = client.get_async_connection().await.expect("连接redis失败");// 判断键是否存在let user = User{name: "zhangsan".to_string(),age: 18,email: "11111111".to_string(),};set_json(&mut con,"user1",&user).await.expect("设置失败");let user :User = get_json(&mut con, "user2").await.expect("获取失败,没有找到User");println!("user:{:?}",user);
}//设置json格式对象
pub async fn set_json<K,T>(con: &mut aio::Connection, key: K, obj : &T) -> RedisResult<String>where K: ToRedisArgs + Send + Sync, T: Serialize{let json = serde_json::to_string(obj);match json {Ok(obj) => {con.set::<K,String, String>(key,obj).await},Err(e) => {return Err(RedisError::from(e));}}
}//获得json格式对象
pub async fn get_json<K, T>(con: &mut aio::Connection, key: K) -> RedisResult<T>where K: ToRedisArgs + Send + Sync, T: DeserializeOwned{let json : String = con.get(key).await?;let result = serde_json::from_str(&json);return match result {Ok(obj) => { Ok(obj) },Err(e) => { Err(RedisError::from(e)) }}
}

通过这两个方法泛型约束据即可实现相关功能

总结

以上就是今天要讲的内容,本文介绍了rust语言tokio异步使用redis教程,后续会出一个扩展使用教程

相关文章:

【从零开始的rust web开发之路 四】rust语言tokio异步使用redis教程

文章目录 前言一、首先引入依赖二、创建redis客户端三、相关操作设置值mset设置多个key值设置含有过期时间的值如果key不存在才设置获取基本类型值删除一个键删除多个键判断键是否存在 如何使用json序列化导入相关依赖代码相关实例 总结 前言 使用rust写web&#xff0c;自然是…...

uniapp本地存储的几种方式localStorage

在uniapp开发中&#xff0c;本地存储是一个常见的需求。本地存储可以帮助我们在客户端保存和管理数据&#xff0c;以便在应用程序中进行持久化存储。本文将介绍uniapp中本地存储的几种方式&#xff0c;以及相关的代码示例。 介绍 在移动应用开发中&#xff0c;我们经常需要将…...

扩展学习|统计学习理论(SLT)与极限学习机(ELM)应用于大社会数据分析

文献来源&#xff1a;[1] Oneto L , Bisio F , Cambria E ,et al.Statistical Learning Theory and ELM for Big Social Data Analysis[J].IEEE Computational Intelligence Magazine, 2016, 11(3):45-55.DOI:10.1109/MCI.2016.2572540. 提取链接&#xff1a;链接&#xff1a;h…...

配置实例—交换机VLAN聚合配置实例

一、组网需求 某公司拥有多个部门且位于同一网段&#xff0c;为了提升业务安全性&#xff0c;将不同部门的用户划分到不同VLAN中。现由于业务需要&#xff0c;不同部门间的用户需要互通。如图1所示&#xff0c;VLAN2和VLAN3为不同部门&#xff0c;现需要实现不同VLAN间的用户可…...

网络开发的隐形壁垒:如何巧妙解决跨域难题?

什么是跨域 跨域是浏览器受同源&#xff08;协议、域名、端口&#xff09;策略的限制&#xff0c;不允许不同源的站点之间进行某些操作&#xff08;如发送ajax请求&#xff0c;操作dom&#xff0c;读取cookie&#xff09;&#xff0c;如果不进行特殊配置是不能操作成功的&…...

【极简】conda同一个服务器上迁移环境 export / create

导出 直接看conda的document&#xff1a;https://docs.conda.io/projects/conda/en/latest/commands/env/export.html conda env export conda env export --file SOME_FILE重建 conda documentation: https://docs.conda.io/projects/conda/en/latest/commands/env/create.…...

HBase 数据导入导出

HBase 数据导入导出 1. 使用 Docker 部署 HBase2. HBase 命令查找3. 命令行操作 HBase3.1 HBase shell 命令3.2 查看命名空间3.3 查看命名空间下的表3.4 新建命名空间3.5 查看具体表结构3.6 创建表 4. HBase 数据导出、导入4.1 导出 HBase 中的某个表数据4.2 导入 HBase 中的某…...

(java版)排序算法----【冒泡,选择,插入,希尔,快速排序,归并排序,基数排序】超详细~~

目录 冒泡排序(BubbleSort)&#xff1a; 代码详解&#xff1a; 冒泡排序的优化&#xff1a; 选择排序(SelectSort)&#xff1a; 代码详解&#xff1a; 插入排序&#xff08;InsertSort&#xff09;&#xff1a; 代码详解&#xff1a; 希尔排序(ShellSort)&#xff1a; 法一…...

服务器托管的作用是什么?

服务器托管是将企业的服务器和相关设备托管到具有完善机房设施、高品质网络环境与运营经验的网络数据中心内&#xff0c;服务器托管在维护方面一般是由客户负责的&#xff0c;或者是由其他的授权人进行远程维护。 那服务器托管的作用都有哪些呢&#xff1f; 服务器托管不需要企…...

美团启动架构调整:聚力核心本地商业,提升科技与境外业务优先级

2月2日&#xff0c;美团CEO王兴发布内部邮件宣布新的组织架构调整。邮件显示&#xff0c;美团对核心本地商业相关多项业务进行了整合&#xff0c;并进一步提升了科技与国际化相关业务的优先级。 在核心本地商业上&#xff0c;美团对过去相对独立的事业群进行了整合。主要调整包…...

监测Tomcat项目宕机重启脚本(Linux)

1.准备好写好的脚本 #!/bin/sh # 获取tomcat的PID TOMCAT_PID$(ps -ef | grep tomcat | grep -v tomcatMonitor |grep -v grep | awk {print $2}) # tomcat的启动文件位置 START_TOMCAT/mnt/tomcat/bin/startup.sh # 需要监测的一个GET请求地址 MONITOR_URLhttp://localhost:…...

道可云元宇宙每日资讯|北京:推进元宇宙在智慧城市应用

道可云元宇宙每日简报&#xff08;2024年2月2日&#xff09;讯&#xff0c;今日元宇宙新鲜事有&#xff1a; 石狮市检察院“元宇宙智慧展馆”正式启用 为深入实施数字检察战略&#xff0c;主动探索元宇宙技术在未成年人检察、公益诉讼检察等方面的应用&#xff0c;打造集案件…...

Logback学习

logback 1、logback介绍 Logback是由log4j创始人设计的另一个开源日志组件&#xff0c;性能比log4j要好。 lockback优点&#xff1a; 内核重写、测试充分、初始化内存加载更小&#xff0c;这一切让logback性能和log4j相比有诸多倍的提升。logback非常自然地直接实现了slf4j…...

【Chrono Engine学习总结】2-可视化

由于Chrono的官方教程在一些细节方面解释的并不清楚&#xff0c;自己做了一些尝试&#xff0c;做学习总结。 0、基本概念 类型说明&#xff1a; Chrono的可视化包括两块&#xff1a;实时可视化&#xff0c;以及离线/后处理可视化。 其中&#xff0c;实时可视化&#xff0c;又…...

pytorch创建tensor

目录 1. 从numpy创建2. 从list创建3. 创建未初始化tensor4. 设置默认tensor创建类型5. rand/rand_like, randint6. randn生成正态分布随机数7. full8. arange/range9. linspace/logspace10. Ones/zeros/eye11. randperm 1. 从numpy创建 2. 从list创建 3. 创建未初始化tensor T…...

Cmake语法学习3:语法

1.双引号 1.1 命令参数 1&#xff09;介绍 命令中多个参数之间使用空格进行分隔&#xff0c;而 cmake 会将双引号引起来的内容作为一个整体&#xff0c;当它当成一个参数&#xff0c;假如你的参数中有空格&#xff08;空格是参数的一部分&#xff09;&#xff0c;那么就可以使…...

JavaScript 基础 - 第1天

介绍 掌握 JavaScript 的引入方式&#xff0c;初步认识 JavaScript 的作用 引入方式 JavaScript 程序不能独立运行&#xff0c;它需要被嵌入 HTML 中&#xff0c;然后浏览器才能执行 JavaScript 代码。通过 script 标签将 JavaScript 代码引入到 HTML 中&#xff0c;有两种方式…...

人口增长问题 T1063

#include<bits/stdc.h> using namespace std; int main(){int n;double x;cin>>x>>n;for(int i1;i<n;i){xx*1.001;}printf("%.4lf",x);return 0; }...

2024年Java算法面试题

2024年Java实战面试题&#xff08;北京&#xff09;_java 5 年 面试-CSDN博客 一、波菲那契递归 System.out.println("banc " banc(10)) public static int banc(int n){if( n0 ){return 0;}else if( n1 ){return 1;}else{return banc(n-1) banc(n-2);} } 二、冒…...

C#——三角形面积公式

已知三角形的三个边&#xff0c;求面积&#xff0c;可以使用海伦公式。 因此&#xff0c;可以执行得到三角形面积公式的计算方法代码如下&#xff1a; /** / <summary>* / 三角形面积公式* / </summary>* / <param name"a">边长a</param>*…...

【SpringBoot】100、SpringBoot中使用自定义注解+AOP实现参数自动解密

在实际项目中,用户注册、登录、修改密码等操作,都涉及到参数传输安全问题。所以我们需要在前端对账户、密码等敏感信息加密传输,在后端接收到数据后能自动解密。 1、引入依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId...

质量体系的重要

质量体系是为确保产品、服务或过程质量满足规定要求&#xff0c;由相互关联的要素构成的有机整体。其核心内容可归纳为以下五个方面&#xff1a; &#x1f3db;️ 一、组织架构与职责 质量体系明确组织内各部门、岗位的职责与权限&#xff0c;形成层级清晰的管理网络&#xf…...

HTML前端开发:JavaScript 常用事件详解

作为前端开发的核心&#xff0c;JavaScript 事件是用户与网页交互的基础。以下是常见事件的详细说明和用法示例&#xff1a; 1. onclick - 点击事件 当元素被单击时触发&#xff08;左键点击&#xff09; button.onclick function() {alert("按钮被点击了&#xff01;&…...

数据库分批入库

今天在工作中&#xff0c;遇到一个问题&#xff0c;就是分批查询的时候&#xff0c;由于批次过大导致出现了一些问题&#xff0c;一下是问题描述和解决方案&#xff1a; 示例&#xff1a; // 假设已有数据列表 dataList 和 PreparedStatement pstmt int batchSize 1000; // …...

OPenCV CUDA模块图像处理-----对图像执行 均值漂移滤波(Mean Shift Filtering)函数meanShiftFiltering()

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 在 GPU 上对图像执行 均值漂移滤波&#xff08;Mean Shift Filtering&#xff09;&#xff0c;用于图像分割或平滑处理。 该函数将输入图像中的…...

使用Spring AI和MCP协议构建图片搜索服务

目录 使用Spring AI和MCP协议构建图片搜索服务 引言 技术栈概览 项目架构设计 架构图 服务端开发 1. 创建Spring Boot项目 2. 实现图片搜索工具 3. 配置传输模式 Stdio模式&#xff08;本地调用&#xff09; SSE模式&#xff08;远程调用&#xff09; 4. 注册工具提…...

android13 app的触摸问题定位分析流程

一、知识点 一般来说,触摸问题都是app层面出问题,我们可以在ViewRootImpl.java添加log的方式定位;如果是touchableRegion的计算问题,就会相对比较麻烦了,需要通过adb shell dumpsys input > input.log指令,且通过打印堆栈的方式,逐步定位问题,并找到修改方案。 问题…...

pikachu靶场通关笔记19 SQL注入02-字符型注入(GET)

目录 一、SQL注入 二、字符型SQL注入 三、字符型注入与数字型注入 四、源码分析 五、渗透实战 1、渗透准备 2、SQL注入探测 &#xff08;1&#xff09;输入单引号 &#xff08;2&#xff09;万能注入语句 3、获取回显列orderby 4、获取数据库名database 5、获取表名…...

CVPR2025重磅突破:AnomalyAny框架实现单样本生成逼真异常数据,破解视觉检测瓶颈!

本文介绍了一种名为AnomalyAny的创新框架&#xff0c;该方法利用Stable Diffusion的强大生成能力&#xff0c;仅需单个正常样本和文本描述&#xff0c;即可生成逼真且多样化的异常样本&#xff0c;有效解决了视觉异常检测中异常样本稀缺的难题&#xff0c;为工业质检、医疗影像…...

全面解析数据库:从基础概念到前沿应用​

在数字化时代&#xff0c;数据已成为企业和社会发展的核心资产&#xff0c;而数据库作为存储、管理和处理数据的关键工具&#xff0c;在各个领域发挥着举足轻重的作用。从电商平台的商品信息管理&#xff0c;到社交网络的用户数据存储&#xff0c;再到金融行业的交易记录处理&a…...