Serverless-Funktionen mit Rust in AWS Lambda: Vollständiger Leitfaden

Online Python-Trainer für Anfänger

Lernen Sie Python einfach ohne theoretische Überlastung. Lösen Sie praktische Aufgaben mit automatischer Überprüfung und schreiben Sie Code direkt im Browser.

Kurs starten

Einleitung: Warum Rust die ideale Sprache für Serverless ist



Serverless-Architektur ist zum Standard für moderne Cloud-Anwendungen geworden. Allerdings leiden klassische Sprachen (Python, Node.js) oft unter langsamen Kaltstarts und hohem Speicherverbrauch. Rust löst diese Probleme: Seine kompilierten Binärdateien starten in Millisekunden und der Speicherverbrauch ist minimal. In diesem Artikel werden wir uns ansehen, wie man AWS Lambda-Funktionen mit Rust erstellt, bereitstellt und optimiert – von der Einrichtung der Umgebung bis zum Production-Deployment.



1. Einrichtung der Umgebung und Werkzeuge



Installation von Rust und Cargo Lambda

Für die Arbeit mit AWS Lambda in Rust benötigen Sie:

  • Rust (Installation über rustup)
  • Cargo Lambda – das offizielle Tool zum Bauen und Bereitstellen
  • AWS CLI mit konfigurierten Anmeldeinformationen


# Rust installierencurl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

# Cargo Lambda installierencargo install cargo-lambda

# Überprüfungcargo lambda --version


Ein neues Projekt erstellen

Cargo Lambda generiert automatisch eine Vorlage mit Unterstützung für die Lambda Runtime API:



cargo lambda new my-rust-lambdacd my-rust-lambda


Die Projektstruktur enthält eine Cargo.toml mit den Abhängigkeiten lambda_runtime und serde sowie eine Datei src/main.rs mit einer grundlegenden Handler-Funktion.



2. Schreiben der ersten Serverless-Funktion in Rust



Grundlegende Handler-Struktur

Betrachten wir eine einfache Lambda-Funktion, die ein JSON mit einem Namen akzeptiert und eine Begrüßung zurückgibt:



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

#[derive(Deserialize)]struct Request { name: String,}

#[derive(Serialize)]struct Response { message: String, request_id: String,}

async fn handler(event: LambdaEvent<Request>) -> Result<Response, Error> { let req = event.payload; let resp = Response { message: format!("Hallo, {}! Du bist auf Rust!", req.name), request_id: event.context.request_id, }; Ok(resp)}

#[tokio::main]async fn main() -> Result<(), Error> { lambda_runtime::run(service_fn(handler)).await}


Wichtige Punkte:

  • service_fn kapselt die asynchrone Funktion in einen Handler
  • LambdaEvent enthält die Nutzlast und den Kontext (request_id, Deadline usw.)
  • Serialisierung/Deserialisierung über serde


Lokales Testen

Vor der Bereitstellung testen wir die Funktion lokal:



cargo lambda watch# In einem anderen Terminal:cargo lambda invoke --data-ascii '{"name": "Welt"}'


Sie sollten die Antwort erhalten: {"message":"Hallo, Welt! Du bist auf Rust!","request_id":"..."}



3. Arbeiten mit AWS-Diensten (S3, DynamoDB)



Integration mit S3 über das AWS SDK

Fügen wir zur Cargo.toml hinzu:



[dependencies]aws-sdk-s3 = "1.0"aws-config = "1.0"


Beispiel einer Funktion, die ein Objekt aus S3 liest:



use aws_sdk_s3::Client;

async fn handler(event: LambdaEvent<Request>) -> Result<Response, Error> { let config = aws_config::load_from_env().await; let s3_client = Client::new(&config);

let bucket = "my-bucket"; let key = &event.payload.name;

let object = s3_client .get_object() .bucket(bucket) .key(key) .send() .await?;

let body = object.body.collect().await?; let content = String::from_utf8(body.to_vec())?;

Ok(Response { message: format!("Dateiinhalt: {}", content), request_id: event.context.request_id, })}


In

Blogs

Buchempfehlungen