2024-03-04 快速入門rust

環(huán)境搭建

rust安裝
編輯器 rust插件安裝
環(huán)境變量配置
國內(nèi)源配置

demo

需求

1 搭建服務(wù),完成一個可以接受任何參數(shù)的post的方法
2 接入opensearch,將post收到的參數(shù)上傳的opensearch
3 將該demo做成docker運行

步驟

1.使用cargo new xx --bin 創(chuàng)建新項目
2.編輯器打開新項目 在Cargo.toml引入需要的包

[dependencies]
 # rocket 接口相關(guān)
rocket = { version = "0.5.0", features = ["json"] }
 # serde json序列化反序列化
serde = { version = "1.0", features = ["derive"] }
 # opensearch 操作包
opensearch = { version = "2.0.0" }
 # tokio 異步線程包
tokio = { version = "1.24.2", features = ["full"] }
 # chrono 時間包
chrono = {version="0.4.23"}

3.編寫代碼

#[launch]
fn rocket() -> Rocket<Build> {
    let rt = Runtime::new().unwrap();
    let client = rt.block_on(init_open_search()).expect("Failed to initialize OpenSearch");
    rocket::build()
        .manage(client)
        .mount("/", routes![index])
        .mount("/data", routes![create])
}

async fn init_open_search() -> Result<OpenSearch, Box<dyn std::error::Error>> {
    let url = Url::parse("url")?;

    let conn_pool = SingleNodeConnectionPool::new(url);
    let transport = TransportBuilder::new(conn_pool)
        .auth(Credentials::Basic("username".parse().unwrap(), "passwrod.".parse().unwrap()))
        .build()?;
    let client = OpenSearch::new(transport);
    Ok(client)
}

#[get("/")]
fn index() -> &'static str {
    "Hello, world!"
}

#[post("/", format = "application/json", data = "<data>")]
async fn create(data: rocket::serde::json::Json<HashMap<String, Value>>, client: &State<OpenSearch>) -> String {
    let params = data.0;
    let _ = send_data(client, params.clone()).await;
    format!("Received data: {:?}", params)
}

async fn send_data(client: &State<OpenSearch>, data: HashMap<String, Value>) -> Result<(), Box<dyn std::error::Error>> {
    let log_data = LogData {
        timestamp: chrono::offset::Utc::now().timestamp(),
        data: data,
    };
    let response = client
        .index(IndexParts::Index("test_stream_rust"))
        .body(json!(log_data))
        .send().await.expect("Failed to add OpenSearch");
    println!("Successfully indexed a document {}", response.status_code());
    Ok(())
}


#[derive(Serialize, Deserialize)]
struct LogData {
    timestamp: i64,
    data: HashMap<String, Value>,
}

4.docker build

ARG RUST_VERSION=1.76
ARG APP_NAME=opensearch-service

################################################################################
# Create a stage for building the application.

FROM rust:${RUST_VERSION} AS build
ARG APP_NAME
RUN USER=root cargo new --bin ${APP_NAME}
WORKDIR /app

COPY ./src ./src
COPY ./Cargo.toml ./Cargo.toml
RUN cargo build --release
RUN cp /app/target/release/${APP_NAME} /app/target/release/server



FROM debian:stable-slim
RUN apt-get update && apt-get install -y libssl3 && rm -rf /var/lib/apt/lists/*
# Copy the executable from the "build" stage.
COPY --from=build /app/target/release/server /usr/local/bin/server

# Configure rocket to listen on all interfaces.
ENV ROCKET_ADDRESS=0.0.0.0

# Expose the port that the application listens on.
EXPOSE 8000

# What the container should run when it is started.
CMD ["/usr/local/bin/server"]

5.測試
5.1 啟動服務(wù)

docker build -t opensearch-service .
winpty docker run -p 8000:8000 -it --rm opensearch-service

5.2 調(diào)用接口
postman測試


image.png

5.3 驗證數(shù)據(jù)
opensearch查看對應(yīng)indexs,看到內(nèi)容成功插入

6.總結(jié)
6.1 關(guān)于cargo中的features
你引用的包里還引用了別人的包,但是默認是不自動引入這些配置了features的包(即可選引用包), 通過features可以把對應(yīng)的包及功能引入
6.2 rocket中#[launch]可以在代碼中不加入main方法
6.3 tikio異步轉(zhuǎn)同步
opensearch的demo全是異步的,但是rocket使用同步,為了引入客戶端,將異步轉(zhuǎn)為同步

 let rt = Runtime::new().unwrap();
 let client = rt.block_on(init_open_search()).expect("Failed to initialize OpenSearch");

6.4 如何在rocket引入一個全局變量

 rocket::build() .manage(client)

此處manage引入后,所有的api方法中都可以通過參數(shù)拿到這個client
6.5 關(guān)于json序列化

#[derive(Serialize, Deserialize)]
struct LogData {
    timestamp: i64,
    data: HashMap<String, Value>,
}

此處的log data 中不要直接引入別人的包中的對象,可能無法直接序列化,盡量用基礎(chǔ)類。
6.6 docker打包問題
一開始用用docker init 構(gòu)建項目后 docker run直接報錯找不到包。
排查方法
6.6.1 先注釋掉 dockerfile中最后一句 "CMD ["/usr/local/bin/server"]",再次運行,找到對應(yīng)文件位置后發(fā)現(xiàn)打好的原生包是存在的,但是命令行運行還是報錯找不到包
6.6.2 內(nèi)核缺少依賴包
ldd filename 通過該命令發(fā)現(xiàn)內(nèi)核缺少依賴包
為了解決這個問題,將運行環(huán)境從alpine切換為debian:stable-slim,發(fā)現(xiàn)還是缺少rocket依賴的openssl3的包
加入命令RUN apt-get update && apt-get install -y libssl3 && rm -rf /var/lib/apt/lists/*
成功打包運行

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 什么是 Docker 概述 和虛擬機一樣,容器技術(shù)也是一種資源隔離的虛擬化技術(shù)。 2000 年的時候 FreeBS...
    索倫x閱讀 1,871評論 0 8
  • 環(huán)境管理 管理 Python 版本和環(huán)境的工具 p:非常簡單的交互式 python 版本管理工具。 pyenv:簡...
    璃沫仙人閱讀 535評論 0 0
  • 基本概念及操作 常用快捷鍵 常用通配符 所有的手冊頁遵循一個常見的布局,為了通過簡單的 ASCII 文本展示而被優(yōu)...
    Jachin111閱讀 286評論 0 1
  • 新手入門 讓我們來創(chuàng)建第一個Rocket應(yīng)用并運行它。首先確認我們安裝了適當(dāng)?shù)腞ust版本,然后創(chuàng)建一個依賴 Ro...
    江河弦音閱讀 10,247評論 2 5
  • 在Java世界工作了10年之后,我最近更認真地看待Rust。我?guī)缀鯖]有開始Rust編程(即,我是一個完整的新手),...
    FrederickLei閱讀 8,350評論 0 9

友情鏈接更多精彩內(nèi)容