Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Algorithmen, Datenstrukturen und Klassendesign (https://www.delphipraxis.net/78-algorithmen-datenstrukturen-und-klassendesign/)
-   -   Delphi Fakturierungsserver (https://www.delphipraxis.net/203308-fakturierungsserver.html)

psycodad 4. Feb 2020 14:17

Fakturierungsserver
 
Grüezi miteinander,

WIr haben hier ein gar nicht mehr so kleines Fakturierungsprogramm, das aus z.B. 100'000 Datensätzen eine Rechnung generiert. Dabei fallen viele Tasks an die meistens seriell getätigt werden müssen. Ich zähl mal grob auf:

1. Datenvalidierung
2. Rechnungskopf schreiben
3. Daten summieren zu Rechnungspositionen und Subpositionen usw.
4. Diverse Reporte (Fastreport) generieren
5. Reports per Mail versenden

Daneben gibt es noch ein paar weitere (ich nenn das jetzt mal Prozesse ) die so oder ähnlich abgearbeitet werden müssen. Im Moment sind die einzelnen Prozesse als moströse Prozeduren direkt im Desktop Programm (MDI-Devexpress Applikation) implementiert als richtig toll zu wartender Sphagetti Code (Ironie off). Da Problem daran ist dass ein solcher Prozess gut mal 5 Min. in Anspruch nehmen kann. Währendessen ist die Applikation so quasi eingefroren. Ich könnte jetzt jeden dieser Prozesse in einen TTask legen und schon ginge das besser. Aber eingentlich hat diese Arbeit gar nichts in dem Desktop Programm zu suchen. Ich möchte diese Verarbeitungsprozesse auslagern in einen Fakturierungsserver. Ein weiterer Grund dafür ist dass die Desktop App in einem Terminalserver läuft und dort so ziemlich viel CPU und RAM abzweigt wenn es ans Fakturieren geht. Deshalb soll das Fakturierungsserver-Programm auf einem anderen Server laufen.
Ich stelle mir vor das man vom Desktop Programm aus einen oder mehrere Jobs aufgibt. Der Fakturierugsserver trägt den Job in eine JobListe ein und liefert eine JobID zurück. Das Desktop-Programm pollt dann beim Fakturierungsserver mit dieser JobID von Zeit zu Zeit den Fakturierungsserver und fragt den Job-Status ab. Wenn Fehler auftreten kann der Desktop-Programm das Log des Jobs abholen und anzeigen.
Ich habe schon solche Sachen als (Webservice) SOAP-Server geschrieben. Das funktioniert gut.
Jetzt zu meiner Frage:
1. Ich würde gerne wissen ob es für die Implementierung einer solcher Task-Abarbeitungs-Maschine irgendwelche Design Patterns gibt? Ich hab da mal was von einer Statefull machine gehört, bin ich da richtig?
2. Gibt es da Librarys die einem dabei helfen können das elegant hinzukriegen (z.B. Spring4D oder so)? Oder ist das Overhead, macht man das mit Bordmitteln?

Ich würde mich über ein paar Tips und Anregungen freuen.

hoika 4. Feb 2020 14:32

AW: Fakturierungsserver
 
Hallo,
zu Punkt 2
Zitat:

und dort so ziemlich viel CPU und RAM abzweigt wenn es ans Fakturieren geht
Welche Datenbank benutzt ihr?
Welche Zugriffskomponenten?
Gerade wenn es ein "älteres" Programm ist, könnte dort mit TXTable usw. gearbeitet worden sein,
was meistens sehr lange dauert.
Eine Stored Procedure bringt da u.U. Wunder.

Zitat:

JobListe
Bedenke hier auch, dass es Abhängigkeiten der Jobs untereinander gibt.
1. Datenvalidierung
2. Rechnungskopf
3. usw.

Ich würde erst mal anfangen, das Speed-Problem zu prüfen (Punkt 2).

jobo 4. Feb 2020 18:29

AW: Fakturierungsserver
 
Ich würde das alles in der Datenbank machen.
Jedes externe Tool / Lib / .. muss naturgemäß die Daten erstmal von der DB lesen, berechnen, neue erzeugen und wegschreiben und dann wieder reporten, mailen, ...
Der Datentransport fällt innerhalb der DB ja schon mal weg und es sollte alles flott gehen.

Wahrscheinlich ist das aber nicht die Antwort, die Du hören willst.

Jenseits der DB wird es dann relativ beliebig. Es gibt dutzende oder hunderte Libs die einem an verschiedenen Stellen die Arbeit erleichtern.
Wenn es wirklich darum geht, voll durchautomatisiert, intelligent Daten aufzubereiten, zu verteilen, zu reporten und zu vermailen, dann vielleicht eine Workflow Engine.
Z.B. sowas wie Camunda, aber das ist natürlich nicht Delphi.

Davon ausgehend dann also vielleicht sowas (hab ich natürlich noch nie benutzt)
https://www.tmssoftware.com/site/workflow.asp

himitsu 4. Feb 2020 21:19

AW: Fakturierungsserver
 
Jupp, wie schon erwähnt wurde, ist ja grade ein gutes DBMS dafür da mit vielen Daten ordentlich zu rechnen.

* in der DB alles berechnen (paar SELECTs von einem Programm aus sind da dann aber nicht unbedingt das opzimale)
** alles in StoredProcs/Trigger, wo dann durch irgendwen regelmäßig eine Berechnungsfunktion angestoßen wird

* Report-Daten und zu versendende Mails (ReportID, Text, Mailadressen uns) in Tabellen sammeln und dann von einem Programm abrufen
** ab und an anfragen ob was da ist, oder direkt über Notifications die Abfrage anstoßen


Gut, mit den dir bekannten Mitteln lässt sich in der DB dann die Berechnung nicht Debuggen, aber auch dafür gibt es entsprechende Lösungen.





Aber wenn du erstmal nur aufräumem willst, dann nicht mit Tasks/Threads anfangen. Vergiss nicht, dass du dort dann auf eine Trennung oder Synchronisierung global/gemeinsam verwendetet Objekte/Variablen/... sorgen mußt.
Mach es einfach wie viele andere Programme ala Browser, Datenbankserver uvm.:
> Lege Einzelteile in eigenständige Programminstanzen, gesteuert/gestartet/verwaltet von einem "einfachen" Masterprogramm.
= RAM hat dann jeder seinen Eigenen, globale Objekte gibt es erstmal auch nicht mehr, ein schlimmer Fehler beeinflusst Andere nicht
und von den Tasks/Threads her macht es für das System keinen Unterschied (ist insgesamt ja gleich) und der gesamte RAM ... OK, der wird etwas mehr (jeder bekommt seine eigene Connection usw.), aber RAM kostet nun wirklich nichts.
= außerdem verreckt dann nicht gleich alles, wenn ein Teil abkratzt,
du kannst die Einzelteile auch viel einfacher Debuggen, wenn nicht ständig was anderes reinkretscht,
und wenn du an einem Teil rumschraubst, ist die Wahrscheinlichkeit viel kleiner, dass andere Teile auch kaputt gehn (bei gemeinsamen Sourcen auch dann nicht, wenn nicht jedesmal alle EXEn neu erstellt werden)

Und wenn jede Programminstanz dann nur einen kleinen Teil erledigt, dann lassen sich davon auch Mehrere starten, wenn noch genügend Rechenleistung frei ist.
(je ein Datensatz und sich dann beendet oder den nächsten Satz abholen)

psycodad 5. Feb 2020 10:34

AW: Fakturierungsserver
 
Erstmal vielen Dank für die detaillierten und informativen Antworten.

Wir benützen einen SQL Server 2018 mit 255GB RAM. Die DB (die grösste) ist so um die 300GB gross. Die einzelnen Datenaufbereitungen (Datenvalidierung, Durchrechnen der Preise, Generieren von Positionen etc.) finden alles bereits in Stored Procedures statt. Die Tabellen der einzelnen Selects innerhalb der STP's sind alle mit Indexes optimiert dort wo es Sinn macht. Wir werden in den nächsten Monaten neuere Storages mit SSD bekommen. Das wird das ganze erheblich beschleunigen.

Das Desktop Programm startet die STP's, wartet auf deren Beendigung und ruft dann einen ebenfalls selbst geschriebenen Reportserver auf, der dann die verschiedenen PDF-Formulare generiert und ggf. versendet. Dieser Reportserver funktioniert auf Basis eines Webservices, dem Jobs übergeben werden können.

Da wir pro Monat tausende Rechnungen generieren (Kleine gehen ein paar Sekunden. Monsterrechnungen eben bis zu 2-5 Min.) macht es aus den im ersten Beitrag erwähnten Überlegungen aus meiner Sicht schon Sinn, diese Aufgabe in ein zweites Programm auszulagern.

Im Gegensatz zu einem Reportserver, wo die Anzahl Prozessschritte sich in Grenzen halten (Reports drucken, ablegen oder versenden) muss der Fakturierungserver einen oder mehrere ziemlich komplizierten Prozesse durchlaufen. Dabei können Warnungen oder Errors anfallen. Deshalb musss jeder Prozessschritt geloggt werden. Je nach Resultat eines Prozesses fallen Entscheidungen an, der Prozess geht also nicht einfach linear durch.


Daher meine Frage nach Design Patterns und Librarys, die mich bei meinem Vorhaben unterstützen könnten.

psycodad 5. Feb 2020 10:38

AW: Fakturierungsserver
 
Zitat:

Zitat von himitsu (Beitrag 1456708)

Gut, mit den dir bekannten Mitteln lässt sich in der DB dann die Berechnung nicht Debuggen, aber auch dafür gibt es entsprechende Lösungen.

Hmm, ich weiss sehr wohl wie man STP's debuggen kann. Woher die Annahme ich könne das nicht?:wink:

jobo 5. Feb 2020 11:04

AW: Fakturierungsserver
 
Interessant!

SSD bringen vermutlich nicht so viel, ich tippe mal Faktor 2 oder 3. Aber gut, kommt darauf an, wie alt / mies die jetzige Hardware ist.

Die größte DB passt also fast in den RAM, das müsste ja dann bei kleineren DB einigermaßen flott gehen. Aber wahrscheinlich laufen die alle zusammen und die Rechnungen werden natürlich immer von verschiedenen Systemen angefordert.

Wenn alles schon in SP ist, ist das schon mal gut. Dann kannst Du eigentlich nur nach Libs schauen, die intelligent mit den Zwischenergebnissen umgehen.


Große Performance Steigerung würde man dann wohl jetzt nur über Tuning von einzelnen Statements erreichen. Und über eine Zugriffsoptimierung, um möglichst viele blockierende Operationen zu finden und zu eleminieren. Dabei wäre z.B. spannend, wie in dem Prozess mit Transaktionen gearbeitet wird. Das Sperrverhalten von sql server war zumindest früher nicht so dolle. 2014 hat aber bestimmt schon dazu gelernt, 2018 wahrscheinlich um so mehr.

Das mit dem Debuggen ist nicht bei jedem System möglich, ich kenne es von der Nutzung her nur von Oracle. Das meint himitsu wahrscheinlich. Am Ende tun es hier aber meist auch ein paar Logausgaben in Textfiles. Um Long Running Statements zu finden, muss man aber wohl nicht debuggen.

jobo 5. Feb 2020 11:27

AW: Fakturierungsserver
 
Was ist so kompliziert an den Rechnungen?
Iterative Preisberechnung? Oder vielfältige Rabattmodelle und Rechnungsvorschriften?

Noch zu Indizes:
Das Anlegen von Rechnungen dürfte ja zu großen Teilen mit dem Anlegen von Datensätzen verbunden sein, da hilft viel nicht unbedingt viel, eher umgekehrt.

psycodad 5. Feb 2020 14:29

AW: Fakturierungsserver
 
Zitat:

Zitat von jobo (Beitrag 1456735)
Was ist so kompliziert an den Rechnungen?
Iterative Preisberechnung? Oder vielfältige Rabattmodelle und Rechnungsvorschriften?

Noch zu Indizes:
Das Anlegen von Rechnungen dürfte ja zu großen Teilen mit dem Anlegen von Datensätzen verbunden sein, da hilft viel nicht unbedingt viel, eher umgekehrt.

Erstmal vielen Dank für die Anregungen/Tips.

Es ist so dass im Extremfall eine Rechnung basierend auf 100'000 Records berechnet werden muss. Dazu werden alle Records durchlaufen und die Felder mit diversen Checks auf Gültigkeit geprüft. Dann wird für jeden Record ein Preis berechnet. Du bringst es auf den Punkt, wir haben hier ein fantasievolles Rabattsystem und ziemlich komplizierte Rechnungsvorschriften. Danach werden die Records gruppiert und dann werden Rechnungspositionen basierend auf diesen Gruppen geschrieben. Jeder Record ist genau einer Rechnungsposition zugeordnet. Wie gesagt, für eine einfache Rechnung bewegen wir uns da inkl. Reporterstellung im Sekundenbereich.

Es gäbe noch einiges zu optimieren in den verschiedenen STP's betreff der Granularität von Transaktionen etc. Da aber bald viele neue Vorschriften dazukommen (z.B: Splitten von Rechnungen auf verschiedene Debitoren etc.) werden haben wir uns für ein Refactoring entschieden.

Es geht nicht darum, das letzte Quentchen Perfomance herauszukitzeln. Es geht mir darum, dass der Job vom User angestossen werden kann ohne dass er auf dessen Ende warten muss. Er soll normal in der Destop-MDI weiter arbeiten können. Er wird informiert, wenn der Job fertig ist. Er kann jederzeit den Status eines Jobs einsehen und das Log des Jobs verfolgen.

Technisch geht es darum, die ebenfalls langsam etwas monströsen STP's in logische Einheiten aufzubrechen. Der Fakturaserver sorgt sich nur um die Job-Verwaltung, Gibt den Status eines Jobs auf Anfrage zurück und führt den Job aus. Dabei soll er einem Prozessplan folgen. Die einzelnen Prozessschritte starten dann z.B. eine STP oder schreiben wieder um einen Job an den Reportserver. Wenn der Prozessschritt ausgeführt ist gehts bei Erfolg zum nächsten Schritt. Ich könnte mir auch vorstellen, dass je nach Resultat/Zustand eines Prozessschrittes ein anderer Prozessbaum abgearbeitet werden kann. Da bin ich jetzt eben am Informationen beschaffen, ob es da Design Patterns oder sogar irgendwelche Frameworks/Libraries gibt wie man so etwas aufbaut.
Ich könnte einfach loslegen und mit ein paar verschachtelten Ifs usw. das ganze niedernageln. Ich suche aber einen mehr generellen Ansatz so etwas zu machen. Ich kann mir gut vorstellen in Zukunft weitere andere Prozesse über den Fakturaserver laufen zu lassen.

Ich habe diese Infos gefunden:
https://www.delphipraxis.net/186504-...er-delphi.html
http://melander.dk/delphi/statemachine/

Ich bin mir nicht sicher, ob das "the way to go" ist. Wie löst man sowas? Gibt es da andere Lösungsansätze soetwas zu machen?

psycodad 5. Feb 2020 14:53

AW: Fakturierungsserver
 
Debuggen von STP geht im SQL Server Management Studio wunderbar. Mehr brauchte ich bis jetzt nicht. Auch SQL Optimierungen, Laufzeitanalysen usw. kann man damit alles machen.


Alle Zeitangaben in WEZ +1. Es ist jetzt 10:02 Uhr.
Seite 1 von 2  1 2      

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