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:
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
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 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!
Es hat die folgende Konfiguration.
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!
Sie können es auf dem Portal erstellen, aber dieses Mal werde ich es mit CLI erstellen.
#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.
Holen Sie sich sofort ein Montagemuster. Zunächst erfolgt die Implementierung des Absenders an ServiceBus.
https://start.spring.io/
--Überprüfen Sie die Web- und Azure-Unterstützung
pom.xml
<!-- for Azure Service Bus -->
<dependency>
<groupId>com.microsoft.azure</groupId>
<artifactId>azure-servicebus-spring-boot-starter</artifactId>
</dependency>
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
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;
}
}
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.";
}
}
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.
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 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
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 Umgebung host.settings.json , Zum Zeitpunkt der Bereitstellung wird eine Zeichenfolge angegeben, die als Umgebungsvariable verwendet werden soll. |
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]"
}
}
UseDevelopmentStorage = true
.SERVICE_BUS_CONNECTIONSTRING
.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.
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.
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.
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.
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".
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.
https://github.com/bokuwakuma/azure-spring-boot-servicebus
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