Je ne parle pas allemand

Wie Azure uns helfen kann, die Welt zu verstehen
Keine Kommentare

Ein Automobilkonzern mit Hauptsitz in Frankreich, eine Fluglinie aus China und ein weltweiter Onlineversandhandel – was diese Unternehmen gemeinsam haben: Kunden, die über die ganze Welt verteilt Waren und Dienstleistungen in Anspruch nehmen. Hin und wieder beschwert sich einer dieser Kunden.

Um einem Kunden kompetent zu helfen, egal wo er auch herkommt, muss die Beschwerdeabteilung breit aufgestellt und gut ausgebildet sein. Damit jedoch nicht jedes Unternehmen pro Land eine eigene Beschwerdebrigade aufbauen muss und diese im schlimmsten Fall noch eine Wissensinsel bildet, ist es sinnvoll, hier eine vereinheitlichte Wissensquelle zu schaffen. Mit Hilfe der drei Azure-Komponenten App Services, Cognitive Services und den Speicherkonten ist es möglich, Übersetzungen anzufertigen und diese über die bestehende Infrastruktur weltweit bereitzustellen (Abb. 1). Somit kann ein Mitarbeiter aus Japan bei Beschwerden zukünftig vom Wissen der europäischen Kollegen profitieren und dem Kunden womöglich schneller eine Lösung anbieten.

Abb. 1: Azure Navigation mit allen notwendigen Komponenten

Abb. 1: Azure Navigation mit allen notwendigen Komponenten

Wie wird das umgesetzt

Ausgangslage ist ein Onlineversandhandel, der seine Webanwendung und seine Datenbank bereits nach Azure ausgelagert hat. Auf der Webseite wurde ein Beschwerdeformular bereitgestellt, von dem die Daten in die Datenbank geschrieben werden und die Beschwerdeabteilung per Mail informiert wird. Der Projektleiter beauftragt den Entwickler nun mit der Konzeption und Umsetzung einer Übersetzungsautomatisierung. Zu Beginn stellt sich dem Entwickler die Frage, wie er dies ohne große Auswirkung auf die Webanwendung realisieren kann. Der Kunde sollte von der Übersetzung nichts mitbekommen und in seiner Nutzererfahrung nicht beeinträchtigt werden. Damit ist ein asynchroner Ablauf unabdingbar. Da das Unternehmen bereits eine Migration in die Cloud vollzogen hat, scheint auch eine Weiterführung dieses Ansatzes zu passen. Azure bietet hier eine Vielzahl an möglichen Komponenten, aus denen es jetzt die richtige Zutatenliste zu finden gilt. Wo der Entwickler vor einigen Jahren noch einen Windows Service geschrieben hätte, lässt sich das in der Cloud nun durch eine Azure-Functions-App realisieren. Der asynchrone Ansatz lässt sich gut über Warteschlangen realisieren. Auch auf Windows-Servern war dieser Ansatz eine der Möglichkeiten, um das gewünschte Ergebnis zu erhalten. Azure bietet hierfür in den Speicherkonten Warteschlangen, auf die zugegriffen werden kann. Ein sehr mächtiges Werkzeug sind die Cognitive Services aus Azure. Diese bieten eine Vielzahl an Möglichkeiten, unter anderem auch eine Textübersetzung die per REST-Schnittstelle angesprochen werden kann. Der Entwickler entscheidet sich also für drei weitere Produkte aus der Cloud: die Warteschlangen, die Azure-Functions-App und die Textübersetzung der Cognitive Services.

Ohne Konfiguration geht es nicht

Als Erstes müssen alle erforderlichen Komponenten über das Azure Portal konfiguriert werden. Es wird davon ausgegangen, dass ein Account mit einem Abonnement besteht, auf dem die anfallenden Kosten verrechnet werden können. Zur Entwicklungszeit wird versucht, die Kosten gering zu halten und die jeweils minimalste Einstellung in den Komponenten gewählt. Da die meisten Komponenten über einen kostenlosen Modus verfügen, der häufig in Umfang oder Leistung limitiert ist, lassen sich hier gerade für die Entwicklung Kosten einsparen. Zum Produktivgang kann dann in den einzelnen Ressourcen nachgebessert werden. Zuerst wird die Übersetzung angelegt, die sich unter dem Punkt KI + Machine Learning | Cognitive Services | Textübersetzung befindet (Abb. 2). Neben dem Namen für den Service und dem hinterlegten Abonnement wird auch das entsprechende Preismodell ausgewählt. Die kostenlose Variante bietet zwei Millionen Zeichen im Monat. Zusätzlich wird eine Ressourcengruppe ausgewählt oder neu erstellt. Im Beispiel ist das WarehouseTranslator. Als nächstes konfiguriert der Entwickler die Warteschlange ebenfalls über das Azure Portal. Über den Menüpunkt Speicherkonten wird diese über Hinzufügen erstellt (Abb. 3). Hierzu werden das Abonnement und die Ressourcengruppe sowie der Name, der Standort und die Leistung des Speicherkontos gewählt. Storagev2 wird unter dem Punkt Kontorart und der Lokal redundante Speicher als Replikation gewählt. Da es sich zumindest zur Entwicklungszeit um keine kritische Komponente handelt, ist diese mit 0,001 Euro pro Gigabyte pro Monat auch extrem kostengünstig.

Abb. 2: Neuanlage des Übersetzungsdienstes und der Ressourcengruppe

Abb. 2: Neuanlage des Übersetzungsdienstes und der Ressourcengruppe

Abb. 3: Erstellen des Speicherkontos über das Azure Portal

Abb. 3: Erstellen des Speicherkontos über das Azure Portal

Endlich wird Code geschrieben

Die Entwicklung beginnt mit dem Befüllen der Warteschlange. Hierzu wird die bestehende Geschäftslogik, in der die Beschwerde in die Datenbank geschrieben wird, um den Schritt zur Einreihung in die Warteschlange erweitert. Der Entwickler muss nun anhand der erwarteten Datengröße entscheiden, was alles in der Datenbank gespeichert wird. Azure limitiert die Nachrichtengröße auf 64 Kilobyte. Um zu vermeiden, dass Nachrichtenelemente nicht übertragen werden und somit verloren gehen, wird lediglich die Referenz-ID zum Datenbankobjekt gespeichert. Um mit den Queues zu kommunizieren, werden nun die notwendigen NuGet-Pakete hinzugefügt; benötigt werden die Microsoft Azure Storage Client Library for .NET und Microsoft Azure Configuration Manager Library for .NET.

Zuerst wird der StorageAccount mit den Verbindungsinformationen zur Warteschlange initialisiert und anschließend genutzt, um den CloudQueueClient zu erstellen. Die Informationen lassen sich bequem über Azure kopieren. Im Portal wird nun über Speicherkonten auf die Liste der vorhandenen Warteschlangen navigiert. Nachdem die passende gewählt wurde, lässt sich die Verbindungszeichenfolge über den Menüpunkt Zugriffsschlüssel kopieren. Diese kann in die Web.config beziehungsweise App.config der Anwendung hinterlegt werden. Da nun alle Informationen zur Verbindung bereitstehen, folgt die Angabe zur passenden Warteschlange. Zuletzt kann die CloudQueueMessage erstellt werden, welche in einen JSON-String übersetzt wird. Die CloudQueueMessage kann nun in die Warteschlange geschrieben werden. Das folgende Codebeispiel zeigt, wie das umgesetzt werden kann:

CloudStorageAccount storageAccount = CloudConfigurationManager.GetSetting(("queueConnection");
CloudQueueClient client = storageAccount.CreateCloudQueueClient();
CloudQueue queue = client.GetQueueReference("queueName"););
Object item = new Object{ Id = complaintId };
CloudQueueMessage message = new CloudQueueMessage(JsonConvert.SerializeObject(item));
queue.AddMessage(message);

Per Standard verbleiben die Nachrichten maximal sieben Tage in einer Warteschlange. Es besteht allerdings die Möglichkeit, die Nachricht über den Parameter ExpirationTime bereits früher ablaufen zu lassen. Weitere Konfigurationen lassen sich über das API auslesen.

Der nächste Schritt ist das Anlegen der Functions-App (Abb. 4). Das wird ohne großen Aufwand in Visual Studio durchgeführt. Ein neues Projekt wird angelegt und im Unterpunkt Cloud die Azure Functions ausgewählt. Es öffnet sich ein neues Fenster, in dem diverse Trigger für die Functions-App angeboten werden. Um die Komponenten zu verheiraten, wählt der Entwickler hier den Queue-Trigger, der im Dropdown Storage Account via Browse mit den zuvor angelegten Konfigurationen verknüpft wird (Abb. 5). Visual Studio bietet hier direkte Unterstützung, um die angebundenen Ressourcen aus Azure anzuzeigen; so lassen sich die richtigen Komponenten direkt zusammenzusetzen. Hierzu wird in der entsprechenden Subscription die gerade angelegte Warteschlange ausgewählt. Erfreulicherweise erstellt Visual Studio direkt alle Verbindungsdaten zur Warteschlange in der Azure-Functions-App. An dieser Stelle kann mit der weiteren Implementierung begonnen werden.

Abb. 4: Anlegen einer Functions-App in Visual Studio

Abb. 4: Anlegen einer Functions-App in Visual Studio

Abb. 5: Queue-Trigger-Konfiguration für die Functions-App

Abb. 5: Queue-Trigger-Konfiguration für die Functions-App

Damit die Functions-App asynchron arbeiten kann, wird der Rückgabewert auf einen asynchronen Task gesetzt. Da die Functions-App über die Warteschlange ausgelöst wird, liefert der Aufruf die in die Warteschlange geschriebenen Daten gleich mit. Im vorherigen Codebeispiel wurde die Beschwerde-ID als JSON in die Warteschlange geschrieben. Die Function nimmt dies als String entgegen, der jetzt wieder deserialisiert wird. Mit diesem Identifier kann nun über den bereits bestehenden Data-Provider die Beschwerde aus der Datenbank geladen werden. Um die Übersetzung auch korrekt zu speichern, wird das Datenmodell um je ein Attribut pro Zielsprache erweitert. Außerdem macht es Sinn, die Ausgangssprache zu speichern, um gegebenenfalls Auswertungen zu machen. Der Data-Provider sowie die Beschwerdeklasse werden über eine Referenz aus dem bestehenden Webanwendungsprojekt der Functions-App hinzugefügt. Das Beschwerdeobjekt kann nun übersetzt werden, indem die entsprechenden Strings an den Cognitive Service gesendet werden. Folgende Konfiguration kann in die Functions-App übernommen werden:

string host = "https://api.cognitive.microsofttranslator.com";
string route = "/translate?api-version=3.0&to=de&to=en&to=fr";
string subscriptionKey = "YOUR_SUBSCRIPTION_KEY";

In diesem Beispiel wird die Übersetzung des Texts ins Deutsche, Englische und Französische durchgeführt. Es wird ein Object-Array angelegt und dem ersten Element das Attribut text mit dem jeweiligen Content der Beschwerde erstellt.

[
  {
    "text": "Il mio oggetto è danneggiato"
  }
]

Das Array wird nun zu einem JSON-String serialisiert. Nachdem die HttpClient erstellt und der Request zusammengebaut wurde, wird die Schnittstelle asynchron angesprochen. Das Codebeispiel in Listing 1 zeigt einen Aufruf der Übersetzung.

Object[] body = new Object[] { new { Text = message } };
string requestBody = JsonConvert.SerializeObject(body);

using (var client = new HttpClient())
using (var request = new HttpRequestMessage())
{
request.Method = HttpMethod.Post;
  request.RequestUri = new Uri(host + route);
  request.Content = new StringContent(requestBody, Encoding.UTF8, "application/json");
  request.Headers.Add("Ocp-Apim-Subscription-Key", subscriptionKey);
  HttpResponseMessage response = await client.SendAsync(request)

  string responseBody = await response.Content.ReadAsStringAsync();

  return JsonConvert.DeserializeObject<List<Object>>(responseBody);
}

Das Antwortobjekt ist ebenfalls ein JSON-String, der zwei weitere Objekte enthält. In Listing 2 ist ein Beispiel für ein Antwortobjekt.

[
  {
    "detectedLanguage": {
      "language": "it",
      "score": 1.0
    },
    "translations": [
      {
        "text": "Mein Artikel ist beschädigt",
        "to": "de"
      },
      {
        "text": "My item is damaged",
        "to": "en"
      },
      {
        "text": "Mon article est endommagé",
        "to": "fr"
      }
    ]
  }
]

Als Erstes wird die erkannte Sprache mit den Attributen language und score zurückgegeben. language gibt den Kurzcode der erkannten Sprache zurück. Der Wert score gibt eine von Azure erstellte Bewertung zur Zuverlässigkeit der Übersetzung wieder. Während 1 der höchste Wert ist, ist 0 der geringste. Je niedriger der Wert, desto weniger zuverlässig ist die Übersetzung. Das zweite Objekt der Antwort ist ein Array mit allen angeforderten Übersetzungen. Das Übersetzungsobjekt hat das Attribut text, das die Übersetzung enthält, sowie to, in dem die Zielsprache als Kurzcode hinterlegt ist. Die Auswahl der Zielsprachen lässt sich über die URL-Parameter steuern. Vielleicht möchte ein Unternehmen mit Sitz in Spanien mit nur wenigen Außenstellen die Texte primär ins Spanische und den Rest nur ins Englische übersetzen. Wichtig beim Ansteuern des Service ist zu wissen, dass lediglich bis maximal 5 000 Zeichen auf einmal übersetzt werden können. Längere Texte sollten somit passend zum Satzende getrennt und einzeln übersetzt werden. Zusätzlich lässt sich der Service in dieser Form nur maximal hundertmal pro Minute aufrufen. Der Rückgabewert kann nun über den bestehenden Data-Provider wieder in die Datenbank geschrieben werden; die Function hat damit ihre Aufgabe erfüllt.

Bereitstellen der App in der Cloud

Um die Function in die Cloud zu bekommen, wird in Visual Studio via Rechtsklick auf das Projekt der Unterpunkt Veröffentlichen ausgewählt. Ein neues Fenster öffnet sich, in dem abgefragt wird, ob ein neues Element angelegt oder ein bereits bestehendes überschrieben werden soll. Bei Anlage einer neuen Function kann der App-Name vergeben werden. Zusätzlich müssen die Subscription, die Ressourcengruppe, der Hostingplan sowie das Speicherkonto ausgewählt beziehungsweise neu erstellt werden. Ganz zu Beginn wurden bereits alle Konfigurationen vorgenommen, sodass hier lediglich der Hostingplan konfiguriert werden kann und für die restlichen Felder die richtigen Werte aus den Drop-down-Menüs gewählt werden müssen. Im Hostingplan lässt sich der Speicherort der App bestimmen (zum Beispiel Westeuropa, Südostasien oder auch Zentralamerika) sowie die Größe der Server. Die Übersetzungs-Function sollte nur geringe Kapazitäten benötigen, daher wird in diesem Fall der Punkt Verbrauch ausgewählt. Nun kann die Functions-App über Erstellen hochgeladen werden. Die App lässt sich jetzt auch unter dem Menüpunkt Function App im Azure Portal finden. Wird die App aufgeklappt, finden sich neben den Punkten Funktionen und Proxys auch der Punkt Slots. Dieser lässt sich nutzen, um die App in der Entwicklung für verschiedene Umgebungen zu testen. So ist es möglich, im laufenden Betrieb die App zum Beispiel von der QS-Umgebung auf die Produktionsumgebung zu heben ohne einen Ausfall zur Laufzeit. Ebenfalls ist es hilfreich, dass jede Stage einen eigenen Anwendungseinstellungsreiter hat, in dem Umgebungsvariablen wie die Datenbankverbindung oder die auslösende Warteschlange konfiguriert werden können.

Zuletzt sollte der Entwickler nur noch eine Anpassung der Webanwendung durchführen, in der eine Sprachauswahl die Anzeige steuert oder beispielsweise ein fließender Wechsel möglich ist.

Tunnel gegen Mauern

Nun gibt es auch Szenarien, in denen zum Beispiel die Datenbank noch nicht in der Cloud gehostet, sondern noch in der eigenen Infrastruktur betrieben wird. Hierfür bietet Azure ebenfalls eine Möglichkeit, um eine Verbindung zu realisieren. Am eben beschrieben Ablauf ändert sich grundsätzlich nichts. Der Connection-String der Datenbank muss hierzu auf den entsprechenden Server in der eigenen Umgebung angepasst werden. Sofern dieser Server nicht in einer DMZ steht und somit aus dem Internet erreichbar ist, kann hierzu eine Hybridverbindung konfiguriert werden. Um die zu konfigurieren, wird in der Functions-App der Reiter Plattform-Features ausgewählt und der Unterpunkt Netzwerk aufgerufen (Abb. 6). Anschließend wird der Punkt Hybrid-Verbindungen ausgewählt und eine neue Hybridverbindung angelegt. Hier wird der Name der Verbindung, der Servername beziehungsweise die IP des Servers sowie der Zielport angegeben. Zusätzlich wird ein Service-Bus-Namespace benötigt und der Standort sowie der Service-Bus-Name angegeben. Nachdem die Verbindung von Azure erstellt wurde, kann in der Übersicht der Hybrid Connection Client heruntergeladen und auf dem Server installiert werden. Der Client benötigt nun eine Verbindungszeichenfolge, die über Azure kopiert werden kann. Dazu wird die Hybridverbindung ausgewählt und der Text unter Gateway-Verbindungszeichenfolge kopiert. Grundsätzlich lässt sich die Hybridverbindung nicht nur für Datenbankserver nutzen, sondern auch für jegliche andere Ressourcen, auf die Azure sonst keinen Zugriff hat.

Abb. 6: Erstellen einer neuen Hybrid-Connection, benötigt im Beispiel die Serveradresse der Datenbank

Abb. 6: Erstellen einer neuen Hybrid-Connection, benötigt im Beispiel die Serveradresse der Datenbank

Und was kostet das?

Für die Kostenrechnung in Tabelle 1 wird eine Beschwerdeantwortlänge von 2 000 Zeichen angenommen. Pro Monat werden 10 000 Beschwerden weltweit aufgegeben.

Speicherkonten mit einem Volumen von 2 GB 0,09 €
Warteschlangenvorgänge 0,004 €/10 000 Vorgänge 0,01 €
Warteschlangenkosten gesamt: 0,10 €

Tabelle 1: Kostenrechnung

Für die Azure-Functions-App gilt: Die ersten 400 000 GB/s bei der Ausführung sowie die erste 1 000 000 Ausführungen sind kostenlos. Somit ist bei einer Verarbeitungszeit von 20 Sekunden und 10 000 Aufrufen pro Monat auch die Nutzung der Functions-App kostenlos.

Die Cognitive Services kosten 8,43 Euro pro Million Zeichen. Damit fallen für 20 Millionen Zeichen (10 000 Beschwerden x 2 000 Zeichen) Kosten in Höhe von 168,66 Euro an. Eine weltweite Bereitstellung der übersetzten Texte ist also für unter 200 Euro im Monat möglich. Es sollte jedoch beachtet werden, dass die Kosten mit der Anzahl der zu übersetzenden Zeichen skalieren.

Unsere Redaktion empfiehlt:

Relevante Beiträge

Hinterlasse einen Kommentar

Hinterlasse den ersten Kommentar!

avatar
400
  Subscribe  
Benachrichtige mich zu:
X
- Gib Deinen Standort ein -
- or -