Erste Schritte mit der Stream-Verarbeitung mit Spring Cloud-Datenfluss

1. Einführung

Spring Cloud Data Flow ist ein in der Cloud entwickeltes Programmier- und Betriebsmodell für Mikrodienste für zusammensetzbare Daten.

Mit Spring Cloud Data Flow können Entwickler Datenpipelines für allgemeine Anwendungsfälle wie z. B. Datenaufnahme, Echtzeitanalyse und Datenimport/-export erstellen und koordinieren .

Diese Datenpipelines gibt es in zwei Ausführungen: Streaming- und Batch-Datenpipelines.

Im ersten Fall wird eine unbegrenzte Datenmenge über die Messaging-Middleware verbraucht oder produziert. Im zweiten Fall verarbeitet die kurzlebige Task eine begrenzte Menge von Daten und endet dann.

Dieser Artikel konzentriert sich auf die Streaming-Verarbeitung.

2. Architektonische Übersicht

Die Schlüsselkomponenten dieser Art von Architektur sind Applications , der Data Flow Server und die Ziellaufzeit.

Zusätzlich zu diesen Schlüsselkomponenten haben wir in der Architektur normalerweise auch eine Data Flow Shell und einen Nachrichtenbroker .

Sehen wir uns all diese Komponenten genauer an.

2.1. Anwendungen

Typischerweise umfasst eine Streaming-Daten-Pipeline das Abrufen von Ereignissen aus externen Systemen, Datenverarbeitung und Polyglott-Persistenz. Diese Phasen werden in der Spring Cloud -Terminologie allgemein als Source , Processor und Sink bezeichnet:

  • Quelle:

  • Prozessor: verbraucht Daten aus der Source , führt einige Verarbeitungsschritte durch

und sendet die verarbeiteten Daten an die nächste Anwendung in der Pipeline Sink: ** verbraucht entweder eine Source oder Processor und schreibt die

Daten auf die gewünschte Persistenzschicht

Diese Anwendungen können auf zwei Arten gepackt werden:

Spring Boot uber-jar, das in einem Maven-Repository, Datei http, gehostet wird

oder eine andere Spring-Ressourcenimplementierung (diese Methode wird in verwendet.) Dieser Beitrag) ** Docker

Viele Quellen-, Prozessor- und Senkenanwendungen für allgemeine Anwendungsfälle (z. B. jdbc, hdfs, http, router) sind bereits bereitgestellt und können vom Spring Cloud Data Flow -Team verwendet werden.

** 2.2. Laufzeit

**

Für die Ausführung dieser Anwendungen ist auch eine Laufzeitumgebung erforderlich. Die unterstützten Laufzeiten sind:

  • Cloud Foundry

  • Apache YARN

  • Kubernetes

  • Apache Mesos

  • Lokaler Server für die Entwicklung (der in diesem Artikel verwendet wird)

** 2.3. Datenfluss-Server

**

Die Komponente, die für die Bereitstellung von Anwendungen für eine Laufzeitumgebung verantwortlich ist, ist der Data Flow Server . Für jede der Ziellaufzeiten ist eine ausführbare Data Flow Server -Datei vorhanden.

Der Data Flow Server ist für die Interpretation verantwortlich:

  • Ein Stream-DSL, der den logischen Datenfluss durch mehrere beschreibt

Anwendungen.

  • Ein Bereitstellungsmanifest, das die Zuordnung von Anwendungen auf beschreibt

die Laufzeit.

2.4. Datenfluss-Shell

Die Data Flow Shell ist ein Client für den Data Flow Server.

Als Beispiel würde das DSL, das den Datenfluss von einer http-Quelle zu einer jdbc-Senke beschreibt, als „http | jdbc ”. Diese Namen in der DSL werden beim Data Flow Server registriert und den Anwendungsartefakten zugeordnet, die in Maven- oder Docker-Repositorys gehostet werden können.

Spring bietet auch eine grafische Oberfläche mit dem Namen Flo zum Erstellen und Überwachen von Streaming-Datenpipelines. Seine Verwendung ist jedoch außerhalb der Diskussion dieses Artikels.

** 2.5. Message Broker

**

Wie wir gesehen haben, haben wir das Pipe-Symbol bei der Definition des Datenflusses verwendet. Das Pipe-Symbol repräsentiert die Kommunikation zwischen den beiden Anwendungen über die Messaging-Middleware.

Die zwei unterstützten Messaging-Middleware-Broker sind:

  • Apache Kafka

  • RabbitMQ

Und jetzt, da wir einen Überblick über die Architekturkomponenten haben, ist es an der Zeit, unsere erste Stream-Verarbeitungs-Pipeline aufzubauen.

** 3. Installieren Sie einen Message Broker

**

Wie wir gesehen haben, benötigen die Anwendungen in der Pipeline eine Messaging-Middleware für die Kommunikation. In diesem Artikel verwenden wir RabbitMQ .

Um alle Details der Installation zu erfahren, folgen Sie den Anweisungen auf der official Site .

4. Der lokale Datenfluss-Server

Um die Generierung unserer Anwendungen zu beschleunigen, verwenden wir Spring Initializr ; Mit seiner Hilfe können wir in wenigen Minuten unsere Spring Boot -Anwendungen erhalten.

Nachdem Sie die Website erreicht haben, wählen Sie einfach eine Group und einen Artifact -Namen.

Klicken Sie anschließend auf die Schaltfläche Projekt generieren, um den Download des Maven-Artefakts zu starten.

Nachdem der Download abgeschlossen ist, entpacken Sie das Projekt und importieren Sie es als Maven-Projekt in die gewünschte IDE.

Fügen wir dem Projekt eine Maven-Abhängigkeit hinzu. Da wir Dataflow Local Server -Bibliotheken benötigen, fügen wir das spring-cloud-starter-dataflow-server-local hinzu Abhängigkeit:

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-dataflow-server-local</artifactId>
</dependency>

Jetzt müssen wir die Spring Boot -Hauptklasse mit der Annotation @ EnableDataFlowServer annotieren:

@EnableDataFlowServer
@SpringBootApplication
public class SpringDataFlowServerApplication {

    public static void main(String[]args) {
        SpringApplication.run(
          SpringDataFlowServerApplication.class, args);
    }
}

Das ist alles. Unser Local Data Flow Server kann nun ausgeführt werden:

mvn spring-boot:run

Die Anwendung wird am Port 9393 gestartet.

5. Die Datenfluss-Shell

Gehen Sie wieder zum Spring Initializr und wählen Sie einen Group - und Artifact -Namen.

Nachdem wir das Projekt heruntergeladen und importiert haben, fügen wir eine Abhängigkeit von spring-cloud-dataflow-shell hinzu:

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-dataflow-shell</artifactId>
</dependency>

Jetzt müssen wir die @ EnableDataFlowShell -Anmerkung zur Spring Boot -Hauptklasse hinzufügen:

@EnableDataFlowShell
@SpringBootApplication
public class SpringDataFlowShellApplication {

    public static void main(String[]args) {
        SpringApplication.run(SpringDataFlowShellApplication.class, args);
    }
}

Wir können jetzt die Shell ausführen:

mvn spring-boot:run

Nachdem die Shell ausgeführt wurde, können Sie den Befehl help in die Eingabeaufforderung eingeben, um eine vollständige Liste der Befehle anzuzeigen, die wir ausführen können.

6. Die Quellanwendung

Auf Initializr erstellen wir nun eine einfache Anwendung und fügen eine Stream Rabbit -Abhängigkeit mit dem Namen https://search.maven.org/search?q=a:spring-cloud-starter-stream-rabbit Starter-Stream-Kaninchen:]

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-stream-rabbit</artifactId>
</dependency>

Dann fügen wir der Spring Boot -Hauptklasse die Annotation @ EnableBinding (Source.class) hinzu:

@EnableBinding(Source.class)
@SpringBootApplication
public class SpringDataFlowTimeSourceApplication {

    public static void main(String[]args) {
        SpringApplication.run(
          SpringDataFlowTimeSourceApplication.class, args);
    }
}

Nun müssen wir die Quelle der Daten festlegen, die verarbeitet werden müssen.

Diese Quelle kann jede potenziell endlose Arbeitslast sein (Sensordaten des Internet of the Things, Verarbeitung von Ereignissen rund um die Uhr, Online-Transaktionsdatenaufnahme).

  • In unserer Beispielanwendung erstellen wir alle 10 Sekunden mit einem Poller ein Ereignis (zur Vereinfachung einen neuen Zeitstempel).

Die Annotation @ InboundChannelAdapter sendet eine Nachricht an den Ausgangskanal der Quelle, wobei der Rückgabewert als Nutzlast der Nachricht verwendet wird:

@Bean
@InboundChannelAdapter(
  value = Source.OUTPUT,
  poller = @Poller(fixedDelay = "10000", maxMessagesPerPoll = "1")
)
public MessageSource<Long> timeMessageSource() {
    return () -> MessageBuilder.withPayload(new Date().getTime()).build();
}

Unsere Datenquelle ist fertig.

** 7. Die Prozessoranwendung

**

Als Nächstes erstellen wir eine Anwendung und fügen eine Stream Rabbit -Abhängigkeit hinzu

Dann fügen wir der Spring Boot -Hauptklasse die Annotation @ EnableBinding (Processor.class) hinzu:

@EnableBinding(Processor.class)
@SpringBootApplication
public class SpringDataFlowTimeProcessorApplication {

    public static void main(String[]args) {
        SpringApplication.run(
          SpringDataFlowTimeProcessorApplication.class, args);
    }
}

Als Nächstes müssen wir eine Methode definieren, um die Daten zu verarbeiten, die von der Quellanwendung stammen.

Um einen Transformer zu definieren, müssen wir diese Methode mit der Annotation @ Transformer annotieren:

@Transformer(inputChannel = Processor.INPUT,
  outputChannel = Processor.OUTPUT)
public Object transform(Long timestamp) {

    DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd hh:mm:yy");
    String date = dateFormat.format(timestamp);
    return date;
}

Es konvertiert einen Zeitstempel vom Eingangskanal in ein formatiertes Datum, das an den Ausgangskanal gesendet wird.

** 8. Die Sink-Anwendung

**

  • Die letzte zu erstellende Anwendung ist die Sink-Anwendung. **

Gehen Sie wieder zum Spring Initializr und wählen Sie eine Group , einen Artifact -Namen. Fügen Sie nach dem Herunterladen des Projekts eine Stream Rabbit -Abhängigkeit hinzu.

Fügen Sie dann die @ EnableBinding (Sink.class) -Anmerkung zur Spring Boot -Hauptklasse hinzu:

@EnableBinding(Sink.class)
@SpringBootApplication
public class SpringDataFlowLoggingSinkApplication {

    public static void main(String[]args) {
    SpringApplication.run(
          SpringDataFlowLoggingSinkApplication.class, args);
    }
}

Jetzt brauchen wir eine Methode, um die Nachrichten abzufangen, die von der Prozessoranwendung kommen.

Dazu müssen wir die StreamListener (Sink.INPUT) __ -Anmerkung zu unserer Methode hinzufügen:

@StreamListener(Sink.INPUT)
public void loggerSink(String date) {
    logger.info("Received: " + date);
}

Die Methode druckt den in ein formatiertes Datum umgewandelten Zeitstempel einfach in eine Protokolldatei.

** 9. Registrieren Sie eine Stream-App

**

Mit der Spring Cloud-Datenfluss-Shell können Sie eine Stream-App mit dem Befehl app register in der App-Registrierung registrieren.

Wir müssen einen eindeutigen Namen, einen Anwendungstyp und einen URI angeben, der in das App-Artefakt aufgelöst werden kann. Geben Sie für den Typ " source ", " processor " oder " sink " an.

Wenn Sie einen URI mit dem Maven-Schema angeben, sollte das Format den folgenden Bedingungen entsprechen:

maven://<groupId>:<artifactId>[:<extension>[:<classifier>]]:<version>

Um die Anwendungen Source , Processor und Sink zu registrieren, rufen Sie die Spring Cloud Data Flow Shell auf und geben Sie an der Eingabeaufforderung die folgenden Befehle ein:

app register --name time-source --type source
  --uri maven://org.baeldung.spring.cloud:spring-data-flow-time-source:jar:0.0.1-SNAPSHOT

app register --name time-processor --type processor
  --uri maven://org.baeldung.spring.cloud:spring-data-flow-time-processor:jar:0.0.1-SNAPSHOT

app register --name logging-sink --type sink
  --uri maven://org.baeldung.spring.cloud:spring-data-flow-logging-sink:jar:0.0.1-SNAPSHOT

10. Erstellen und Bereitstellen des Streams

Um eine neue Stream-Definition zu erstellen, gehen Sie zur Spring Cloud Data Flow Shell und führen Sie den folgenden Shell-Befehl aus:

stream create --name time-to-log
  --definition 'time-source | time-processor | logging-sink'

Dies definiert einen Stream mit dem Namen time-to-log basierend auf dem DSL-Ausdruck 'time-source | Zeitprozessor | logging-sink’ .

Führen Sie anschließend den folgenden Shell-Befehl aus, um den Stream bereitzustellen:

stream deploy --name time-to-log

Der Data Flow Server löst time-source , time-processor und logging-sink in Koordinaten um und verwendet diese zum Starten der time-source -, time-processor - und logging-sink -Anwendungen des Streams.

Wenn der bereitgestellte Stream in den Data Flow Server -Protokollen angezeigt wird, dass die Module gestartet und verbunden wurden

2016-08-24 12:29:10.516  INFO 8096 ---[io-9393-exec-10]o.s.c.d.spi.local.LocalAppDeployer: deploying app time-to-log.logging-sink instance 0
   Logs will be in PATH__TO__LOG/spring-cloud-dataflow-1276836171391672089/time-to-log-1472034549734/time-to-log.logging-sink
2016-08-24 12:29:17.600  INFO 8096 ---[io-9393-exec-10]o.s.c.d.spi.local.LocalAppDeployer       : deploying app time-to-log.time-processor instance 0
   Logs will be in PATH__TO__LOG/spring-cloud-dataflow-1276836171391672089/time-to-log-1472034556862/time-to-log.time-processor
2016-08-24 12:29:23.280  INFO 8096 ---[io-9393-exec-10]o.s.c.d.spi.local.LocalAppDeployer       : deploying app time-to-log.time-source instance 0
   Logs will be in PATH__TO__LOG/spring-cloud-dataflow-1276836171391672089/time-to-log-1472034562861/time-to-log.time-source

** 11. Ergebnis überprüfen

**

In diesem Beispiel sendet die Quelle einfach jede Sekunde den aktuellen Zeitstempel als Nachricht, der Prozessor formatiert sie und die Protokollsenke gibt den formatierten Zeitstempel unter Verwendung des Protokollierungsframeworks aus.

Die Protokolldateien befinden sich in dem Verzeichnis, das in der Protokollausgabe des Data Flow Server angezeigt wird (siehe oben). Um das Ergebnis zu sehen, können wir das Protokoll protokollieren:

tail -f PATH__TO__LOG/spring-cloud-dataflow-1276836171391672089/time-to-log-1472034549734/time-to-log.logging-sink/stdout__0.log
2016-08-24 12:40:42.029  INFO 9488 ---[r.time-to-log-1]s.c.SpringDataFlowLoggingSinkApplication : Received: 2016/08/24 11:40:01
2016-08-24 12:40:52.035  INFO 9488 ---[r.time-to-log-1]s.c.SpringDataFlowLoggingSinkApplication : Received: 2016/08/24 11:40:11
2016-08-24 12:41:02.030  INFO 9488 ---[r.time-to-log-1]s.c.SpringDataFlowLoggingSinkApplication : Received: 2016/08/24 11:40:21

12. Fazit

In diesem Artikel haben wir gesehen, wie Sie mithilfe von Spring Cloud Data Flow eine Datenpipeline für die Stream-Verarbeitung erstellen.

Außerdem haben wir die Rolle von Source -, Processor - und Sink -Anwendungen innerhalb des Streams gesehen und erfahren, wie dieses Modul mithilfe von Data Flow Shell in einen Data Flow Server eingebunden und verbunden wird.

Der Beispielcode ist im Projekt https://github.com/eugenp/tutorials/tree/master/spring-cloud-data-flow [GitHub zu finden.