Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi DataSnap, dbexpress und Einzelplatz/Netzwerklösungen mit XE2 (https://www.delphipraxis.net/165395-datasnap-dbexpress-und-einzelplatz-netzwerkloesungen-mit-xe2.html)

cytrinox 28. Dez 2011 14:09

DataSnap, dbexpress und Einzelplatz/Netzwerklösungen mit XE2
 
Hi,

da nun nach einigen Jahren die Portierung einer alten (großen) Delphi-Anwendung auf Delphi XE2 ansteht, habe ich mir Features wie DataSnap, DBExpress usw. einmal genauer angesehen. Zuerst etwas zur Theorie:

Die Anwendung besteht aus 3 Komponenten: Client, Server und Datenbank (z.B. MS-SQL oder Firebird).
Meine Überlegung zur Architektur war bisher wie folgt:

Der Server läuft als Windows-Dienst. Der Client stellt mittels Datasnap eine TCP/IP Verbindung zu eben diesem Server her. Datenbankverbindungen werden vom Server aufgebaut (d.h. DB-Client Libraries wie z.B. fbclient.dll oder sqlncli werden NUR auf dem Serversystem installiert) und die Clients arbeiten mit der Datenbank ausschließlich über die Datasnap-Verbindung zum Dienst.

Dazu nun folgende Fragen/Probleme:

Ich habe öfters gelesen, dass nicht die Connection per Datasnap an die Clients getunnelt werden (und auf Client-Seite dann ein TDatasetProvider, TClientDataset, ...) sondern auf Serverseite ein TDatasetProvider bereitgestellt wird, und nur der Provider an den Client weitergereicht wird (d.h. auf Clientseite nur ein TClientDataset).
Hat dies irgendwelche Vorteile, z.B. bezüglich der Geschwindigkeit/Traffic? Ich würde es vorziehen nur eine zentrale Connection auf Serverseite zu haben und die Provider auf Clientseite, wenn nichts dagegen spricht (Hauptsächlich weil es kaum Logik gibt die serverseitig implementiert werden müsste, d.h. wird eine neue Tabelle/Bereich eingebaut, müssten sowohl der Client als auch der Dienst angepasst werden, was ich gern vermeiden möchte).

Der Server soll ein paar einfache Methoden für die Clients bereitstellen, um z.B. Konfigurationsparameter abzurufen. Das ließe sich da über einen Datasnap Server sehr einfach lösen. Allerdings ist mir das mit der Lifecycle nicht nicht klar. Angenommen ich wähle "Server", dann existiert ja nur eine Instanz, auf die aber von mehreren Clients/Connections zugegriffen wird. Kümmert sich Datasnap da schon um's Locking oder muss ich die Klasse thread-safe bauen?

Mehrfach steht im Docwiki, dass diese ganze DataSnap/RemoteMethod Sache irgendwo über ein IAppServer Interface läuft, bzw. Klassen die dieses Interface implementieren auch um Methoden ergänzt werden können, die Clients widerum aufrufen. Ich habe über diesen Datasnap Expert mal anhand des Tutorials so ein Mini-Server & Client gebaut, aber ich konnte im Code (und den verwendeten Basisklassen) nichts finden, was IAppServer implementiert. Wo steckt das genau, und wird unterschieden zwischen Methoden die per TDSServerClass bereitgestellt werden (da muss ich für den Client-Code ja noch den passenden Code erzeugen -> "Generate Datasnap Client classes") und zwischen Methoden die über IAppServer bereitgestellt werden? Wie können diese dann überhaupt vom Client aufgerufen werden?

Angenommen ich nehme die Variante bei der lediglich eine TSQLConnection serverseitig erstellt wird und die Clients diese per Datasnap mitbenutzen, dann schätze ich mal muss ich pro Session eine Connection erzeugen. Zumindest habe ich das so unter http://www.andreanolanusse.com/en/sh...erver-modules/ verstanden. Müsste dann aber nicht auch Dinge wie TDatasetProvider usw. pro Session erstellt werden? Sonst hab ich da vielleicht 10 Clients, die alle gerade (serverseitig) den "tblArtikelProvider" nutzen wollen?!

Abschließend noch die Frage, ob es möglich ist den Datasnap Server als Einzelplatz Lösung "im" Client laufen zu lassen (z.B. den DataSnap Server in ein BPL Modul auslagern, was bei einer Einzelplatzversion per Compilerschalter mit eingebaut wird). Dabei würde auch nur eine embedded Firebird-Datenbank zum Einsatz kommen.



Gruß
Daniel

Phoenix 28. Dez 2011 15:07

AW: DataSnap, dbexpress und Einzelplatz/Netzwerklösungen mit XE2
 
Lass am besten die Finger von DataSnap.

Mal von ein paar Beispiel-Clicki-Bunti Samples die funktionieren abgesehen wirst Du mit DataSnap 'in the wild' feststellen, dass mal dies, mal jenes nicht funktioniert, und wenn man es dann doch irgendwie hintenrum hingefrickelt hast wirst Du feststellen, dass DataSnap nicht sauber skalieren kann.

Stelle Dir lieber zuerst die Frage, ob Du den massiven(!) overhead eines N-Tier Systems wirklich brauchst und Dir wirklich antun musst. Wenn nicht, dann lass es bleiben.

Wenn Du aber wirklich ein N-Schichten-System aufbauen musst, dann mach es von Hand (deutlich flexibler als DataSnap und unter Garantie Bugfreier) oder benutze Tools die das wirklich beherrschen und nicht nur so tun als könnten sie es, um dann in den entscheidenden Momenten grandios zu versagen.

cytrinox 28. Dez 2011 16:03

AW: DataSnap, dbexpress und Einzelplatz/Netzwerklösungen mit XE2
 
Kannst du die Probleme bzw. was auch immer nicht funktioniert genauer beschreiben?

Ich möchte hauptsächlich folgende Dinge damit erledigen:

- Keine Database-Clientbibliotheken auf den Clients, sondern nur Serverseitig, wobei ich auf dem Server dann die Native Libs per dbexpress verwenden will (fbclient.dll, sqlncli, usw, und nicht wie z.B. ZEOS für MS-SQL irgendwie über ADO hinbiegen).

- Statt zwei TCP Verbindungen (Datenbank + AppServer) nur noch eine, die aber grundsätzlich komprimiert + verschlüsselt ist (beides Dinge, die manche Systeme - z.B. Firebird - nicht direkt anbieten).

- Eine einfache Möglichkeit (verschlüsselt) zwischen einem Client und dem AppServer zu kommunizieren. Bisher habe ich dafür immer ein kleines Protokoll gestrickt (z.B. Binary, Plaintext oder XML, je nach Anforderung) und das über TCP Indy Sockets gemacht. Die gleiche Funktionalität hatte ich mit Datasnap nun aber in ein paar Minuten zusammengklickt.

himitsu 28. Dez 2011 16:09

AW: DataSnap, dbexpress und Einzelplatz/Netzwerklösungen mit XE2
 
Callbacks sind Schrott (auch wenn sie sich in XE2 angeblich ein bissl gebessert haben sollen)

Speicherlecks (auch Dank einiger fehlerhafter und weitverbreiteter Beispiele im Netz)

Vorallem wenn die Verbindung nicht 100% stabil ist, gibt es schöne Nebenwirkungen, da die offenen Verbindungen gerne mal hängen bleiben.

Die automatisch generierten Klientklassen sind Schrott, da man eine getrennte/abgebrochene Verbindung nich wiederverbinden kann, weil die DBXConnection schrottig verwaltet wird (macht man das alles selber, läuft es besser).

Die Dokumentation ist das Schlimmste ... es gibt praktisch keine. (abgesehn von einigen netten Büchern, welche man sich unbedingt kaufen sollte, will man wirklich mehr machen, als die schrottigen Beispiele einem aufzeigen)

~3-5 MB pro Klientverbindung ... da ist der Server schnell voll.

Multithread im Klienten geht nur durch mehrfache Datenverbindungen. (möchte man ein fehlerfreieres Verhalten haben)

Für jeden Clallback-Channel (über den Callbackmanager) eine weitere Datenverbindung.

In XE hatte es praktisch nicht funktioniert mehrere Callbacks an einem Callbackmanager zu registrieren,

Callbacks und Authentifizierung, bzw. eine verschlüsselte Datenübertragung, kannste zusammen vergessen. (der schrottige Callbackmanager verhindert das Zusammenspiel)

usw.

cytrinox 28. Dez 2011 16:19

AW: DataSnap, dbexpress und Einzelplatz/Netzwerklösungen mit XE2
 
Ja was genau ist denn nun Schrott? Diese Meinung ist nicht hilfreich, solange niemand weiß wie du zu der Entscheidung kommst...

Und warum sollte man bei einem Disconnect nicht einfach die TSQLConnection reconnecten? Ich sehe da zumindest von der Codestruktur her grad keine Probleme, wirklich tief durch die Units hab ich mich jetzt aber noch nicht durchgeklickt.

himitsu 28. Dez 2011 16:33

AW: DataSnap, dbexpress und Einzelplatz/Netzwerklösungen mit XE2
 
Bei meinem Streßtest haben sich am Ende durchschnittlich über 80% der Callbacks verabschiedet (reagierten einfach nicht mehr), bei Vielen kamen nichtmal alle Messages an.

Da die (internen) DBXCommands "standardmäßig" nur am Anfang erstellt werden, bei der ersten Benutzung, bekommen sie es nicht mit, wenn die SQLConnection neu verbunden wurde.
Für die DBXConnection enthalten sie dann noch die alten Objektzeiger, zur alten und nicht mehr existierenden DBXConnection ... die Folge sind Exceptions.
Ein Rücksetzen ist nicht vorgesehn. Meine einzige Lösung, für die automatisch generierten Klientklassen > das ganze Datenmodul freigeben und neu erstellen.

Bricht die Verbindung zusammen (z.B. Netzwerkproblem) dann bekommt das der Server und der Klient nicht mit.
Die Connection Der Channel bleibt im Server erhalten > Speicherleck.

Werden dabei registrierte Callbackverbindungen getrennt, ohne daß sie sich ordentlich abmelden konnten, bleiben sie im Server zurück.
Ein Runterfahren des Servers kannst'e dann vergessen, da er dabei oftmals hängen bleibt.

Das Neustarten des Servers kannst'e vergessen, ohne daß danach alle Klienten ebenfalls neu gestartet werden müssen. (genauso, wie bei einer getennten Verbindung)




Um die Verbindungsprobleme zu minimieren: (Lösung für die automatischen Klassen)
- keine Heavyweight Callbacks (die kleinen Callbacks, wärend eines Funktionsaufrufes ausgeschlossen)
- die Verbindung nach jedem Funktionsaufruf trennen (oh, geht ja nicht, ohne das Datenmodul neu zu machen)
- bei einem Verbindungsproblem das Datenmodul zerstören und ein Neues erstellen

Und alleine die 3 Punkte wiedersprechen IMHO einem professionellen Einsatz.





Durch eine standardmäßig auf Localhost festgelegte Verbindung, "lokale" Tests auf unserem Server und durch eine mangelnde Dokumentation hatten wir uns einige nette Problemchen eingehandelt, welche sich erst im realen Einsatz (beim Kunden) zeigten ... das kommt super an :thumb:

Wir haben es jetzt seit knapp einem Jahr im Einsatz und immernoch nicht alle Probleme beseitigt.
Zum Glück wurden inzwischen einige Dinge gelöst (mehr/neue Infomationen (Bücher) sind im Umlauf, aber nicht die von Emba).

cytrinox 29. Dez 2011 08:40

AW: DataSnap, dbexpress und Einzelplatz/Netzwerklösungen mit XE2
 
Danke für die ausführliche Beschreibung, jetzt kann ich deinen Standpunkt auch besser nachvollziehen. :)

Ich möchte mir aber doch gern die Zeit nehmen und unter XE2 das alles mal probieren & debuggen und auch Netzwerkprobleme zu simulieren. Ergebnisse würde ich hier ergänzen.

Daher wäre es super wenn wir die ursprünglichen Fragen noch klären könnten damit es nicht schon daran scheitert ;)


Alle Zeitangaben in WEZ +1. Es ist jetzt 10:20 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz