webentwicklung-frage-antwort-db.com.de

Wie kann ich eine große Datei über eine Azure-Funktion hochladen?

Ich erforsche Azure-Funktionen. Die Szenarien, die ich bisher getestet habe, funktionieren großartig.

Ich bin an einem Punkt, an dem ich versuche, eine Methode zum Hochladen von Dateien (20 MB +) über eine Azure-Funktion zu finden. 

Die Idee ist, dass die Azure-Funktion zuerst überprüfen soll, ob der authentifizierte Benutzer die Datei hochladen darf oder nicht, bevor der Stream der Anforderung angehalten und im BLOB-Speicher gespeichert wird.

Hier ist der Code von der Clientseite, der eine StreamContent erstellt, um die Bytes zum Server zu übertragen: 

using (Stream fileStream = ...)
{
    var streamContent = new StreamContent(fileStream);

    streamContent.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
    streamContent.Headers.ContentLength = fileStream.Length;
    streamContent.Headers.Add("FileId", fileId);

    var responseMessage = await m_httpClient.PutAsync(<validURI>, streamContent);

    responseMessage.EnsureSuccessStatusCode();

    succeeded = true;
}

Hier ist der Code auf der Serverseite.

[FunctionName("upload-data")]
public static async Task<HttpResponseMessage> Run([HttpTrigger(AuthorizationLevel.Function, "put")]HttpRequestMessage req, TraceWriter log)
{
    try
    {
         //  Initialize stuff.

         //  Validate authenticated user & privileges.  

         //  Get the content stream of the request and 
         //  save it in the BLOB storage.

         return req.CreateResponse(HttpStatusCode.OK);
    }
    catch (Exception exc)
    {
        return req.CreateResponse(HttpStatusCode.InternalServerError, exc);
    }
}

Ich habe einen Haltepunkt direkt am Anfang der Methode gesetzt. Ich hatte erwartet, dass der Haltepunkt direkt nach dem Senden der Anforderung durch den Client getroffen wurde, unabhängig davon, wie groß die Datei ist. Tut es aber nicht. 

Ich vermute, dass die Azure-Funktion vor dem Aufruf der Methode versucht, den gesamten Inhalt der Anforderung abzurufen. Ich denke auch, dass ich eine Datei sende, die die 4 MB-Grenze des zugrunde liegenden Web-Jobs überschreitet, aber ich habe keine Möglichkeit gesehen, dies zu konfigurieren.

Ist es möglich, eine große Datei durch Streaming in eine Azure-Funktion hochzuladen? Gibt es eine Möglichkeit, dies zu erreichen?

8
Kzrystof

Ich habe einen anderen Weg gefunden, Dinge zu tun. Hier ist die Lösung, die für mich funktioniert.

Wenn ein Client eine Datei hochladen muss, ruft er die Azure-Funktion auf, um authentifiziert (unter Verwendung der vom Framework bereitgestellten Identität) und autorisiert zu werden (dies kann eine einfache gezielte Überprüfung in einem Tabellenspeicher sein, das heißt, er darf dies tun solche Operation). 

Die Azure-Funktion fragt nach einer Shared Access-Signatur, um auf einen bestimmten Blob zuzugreifen. Die SAS gibt dem Client für eine begrenzte Zeit Zugriff auf den Blob-Speicher mit Schreibrechten (achten Sie auf den Zeitversatz der Uhr in Azure).

Der Client verwendet dann die zurückgegebenen SAS, um die Datei direkt in den Blob-Speicher hochzuladen. Auf diese Weise wird die von Afzaal Ahmad Zeeshan erwähnte langfristige Kommunikation mit dem Client vermieden, und die Gesamtkosten werden noch weiter reduziert, da die Azure-Funktion nicht mehr von der Verbindungsgeschwindigkeit des Clients abhängt.

7
Kzrystof

Sie verfolgen hier eine schlechte Praxis, Kzrystof. Azure-Funktionen sind nicht für die langfristige Kommunikation mit den Clientgeräten gedacht. Ich bin mir nicht sicher, warum jemand daran interessiert sein könnte, Sie überhaupt dazu zu bringen, ein Programm zu schreiben, das die Azure-Funktion verwaltet und dazu zwingt, das zu tun, was nicht beabsichtigt ist. 

Große, lange laufende Funktionen können zu unerwarteten Timeout-Problemen führen.

Nun stellen Sie sich vor, Sie verfügen möglicherweise über eine gute Internetverbindung, die Benutzer jedoch möglicherweise nicht. Es gibt einige andere Probleme, die Sie vor allem beachten sollten. Und dies ist ein Auszug aus der offiziellen Dokumentation, https://docs.Microsoft.com/de-de/Azure/azure-functions/functions-best-practices

Wenn ich diese Anwendung entwerfen müsste, würde ich App Service → Azure-Speicher → Azure-Funktionen verwenden. Dies wäre der Workflow der Architektur meiner Anwendung.

Beim Designansatz würden sich meine Anwendungen bei der Verarbeitung dieser Informationen abwechseln, z. B. könnte App Service das Hochladen des Bildes übernehmen, und ich kann angeben, ob der Benutzer das Hochladen durchführen kann oder nicht. ASP.NET Core oder eine andere Sprache oder ein anderes Framework kann zur Entwicklung dieser Seite der Webanwendung verwendet werden, und Sie wissen, dass dies leicht erhöht werden kann, um einen Dateiupload von bis zu 20 MB zu unterstützen.

Warum habe ich Sie gebeten, das Design zu verdrehen? Sie hatten eine Funktion für Blob, und ich empfehle einen Blob für Funktion, weil 

Funktionen sollten zustandslos und idempotent sein, wenn möglich. Verknüpfen Sie alle erforderlichen Statusinformationen mit Ihren Daten. Beispielsweise würde eine in Bearbeitung befindliche Bestellung wahrscheinlich ein zugehöriges Mitgliedsmitglied haben. Eine Funktion kann eine Reihenfolge basierend auf diesem Status verarbeiten, während die Funktion selbst zustandslos bleibt.

Die Funktionen selbst müssen statusfrei sein, was bedeutet, dass sie keine Informationen über irgendetwas enthalten dürfen. Um dies zu lösen, müssen Sie eine andere Middleware (oder frontware) verwenden, um mit den Identity-Servern zu kommunizieren, weshalb ich dies vorschlage Verwenden Sie den App Service hier, da er die erforderlichen Informationen enthalten kann, um die Benutzer zu authentifizieren, und dann Blob und schließlich Funktion, , falls erforderlich.

Sobald es von dort aus in den Azure-Speicher gelangt ist, kann ich die WebHooks oder die direkten Blob-Speicher-Auslöser für die Delegierung von dort aus beauftragen und das Image in der Azure-Funktion verarbeiten - falls die Funktion benötigt wird nicht mehr. Sehen Sie sich an, wie ein Blob-Speicher-Trigger zum Starten einer Funktion für verschiedene Zwecke verwendet werden kann. https://docs.Microsoft.com/en-us/Azure/azure-functions/functions-create-storage-blob- ausgelöste Funktion .

Sobald Sie den ContentLength-Header festgelegt haben, werden Sie nicht mehr gestreamt. Sie müssen die PushStreamContent-Klasse verwenden und in Streams in Chunks schreiben.

Ob Sie auf diesem Server als Chunks noch auf diesen Stream zugreifen können, weiß ich nicht. Es ist möglich, dass etwas in der Azure Functions-Pipeline Streams puffert, bevor sie der Funktion bereitgestellt werden.

1
Darrel Miller

Eine alternative Lösung (möglicherweise nicht die beste Vorgehensweise) ist das POSTEN der Datei mit Chunks. Sie müssen jedoch den Überblick über diese Chunks behalten und sie anschließend konsolidieren.

Zum Beispiel:

  • Front-End - Mehrere Chunks an den Endpunkt senden (mehrere POSTs)
  • Back End - Speichert Chunks
  • Front-End - Nach Abschluss des Sendevorgangs bestätigen Sie mit dem Endpunkt
  • Back End - Führt Blöcke zusammen

Dropzone JS - Chunking

0
David Nguyen