Messaging

Übersicht

Messaging ist eine zentrale Technologie für die Kommunikation von Anwendungen untereinander. Dabei wird eine lose Kopplung über sogenannte Messages etabliert, die über einen Message-Provider verteilt werden. Wichtig hierbei ist eine garantierte und nachvollziehbare Übermittlung der Messages. Als Beispiel für Message-Provider dienen die etablierten Applikationsserver der JEE oder separate Produktlösungen wie Apache ActiveMQ/Artemis.

Im Rahmen einer Service-orientierten Architektur und einer Umsetzung beispielsweise mit Microservices steigt die Anzahl der zu übermittelnden Nachrichten sehr schnell an, damit die Services sich untereinander synchronisieren können. Auch hier ist ein möglichst flexibler Ansatz notwendig, um den Konfigurations- und Administrationsaufwand beherrschen zu können. Nachdem Microservices auf Grund der dezentralen Datenhaltung im Normalfall auf einer BASE-Architektur beruhen ist hier die Garantie des Message-Transports zwar immer noch gewünscht, allerdings liegt der Schwerpunkt hier mehr auf einer horizontal skalierbaren Lösung, die eine immense Menge von Messages verteilen kann. Hier hat sich insbesondere in der Java-Welt das auf Streaming basierende Apache Kafka etabliert. 

Producer und Consumer

Um die Message-basierte Kommunikation zu veranschaulichen dient das folgende Bild aus der ActiveMQ-Dokumentation.

Producer und Consumer

Diese Bild ist leicht zu verstehen: Producer senden Messages an eine Queue, die dann die eingetroffenen Nachrichten an die registrierten Consumers verteilt.

Im klassischen Messaging werden hierzu zwei unterschiedliche Strategien unterstützt:

  • Beim Point-to-Point-Messaging wird die Nachricht an exakt einen Consumer übermittelt.
  • Bei Publish-Subscribe werden alle Consumer die Message erhalten. 

Bei Active MQ werden die Messages garantiert in einem Message Buffer auf Platte gespeichert und sind damit auch bei einem Neustart verfügbar. Weiterhin ist die Verweildauer der Message in der Queue prinzipiell beliebig lange möglich, so dass die Queue Lastspitzen ausgleichen kann bzw. bei ausgefallenen Consumern auch als Zwischenpuffer fungieren kann. 

Streaming

Streaming funktioniert etwas anders: Hier werden die Nachrichten als (potenziell unendlich langer) Stream von Eingangsdaten aufgefasst, die von einem Stream Processor transformiert und damit verarbeitet werden. Dieses Konzept wird von Apache Kafka umgesetzt:

Streaming mit Apache Kafka

Wie in obigem Bild, das der Apache Kafka Webseite entnommen ist, erkennbar ist unterstützt Kafka zusätzlich noch das etablierte Producer/Consumer-Konzept, ist aber noch zusätzlich in der Lage, über Connectors Datenbank-Systeme anzubinden. 

Durchsatz und Clusterbetrieb

ActiveMQ und Kafka sind beides Systeme, die auf hohen Nachrichtendurchsatz ausgerichtet sind. Wobei tausende von Nachrichten pro Sekunde für beide System noch nicht wirklich viel sind. 

Trotzdem lohnt es sich, die beiden Systeme im Hinblick auf den Durchsatz und die Skalierbarkeit im Cluster-Betrieb zu vergleichen.

ActiveMQ verliert durch die Art der Nachrichtenpersistierung im Vergleich zu Apache Kafka deutlich. Dies liegt an der Art der Ablage der Messages, die bei ActiveMQ viel Wert auf eine sichere Ablage in einem, wahrscheinlich Datei-basierten, Message-Store legt. Der Aufbau eines ActiveMQ-Clusters verlangt eine relativ komplexe Systemarchitektur: Jeder einzelne Knoten benötigt eine Active/Passive-Instanz und die Skalierung des Systems verlangt eine intensive und aufwändige Kommunikation der Knoten untereinander.

Apache Kafka ist im Gegensatz hierzu recht einfach: Der Cluster skaliert horizontal und unterstützt ein automatisches Scale Up/Down. Die Ausfallsicherheit erreicht der Cluster durch eine interne Replikation der Nachrichten an mehrere Knoten. 

Damit ist der Durchsatz und die Skalierbarkeit eines Kafka-Clusters wesentlich besser als ein äquivalentes ActiveMQ-System. Allerdings ist hierbei zu beachten, dass eine alleinige Betrachtung dieser beiden Features bei der Auswahl eines Produkts nicht ausreicht: Ein klassisches Messaging-System bietet mit Queues, Selectors, den verschiedenen Acknowledge-Modi, Redelivery und Dead Letter Queues viele interessante zusätzliche Dienste an, muss für deren Umsetzung dann aber auch mehr Aufwand betreiben.


Seminare zum Thema

Weiterlesen

Docker mit Portainer im Überblick behalten

Docker ist für den produktiven Betrieb von Anwendungen in den letzten Jahren ein sehr wichtiges und etabliertes Produkt geworden. Allerdings ist Docker keine vollständige Plattform, sondern muss beispielsweise mit Kubernetes zur Orchestrierung, Administration und Überwachung ergänzt werden.

Aber auch für Anwendungsentwickler und für die Bereitstellung einer Testumgebungen ist Docker äußerst praktisch. Allerdings ist hier das Aufsetzen eines Kubernetes-Clusters häufig dann doch etwas zu kompliziert. Aber wir können auch Docker mit Portainer im Überblick behalten.

Was ist Portainer?

Portainer ist eine schlanke We b-Anwendung, die die Verwaltung einer Docker-Umgebung über ein komfortables Web-Frontend ermöglicht. Ein erster Überblick ist über ein Online-Demo verfügbar.

Das Online Demo einer Portainer-Installation

Portainer ermöglicht eine komplette Verwaltung der Docker-Umgebung:

  • Pull von Images
  • Erzeugen, Starten, Stoppen und Überwachen von Containern
  • Anlegen von Volumes
  • Verwaltung der Docker-Netzwerke

Installation auf eine lokale Docker-Umgebung

 Hierzu wird Portainer sinnvollerweise selbst in einem Docker-Container betrieben. Allerdings muss der lokale Unix-Socket des Hosts gemounted werden. Ebenso ist es sinnvoll, die Portainer-Konfiguration in ein Volume auszulagern:

docker volume create portainer_data
docker run -d -p 9000:9000 -p 8000:8000 --name portainer --restart always -v /var/run/docker.sock:/var/run/docker.sock -v portainer_data:/data portainer/portainer

Die Web-Seite ist über das Port-Mapping 9000 unter der Host-Adresse verfügbar:

Ein Portainer mit Zugriff auf die lokale Docker Engine

 


Seminare zum Thema

Weiterlesen

Spring Data Couchbase

Mit Spring Data Couchbase kann eine Java-Applikation sehr einfach auf die Dokumente des Couchbase Servers zugreifen. 

Das im Folgenden erläuterte Beispiel ist unter https://github.com/Javacream/org.javacream.training.couchbase zu finden.

Das POM

Couchbase wird von der Spring Boot Community unterstützt und durch einen eigenen Starter realisiert:

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-couchbase</artifactId>
</dependency>

Java-Document-Mapping

Die Struktur einer Java-Klasse wird über Couchbase-Annotationen in ein Dokument gemapped. Die folgende Klasse entspricht einer Airline aus dem travel-demo der Couchbase-Installation:

package org.javacream.training.couchbase.spring.data.travel;

import org.springframework.data.couchbase.core.mapping.Document;

import com.couchbase.client.java.repository.annotation.Field;
import com.couchbase.client.java.repository.annotation.Id;

@Document
public class Airline {

	@Id
	private String id;

	@Field
	private String type;

	@Field
	private String name;

	@Field("iata")
	private String iataCode;

	
	@Field
	private String icao;

	@Field
	private String callsign;

	@Field
	private String country;

        //getter und setter
}

Das Repository

Das Repository wird wie bei Spring Data üblich als Interface realisiert:

package org.javacream.training.couchbase.spring.data.travel;

import java.util.List;

import org.springframework.data.couchbase.core.query.N1qlPrimaryIndexed;
import org.springframework.data.couchbase.core.query.View;
import org.springframework.data.couchbase.core.query.ViewIndexed;
import org.springframework.data.repository.CrudRepository;

/**
 * Repository interface to manage {@link Airline} instances.
 *
 */
@N1qlPrimaryIndexed
@ViewIndexed(designDoc = "airlines")
public interface TravelRepository extends CrudRepository<Airline, String> {

	/**
	 * Derived query selecting by {@code iataCode}.
	 *
	 * @param code
	 * @return
	 */
	Airline findAirlineByIataCode(String code);

	/**
	 * Query method using {@code airlines/all} view.
	 *
	 * @return
	 */
	@View(designDocument = "airlines", viewName = "allAirlines")
	List<Airline> findAllAirlinesBy();
}

Die Anwendung

Die Spring Boot-Applikation wird über die application.properties konfiguriert:


spring.couchbase.bucket.name=travel-sample
spring.couchbase.bootstrap-hosts=localhost
spring.couchbase.username=*****
spring.couchbase.password=*****

Die Anwendung benutzt dann das Repository, um mit der Couchbase zu kommunizieren.


Seminare zum Thema

Weiterlesen

Installation des Couchbase Servers

Die Installation des Couchbase Servers, eines Dokumenten-orientierten Datenbanksystems, ist durch die Verwendung eines Docker-Images einfach durchzuführen. 

Dazu wird das zugehörige offizielle Image vom Docker Hub geladen:

docker pull couchbase

Als Datenbank-Server muss der daraus erzeugte Container natürlich durch Port-Mapping den Zugriff auf die internen Server-Endpoints gewährleisten. Sollen die Daten einen Upgrade des Containers überstehen, was in den allermeisten Fällen gewünscht ist, so wird ein Volume oder einen Mount verwendet:

docker run -d -p 8091-8093:8091-8093 -p 11210:11210 --name db -v couchbase_volume:/opt/couchbase/var couchbase

Beim ersten Aufruf der Web Konsole über 

http://localhost:8091

kann die Installation angeschlossen werden. Hierbei werden der Clustername sowie der Administrator-Account angelegt. Der Couchbase Server ist damit einsatzbereit.

Die Couchbase Web Console

 


Seminare zum Thema

Weiterlesen

Dokumenten-orientierte Datenbanksysteme

Dokumenten-orientierte Datenbanksysteme sind im Rahmen der  NoSQL-Bewegung entstanden und haben sich in den letzten Jahren zu stabilen und etablierten Produkten entwickelt. Im aktuellen Ranking von Datenbanksystemen steht mit der kommerziellen MongoDB ein Document-Store unter den Top 5, aber auch die in einer vollwertigen Community-Edition vorliegende Couchbase ist, wenn auch deutlich schwächer, vertreten.  

Was sind Dokumente?

Ein Dokument ist eine Datenstruktur, die ähnlich wie eine Datenbank-Tabelle einem definierten Schema genügt. Allerdings wird dieses Schema von der Datenbank in der Regel nicht über Constraints beim Schreiben des Datensatzes geprüft (“Schema on write”), sondern erst bei Abfragen (“Schema on read”):  Dokumente, die der Query entsprechen, werden in die Treffermenge aufgenommen, nicht-passende Dokumente eben nicht. Eine Dokumenten-orientierte Datenbank benötigt deshalb nicht unbedingt verschiedene Tabellen-Definitionen, sondern kann alle Dokumente in einer einzigen Collection oder einem “Bucket” ablegen.

So können beispielsweise in einer Datenbank sämtliche Dokumente einer Reiseagentur (Fluglinien, Flughäfen, aber auch Flugpläne und Routen) gemeinsam abgelegt werden.

Dokumente werden über eine innerhalb der Datenbank eindeutigen Document-ID identifiziert.

Links versus Joins

Im Gegensatz zu einem relationalen Modell unterstützen Dokumente Server-seitige Joins nicht unbedingt. Es ist eher üblich, Dokumente zu Verlinken und damit im Endeffekt dem Client das Nachladen von Assoziationen zu überlassen. 

Dokumenten-Formate

Als Quasi-Standard für das Format von Dokumenten hat sich JSON herauskristallisiert. Dies ist einesteils etwas überraschend, da JSON bis heute keinen wirklichen Standard für Links definiert hat. Hier ist XML klar überlegen. Andererseits werden Dokumente sehr häufig im Rahmen einer RESTful Architektur benutzt, so dass in der Praxis als Implementierung http genutzt wird. Und dafür ist JSON die natürliche Wahl.

Clusterbetrieb

Dokumenten-orientierte Datenbanksysteme sind immer auf einen Cluster-Betrieb ausgerichtet. Das ergibt sich klar aus dem Bezug zur NoSQL-Bewegung und damit dem “Big Data”-Umfeld. 

Für die Umsetzung eines dynamisch skalierenden Clusters bieten sich zwei Strategien an:

  • Sharding: Hier werden die Dokumente auf Grund eines Sharding Keys, der nicht unbedingt der Document-ID entsprechen muss, auf die verschiedene Knoten des Clusters verteilt. Ein zentraler Master oder Router nimmt alle Anfragen entgegen und verteilt diese dann an Hand von Konfigurations-Informationen auf die Knoten, die die Daten enthalten. Die MongoDB ist ein Beispiel für diese Cluster-Architektur. Die folgende Abbildung entstammt der Dokumentation unter https://docs.mongodb.com/manual/core/sharded-cluster-components/:
    Ein einfacher Mongo Cluster
     
  • Ring Cluster: Hier wird auf den Master und den Konfigurationsserver verzichtet; jeder Knoten des Clusters ist gleichberechtigt. Ein Beispiel hierfür ist der Couchbase Server, siehe https://docs.couchbase.com/server/5.0/architecture/architecture-intro.html:
    Couchbase Cluster

 


Seminare zum Thema

Weiterlesen