Rust云原生应用部署库shuttle-runtime的使用,shuttle-runtime简化Rust后端服务的云端托管与自动化部署

Rust云原生应用部署库shuttle-runtime的使用

Shuttle Logo

Shuttle是一个Rust原生的云开发平台,可以免费部署你的Rust应用。

使用方法

首先安装Shuttle CLI:

# Linux / macOS
curl -sSfL https://www.shuttle.dev/install | bash

# Windows (Powershell)
iwr https://www.shuttle.dev/install-win | iex

使用Axum模板初始化项目:

shuttle init --template axum my-axum-app

生成的Cargo.toml依赖:

axum = "0.8.1"
shuttle-axum = "0.56.0"
shuttle-runtime = "0.56.0"
tokio = "1.28.2"

示例代码

以下是内容中提供的完整示例:

// 依赖项
use axum::{routing::get, Router};
use serde::Serialize;

// 定义一个简单的JSON响应结构
#[derive(Serialize)]
struct ApiResponse {
    message: String,
    status: u16,
}

// 根路由处理函数
async fn root_handler() -> &'static str {
    "Welcome to Shuttle Demo API"
}

// API路由处理函数
async fn api_handler() -> axum::Json<ApiResponse> {
    axum::Json(ApiResponse {
        message: "Hello from Shuttle!".to_string(),
        status: 200,
    })
}

// 主函数,使用shuttle-runtime宏标记
#[shuttle_runtime::main]
async fn main() -> shuttle_axum::ShuttleAxum {
    // 创建路由
    let router = Router::new()
        .route("/", get(root_handler))
        .route("/api", get(api_handler));

    Ok(router.into())
}

完整示例demo

以下是一个扩展的完整示例,包含更多功能:

// 依赖项
use axum::{
    routing::{get, post},
    Router, extract::Json,
};
use serde::{Serialize, Deserialize};
use std::sync::Arc;
use tokio::sync::Mutex;

// 共享状态
#[derive(Default)]
struct AppState {
    counter: Mutex<u32>,
}

// 请求和响应数据结构
#[derive(Deserialize, Serialize)]
struct UserRequest {
    name: String,
}

#[derive(Serialize)]
struct UserResponse {
    greeting: String,
    count: u32,
}

// 根路由处理函数
async fn root_handler() -> &'static str {
    "Welcome to Shuttle Counter API"
}

// 计数器路由处理函数
async fn counter_handler(state: Arc<AppState>) -> String {
    let mut counter = state.counter.lock().await;
    *counter += 1;
    format!("Counter: {}", *counter)
}

// 用户问候路由处理函数
async fn greet_handler(
    Json(payload): Json<UserRequest>,
    state: Arc<AppState>,
) -> Json<UserResponse> {
    let mut counter = state.counter.lock().await;
    *counter += 1;
    
    Json(UserResponse {
        greeting: format!("Hello, {}!", payload.name),
        count: *counter,
    })
}

// 主函数
#[shuttle_runtime::main]
async fn main() -> shuttle_axum::ShuttleAxum {
    // 初始化共享状态
    let state = Arc::new(AppState::default());
    
    // 创建路由
    let router = Router::new()
        .route("/", get(root_handler))
        .route("/counter", get(counter_handler))
        .route("/greet", post(greet_handler))
        .with_state(state);

    Ok(router.into())
}

本地运行和部署

本地测试:

shuttle run

部署到云端:

shuttle deploy

功能说明

  1. 使用共享状态管理计数器
  2. 实现GET和POST路由
  3. 处理JSON请求和响应
  4. 使用Arc和Mutex实现线程安全
  5. 保持与shuttle-runtime的兼容性

1 回复

Rust云原生应用部署库shuttle-runtime的使用指南

简介

shuttle-runtime是一个专为Rust设计的云原生应用部署库,它简化了Rust后端服务的云端托管与自动化部署流程。这个库允许开发者专注于业务逻辑,而无需花费大量时间配置基础设施和部署流程。

主要特性

  • 一键部署Rust应用到云端
  • 自动配置数据库和其他基础设施
  • 内置监控和日志功能
  • 支持多种框架(Actix-web, Rocket, Axum等)
  • 提供免费开发环境

安装与设置

首先,安装shuttle命令行工具:

cargo install cargo-shuttle

然后创建一个新项目:

cargo shuttle init --axum my-shuttle-app
cd my-shuttle-app

基本使用示例

下面是一个使用Axum框架的简单示例:

use axum::{routing::get, Router};
use shuttle_runtime::CustomError;

async fn hello_world() -> &'static str {
    "Hello, Shuttle!"
}

#[shuttle_runtime::main]
async fn axum() -> shuttle_axum::ShuttleAxum {
    let router = Router::new().route("/", get(hello_world));
    
    Ok(router.into())
}

完整示例代码

基于Axum框架和PostgreSQL数据库的完整示例:

use axum::{
    routing::{get, post},
    Router,
    extract::{State, Json},
    response::IntoResponse,
};
use serde::{Deserialize, Serialize};
use sqlx::{PgPool, FromRow};
use shuttle_runtime::CustomError;

// 定义数据结构
#[derive(Debug, FromRow, Serialize, Deserialize)]
struct Task {
    id: i32,
    title: String,
    completed: bool,
}

// 获取所有任务
async fn get_tasks(State(pool): State<PgPool>) -> impl IntoResponse {
    let tasks = sqlx::query_as::<_, Task>("SELECT * FROM tasks")
        .fetch_all(&pool)
        .await
        .unwrap();
    
    Json(tasks)
}

// 创建新任务
async fn create_task(
    State(pool): State<PgPool>,
    Json(task): Json<Task>,
) -> impl IntoResponse {
    let _ = sqlx::query(
        "INSERT INTO tasks (title, completed) VALUES ($1, $2)"
    )
    .bind(&task.title)
    .bind(task.completed)
    .execute(&pool)
    .await
    .unwrap();
    
    "Task created successfully"
}

#[shuttle_runtime::main]
async fn axum(
    #[shuttle_shared_db::Postgres] pool: PgPool,
) -> shuttle_axum::ShuttleAxum {
    // 运行数据库迁移
    sqlx::migrate!()
        .run(&pool)
        .await
        .map_err(CustomError::new)?;

    // 创建路由
    let router = Router::new()
        .route("/tasks", get(get_tasks))
        .route("/tasks", post(create_task))
        .with_state(pool);

    Ok(router.into())
}

数据库集成

shuttle-runtime可以自动配置数据库。以下是如何使用PostgreSQL的示例:

use sqlx::PgPool;

#[shuttle_runtime::main]
async fn axum(
    #[shuttle_shared_db::Postgres] pool: PgPool,
) -> shuttle_axum::ShuttleAxum {
    sqlx::migrate!()
        .run(&pool)
        .await
        .map_err(CustomError::new)?;

    let router = Router::new()
        .route("/", get(hello_world))
        .with_state(pool);

    Ok(router.into())
}

配置环境变量

可以通过Secrets.toml文件管理环境变量:

MY_API_KEY = "secret-value"

然后在代码中访问:

use shuttle_runtime::SecretStore;

#[shuttle_runtime::main]
async fn axum(
    #[shuttle_runtime::Secrets] secrets: SecretStore,
) -> shuttle_axum::ShuttleAxum {
    let api_key = secrets.get("MY_API_KEY").unwrap();
    // ...
}

支持的框架

shuttle-runtime支持多种Rust web框架:

  1. Axum:

    use shuttle_axum::ShuttleAxum;
    
  2. Rocket:

    use shuttle_rocket::ShuttleRocket;
    
  3. Actix-web:

    use shuttle_actix_web::ShuttleActixWeb;
    
  4. Poem:

    use shuttle_poem::ShuttlePoem;
    

进阶功能

  • 自定义Dockerfile:可以覆盖默认的构建过程
  • 持久化存储:提供持久化文件存储功能
  • 定时任务:支持cron风格的定时任务
  • WebSocket支持:内置WebSocket功能

部署状态检查

cargo shuttle status

本地开发

cargo shuttle run

优势总结

  1. 开发者体验优先:减少配置时间,专注业务逻辑
  2. Rust原生支持:专为Rust生态系统设计
  3. 基础设施即代码:自动配置所需资源
  4. 快速迭代:本地开发与云端部署无缝衔接

shuttle-runtime是快速部署Rust后端服务的理想选择,特别适合希望快速上线的项目和小型团队。

回到顶部