前言
本后端項(xiàng)目用到的技術(shù)棧主要包括:
Log 日志庫(kù);
Serde 序列化;
SnowFlake Id生成;
dotenv 獲取環(huán)境配置;
MongoDB 存?。?/p>
lazy_static 全局靜態(tài)初始化;
ELO 算法;
使用 Pre-Commit 在 Git Commit 前進(jìn)行校驗(yàn);
使用 Github Action 進(jìn)行 CI;
使用中間鏡像對(duì)代碼進(jìn)行編譯并創(chuàng)建部署鏡像;
……
閱讀了本文,你應(yīng)該也能夠?qū)W會(huì)上面這些庫(kù)的用法;
那么廢話不多說(shuō),直接開(kāi)始!
代碼實(shí)現(xiàn)
代碼目錄結(jié)構(gòu)
整個(gè)項(xiàng)目的目錄結(jié)構(gòu)如下(已去掉無(wú)關(guān)文件):
下面來(lái)說(shuō)明:
.github目錄:Github Actions 相關(guān)配置;
src目錄:項(xiàng)目源代碼目錄;
.pre-commit-config.yaml:Pre-Commit 配置;
.env:項(xiàng)目環(huán)境變量配置;
Cargo.toml:Cargo 項(xiàng)目配置;
Makefile:項(xiàng)目編譯腳本;
Dockerfile:項(xiàng)目Docker鏡像配置;
build-image.sh:打包鏡像腳本;
對(duì)于 src 目錄下的各個(gè)子目錄,見(jiàn)名知意,基本上很好理解了!
服務(wù)入口
Cargo 項(xiàng)目約定程序的入口都是:src/main.rs下;
我們從 main 函數(shù)來(lái)看做了些什么:
src/main.rs
在入口文件中,首先啟用了一些庫(kù)的宏(Macro),并聲明了 Actix-Web 框架的 main 函數(shù);
在 main 函數(shù)中,做了一般后端服務(wù)都會(huì)做的事情:
獲取環(huán)境配置;
初始化項(xiàng)目日志;
初始化資源:數(shù)據(jù)庫(kù)、Id生成器等;
注冊(cè)并啟動(dòng)服務(wù);
下面我們分別來(lái)看
配置與日志
獲取環(huán)境配置
我們可以通過(guò)dotenv庫(kù)解析位于項(xiàng)目下、以及系統(tǒng)環(huán)境變量中的配置;
只需要下面一句話即可:
dotenv().ok();
配置文件如下:
.env
MONGODB_URI=mongodb://admin:123456@localhost:27017/?retryWrites=true&w=majority
LOG_LEVEL=INFO
SNOWFLAKE_MACHINE_ID=1
SNOWFLAKE_NODE_ID=1
主要是配置了 MongoDB 的連接地址、日志級(jí)別、SnowFlake 的配置;
上面的語(yǔ)句會(huì)將這些配置解析;
初始化Logger
main 函數(shù)中的這條語(yǔ)句初始化了 Logger:
logger::init();
這個(gè)是 logger 模塊封裝的一個(gè)函數(shù):
logger/mod.rs
上面的代碼首先定義了一個(gè)全局日志類(lèi)型 Logger;
并在 init 函數(shù)中初始化了全局靜態(tài)變量:LOGGER,并使用log::set_logger進(jìn)行了設(shè)置;
同時(shí),我們我們從環(huán)境變量中獲取LOG_LEVEL日志級(jí)別配置(如果未設(shè)置,則默認(rèn)為INFO級(jí)別),隨后進(jìn)行了設(shè)置;
我們?yōu)槲覀兊?Logger 實(shí)現(xiàn)了log::LogTrait,這也是為什么我們能將該類(lèi)型的變量設(shè)置為L(zhǎng)ogger的原因!
在log::LogTrait 的實(shí)現(xiàn)中,我們簡(jiǎn)單定義了日志的輸出格式以及輸出顏色;
可以看到有了很多第三方庫(kù)的支持,rust 還是非常好用的!
初始化資源
接下來(lái)我們調(diào)用:
resource::check_resources().await;
service::init_file_service().await;
來(lái)等待資源初始化完成;
下面初始化文件服務(wù)的邏輯非常簡(jiǎn)單,只是創(chuàng)建了一個(gè)臨時(shí)文件:
我們重點(diǎn)來(lái)看check_resources()函數(shù),在其中初始化并校驗(yàn)了 MongoDB 連接以及 SnowFlake Id生成器;
資源相關(guān)的初始化都是在 resource 模塊中完成的;
resource 模塊的入口 mod.rs 中定義了資源的校驗(yàn)函數(shù):
resource/mod.rs
MongoDB 通過(guò) Ping 校驗(yàn)了數(shù)據(jù)庫(kù)連接,而 SnowFlake 通過(guò)創(chuàng)建了一個(gè) Id 校驗(yàn)了正確性;
那么這些資源是在哪里初始化的呢?
主要是通過(guò)lazy_static在首次使用的時(shí)候初始化的!
lazy_static的一個(gè)特性是:在首次使用這個(gè)變量的時(shí)候,才會(huì)進(jìn)行靜態(tài)初始化;
下面分別來(lái)看:
src/resource/mongo.rs
上面的代碼在lazy_static!宏中,異步初始化了 MongoDB 的連接:
首先,從環(huán)境變量中獲取配置MONGODB_URI,隨后進(jìn)行了初始化,并保存至變量:MONGO_CLIENT中;
src/resource/id_generator.rs
與上面的初始化類(lèi)似,這里從環(huán)境變量中獲?。篠NOWFLAKE_MACHINE_ID和SNOWFLAKE_NODE_ID,隨后使用SnowflakeIdBucket::new進(jìn)行了初始化;
同時(shí),和 MongoDB 不同的是,這里需要使用Mutex進(jìn)行封裝,因?yàn)闃O有可能多個(gè)出現(xiàn)多個(gè)線程并發(fā)獲取Id;
而 MongoDB 的 Client 已經(jīng)是:Arc
我們也封裝了 get_id 函數(shù),直接供外部調(diào)用,而無(wú)需暴露ID_GENERATOR_BUCKET變量!
最下面是一個(gè)單測(cè),用于測(cè)試我們的 Id 生成器;
至此,我們的資源初始化完成。
審核編輯:劉清
-
生成器
+關(guān)注
關(guān)注
7文章
322瀏覽量
21845 -
rust語(yǔ)言
+關(guān)注
關(guān)注
0文章
57瀏覽量
3139 -
mongodb
+關(guān)注
關(guān)注
0文章
24瀏覽量
463
原文標(biāo)題:用Actix寫(xiě)的一個(gè)類(lèi)似于Facemash的小項(xiàng)目總結(jié)
文章出處:【微信號(hào):Rust語(yǔ)言中文社區(qū),微信公眾號(hào):Rust語(yǔ)言中文社區(qū)】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
求一個(gè)高低壓隔離電路,類(lèi)似于氬弧焊電路
想做一個(gè)類(lèi)似于電子琴里面那個(gè)集成電路,求大神幫忙
labview中有類(lèi)似于c語(yǔ)言中的宏定義嗎
請(qǐng)問(wèn)有沒(méi)有類(lèi)似于按鍵的東西
請(qǐng)問(wèn)類(lèi)似于正弦函數(shù)的查找表怎么實(shí)現(xiàn)?
請(qǐng)問(wèn)6678 DSP有一個(gè)類(lèi)似于ID的唯一的東西來(lái)標(biāo)識(shí)該DSP嗎?
設(shè)計(jì)一個(gè)類(lèi)似于充電寶指示燈的電路
需要一個(gè)類(lèi)似于讀取16位ADC數(shù)據(jù)的項(xiàng)目
如何用Qt做一個(gè)類(lèi)似于發(fā)燒友哥的串口助手?
請(qǐng)問(wèn)類(lèi)似于下面式子是怎么計(jì)算的?
請(qǐng)問(wèn)persimmon如何創(chuàng)建類(lèi)似于EXCELL的表格呢?
Facebook推全新AR眼鏡項(xiàng)目,功能類(lèi)似于谷歌的Glass
ADF9010:900 MHz ISM磁帶,類(lèi)似于RF前線數(shù)據(jù)Sheet

類(lèi)似于舊Valco和Vox放大器的EQD蜂鳥(niǎo)顫音

評(píng)論