Verteilte Anwendungen

TopLogic bietet die Möglichkeit Daten zwischen verschiedenen TL-Systemen zu synchronisieren. Hierfür werden Daten von dem Quellsystem an das externe Bus-System ​Kafka gegeben. Dieses verteilt dann die Daten an die Zielsysteme. Eine gute Einführung zu Kafka findet man in ​Kafka Tutorial. Mittels des ​Kafka Tools kann man Kafka-Instanzen untersuchen.

Der Ablauf bei der Synchronisation ist folgender:

  • Im Quellsystem TL1 werden Änderungen vorgenommen.
  • Diese Änderungen werden von der KnowledgeBase an einen Kafka-Listener innerhalb TL1 geschickt.
  • Innerhalb des Kafka-Listener werden diese Änderungen gefiltert und aufbereitet, so dass nur die zu exportierenden Informationen enthalten sind. Weiterhin werden technische Daten hinzugefügt, die keinerlei fachliche Relevanz haben.
  • Das Event wird an das vorhandene Kafka-System gegeben.
  • Das Zielsystem TL2 empfängt als Listener an Kafka die Änderungen.
  • TL analysiert den Event um nur die relevanten Informationen zu importieren.
  • Die Änderungen werden eingespielt.

Technische Vorraussetzung

  • Das exportierende TL-System muß das Module com.top_logic.kafka nutzen.
  • Das importierende TL-System muß das Module com.top_logic.kafka nutzen.
  • Es muß ein laufendes Kafka vorhanden sein. Das Modul com.top_logic.kafka.server enthält einen Kafka-Server und Launchkonfigurationen um Kafka zu starten.
  • Der Alias %KAFKA_SERVER% muß korrekt auf die URL des Kafka-Server gesetzt sein.
  • Der Alias %DATA_CHANGE_CONSUMER_GROUP_NAME% sollte gesetzt sein. Hintergrund ist, dass alle TL-Systeme mit dem selben Wert dieser Variable als eine Gruppe angesehen werden, d.h. wenn ein importierendes TL-System die Änderungen bekommt, bekommen alle anderen Systeme diese Änderungen nicht mehr. Falls verschiedene System von einer gemeinsamen Quelle importieren, müssen diese Systeme also in verschienden Gruppen sein.

Exportierte Informationen

Welche Informationen aus dem Quellsystem TL1 exportiert werden, wird in der Modellkonfiguration festgelegt.

  • Wird an einem Typ die Annotation "TLExported" oder als shortcut <exported /> gesetzt, so werden alle Instanzen dieses Types (und aller Subtypen #22251) exportiert.
    • Standardmäßig werden das Objekt selber und alle Werte exportiert.
    • Soll eine Eigenschaft nicht exportiert werden, kann an dem Property die Annotation <exported value="false"/> gesetzt werden.
  • Diese Konfigurationen können auch in der GUI vorgenommen werden.

Bsp.:

<model xmlns="http://www.top-logic.com/ns/dynamic-types/6.0">
  <modules>
    <module name="tl1_module">
      <types>
        <class name="tl1_type">
          <annotations>
            <exported /> <!-- Sorgt dafür das tl1_type exportiert wird -->
          </annotations>
          <attributes>
            <property name="prop1" />  <!-- Wird exportiert da tl1_type exportiert wird -->
            <property name="prop2" >
              <annotations>
                <exported value="false"/> <!-- Sorgt dafür das prop2 nicht exportiert wird -->
              </annotations>
            </property>
        ....
          </attributes>
        </class>
      </types>
    </module>
  </modules>
</model>

Importierte Informationen

Welche Informationen in das Quellsystem TL2 importiert werden, wird in der Modellkonfiguration festgelegt.

  • Wird an einem Typ ("tl2_module:tl2_type") die Annotation "TLImported" (oder als shortcut <imported />) gesetzt, so werden Objekte dieses Types durch Importe angelegt, geändert und gelöscht.
    • Welcher der Quelltyp in Quellsystem ist wird durch <imported source="tl1_module:tl1_type" /> gesetzt. Kommt von dem Quellsystem ein Objekt mit dem Type "tl1_module:tl1_type" (im Quellsystem), so werden diese Änderung zu dem Zieltyp "tl2_module:tl2_type" umgeschlüsselt.
    • Wird in der <imported /> Annotation kein source angegeben, wird als Quelltyp ein Typ mit dem selben Modul- und Typnamen, wie im Zieltyp erwartet, d.h für einen Typ tl2_module:tl2_class wäre die Annotation <imported /> gleichbedeutend mit <imported source="tl2_module:tl2_class"/>.
    • Eigenschaften des Objektes "tl2_module:tl2_type" werden mit den entsprechenden Eigenschaften von "tl1_module:tl1_type" identifiziert.
    • Soll die Eigenschaft "tl2_module:tl2_type#foo" mit der Eigenschaft "tl1_module:tl1_type#bar" identifiziert werden, so muß bei der Definition "tl2_module:tl2_type#foo" die Annotation <imported source="bar"/> benutzt werden.
  • Diese Konfigurationen können auch in der GUI vorgenommen werden.

Bsp.:

<model xmlns="http://www.top-logic.com/ns/dynamic-types/6.0">
  <modules>
    <module name="tl2_module">
      <types>
        <class name="tl2_type">
          <annotations>
            <imported source="tl1_module:tl1_class" /> <!-- Objekte vom Typ "tl1_module:tl1_class" werden auf "tl2_module:tl2_class" gemappt-->
          </annotations>
          <attributes>
            <property name="prop1" />  <!-- Wird mit dem Attribut "tl1_module:tl1_class#prop1" identifiziert -->
            <property name="myFunnyProp2" >
              <annotations>
                <imported source="prop2"/> <!-- Sorgt dafür das "tl2_module:tl2_class#myFunnyProp2" mit "tl1_module:tl1_class#prop2" identifiziert -->
              </annotations>
            </property>
        ....
          </attributes>
        </class>
      </types>
    </module>
  </modules>
</model>

Nachrichten über 1 MB

In der Standardkonfiguration überträgt Kafka nur Nachrichten bis 1 MB Größe. Dieses Limit kann zum Beispiel bei Gallery-Attributen oder anderen Datei-Uploads schnell erreicht werden. Sobald in der Standardkonfiguration eine Nachricht größer 1 MB übertragen werden soll, stoppt die TL-Sync-Übertragung dauerhaft, bis das Problem behoben wurde. Es gibt zwei Wege, dies zu vermeiden:

Anpassung der Kafka-Konfiguration

Um größere Nachrichten zu übertragen, müssen folgende Konfigurationen geändert werden:

  • Nachrichten größer als 1 MB und kleiner als 32 MB:
    • Kafka-Server Konfiguration: message.max.bytes
    • In TL ist das die Datei: com.top_logic.kafka.server/webapp/WEB-INF/conf/kafka/server.properties
    • Das muss der Kunde bei sich umkonfigurieren, da er den Kafka-Server bereitstellt, nicht wir. Die obige Datei ist der Server für den Eclipse-Workspace und für das (nächtliche) Build, nicht für den Kunden.
    • Fehlermeldung, falls diese Grenze überschritten wird:
      • RecordTooLargeException: The request included a message larger than the max message size the server will accept.
  • Nachrichten größer als 32 MB:
    • Nicht ohne weiteres möglich.
    • Fehlermeldung, falls diese Grenze überschritten wird:
      • The message is 80895596 bytes when serialized which is larger than the total memory buffer you have configured with the buffer.memory configuration.
  • Eventuell müssen weitere Einstellungen vorgenommen werden. Das muss vorher entsprechend getestet werden. Mögliche weitere Einstellungen, die eventuell geändert werden müssen:
    • In der Datei ext.org.apache.kafka/config/server.properties die Einstellung: socket.request.max.bytes
    • In der Datei com.top_logic.kafka.server/webapp/WEB-INF/conf/kafka/server.properties die Einstellungen: socket.request.max.bytes und replica.fetch.max.bytes
    • Es gibt eventuell noch mehr Einstellungen.

Einschränkung der maximalen Größe eines Commits

Mittels Constraints muss die maximale Datenmenge an potentiell großen Attributen beschränkt werden. Dabei ist zu beachten, dass Dateien bei der Übertragung etwa die 1,4-fache Menge an Bytes benötigen. Ein Bild das 59 MB groß war, hat eine Kafka-Message der Größe 81 MB erzeugt. Das muss man bei den Constraints entsprechend beachten.