2024-03-04 快速入门rust

环境搭建

rust安装
编辑器 rust插件安装
环境变量配置
国内源配置

demo

需求

1 搭建服务,完成一个可以接受任何参数的post的方法
2 接入opensearch,将post收到的参数上传的opensearch
3 将该demo做成docker运行

步骤

1.使用cargo new xx --bin 创建新项目
2.编辑器打开新项目 在Cargo.toml引入需要的包

[dependencies]
 # rocket 接口相关
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 启动服务

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

5.2 调用接口
postman测试


image.png

5.3 验证数据
opensearch查看对应indexs,看到内容成功插入

6.总结
6.1 关于cargo中的features
你引用的包里还引用了别人的包,但是默认是不自动引入这些配置了features的包(即可选引用包), 通过features可以把对应的包及功能引入
6.2 rocket中#[launch]可以在代码中不加入main方法
6.3 tikio异步转同步
opensearch的demo全是异步的,但是rocket使用同步,为了引入客户端,将异步转为同步

 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方法中都可以通过参数拿到这个client
6.5 关于json序列化

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

此处的log data 中不要直接引入别人的包中的对象,可能无法直接序列化,尽量用基础类。
6.6 docker打包问题
一开始用用docker init 构建项目后 docker run直接报错找不到包。
排查方法
6.6.1 先注释掉 dockerfile中最后一句 "CMD ["/usr/local/bin/server"]",再次运行,找到对应文件位置后发现打好的原生包是存在的,但是命令行运行还是报错找不到包
6.6.2 内核缺少依赖包
ldd filename 通过该命令发现内核缺少依赖包
为了解决这个问题,将运行环境从alpine切换为debian:stable-slim,发现还是缺少rocket依赖的openssl3的包
加入命令RUN apt-get update && apt-get install -y libssl3 && rm -rf /var/lib/apt/lists/*
成功打包运行

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 219,753评论 6 508
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,668评论 3 396
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 166,090评论 0 356
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,010评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,054评论 6 395
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,806评论 1 308
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,484评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,380评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,873评论 1 319
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,021评论 3 338
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,158评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,838评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,499评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,044评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,159评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,449评论 3 374
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,136评论 2 356

推荐阅读更多精彩内容