Wie setzt man eine Rust-Anwendung ein?

How to Deploy an Rust Application_
How to Deploy an Rust Application_

Rust ist in der StackOverflow-Umfrage unter Entwicklern seit mehr als 4 Jahren die am meisten bewunderte Sprache, da sie den Anwendern zahlreiche Funktionen bietet.

Mozilla hat Rust entwickelt, um zuverlässig, leistungsfähig und entwicklerfreundlich zu sein. Rust hat eine ähnliche Syntax wie Sprachen wie C++ und C, deren Entwickler das Hauptziel der Sprache sind.

Rust konzentriert sich auch auf Speichersicherheit und Gleichzeitigkeit mit Modellen, die die damit verbundenen Fallstricke vermeiden, mit denen Entwickler in anderen Sprachen konfrontiert sind.

Sie werden lernen, wie man APIs in Rust erstellt, um die Vorteile dieses Artikels zu nutzen. Sie werden lernen, indem Sie eine Rust-Anwendung mit dem kostenlosen Containerisierungsdienst von Back4app erstellen, containerisieren und bereitstellen.

Vorteile der Verwendung von Rust

Die Verwendung von Rust in Ihren Projekten bietet Ihnen viele Vorteile. Hier sind einige der wichtigsten davon:

Null-Kosten-Abstraktionen

Rust bietet Abstraktionen auf hoher Ebene, ohne zusätzliche Laufzeitkosten zu verursachen. Dies bedeutet, dass die Abstraktionen, die Sie in Ihrem Code verwenden (Funktionen, Iteratoren oder Generika), Ihre Programme nicht langsamer machen.

Der Rust-Compiler optimiert die Abstraktionen für kompilierten Low-Level-Code manuell. Rust überbrückt die Lücke zwischen ausdrucksstarkem Low-Level-Code und feinkörniger Kontrolle über die Leistung.

Der Fearless Concurrency-Ansatz für Speichersicherheit in nebenläufigen Programmen

Rust verfolgt einen “furchtlosen Ansatz” für Gleichzeitigkeit, der sich durch Sicherheit und Effizienz auszeichnet. Das Gleichzeitigkeitsmodell von Rust nutzt sein Eigentumsmodell und die Typüberprüfung, um Datenrennen zur Kompilierungszeit zu verhindern.

Mit dieser Funktion können Sie Anwendungen mit mehreren Threads schreiben, ohne die Nachteile der Gleichzeitigkeit von gemeinsam genutzten Zuständen, wie Deadlocks und Race Conditions.

Fortgeschrittenes Typensystem und Eigentumsmodell

Das Typsystem von Rust und seine Eigentumsregeln sind einzigartige Eigenschaften, die helfen, Speichersicherheit zu erzwingen.

Das Eigentumsmodell verwendet den Borrow Checker, um sicherzustellen, dass jedes Datenelement einen einzigen Eigentümer hat, und verwaltet seinen Lebenszyklus, um Probleme wie “Dangling Pointers” und Speicherlecks zu vermeiden.

Plattformübergreifende Kompatibilität und Integration

Rust ist eine gute Wahl, wenn Sie plattformübergreifende Anwendungen erstellen möchten. Sie können den Code einmal schreiben und ihn auf mehreren Plattformen kompilieren, ohne die bestehende Codebasis wesentlich zu verändern.

Rust lässt sich gut in andere Programmiersprachen, insbesondere C, integrieren, so dass sich die Sprache für Web-Assembly und Aufgaben in eingebetteten Systemen eignet.

Beschränkungen bei der Verwendung von Rust

Bei der Entwicklung produktionsreifer Anwendungen mit Rust werden Sie zwangsläufig auf einige Rückschläge stoßen.

Einige davon sind die steile Lernkurve von Rust, die längere Kompilierungszeit aufgrund von Speicher- und anderen Prüfungen und das neue, kleine Ökosystem.

Es gibt einige Nachteile, auf die Sie bei der Erstellung produktionsreifer Produkte mit Rust stoßen können. Hier sind einige von ihnen:

Die Lernkurve für Rust-Programmierung ist steil

Im Vergleich zu anderen beliebten Sprachen (Go, Python, JavaScript usw.) ist es sehr zeitaufwändig, Rust zu beherrschen und produktionsreife Anwendungen mit dieser Sprache zu erstellen.

Das sollte Sie nicht von der Verwendung von Rust abhalten. Wenn Sie Rust beherrschen, werden Sie wirklich produktiv beim Erstellen und Bereitstellen von Anwendungen, und Sie erhalten alle Vorteile der Verwendung von Rust.

Rust-Programme haben lange Kompilierzeiten

Die Speicher- und Gleichzeitigkeitsprüfungen zur Kompilierungszeit führen in Verbindung mit mehreren anderen Faktoren zu langen Kompilierungszeiten für Rust-Programme.

Je nach Größe der Anwendung können lange Kompilierungszeiten zu Engpässen in der Entwicklungs- oder Produktionsphase führen.

Rust hat ein kleineres Ökosystem von Bibliotheken

Rust ist im Vergleich zu vielen anderen populären Sprachen relativ neu, und es gibt ein begrenztes Ökosystem von Bibliotheken, die Sie verwenden können.

Viele Bibliotheken (Crates) befinden sich noch in der Produktion, und Sie können sich auf Websites wie AreWeWebYet einen Überblick über produktionsreife Crates verschaffen, die Sie zum Erstellen von Webanwendungen in Rust verwenden können.

Optionen für den Einsatz von Rust

Rust hat sich bereits weit verbreitet, so dass Sie viele Einsatzmöglichkeiten für Ihre Anwendungen wählen können.

Die meisten der Rust-Bereitstellungsoptionen sind IaaS- oder CaaS-basierte Plattformen. Sie können je nach Ihren Projektspezifikationen eine davon auswählen.

Infrastruktur als Dienstleistung (IaaS) wie AWS

Anbieter von Infrastructure as a Service (IaaS) stellen Ihnen die Infrastruktur für die Bereitstellung und Verwaltung Ihrer Anwendungen auf virtuellen Maschinen in der Cloud zur Verfügung.

Sie können die von IaaS-Plattformen angebotenen Dienste nutzen, um Ihre Rust-Anwendungen auf virtuellen Maschinen mit Betriebssystemen wie Linux, Windows, macOS und anderen von Rust unterstützten Betriebssystemen bereitzustellen.

Hier finden Sie eine Liste der beliebtesten IaaS-Plattformen:

  • Amazon Web Services
  • Digital Ocean
  • Google Cloud
  • Linode
  • Microsoft Azure

Containerisierung als Service wie bei Back4app Containers

Anbieter von Containerisierungsdiensten (CaaS) helfen Ihnen, die Bereitstellung Ihrer Anwendung mit Containerisierungstechnologien zu erleichtern.

Um Ihre Anwendung auf Plattformen einzusetzen, die Containerisierung unterstützen, bündeln Sie Ihre Anwendung und alle ihre Abhängigkeiten in einem isolierten Container.

Container sind isoliert und portabel, aber Sie müssen innerhalb der Grenzen der Funktionen des CaaS-Anbieters arbeiten.

Einige IaaS-Anbieter bieten CaaS-Funktionen an. Außerdem gibt es Plattformen, die nur flexible CaaS-Funktionen isoliert anbieten.

Hier finden Sie eine Liste einiger CaaS-Plattformen:

  • Oracle Container Service
  • Back4app
  • Mirantix
  • Docker Enterprise

Der Prozess der Bereitstellung von Rust-Anwendungen

In diesem Abschnitt erfahren Sie, wie Sie Ihre Rust-App auf der CaaS-Plattform von Back4app bereitstellen können.

Was ist Back4app?

Back4app ist eine Cloud-Plattform, mit der Sie alle Arten von Backend-Services für Ihre mobilen, Web- und anderen Anwendungen erstellen und bereitstellen können.

Back4app bietet einen KI-Agenten, mit dem Sie die Bereitstellung Ihrer App auf der Plattform optimieren können. Mit ihm können Sie Ihre GitHub-Repositories verwalten, Code einfach in der Cloud bereitstellen und Ihre laufenden Apps verwalten.

Auf Back4apps Backend-Servern können benutzerdefinierte Container über die CaaS-Funktionalität bereitgestellt und ausgeführt werden.

Mithilfe Ihrer Container-Images können Sie die Logik Ihrer Anwendung erweitern, ohne sich um die Wartung Ihrer Serverarchitektur kümmern zu müssen.

ein Bildschirmfoto des Back4app AI-Agenten

Aufbau und Einsatz

Sie müssen Rust auf Ihrem Computer installiert haben, um diesem Tutorial folgen zu können. Sie können die Seite Rust-Installationen besuchen, um die verschiedenen verfügbaren Installationsoptionen kennenzulernen.

Sobald Sie Rust installiert haben, erstellen Sie eine Terminalsitzung und führen Sie diesen Befehl aus, um ein neues Rust-Projekt zu initialisieren

mkdir back4app-rust-deployment && cd back4app-rust-deployment && cargo init

Wenn Sie den Befehl ausführen, sollten Sie eine Datei cargo.toml in dem neuen Verzeichnis sehen, das Sie gerade erstellt haben. Die Datei cargo.tom l wird zur Verwaltung von Abhängigkeiten verwendet.

Als Nächstes fügen Sie diese Direktiven in den Abschnitt [dependencies] Ihrer Cargo.toml-Datei ein, um diese Abhängigkeiten zu installieren, wenn Sie Ihre Anwendung erstellen.

[dependencies]
actix-web = "4.0"
serde = { version = "1.0", features = ["derive"] }
serde_derive = { version = "1.0" }
serde_json = "1.0"
lazy_static = "1.4"

Die Kiste actix-web stellt Routing und andere HTTP-bezogene Funktionen bereit, die Kisten serde, serde_derive und serde_json bieten Funktionen für die verschiedenen JSON-Operationen und die Kiste lazy_static stellt die In-Memory-Datenspeicherung für die API zur Laufzeit bereit.

Fügen Sie diese Importe am Anfang Ihrer [main.rs]() Datei ein:

use serde::{Serialize, Deserialize};
use actix_web::{web, App, HttpServer, HttpResponse, Error};
use std::sync::Mutex;
extern crate lazy_static;
use lazy_static::lazy_static;

Sie können eine Struktur verwenden, um die Datenstruktur für Ihre API auf der Grundlage der benötigten Felder zu definieren. Hier ist eine Struktur, die eine Person mit einer ID, einem Benutzernamen und einer E-Mail darstellt.

#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct Person {
    pub id: i32,
    pub username: String,
    pub email: String,
}

Die #[derive(Serialize, Deserialize, Debug, Clone)] sind Implementierungen der serde_derive crate für die Person-Struktur, um auf deren Funktionen zuzugreifen und sie zu nutzen.

So können Sie die lazy_static-Kiste verwenden, um einen speicherinternen Datenspeicher für Ihre API auf der Grundlage des Strukturtyps Person einzurichten:

lazy_static! {
    static ref DATA_STORE: Mutex<Vec<Person>> = Mutex::new(Vec::new());
}

Sie haben einen lazily initialisierten, thread-sicheren gemeinsamen Speicher für die People-Struktur erstellt. Sie werden ihn in Ihren Handler-Funktionen zum Speichern und Abrufen von Daten verwenden.

Die POST-Handler-Funktion

Die Funktion POST request handler akzeptiert eine JSON-Darstellung der Person-Struktur als Eingabe. Sie gibt dann auf Anfrage eine HTTP-Antwort und einen Fehler an den Client zurück.

Fügen Sie diesen Codeblock in Ihre Datei [main.rs]() ein, um die POST-Anfrage-Handler-Funktionalität zu implementieren.

async fn create_person(new_person: web::Json<Person>) -> Result<HttpResponse, Error> {
    let mut data_store = DATA_STORE.lock().unwrap();
    let new_id = data_store.len() as i32 + 1;
    let mut person = new_person.into_inner();
    person.id = new_id;
    data_store.push(person.clone());

    Ok(HttpResponse::Ok().json(person))
}

Die Funktion create_person ist eine asynchrone Funktion, die auf den gemeinsamen Datenspeicher zugreift, eine neue ID für die Person-Struktur erzeugt, die JSON-Darstellung Person in eine Struktur umwandelt und sie in den Datenspeicher schiebt.

Nach einer erfolgreichen Anfrage liefert die Funktion dem Client die in die Datenbank eingegebenen Daten zusammen mit einem 200-Statuscode.

Die GET-Handler-Funktion

Hier demonstriert eine GET-Handler-Funktion das Lesen aller Daten im Datenspeicher und deren Rückgabe an den Client als JSON.

Fügen Sie diesen Codeblock zu Ihrem Projekt hinzu, um eine GET-Handler-Funktion zu implementieren

async fn get_people() -> Result<HttpResponse, Error> {
    let data_store = DATA_STORE.lock().unwrap();
    let people: Vec<Person> = data_store.clone();

    Ok(HttpResponse::Ok().json(people))
}

Die Funktion get_people ist eine asynchrone Funktion, die auf den Datenspeicher zugreift und den Inhalt als Antwort an den Client schreibt.

Bei einer erfolgreichen Anfrage antwortet die Funktion mit dem Statuscode 200 an den Client mit allen Daten im Datenspeicher.

Die PUT-Handler-Funktion

Ihre PUT-Request-Handler-Funktion sollte einen Eintrag im Datenspeicher auf der Grundlage eines Feldes des Objekts aktualisieren.

So können Sie eine PUT-Handler-Funktion für Ihre API implementieren:

async fn update_person(
    id: web::Path<i32>,
    person_update: web::Json<Person>,
) -> Result<HttpResponse, Error> {
    let mut data_store = DATA_STORE.lock().unwrap();

    if let Some(person) = data_store.iter_mut().find(|p| p.id == *id) {
        *person = person_update.into_inner();
        Ok(HttpResponse::Ok().json("Person updated successfully"))
    } else {
        Ok(HttpResponse::NotFound().json("Person not found"))
    }
}

Die Funktion update_person übernimmt die ID und den neuen Eintrag aus der Anfrage. Sie durchläuft dann den Datenspeicher und ersetzt den Eintrag durch den neuen, falls er existiert.

Die DELETE-Handler-Funktion

Die Funktion DELETE nimmt ein Argument entgegen: das ID-Feld aus der gestellten Anfrage. Bei Ausführung der Funktion wird der Eintrag mit der ID aus dem Datenspeicher gelöscht.

Fügen Sie diese Implementierung der DELETE-Handler-Funktion in Ihr Programm ein.

// DELETE
pub async fn delete_person(id: web::Path<i32>) -> Result<HttpResponse, Error> {
    let mut data_store = DATA_STORE.lock().unwrap();

    if let Some(index) = data_store.iter().position(|p| p.id == *id) {
        data_store.remove(index);
        Ok(HttpResponse::Ok().json("Deleted successfully"))
    } else {
        Ok(HttpResponse::NotFound().json("Person not found"))
    }
}

Die Funktion delete_person löscht den Eintrag mit der angegebenen ID aus dem Datenspeicher. Je nach Status der Operation gibt die Funktion dem Client einen String und einen Statuscode zurück.

Zuordnung der Handlerfunktionen zu Routen

Nachdem Sie die Endpunkte definiert haben, müssen Sie den Handler-Funktionen Routen zuordnen, um Zugriff auf die Funktionalität der Handler-Funktionen zu erhalten.

So können Sie den Handler-Funktionen Routen zuweisen:

#[actix_web::main]
async fn main() -> std::io::Result<()> {
    HttpServer::new(|| {
        App::new()
            .route("/person", web::post().to(create_person))
            .route("/people", web::get().to(get_people))
            .route("/person/{id}", web::put().to(update_person))
            .route("/person/{id}", web::delete().to(delete_person))
    })
        .bind("0.0.0.0:8000")?
        .run()
        .await
}

Die Hauptfunktion ist eine asynchrone Funktion, die den Server nach der Zuordnung von Routen zu Handlerfunktionen einrichtet.

Die Funktion HttpServer::new instanziiert einen HTTP-Server, die Funktion App::new() erstellt eine neue App-Instanz, und die Funktion route ordnet Routen der Handler-Funktion zu.

Die Funktion bind gibt die Adresse für die neue Anwendung an, und die Funktion run führt die Anwendung aus.

Containerisierung von Rust-Anwendungen mit Docker

Docker ist die beliebteste Containertechnologie auf dem Markt. Sie können Ihre Rust-Anwendungen mit Docker containerisieren und mit wenigen Klicks auf Back4app bereitstellen.

Führen Sie diesen Befehl aus, um ein neues Dockerfile in Ihrem Projekt zu erstellen:

touch Dockerfile

Öffnen Sie das Dockerfile und fügen Sie diese Build-Anweisungen dem Dockerfile hinzu:

# Use Rust Nightly as the base image
FROM rustlang/rust:nightly

# Set the working directory inside the container
WORKDIR /usr/src/myapp

# Copy the current directory contents into the container
COPY . .

# Build the application
RUN cargo build --release

# Expose port 8000
EXPOSE 8000

# Define the command to run the application
CMD ["./target/release/back4app-rust-deployment"]

Diese Anleitung beschreibt das Basis-Image und die Build-Anweisungen für die Containerisierung Ihrer Rust-Anwendung mit Docker.

Hier ist eine Aufschlüsselung des Inhalts der Dockerdatei:

  1. Die Direktive FROM rustlang/rust:nightly gibt das Basis-Image für das Dockerfile an. Docker zieht dieses Image aus dem Repository und baut Ihre Programme darauf auf.
  2. Die Direktive WORKDIR /usr/src/myapp legt das Arbeitsverzeichnis für Ihre Anwendung innerhalb des Containers fest.
  3. Die Anweisung COPY . . kopiert den gesamten Inhalt Ihres Arbeitsverzeichnisses in das aktuelle Arbeitsverzeichnis des Containers.
  4. Die Direktive RUN cargo build --release führt den Befehl zur Erstellung Ihrer Anwendung im Container aus.
  5. Die Anweisung EXPOSE 8000 gibt den Port 8000 des Containers für eingehende Anfragen frei.
  6. Die CMD ["./target/release/back4app-rust-deployment"] führt das Programm aus (die ausführbare Datei aus dem Build-Vorgang).

Sobald Sie die Dockerdatei geschrieben haben, können Sie den Container über den Containerdienst von Back4app bereitstellen.

Bereitstellung eines Containers auf Back4app

Sie müssen ein Konto bei Back4app erstellen, um Container bereitzustellen.

Hier sind die Schritte zur Erstellung eines Back4app-Kontos.

  1. Besuchen Sie die Back4app-Website
  2. Klicken Sie auf die Schaltfläche Anmelden in der oberen rechten Ecke der Seite.
  3. Füllen Sie das Anmeldeformular aus und senden Sie es ab, um das Konto einzurichten.

Nachdem Sie erfolgreich ein Back4app-Konto erstellt haben, melden Sie sich an und klicken Sie auf die Schaltfläche NEUE APP in der oberen rechten Ecke der Landing Page.

Sie erhalten Optionen, um auszuwählen, wie Sie Ihre Anwendung erstellen möchten. Wählen Sie die Option Container as a Service.

Auswählen eines back4app-Dienstes

Verbinden Sie nun Ihr Github-Konto mit Ihrem Back4app-Konto und konfigurieren Sie den Zugriff auf die Repositories in Ihrem Konto oder ein bestimmtes Projekt.

Konfigurieren Sie Ihr GitHub-Konto so, dass Back4app Zugang zum Importieren eines Repo erhält

Wählen Sie die Anwendung, die Sie bereitstellen möchten (die aus diesem Tutorial), und klicken Sie auf Auswählen.

Auswahl und Konfiguration der zugänglichen Repo's

Wenn Sie auf die Schaltfläche “Auswählen” klicken, gelangen Sie zu einer Seite, auf der Sie Informationen über Ihre Anwendung eingeben können, darunter den Namen der Verzweigung, das Stammverzeichnis und die Umgebungsvariablen.

Der Verteilungsprozess beginnt automatisch,

Einsatz mit dem Back4app AI Agent

Um Ihren Entwicklungs-Workflow zu optimieren, können Sie Ihre App auch mit dem Back4app AI-Agenten bereitstellen, wie Sie in der Abbildung unten sehen können:

Aufforderung an den KI-Agenten mit einem Einsatzbefehl

Folgen Sie diesem Link , um die Back4app-Container-App in Ihrem GitHub-Konto zu installieren, und folgen Sie den Schritten im obigen Bild, um sie zu konfigurieren.

Wenn Sie die Einrichtung der App abgeschlossen haben, können Sie mit der Bereitstellung Ihrer App mit dem KI-Agenten fortfahren.

Ihr Container-Einsatz wurde mit einer Meldung initialisiert

Folgen Sie dem angegebenen Link, um den Fortschritt der Bereitstellung Ihrer Anwendung zu überwachen.

Ein Screenshot Ihres Container-Dashboards zur Überwachung der Bereitstellung

Schlussfolgerung

Sie haben gelernt, wie man eine Rust-Anwendung in Docker-Containern auf Back4app erstellt und einsetzt.

Die Bereitstellung Ihrer Anwendungen auf Back4app ist eine großartige Möglichkeit, die Verwaltung der Backend-Infrastruktur zu vereinfachen.

Back4App bietet leistungsstarke Tools für die Verwaltung Ihrer Daten, die Skalierung Ihrer Anwendung und die Überwachung ihrer Leistung.

Es ist eine ausgezeichnete Wahl für Entwickler, die großartige Anwendungen erstellen und keine Server verwalten wollen.


Leave a reply

Your email address will not be published.