Rust学习笔记 --雪花ID生成

雪花ID现在应该大家用的都不少了,雪花ID的作用是生成唯一标识符,一般用在生成订单上面,使订单不重复,但用rust应该怎么写一个雪花ID的生成器呢,下面是我的学习思路,首先我们要导入相关的依赖库rs-snowflake,在cargo.toml导入这个依赖。

要生成雪花ID的话需要用到机器码,我从redis里面捞取机器码,redis的安装需要自己下载安装,不过redis目前在Windows的安装是通过第三方的,所以我选择把redis装在了阿里云ECS服务器里面,安装好之后,就可以往redis里面存入值来捞取机器码了,为了用rust连接上redis,需要导入redis这个依赖库,redis的连接代码如下

ini 复制代码
let client = redis::Client::open(redis://default:password@localhost:6379/).unwrap();
let mut connection = client.get_async_connection().await.unwrap();

一般redis用户默认名为default,测试连接通过之后,就可以编写代码来捞取机器码,并通过机器码来生成雪花ID了,废话不多说,直接上代码

rust 复制代码
use snowflake::SnowflakeIdBucket;
use std::sync::Mutex;
use tokio::sync::OnceCell;
use crate::service:: CONTEXT;

static SNOWFLAKE_BUCKET: OnceCell<Mutex<SnowflakeIdBucket>> = OnceCell::const_new();

pub struct SonwflakeUtil {}

impl SonwflakeUtil {         
    async fn get_machine_id_from_redis() -> i32 {
        CONTEXT.cache_service.get_string("MACHINE_ID")
            .await
            .expect("faild")
            .parse::<i32>()
            .expect("faild")
        }  
   pub async fn get_id() -> u64 {
        SNOWFLAKE_BUCKET.get_or_init(|| async{
                let machine_id = SonwflakeUtil::get_machine_id_from_redis().await;
                Mutex::new(SnowflakeIdBucket::new(machine_id, 0)
            )})
            .await
            .lock()
            .expect("faild get_id")
            .get_id() as u64
        }
}

我的逻辑是创建一个全局静态变量SNOWFLAKE_BUCKET来存储我的SnowflakeIdBucket,SnowflakeIdBucket的作用是存储获取的机器码,我在创建SNOWFLAKE_BUCKET的时候使用了OnceCell,这个是为了能够调用get_or_init()这个函数,我调用这个函数的作用是什么呢,是因为我想只初始化一次SnowflakeIdBucket,意思就是只捞取一次机器码,后面就把捞取下来的机器码保存下来复用,还用到Mutex互斥锁,是为了避免有多个对象同时竞争同一资源的事件发生,也就是数据竞争,

rust 复制代码
 async fn get_machine_id_from_redis() -> i32 {
        CONTEXT.cache_service.get_string("MACHINE_ID")
            .await
            .expect("faild")
            .parse::<i32>()
            .expect("faild")
        }  

这一段代码是我从redis里面捞取机器码的过程,get_string()这个端口是连接redis并获取"MACHINE_ID"这个对象的机器码的,是已经编写好的一个端口,涉及到比较多文件,就不细讲了,实现这个的原理还是比较简单的,首先要连接上自己的redis,例子上面有,连接上之后,用get()函数获取对象的值,例如

ini 复制代码
value = redis_client.get('my_key')

获取到值后把值转换成i32就是你拿到的机器码了,拿到机器码后把机器码存到SnowflakeIdBucket中,

php 复制代码
let machine_id = SonwflakeUtil::get_machine_id_from_redis().await;
                Mutex::new(SnowflakeIdBucket::new(machine_id, 0)

因为我是只拿一次机器码,所以我调用了get_or_init()这个函数,

rust 复制代码
 SNOWFLAKE_BUCKET.get_or_init(|| async{
                let machine_id = SonwflakeUtil::get_machine_id_from_redis().await;
                Mutex::new(SnowflakeIdBucket::new(machine_id, 0)
            )})

闭包里的语句就是将获得的机器码初始化,存进SnowflakeIdBucket里面,这些语句只在get_or_init()第一次执行时启动,后面都是只会获取SnowflakeIdBucket里面的值,最后可以直接通过get_id()这个函数来直接生成雪花ID了

rust 复制代码
 .get_id() as u64

最后的测试生成结果如下

以上仅为个人学习总结,欢迎大家一起来讨论

相关推荐
架构技术专栏6 小时前
Agent 工具调用:从工具声明到执行反馈
前端·人工智能·后端
码事漫谈7 小时前
你让AI干的活,它可能只干了十分之一——而你根本看不出来
后端
Wx-bishekaifayuan7 小时前
express皖美特色农产品网售系统53118-计算机课程设计、毕业设计
人工智能·spring boot·后端·python·课程设计·express·旅游
Wx-bishekaifayuan8 小时前
springboot汉中旅游服务平台41442-计算机课程设计、毕业设计
spring boot·后端·python·django·课程设计·express·旅游
WeiXin_DZbishe8 小时前
基于springboot城市公交实时运营与调度系统-计算机毕设 附源码【课程设计】66173
java·vue.js·spring boot·后端·python·php·课程设计
WeiXin_DZbishe8 小时前
基于Springboot+AI的kuall音乐广场的设计与实现-计算机毕设 附源码【课程设计】12715
vue.js·人工智能·spring boot·后端·python·php·课程设计
A接拉起0079 小时前
2026 年 JavaScript 开发者需要了解的知识
前端·javascript·后端
Bazingga9 小时前
RAG评测体系保姆级教程:生产级实践指南
后端
tachibana210 小时前
使用for range 的时候,它的地址会发生变化吗?
开发语言·后端·golang·go·语法
蜗牛互联网10 小时前
GPT-6 与 Intelligent UI:从回答到可审计操作的产品迁移
java·人工智能·后端