|
Unsere Projekte
Untenstehend finden Sie eine Auswahl interessanter
Kundenprojekte, bei denen wir entweder mit besonders
wichtigen Aufgaben betraut waren oder die wir
eigenständig umsetzten. Diese spiegeln die Breite und
Tiefe unserer fachlichen Kompetenzen wider.
Inhalt
Hard Realtime Embedded
Controller Plattform Neuentwicklung (2013-2015)
Aufgabe:
Architektur, Schlüsselkomponenten-Design, Entwicklung
bei einem prominenten Industrieunternehmen
Ziele:
- OS-unabhängige Schichtenarchitektur der Plattform
- Transparente Kommunikation zwischen Plattofrm-SW und
zahlreicher angeschlossener HW (auch
Multikontrollernetze auf IP-Basis)
- Beliebig erweiterbarer Initialisierungsprozess
- Robuste und hochperformante SW-Komponenten
Lösung:
- Implementierung der OS Abstraktiosschicht mittels der
boost-Bibliothek. Nicht-intrusive Portierung von
POSIX boost auf den nicht POSIX-kompatiblen
VxWorks-Kernel mit Einsatz vom Adapter-Entwurfsmuster.
- Implementierung einer netzwerkfähigen konfigurierbaren
Middleware. Der User ist somit in der Lage, zu
bestimmen wie beliebige Producer und Consumer von Daten
diese austauschen. Ein proprietäres Format ist
nicht nötig, da die Datenbeziehungen
(OUTPUT->INPUT) ähnlich zu SQL auf der
Basisdatentypen-Ebene formuliert werden. Um die
Middleware zu verwenden, brauchen die
Komponentenentwickler lediglich eine Handvoll einfacher
Interfaces zu implementieren. Der Datenaustausch (auch
über die Gerätegrenze hinweg) inkl. QoS wird
transparent von der Middleware abgewickelt.
- Um beliebige Komponenten laden und initialisieren zu
können, wurde ein Extension-Mechanismus
eingeführt. Eine SW-Komponente braucht lediglich
den entsprechenden Extension-Kontrakt erfüllen,
um eine flexible mehrstufige Initialisierung innerhalb
der Plattform ausführen zu können. Das
Framework ist in der Lage, Komponenten automatisch zu
aktualisieren, um den Betrieb von Multinode-Systemen
deutlich zu vereinfachen.
- Da die schwache Typisierung von C für den
Grossteil der Laufzeitproblemen verantwortlich ist,
wurde als Strategie der konsequente Einsatz von C++-Templates
gewählt um die starke Typisierung zu erzwingen,
sodass der C++-Compiler bereits eine gründliche
Prüfung des Codes vornimmt. Zusammen mit dem
Einsatz von hochqualitativen Datenstrukturen und
Algorithmen aus STL und boost-Frameworks trägt dies
wesentlich dazu bei, dass der erstellte Code sehr robust
ist und performant abläuft.
Failover für FIX-basierte
Handelsplattformen (2012-2013)
Aufgabe:
Design und Implementierung vom transparentem Failover
zwischen 2 FIX-Server (auf QuickFIX Basis) Instanzen (ein
prominenter Wertpapierhandelsplatz)
Ziele:
Transparentes und zuverlässiges Failover zwischen 2
FIX-Serverintanzen bei Ausfall einer Instanz vom
Handelssystem-Backend.
Lösung:
Das QuickFix-Framework besitz keinen Failover-Mechanismus.
Eine eingehende Analyse der Schnittstelle ergab einen
günstigen Eintrittspunkt zum Auswerten des aktuellen
Zustands von dem verbundenen Backend. Transaktionale
Fähigkeiten (Row-Locking) der über JDBC
angeschlossenen MySQL-Datenbank (mit dem InnoDB-Engine)
erlauben einen sicheren Zustandsaustausch zwischen 2
FIX-Serverinstanzen. Sollte der aktuelle Zustand des
Systems auf eine notwendige Übernahme hindeuten,
erfolgt diese in der QuickFix-Entrittsroutine atomisch und
der FIX-Nachrichtentransfer erfolgt von nun an über
die nun aktive Instanz.
Instant
Replication mit Oracle und MySQL-Datenbanken (2011)
Aufgabe:
Aktive Überwachung von Datenbanktabellen zwecks
Aktualisierung von Datensnapshots in einer
InMemory-Datenbank
Ziele:
Bereitstellen der aktuellsten Daten aus diversen RDBMS
für eine hochperformante In-Memory NoSQL Datenbank.
Lösung:
RDBMS implementieren proprietäre
Replikationsmechanismen, bieten aber keine
öffentlchen Schnittstellen für 3rd Party
Systeme. Es wurde deshalb ein Triggeransatz gewählt.
Die InMemory-Datenbank analysiert die Konfiguration und
erzeugt (sofern nicht vorhanden) die entsprechenden
Trigger für alle CRUD-Operationen auf
gewünschten Tabellen. Die Datenübertragung
erfolgt auf Oracle mittels PL/SQL UTL_HTTP Paket. Für
MySQL werden eigenentwickelte Komponenten benutzt - eine
Reihe von s.g. Custom Functions (benutzerdefinierte
Erweiterungen der MySQL-eigenen SQL-Sprache) sowie ein
MySQL PlugIn - und damit direkter TCP-Transfer der
geänderten Daten zur NoSQL DB hin umgesetzt. Alle
weiteren Aspekte wie Verbindungsverwaltung, laufende
Überwachung der Tabellenstruktur und
Konfigurationsänderungen auf der NoSQL DB-Seite sind
bei der Implementierung berücksichtigt.
Optimierung einer Pricing
Engine für den Derivatenhandel (2010)
Aufgabe:
Optimierung der Abläufe in der Verteilung der
Pricing-Informationen (eine Grossbank)
Ziele:
Eine 3rd-Party Lösung für die Berechnung und
Verteilung von aktuellen Pricing-Informationen an
Wertpapierhändler und automatische
Derivaten-Handelssysteme weist nach Anschluss an Reuters
etc. starke Verzögerungen auf, die für den
schnellen Derivatenhandel inakzeptabel sind. Da der
Hersteller selbst und die hauseigene IT-Abteilung keine
Lösung finden, erfolgt die Beauftragung an uns.
Lösung:
Es wurden eingehend die zum Einsatz gekommenen
Verteilungsmuster analysiert.Dabei wurde festgestellt dass
eine schlecht skalierbare Methode ausgewählt wurde,
die bei zunehmender Anzahl Teilnehmer zu einem drastischen
Anstieg an Latenz infolge ungeschickter Synchronisierung
führt. Das Problem wird gelöst, indem eine
fortgeschrittene Variante des Producer/Consumer
Entwurfsmuster mit dem Umstieg auf die asynchrone
Verarbeitung von Netzwerkaktivitäten (das Proaktor
Entwurfsmuster) in den UNIX-basierten Handelssystemen und
in den grafischen Windows-basierten Handler-Frontends
eingeführt wird. Durch diese Massnahme allein gelingt
es, die Latenz wieder unter eine akzeptable Schwelle zu
drücken.
Hochperformanter Market Data
Verteilungsserver (2009)
Aufgabe:
Implementierung von einem hochperformanten
Marktdaten-Verteilungsserver (ein prominenter
Wertpapierhandelsplatz).
Ziele:
Aus sicherhetstechnischen Gründen getrennte
Client-Prozesse sollen auf eine gemeinsame Marktdatenbank
zugreifen, die von einem Serverprozess auf demselben
Computer anhand der Handelsplattform-Backenddaten gepflegt
wird.
Lösung:
Hier spielen die Skalierung und die Synchronisierung eine
grosse Rolle. Die im Server aufgebauten Datenstrukturen
sind hochoptimiert und deshalb komplex und werden aus
Performanzgründen im Hauptspeicher gehalten. Aus
diesem Grund ist direkter Clientzugriff auf die
Serverdateien, wie es in der Legacy-Implementierung der
Fall war, nicht mehr möglich - Dateien werden
lediglich aus Datenlogging-Gründen gespeichert, um
den Wiederanlauf vom Serverprozess zu gewährleisten.
Ein kompletter Aufbau von einem Kommunikationsprotokoll
zwischen Server und Client kommt wg. hohem Aufwand in
dieser Projektphase nicht in Frage. Für diesen Fall
wurde von uns vorgeschlagen, die komplexen Datenstrukturen
im SharedMemory zu verwalten, wofür lediglich eine
entsprechende Umsetzung der bekannten STL-Container
nötig ist. Das erlaubt es den Klienten, direkt auf
diese Strukturen zuzugreifen und zahlreiche komplexe
Abfragen der externen Verbraucher (i.d.R. Grossbanken) mit
geringer Latenz und Last zu beantworten. Für die
Reader/Writer-Synchronisierung zwischen Server und Client
wird indes eine an die POSIX pthread API angelehnte
Implementierung von verteilten Locks auf der Basis von
robusten SystemV IPC-Semaphoren eingesetzt.
Diese Lösung war schnell zu implementieren und ist
äusserst robust, da sämtliche (meist nicht
trivialen) kommunikationstechnischen Aufgaben vollends
vermieden werden.
Komplexe Prozesslogik im
asynchronen Server (2008)
Aufgabe:
Implementierung von komplexen Vorgängen bei der
Replikation von Leases zwischen den redundant geschalteten
DHCP-Servern (ein prominenter Anbieter von
Netwerkinfrastruktur)
Ziele:
Das in der Anwendungssuite des Herstellers
durchgängig eingesetze Proaktor-Entwufsmuster erlaubt
keine blockierenden Vorgänge in der Anwendung, da die
Anzahl Threads klein gehalten wird und blockierde
Vorgänge somit schnell zum Stillstand des
Gesamtsystems führen würden. Bei der
Lease-Replikation ist es allerdings notwendig, komplexe
hierarchische Kommunkationsprozesse abzubilden, die
man am liebsten in jeweils einen eigenen Thread verlegen
würde, um den Prozesszustand elegant zu verwalten.
Lösung:
Es wird der Begriff von asynchronen Activites und Actions
eingeführt. Eine Activity ist die Abbildung von einem
Prozess der gemäss dem Composite-Entwurfsmuster eine
beliebige Anzahl an weiteren Activities starten kann und
nicht-blockierend wartet bis diese abgeschlossen sind,
bevor er den nächsten Prozessschritt ausführt.
Auf der untersten Ebene dieser Prozesshierarchie treten
Actions auf die mit externen Ereignissen (wie z.B. das
Eintreffen einer Nachricht) verknüpft sind und dieses
der Superactivity signalisieren können. Verbunden mit
dem Weiterreichen von Ausnahmen entlang der
Activity-Hierarchie erlaubt dieses Framework Prozesse
umzusetzen, in etwa so, als ob jeder davon in einem
eigenen Thread laufen würde. Dies vereinfacht die
asynchrone Programmierung stark.Da diese Systematik
universell einsetzbar ist und auch eingesetzt wurde, hat
sie in den folgenden Jahren einige Verbesserungen
erfahren.
Online Messeplatz (2007)
Aufgabe:
Architektur, Software- und Datenbankdesign, Entwicklung
der Backend-Komponente, Projektleitung (prominenter
Handelsmessenveranstalter) eines Teams von ca. 10
Personen.
Ziele:
Realisierung von einer kompletten Applikationssuite
bestehend aus Web-Frontend, webbasiertem Redaktionssystem
und Business Logic Backend für einen
Online-Messeplatz, der den Ausstellern über ein
ganzes Jahr zur Verfügung steht.
Lösung:
Hier wurden grösstenteils Standardkomponenten wie
PHP, MySQL sowie JEE/JPA für das Business Logic
Backend eingesetzt. Eine Ausnahme bildete die eigene
Suchmaschine (hier als ein Java-Serverprozess), die
Volltextsuche und relationale Suche auf eine elegante
Weise vereint.
Diese, technisch zwar nicht besonders anspruchsvolle,
dennoch eine sehr umfangreiche, Aufgabe wurde unter
grossem Zeitdruck termingerecht und in vollem
funktionellen Umfang gemeistert. Die damals entsandene
Anwendungsarchitektur wird im Jahr 2015 weiterhin für
die Weiterentwicklung des Systems verwendet.
Massendaten-Adressverwaltungssystem
/ Projekt U4 (2005-2006) -> zur
Ressourcen-Seite
Aufgabe:
Entwicklung von einem komfortablen Adressverwaltungssystem
(grosser Auskunftsdienstleister)
Ziele:
- Implementierung von einem Serverprozess für die
Verwaltung von grossen Adressmengen (ca. 10 Mio
Datensätze)
- Zügige Verarbeitung von täglichen
Datenupdates der Deutschen Telekom mit durschnittlich
300 000 Einträgen
- Automatische Generierung von Exportfiles für den
Betrieb der hauseigenen Internetauskunft
- ein komfortabler Redaktions-Frontend mit
mächtigen und performanten
Suchfunktionalitäten, mit dem man sich schnell und
zuverlässig im grossen Datenbestand bewegen kannn,
Mengen von Einträgen per Knopfdruck verändern
oder löschen, sowie auskunftsrelevante
übergeordnete Strukturen bilden.
Lösung:
- Für diese Mengen von Daten existieren keine
COTS-Lösungen. Eine RDBMS-basierte Lösung
wäre weder in der Lage, komplexe Massenimporte
performant durchzuführen, noch wäre es
möglich, auf dieser Grundlage ein flinkes und
flexibles GUI-Frontend zu entwickeln. Das Hauptproblem
liegt darin, dass man mit SQL einschl. diverser
proprietäter Erweiterungen wie PL/SQL keine
komplexe Geschäftslogik auf eine performante Art
und Weise umsetzen kann. Selbst im Jahr 2015, wo
SQL-Dialekte (z.B. Oracle) eine starke Weiterentwicklung
erfahren haben, fehlen viele wichtige
Funktionalitäten, allem voran die Fähigkeit,
Datensätze als Objekte zu behandeln und eine
komplette In-Memory Datenbankstruktur die für
schnelle Abfragen und performante Navigation im Bestand
essentiell ist.
- Als Lösung wurde somit die Entwicklung von einer
neuartigen Programmiersprache (u) in Kauf genommen - man
kann dies als die grossdimensionierte Anwendung vom
Interpreter-Entwurfsmuster betrachten. Die Sprache ist
objektrelational und setzt einen mächtigen
Interpreter (U4) voraus, der vom Aufbau her stark einem
RDBMS-Server ähnelt. So ist er in der Lage, eine
Vielzahl Skripte zur Laufzeit zu kompilieren und diese
nach Bedarf auszuführen. Die Sprache ist auf die
Massenverarbeitung ausgelegt und beinhaltet komplexe
relationale Logik inkl. Outer Joins, diverse Container
inkl. normale Tabellen, Stacks, Queues und Dictionaries,
eine integrierte Volltextsuche und fortgeschrittene
Mittel, um Abfragen drastisch zu optimieren. Der
komplette suchbare Datenbestand befindet sich im
Hauptspeicher, reine Informationen lassen sich auf die
Festplatte auslagern, um die Speicheranforderungen zu
reduzieren. Statt Foreign Keys werden explizite
Assoziationen(Relationships) verwendet. Das System ist
transaktionsfähig und unterstützt die
Historie-Funktion, mit der man die komplette Evolution
der Daten verfolgen kann.
- ein komplexer Datenimport wird als ein
vollständig in U realisierter Skript implementiert.
Er liest Daten aus einer CSV-Datei ein und benutzt
kaskadierende Abfragen(inkl. Group-Queries) um in einem
Durchgang die komplette Import-Struktur in die
gewünschten Eingabeentities aufzubrechen und diese
in passenden Container-Strukturen abzulegen.
Anschliessend werden mit Hilfe von Outer Joins diese
Strukturen auf den Datenbestand angewandt, fehlende
Einträge erstellt, bestehende verändert und
die zu Löschenden gelöscht. Auch Assoziationen
werden wie gewünscht aktualisiert. Datenexporte
beinhalten nur tatsächliche Änderungen des
Datenbestands seit dem letzten Export, diese lassen sich
leicht aus den Historie-Daten ableiten.
- Auch der GUI-Client(mit MFC entwickelt) benutzt das
Client/Server-Kommunikationsprotokoll von U4. Somit kann
er beliebige Skripte auf den Server laden und Daten auch
leicht mengenorientiert bearbeiten. Somit ist die Suche
mächtig und die Kriterien miteinander frei
kombinierbar. Die Ausführung von Skripten auf dem
Server erfolgt blitzschnell, die evtl. sehr grosse
Suchergebnisse werden vom Client mittels Paging auf ein
vernünftiges Mass reduziert, um unnötige
Datentransfers zu vermeiden. Somit kann der User nach
Belieben im Bestand browsen und leicht die
gewünschten Einträge aussuchen.
- Das Produkt U4 hat auch international Beachtung
gefunden und ist in einem Artikel der "Cordis Focus" -
Zeitschrift beschrieben worden (s. den angegebenen
Ressourcen-Link)
Online Branchenauskunft
(2001-2003)
Aufgabe:
Architektur, Software- und Datenbankdesign,
Entwicklung der Backend-Komponente und Suchmaschine,
Projektleitung eines Teams von ca. 10 Personen.
(renommierter Auskunftsdienstleister)
Ziele:
Realisierung von einer Online-Branchenauskunft auf einem
tagesaktuellen Datenbestand mit performanter und flexibler
Suchfunktionalität. Vollständiger
Produktionsprozess für Premium
Branchenbucheinträge .
Lösung:
Für die Entwicklung der Plattform wurde im
Wesentlichen ein Standard-Softwarestack verwendet,
nämlich ein Java-Applikationssserver (WebObjects) und
ein SQL-Datenbankserver (Oracle) auf Sun Solaris OS.
Abgesehen von der Projektgrösse war die andere grosse
Herausforderung für uns die Implementation der
Suchmaschine , da es kein ausreichend performantes Produkt
auf dem Markt gegeben hat, welches die Volltextsuche,
relationale Suche sowie die geografische Suche( z.B.
Umkreissuche) in sich vereinen konnte. Hier wurde von uns
auf der Basis von Radix Trees ein Suchalgorithmus
entwickelt, der sich als äusserst performant und
ressourcensparend erwiesen hat und somit bei relativ
kleiner Rechenpower hohe Benutzerzahlen mit Bravour
verkraften konnte. Die Weiterentwicklung von diesem
Algorithmus fand nachher Verwendung in weiteren
Kundenprojekten von uns.
|