[JAVA] Versuchen Sie, die asynchrone Verarbeitung in Azure zu implementieren

ALH Advent Calender Dies ist ALH Adventskalender! Ich habe am Nori teilgenommen. Heimlich vorstellen

Dieses Mal werde ich die Architektur in Azure in einem praktischen Format vorstellen.

Es basiert auf rudimentärem Wissen in Azure, also tut mir Hatsumi-san leid, aber es tut mir leid: weinen:

Asynchrone Architektur in Azure

Ich möchte Azure Service Bus verwenden, einen verwalteten Messaging-Dienst. ..

Warum asynchron? Über,

Es gibt Verdienste wie.

Zu den Optionen für die Online-Verzögerungsarchitektur gehört ein Muster, das Azure Queue Storage und DB-Polling verwendet. Ich habe mich jedoch für Service Bus entschieden, da die Implementierung einfach zu sein scheint. (Ich möchte es eher benutzen)

Messaging wie MQ ist ein Nischenbereich, aber ich denke, es ist eine unverzichtbare Architektur für Cloud-native Anwendungen.

Obwohl es auf Englisch ist, empfehlen wir Ihnen, einen Blick nach unten zu werfen. Enterprise Integration Patterns

Eingabe in der vorherigen Stufe

Best Practices für die Architektur finden Sie in der offiziellen Azure-Dokumentation.

Andere Kapitel werden ebenfalls empfohlen, da Sie lernen können, indem Sie sie persönlich lesen!

[Azure] Verbessern der Skalierbarkeit von Azure-Webanwendungen [Azure] Warteschlangenbasiertes Lastausgleichsmuster

Die Gelegenheit zu schreiben

Azure Java-Dokumentation und -Beispiele sind schwierig

Die praktischen Materialien sind ziemlich umfangreich, aber wenn Sie versuchen, sie mit ein wenig detailliertem Inhalt zu implementieren, gibt es viele C # - und Node.js-Dokumente, und die Java-Implementierung ist schwierig. Es ist notwendig, eine Sprache auszuwählen, die zu Ihrer Umgebung passt.

Ab sofort (Stand 07.12.2019) scheint Pivotal jedoch hart zu arbeiten.

https://pivotal.io/azure-spring-cloud

Darüber hinaus weist das SDK für Azure Storage die folgenden Probleme auf, und Version 12 verfügt über eine Vorschau: Unschuldig: Es gibt einen GA-Mythos, aber wenn man ihn in einem tatsächlichen Projekt verwendet, ist die Vorschau wirklich beängstigend, nicht wahr?

Microsoft Azure Storage SDK for Java Verwenden Sie nicht v10,11

Ich hoffe, dieser Beitrag wird jedem helfen!

Diagramm

Es hat die folgende Konfiguration.

async-architecture2.png

ServiceBus kann grob in Warteschlangen und Themen sowie in JMS und MQ unterteilt werden. Dieses Mal werden wir sie jedoch in Warteschlangen erstellen.

https://www.draw.io/ Ich habe das benutzt, um die Figur zu erstellen. Praktisch!

Vorbereiten von ServiceBus-Ressourcen

Sie können es auf dem Portal erstellen, aber dieses Mal werde ich es mit CLI erstellen.

Ausführungsumgebung

#Azure-Anmeldung
az login

#Ressourcengruppe erstellen
az group create --name async-test --location japaneast

#Erstellung des ServiceBus-Namespace (Ressourcenzuweisung) ca. 1 Minute
az servicebus namespace create --resource-group async-test --name serbicebusqueue --location japaneast --sku Basic

#Warteschlange erstellen
az servicebus queue create --resource-group async-test --namespace-name serbicebusqueue --name funcqueue

In Bezug auf "--name" zum Zeitpunkt der Erstellung muss es in Azure eindeutig sein. Wenn also der folgende Fehler auftritt, ändern Sie ihn in einen anderen Namen.

#Wenn der Setname nicht verwendet werden kann
BadRequest - The specified name is not available. CorrelationId: XXXXXXXXXXXXXXXXXXXXXXX

Das Portal setzt $ RANDOM. https://docs.microsoft.com/ja-jp/azure/service-bus-messaging/service-bus-quickstart-cli

Führen Sie den folgenden Befehl aus. Wenn die Verbindungszeichenfolge normal angezeigt wird, ist die Erstellung abgeschlossen.

az servicebus namespace authorization-rule keys list --resource-group async-test --namespace-name serbicebusqueue --name RootManageSharedAccessKey --query primaryConnectionString --output tsv

Endpoint=sb://serbicebusqueue.servicebus.windows.net/;SharedAccessKeyName=RootManageSharedAccessKey;SharedAccessKey=[Zufällige Zeichenfolge]

Obwohl dies die Grundlagen der Cloud sind, seien Sie beim Umgang mit Zugriffsschlüsseln vorsichtig.

Erstellen von WebApps

Holen Sie sich sofort ein Montagemuster. Zunächst erfolgt die Implementierung des Absenders an ServiceBus.

Erstellen Sie mit Spring Boot Initializr ein leeres Projekt

https://start.spring.io/

--Überprüfen Sie die Web- und Azure-Unterstützung

Abhängigkeit hinzufügen

pom.xml



		<!-- for Azure Service Bus -->
		<dependency>
			<groupId>com.microsoft.azure</groupId>
			<artifactId>azure-servicebus-spring-boot-starter</artifactId>
		</dependency>

Anwendungs.Eigenschaften einstellen

Die Verbindungseinstellung zu ServiceBus wird von der Konfigurationsklasse im Starter festgelegt. Legen Sie daher die Verbindungszeichenfolge und die Warteschlange von ServiceBus fest, die zuvor erstellt wurden.

application.properties


#Service Bus-Einstellungen
azure.servicebus.connection-string=Endpoint=sb://serbicebusqueue.servicebus.windows.net/;SharedAccessKeyName=RootManageSharedAccessKey;SharedAccessKey=[Zufällige Zeichenfolge]
azure.servicebus.queue-name=funcqueue
azure.servicebus.queue-receive-mode=peeklock

Erstellen einer Serviceklasse

Implementieren Sie es nach dem MVC-Modell als Service-Klasse, die vom Controller aufgerufen wird.

EnqueueService.java


package com.example.async.domain;

import com.microsoft.azure.servicebus.Message;
import com.microsoft.azure.servicebus.QueueClient;
import com.microsoft.azure.servicebus.primitives.ServiceBusException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.nio.charset.StandardCharsets;

@Service
public class EnqueueService {

    private static final Logger logger = LoggerFactory.getLogger(EnqueueService.class);

    /**
     *AutoConfigure verbirgt die Verbindungseinstellungen zu ServiceBus.
     */
    @Autowired
    QueueClient queueClient;

    public boolean sendQueueMessage() {
        String messageBody = "queue Message";
        logger.info("message body:{}", messageBody);
        //Nachricht zum Senden generieren
        Message message = new Message(messageBody.getBytes(StandardCharsets.UTF_8));
        try {
            //An Service Bus senden
            queueClient.send(message);
            queueClient.close();
        } catch (ServiceBusException e) {
            e.printStackTrace();
            return false;
        } catch (InterruptedException e) {
            e.printStackTrace();
            return false;
        }
        return true;
    }
}

Controller erstellen

Bereiten Sie einen Endpunkt vom Client aus vor und rufen Sie die Service-Klasse auf, um sie an ServiceBus zu senden.

AsyncController.java


package com.example.async.controller;

import com.example.async.domain.EnqueueService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("async")
public class AsyncController {

    @Autowired
    EnqueueService enqueueService;

    @PostMapping
    public String sendMessage() {
        boolean result = enqueueService.sendQueueMessage();
        if(!result) {
            return "Fail.";
        }
        return "Complete.";
    }
}

Lokale Ausführung

Stellen Sie zu diesem Zeitpunkt sicher, dass es lokal an ServiceBus gesendet wird.

mvn spring-boot:run

Versuchen Sie, Curl von einer anderen Konsole aus zu schlagen.

curl -X POST localhost:8080/async

Wenn es richtig funktioniert, können Sie es im Portal überprüfen.

service_bus_portal.png

Funktionen erstellen

Nachdem wir den Absender erstellt haben, werden wir den Empfänger implementieren. Verwenden Sie die Triggerfunktion von Funktionen.

Ich habe versucht, es mit Spring Cloud Function zu implementieren, aber ich kann die Funktionserweiterung nicht gut verwenden und implementiere es mit reinem Java. Ich möchte es zu einem späteren Zeitpunkt noch einmal überprüfen: schluchzen:

Erstellen Sie ein Projekt aus dem Maven-Archetyp

Erstellen Sie ein leeres Projekt aus dem Maven-Archetyp gemäß der offiziellen Dokumentation. Da es sich im interaktiven Modus befindet, habe ich es wie folgt eingestellt.

mvn archetype:generate \
    -DarchetypeGroupId=com.microsoft.azure \
    -DarchetypeArtifactId=azure-functions-archetype 

[Kürzung]

Define value for property 'groupId' (should match expression '[A-Za-z0-9_\-\.]+'): com.example.function
[INFO] Using property: groupId = com.example.function
Define value for property 'artifactId' (should match expression '[A-Za-z0-9_\-\.]+'): functions
[INFO] Using property: artifactId = functions
Define value for property 'version' 1.0-SNAPSHOT: : 0.0.1-SNAPSHOT
Define value for property 'package' com.example.function: : 
Define value for property 'appName' functions-20191208134240755: : async-functions
Define value for property 'appRegion' westus: : japaneast
Define value for property 'resourceGroup' java-functions-group: : async-test
Confirm properties configuration:
groupId: com.example.function
groupId: com.example.function
artifactId: functions
artifactId: functions
version: 0.0.1-SNAPSHOT
package: com.example.function
appName: async-functions
appRegion: japaneast
resourceGroup: async-test
 Y: : y

Erstellen einer Funktion, die ServiceBus auslöst

Implementieren Sie wie folgt.

ServiceBusFunctions.java


package com.example.function;

import com.microsoft.azure.functions.ExecutionContext;
import com.microsoft.azure.functions.annotation.FunctionName;
import com.microsoft.azure.functions.annotation.ServiceBusQueueTrigger;

/**
 * Azure Functions with ServiceBus Trigger.
 */
public class ServiceBusFunction {

    /**
     *Service Bus auslösen
     * @param message
     * @param context
     */
    @FunctionName("servicebus-trigger")
    public void run(
            @ServiceBusQueueTrigger(name = "message",queueName = "funcqueue", connection="SERVICE_BUS_CONNECTIONSTRING") String message,
            final ExecutionContext context) {
        context.getLogger().info("ServiceBusTrigger start.");
        context.getLogger().info(message);
    }
}

Einstellwert von @ ServiceBusQueueTrigger

attribute Erläuterung
name Geben Sie einen beliebigen Namen an.
queueName Geben Sie den Warteschlangennamen von ServiceBus an.
connection Gibt die Servicebus-Verbindungszeichenfolge an.
Diesmal in der lokalen Umgebunghost.settings.json, Zum Zeitpunkt der Bereitstellung wird eine Zeichenfolge angegeben, die als Umgebungsvariable verwendet werden soll.

Local.settings.json-Einstellungen

Standardmäßig wird eine Konfigurationsdatei für die lokale Umgebung erstellt.

json:local.settings.json


{
  "IsEncrypted": false,
  "Values": {
    "AzureWebJobsStorage": "UseDevelopmentStorage=true",
    "FUNCTIONS_WORKER_RUNTIME": "java",
    "SERVICE_BUS_CONNECTIONSTRING": "Endpoint=sb://serbicebusqueue.servicebus.windows.net/;SharedAccessKeyName=RootManageSharedAccessKey;SharedAccessKey=[Schlüsselwert]"
  }
}

In lokaler Umgebung ausführen

Lassen Sie uns Funktionen lokal ausführen und die Nachricht durch lokale Ausführung früher an ServiceBus senden.

mvn clean package
mvn azure-functions:run

Hoffentlich sollte das folgende Protokoll ausgegeben werden.

[Auslassen des Protokolls für den HTTP-Trigger]

[2019/12/08 5:15:56] Executed 'Functions.servicebus-trigger' (Succeeded, Id=e1c75286-c80f-45d9-88ae-d5e8dfb2cd8a)
[2019/12/08 5:18:52] Executing 'Functions.servicebus-trigger' (Reason='New ServiceBus message detected on 'funcqueue'.', Id=07b50ad5-256e-45ee-8bfa-0fb5ddfb7172)
[2019/12/08 5:18:52] Trigger Details: MessageId: 3c3bffa6-c533-41f3-9bf4-7664e16e44bc, DeliveryCount: 1, EnqueuedTime: 2019/12/08 5:18:52, LockedUntil: 2019/12/08 5:19:52, SessionId: (null)
[2019/12/08 5:18:52] ServiceBusTrigger start.
[2019/12/08 5:18:52] queue Message
[2019/12/08 5:18:52] Function "servicebus-trigger" (Id: 07b50ad5-256e-45ee-8bfa-0fb5ddfb7172) invoked by Java Worker
[2019/12/08 5:18:52] Executed 'Functions.servicebus-trigger' (Succeeded, Id=07b50ad5-256e-45ee-8bfa-0fb5ddfb7172)

Sie haben nun bestätigt, dass Local Web App-> Serbvice Bus-> Local Functions erfolgreich ausgeführt werden kann.

Bereitstellung in einer Azure-Umgebung

Stellen Sie die erstellte Anwendung in Azure bereit.

Sie können Ressourcen auch mit der CLI erstellen. Azure-Beispiele werden jedoch häufig automatisch zur Bereitstellungszeit erstellt und enthalten zufällige Zeichenfolgen. Erstellen Sie daher einen AppService im Portal.

App-Service erstellen

AppService weist Ressourcen für Web-Apps zu. Sie können Ressourcen sparen, indem Sie mehrere Anwendungen auf demselben App Service bereitstellen. Da jedoch Ressourcen wie die CPU gemeinsam genutzt werden, ist es sicherer, die Funktionen in einen Umlageplan für den tatsächlichen Betrieb zu unterteilen.

Ich habe beim Erstellen des Service-Busses eine Ressourcengruppe für "Async-Test" erstellt, daher werde ich diese verwenden.

portal_appservice.png

Ab dem 7. Dezember 2019 ist bei der Implementierung von Java mit Funktionen das Betriebssystem des App-Dienstes nur Windows. Wählen Sie daher Windows aus.

Bereitstellen von Web Apps

Fügen Sie das Maven-Plugin zu pom.xml hinzu.

pom.xml


      <plugin>
        <groupId>com.microsoft.azure</groupId>
        <artifactId>azure-webapp-maven-plugin</artifactId>
        <version>1.8.0</version>
        <configuration>
          <schemaVersion>V2</schemaVersion>
          <resourceGroup>async-test</resourceGroup>
          <appName>async-app</appName>
          <appServicePlanName>appservice-async-test</appServicePlanName>
          <region>japaneast</region>
          <!--AppServicePlan-Plan-->
          <pricingTier>S1</pricingTier>
          <runtime>
            <os>windows</os>
            <javaVersion>1.8</javaVersion>
            <webContainer>java 8</webContainer>
          </runtime>
          <deployment>
            <resources>
              <resource>
                <directory>${project.basedir}/target</directory>
                <includes>
                  <include>*.jar</include>
                </includes>
              </resource>
            </resources>
          </deployment>
        </configuration>
      </plugin>

Bereitstellung mit dem "Azure-Webapp-Maven-Plugin" von maven.

mvn clean package
mvn azure-webapp:deploy

Curl-Befehl

curl -H 'Content-Length:0' -X POST https://async-app.azurewebsites.net/async

Benötigt den Header "Content-Length".

Funktionen bereitstellen

Da die Vorlage beim Erstellen eines leeren Projekts generiert wird, legen Sie AppServiePlan fest.

pom.xml


      <plugin>
        <groupId>com.microsoft.azure</groupId>
        <artifactId>azure-functions-maven-plugin</artifactId>
        <configuration>
          <resourceGroup>${functionResourceGroup}</resourceGroup>
          <appName>${functionAppName}</appName>
          <region>${functionAppRegion}</region>
          <!--AppServicePlan-Einstellungen-->
          <appServicePlanName>appservice-async-test</appServicePlanName>

          <appSettings>
            <!-- Run Azure Function from package file by default -->
            <property>
              <name>WEBSITE_RUN_FROM_PACKAGE</name>
              <value>1</value>
            </property>
            <property>
              <name>FUNCTIONS_EXTENSION_VERSION</name>
              <value>~2</value>
            </property>
          </appSettings>
        </configuration>
        <executions>
          <execution>
            <id>package-functions</id>
            <goals>
              <goal>package</goal>
            </goals>
          </execution>
        </executions>
      </plugin>

Bereitstellung mit dem "Azure-Functions-Maven-Plugin" von Maven.

mvn clean package
mvn azure-functions:deploy

Nach der Bereitstellung wurde die Funktion erstellt. Legen Sie daher die ServiceBus-Verbindungszeichenfolge in den Anwendungseinstellungen fest.

portal_functions.png

Beispielquelle

https://github.com/bokuwakuma/azure-spring-boot-servicebus

Zusammenfassung

Am Ende habe ich mich mit der Azure-Dokumentation vertraut gemacht, bin aber in vielerlei Hinsicht süchtig nach Azure-Funktionen. Es gibt einige süchtig machende Punkte, wenn Sie nicht versuchen, ein bisschen mehr App zu machen.

Ich glaube auch nicht, dass ich eine direkte Bereitstellung von lokal aus durchführen werde. Daher möchte ich versuchen, die Bereitstellung in einer Pipeline mithilfe von GitHub-Aktionen durchzuführen. Nächstes Mal möchte ich mehr dagegen tun.

Recommended Posts

Versuchen Sie, die asynchrone Verarbeitung in Azure zu implementieren
Versuchen Sie, Yuma in Kinx zu implementieren
Versuchen Sie, Android Hilt in Java zu implementieren
Implementierung der asynchronen Verarbeitung in Tomcat
Implementierung einer mandantenfähigen kompatiblen asynchronen Verarbeitung in Tomcat
Android Asynchrone UI-Thread-Verarbeitung
So implementieren Sie die asynchrone Verarbeitung in Outsystems
Implementierung der asynchronen Verarbeitung für einen einzelnen Mandanten in Tomcat
Es ist spät! Versuchen Sie, Android Notification in Java (Anfänger) zu implementieren.
Azure funktioniert in Java
Versuchen Sie LetCode in Ruby-TwoSum
Asynchrone Verarbeitung und Web-API-Integration in Android Studio
Verwenden Sie MouseListener für die Verarbeitung
Es ist spät! Versuchen Sie, Android Work Manager in Java zu implementieren (Anfänger)
Lassen Sie uns die Signaturüberprüfung des Codes für elliptische Kurven in Java implementieren
Versuchen Sie, über MQ zur asynchronen Verarbeitung zu wechseln, ohne den Code zu ändern
Versuchen Sie es mit RocksDB mit Java
API (bei der Implementierung der asynchronen Kommunikation)
Versuchen Sie, JavaScript in Java aufzurufen
Lassen Sie uns Spresense mit Java entwickeln (1)
Probieren Sie den Funktionstyp in Java aus! ①
Schreibverarbeitung in IntelliJ IDEA
Feder mit Kotorin --6 Asynchrone Verarbeitung
Erstellen Sie Azure-Funktionen in Java
Versuchen Sie, eine WebFlux-Sitzung zu implementieren
Gemessene Parallelverarbeitung mit Java
Mazume Urteilsverarbeitung in der Fischerei
Versuchen Sie, einen WebFlux-Filter zu implementieren
[Swift] Asynchrone Verarbeitung mit PromiseKit
[Verarbeitung] Versuchen Sie es mit GT Force.
Gleichzeitiger Tastendruck in der Verarbeitung