Serverless Operations, inc

>_cd /blog/id_hpeq4z7brm9

title

AWS Lambda が Rust を正式サポートしました 

https://aws.amazon.com/jp/blogs/compute/building-serverless-applications-with-rust-on-aws-lambda/

いままで AWS Lambda のRustはExperimentalとして提供されていましたが、2025年11月14日に一般提供開始となりました。

Custom Runtime と Cargo Lambda

LambdaのRustサポートはCargo Lambdaというオープンソースフレームワークにより実装されています。

2018年にLambdaがCustom Runtimeをサポートしました。これにより公式サポート外の言語(Rustを含む)でLambda関数が書けるようになりました。そのあとCustom Runtimeを使用したRust RuntimeがAWSにより開発されリリースされました。

https://github.com/aws/aws-lambda-rust-runtime

しかしながら標準でLambdaがRuntimeをサポートしていたなかったこともあり、ビルド・デプロイはかなり複雑でした。この問題を解決するためにコミュニティベースで開発されているものがCargo Lambdaです。今回のRust正式サポートでもこのCargo Lambdaを前提としています。

さっそくやってみる

環境はWSLで行っています。

Rust と Cargo Lambda 環境の整備

以下のコマンドで必要なライブラリをインストールした後WSLを再起動します。(一度閉じて開きなおせばOKです)

curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
source $HOME/.cargo/env

cargo install cargo-lambda

sudo snap install zig --classic --beta

プロジェクトの作成

cargo lambda new new-lambda-project
cd new-lambda-project

Lambda 関数のデプロイ

cargo lambda build --release
cargo lambda deploy

デフォルトでは`us-west-2`にデプロイされます。

Runtimeがカスタムでデプロイされていることがわかります。

テスト

以下のイベントを使ってコンソールからテストを行います。

{
  "command": "test command"
}

パフォーマンステスト

1から1000の間の素数を求める計算を行ってみます。

src/generic_handler.rs を以下に置き換えます。

use lambda_runtime::{Error, LambdaEvent};
use serde::{Deserialize, Serialize};

#[derive(Deserialize)]
pub(crate) struct IncomingMessage {
    max_number: Option<u32>, // オプション: 指定がなければ1000
}

#[derive(Serialize)]
pub(crate) struct OutgoingMessage {
    req_id: String,
    primes: Vec<u32>,
    count: usize,
    msg: String,
}

// 素数判定関数
fn is_prime(n: u32) -> bool {
    if n < 2 {
        return false;
    }
    if n == 2 {
        return true;
    }
    if n % 2 == 0 {
        return false;
    }
    
    let sqrt_n = (n as f64).sqrt() as u32;
    for i in (3..=sqrt_n).step_by(2) {
        if n % i == 0 {
            return false;
        }
    }
    true
}

// 素数を探す関数
fn find_primes(max: u32) -> Vec<u32> {
    (1..=max).filter(|&n| is_prime(n)).collect()
}

pub(crate) async fn function_handler(event: LambdaEvent<IncomingMessage>) -> Result<OutgoingMessage, Error> {
    // デフォルトは1000、指定があればその値を使用
    let max_number = event.payload.max_number.unwrap_or(1000);
    
    // 素数を検索
    let primes = find_primes(max_number);
    let count = primes.len();
    
    let resp = OutgoingMessage {
        req_id: event.context.request_id,
        primes,
        count,
        msg: format!("Found {} primes between 1 and {}", count, max_number),
    };
    
    Ok(resp)
}

#[cfg(test)]
mod tests {
    use super::*;
    use lambda_runtime::{Context, LambdaEvent};
    
    #[test]
    fn test_is_prime() {
        assert_eq!(is_prime(2), true);
        assert_eq!(is_prime(3), true);
        assert_eq!(is_prime(4), false);
        assert_eq!(is_prime(17), true);
        assert_eq!(is_prime(100), false);
    }
    
    #[tokio::test]
    async fn test_generic_handler() {
        let event = LambdaEvent::new(
            IncomingMessage { max_number: Some(20) }, 
            Context::default()
        );
        let response = function_handler(event).await.unwrap();
        
        // 1-20の素数は: 2, 3, 5, 7, 11, 13, 17, 19
        assert_eq!(response.count, 8);
        assert_eq!(response.primes, vec![2, 3, 5, 7, 11, 13, 17, 19]);
    }
}

再度以下のコマンドでデプロイします。

cargo lambda build --release 
cargo lambda deploy

関数を4回実行して2-4回目の平均実行時間は1.45msでした。同様の事を以下のNode関数で行うと9.34msでした。は、はやい。

// 1から1000までの素数を探す
function isPrime(n) {
    if (n < 2) return false;
    if (n === 2) return true;
    if (n % 2 === 0) return false;
    
    const sqrt = Math.sqrt(n);
    for (let i = 3; i <= sqrt; i += 2) {
        if (n % i === 0) return false;
    }
    return true;
}

function findPrimes(max) {
    const primes = [];
    for (let i = 1; i <= max; i++) {
        if (isPrime(i)) {
            primes.push(i);
        }
    }
    return primes;
}

export const handler = async (event) => {
    const maxNumber = event.max_number || 1000;
    
    const primes = findPrimes(maxNumber);
    
    const response = {
        statusCode: 200,
        body: JSON.stringify({
            primes: primes,
            count: primes.length,
            message: `Found ${primes.length} primes between 1 and ${maxNumber}`
        })
    };
    
    return response;
};

Written by
編集部

亀田 治伸

Kameda Harunobu

  • Facebook->
  • X->
  • GitHub->

Share

Facebook->X->
Back
to list
<-