新聞中心
Rust 是一門很棒的語(yǔ)言,也是我在 2019 年和 2020 年(截止當(dāng)前)學(xué)的最多的語(yǔ)言。Rust 幾乎可以和任何語(yǔ)言互操作,同時(shí)對(duì)于容器和在 Kubernetes 上運(yùn)行也非常友好。

成都創(chuàng)新互聯(lián)網(wǎng)站建設(shè)公司一直秉承“誠(chéng)信做人,踏實(shí)做事”的原則,不欺瞞客戶,是我們最起碼的底線! 以服務(wù)為基礎(chǔ),以質(zhì)量求生存,以技術(shù)求發(fā)展,成交一個(gè)客戶多一個(gè)朋友!專注中小微企業(yè)官網(wǎng)定制,成都網(wǎng)站制作、成都網(wǎng)站建設(shè),塑造企業(yè)網(wǎng)絡(luò)形象打造互聯(lián)網(wǎng)企業(yè)效應(yīng)。
今天,我想展示下如何使用 Rust 構(gòu)建一個(gè)簡(jiǎn)單的微服務(wù)。本文中,我們將使用 Actix、Tokio-Postgress 和其他一些庫(kù),使用 Postgres 作為唯一數(shù)據(jù)源,同時(shí)為了便于開(kāi)發(fā),我們會(huì)將其運(yùn)行在 Docker 容器中。另外,我還會(huì)使用自己開(kāi)發(fā)的 Barrel 作為數(shù)據(jù)庫(kù)遷移工具。代碼將全部使用異步和非阻塞 IO 實(shí)現(xiàn)。
1. 總體架構(gòu)
這里我們采用多層架構(gòu),業(yè)務(wù)規(guī)則和 REST 請(qǐng)求定義在 news-contract 中實(shí)現(xiàn)。SOA 約定定義在 news-contract + news-service,數(shù)據(jù)結(jié)構(gòu)(News)定義在 news-contract。REST 請(qǐng)求的 endpoint 和服務(wù)定義在 news-service 中。Postgres 持久化相關(guān)功能定義在 news-dao 中。
2. 代碼結(jié)構(gòu)
我們一個(gè)有 5 個(gè)工程,最頂層是一個(gè)全局工作空間,作為第一個(gè)工程。其余工程有:
news-contract:SOA 約定部分,這里定義了其他工程使用的 News 結(jié)構(gòu)體。
news-dao:包含響應(yīng)式持久化代碼,基于 tokio-postgres 實(shí)現(xiàn)對(duì) News 資源的增刪改查操作。
news-migrations:我們使用 barrel 和自定義邏輯來(lái)創(chuàng)建表結(jié)構(gòu)和初始化測(cè)試數(shù)據(jù)。
news-service:這里我們有 endpoint、服務(wù)實(shí)現(xiàn)和包含 actix-web 框架配置的入口代碼。
每個(gè)工程都有自己的依賴,定義在其 Cargo.toml 文件中。
同時(shí),工程中還有 2 個(gè)處理 Docker 容器的腳本,一個(gè)用于運(yùn)行 Postgres,另一個(gè)用于運(yùn)行 psql。
3. 數(shù)據(jù)遷移
現(xiàn)在,讓我們來(lái)看看如何實(shí)現(xiàn)數(shù)據(jù)遷移(在 Postgres SQL 中創(chuàng)建表和插入記錄)。
首先,我們需要連接運(yùn)行在 Docker 容器中的 Postgres 數(shù)據(jù)庫(kù),創(chuàng)建一個(gè)向量,向其中添加所有需要運(yùn)行的數(shù)據(jù)遷移邏輯。然后循環(huán)執(zhí)行其中的所有數(shù)據(jù)遷移邏輯,并檢查結(jié)果是否正常。
現(xiàn)在,讓我們看下一段代碼,數(shù)據(jù)遷移邏輯。
我創(chuàng)建了一個(gè)名為 NewsMigration 的 trait,其中包含 new 函數(shù)(用于創(chuàng)建結(jié)構(gòu)體)和 run 函數(shù)(用于運(yùn)行數(shù)據(jù)遷移)。如你所見(jiàn),然后創(chuàng)建了 CreateTableNewsMigration 結(jié)構(gòu)體,使用 impl 關(guān)鍵字實(shí)現(xiàn)了這個(gè) trait。這里我使用了 barrel 來(lái)創(chuàng)建表結(jié)構(gòu),barrel 將會(huì)生成 Postgres SQL 的 INSERT 語(yǔ)句。最后,我們使用 pg_client 在 Postres 中運(yùn)行生成的腳本。這段代碼看上去很繞:&news_table[..],這里我們?cè)趥鬟f String 類型 news_table 的引用,將其變成 slice 之后,傳給 pg_client 的 execute 函數(shù)。
4. SOA 約定
首先讓我們來(lái)看下約定的第一部分,News 結(jié)構(gòu)體。
我們定義了一個(gè)名為 News 的結(jié)構(gòu)體,同時(shí)使用了 serde 和 serde_json,以便于該結(jié)構(gòu)體的序列化和反序列化。這個(gè)結(jié)構(gòu)體還實(shí)現(xiàn)了 Display trait,用于打印結(jié)構(gòu)體內(nèi)容。最后在文件的末尾有一個(gè)單元測(cè)試,用于測(cè)試結(jié)構(gòu)體的打印。
5. Endpoint 和服務(wù)
這里我定義了一個(gè)基于 actix 的 HttpServer,然后定義了一系列處理器:index、list_news、insert_news、get_news_by_id 和 delete_news_by_id。服務(wù)將會(huì)運(yùn)行在本地的 8080 端口上。所有的信息都使用 log 和 env_logger creates 進(jìn)行日志記錄。
現(xiàn)在讓我們來(lái)看下 endpoint.rs,這里有 REST 請(qǐng)求的定義。
這里我們使用宏來(lái)定義 REST 操作,例如 PUT、DELETE 和 GET。每個(gè)函數(shù)處理器都定義成公有且非常簡(jiǎn)單,僅僅調(diào)用對(duì)應(yīng)的服務(wù),將返回結(jié)果序列化成 json 結(jié)構(gòu)返回。
這是服務(wù)的實(shí)現(xiàn),這里沒(méi)有任何 REST 或者 actix 框架的依賴。這里是實(shí)現(xiàn)校驗(yàn)、業(yè)務(wù)邏輯和代理請(qǐng)求 dao crate 的地方。所有函數(shù)的增刪改查操作都是異步的。
6. DAO
這里是魔法發(fā)生的地方,我們使用了 tokio-postgress 庫(kù)。先來(lái)看下代碼。
這是 DAO 層的實(shí)現(xiàn)。這里有一個(gè)名為 connect() 的函數(shù)用于連接 Postgres 數(shù)據(jù)庫(kù),它使用異步非阻塞的方式實(shí)現(xiàn)。然后展示的是如何實(shí)現(xiàn) find_by_id 功能。在 Postgres 中 ID 使用 UUID 來(lái)生成,因此需要將其轉(zhuǎn)成字符串類型,這就是為什么代碼中會(huì)看見(jiàn) id::text=$1。同樣在這一行中,我將從入?yún)@取到的 ID 轉(zhuǎn)換成了 &[&id] 傳入。DAO 層還有很多函數(shù),有興趣的話可以在我的 GitHub 上查看完整代碼。
視頻:代碼走讀和功能演示
https://vimeo.com/384505355
完整代碼
https://github.com/diegopacheco/rust-playground/tree/master/rust-microservice
參考鏈接
http://diego-pacheco.blogspot.com/2020/01/building-microservice-with-rust.html
本文名稱:如何使用Rust來(lái)構(gòu)建微服務(wù)?
文章起源:http://fisionsoft.com.cn/article/djecssp.html


咨詢
建站咨詢
