Session D-MTS

Verteilte Anwendungen
in der Praxis

Patrick E. Schärer
Business & System


Wozu verteilte Anwendungen?

Entlastung der Rechnerkapazität

Der einfachste und für den VFP-Entwickler zuerst einmal naheliegenste Fall ist dieser:

Wir haben ein Netzwerk von einigen Computern, die mit einer VFP-Anwendung auf einen gemeinsamen Datenbestand auf einem Server zugreifen. Die Clients sind beschäftigt mit irgendwelchen Dateneingaben, Abfragen etc.

Nun soll entweder von einem Administrator, von bestimmten Usern, die dafür Berechtigung haben, oder durch zeitgesteuertes Starten eine Operation auf der oder den gemeinsamen Datenbanken des Servers durchgeführt werden. Unter Umständen ist dies eine zeitintensive Operation.

An dieser Stelle soll nun der Client-Computer, der den Vorgang aufruft, nicht mit der Ausführung dieses Vorgangs belastet werden. Er soll unmittelbar auf dem Server selbst oder auf einem weiteren Rechner, der über freie Rechnerkapazität verfügt, ausgeführt werden.

In dieser Session beschäftigen wir uns damit,

  1. wie wir eine solche Anwendung konzipieren müssen
  2. wir wir dafür sorgen können, dass sie auf dem richtigen Server ausgeführt wird, und dies von Windows für uns verwaltet wird. Speziell bei diesem zweiten Punkt kann man eine Reihe mühevoller Wege gehen, die sich danach doch als untauglich erweisen - darum einige Tips...

Middle-tier Anwendung

Haben wir eine Anwendung sauber aufgeteilt in Datenschicht - Geschäftslogik - Präsentationsschicht (oder ggf. weitere Layers) und soll die Präsentationsschicht offen sein (d.h. möglicherweise auch der Internetbrowser anstelle eines VFP-Frontends), so muß ohnehin die Geschäftslogik zentral verwaltet werden (und dabei u.U. viele Aufrufe gleichzeitig verarbeiten). Dies wird hervorragend vom Microsoft Transaction Server (s.u.) für uns bewerkstelligt. Dies ist besonders auch darum von Vorteil, weil die Geschäftslogik und damit die Mittelschicht relativ häufigen Veränderungen unterworfen ist (Geschäftsregeln müssen aktuellen Gegebenheiten angepasst werden) und leicht zentral verändert werden muß ohne Eingriff auf vielen Arbeitsplätzen.

Konzipierung der Anwendung selbst

Eine Anwendung, deren Ausführung auf andere Rechner als den aufrufenden festgelegt ist, sollte von vorn herein als COM-Server konzipiert sein. Ohne dies im Detail hier besprechen zu können (meine zweite Session D-OLE beschäftigt sich damit genauer), seien die überlebensnotwendigsten Kennzeichen hier genannt, die wir in der Session und auf der CD mithilfe einer Beispielanwendung angewendet sehen:

  1. Die Anwendung hat kein Hauptprogramm sondern hat eine zentrale Klasse, die als "OLE-Public" definiert wird 
    (unter "Klassen-Info" im "Klassen"-Menü).
  2. Die Anwendung verzichtet auf jegliches User Interface (was sie - nebenbei gesagt - wesentlich schneller macht). 
    Jeder Modale Zustand, der eine Antwort erfordert (Messagebox, Wait Window, etc) muß streng verhindert werden.
  3. Die Anwendung wird von außen nicht durch ausführen einer Exe sondern durch instanziieren einer öffentlichen Klasse 
    und ansprechen derer Methoden ausgeführt. "Von außen" kann heißen von einer VFP-Instanz oder von einer beliebigen 
    anderen OLE-fähigen Anwendung.
  4. Da eine COM-Server Anwendung immer in dem Verzeichnis gestartet wird, wo die entsprechende VFP-Runtime liegt, 
    muß dafür gesorgt werden, dass in das Verzeichnis der DLL selbst gewechselt wird, z.B. durch:
    •  
      lcDir =
      SUBSTR(JUSTPATH(SYS(16)),AT(":",SYS(16))-1)
      SET DEFA TO (lcDir)
  5. Da OLE-Fehlermeldungen sehr nichtssagend sind, muß (zumindest noch bei VFP6) die ab SP3 verfügbare Funktion 
    COMRETURNERROR in den ERROR-Event eingebaut werden, z.B. durch
      IF INLIST(application.startmode,1,2,3,5)
        LOCAL lcReturn lcReturn = ;
          ALLT(STR(nError))+; ': '+MESSAGE()+' bei Zeile '+ALLT(STR(nLine))
        COMRETURNERROR(cMethod,lcReturn)
      ELSE
        DODEFAULT(nerror,cmethod,nline)
      ENDIF

Beispiel-DLL

Als Beispiel erzeugen wir eine sehr einfache COM-Anwendung, um das Prinzip der Arbeitsweise leicht verstehen zu können: Die Anwendung kann gestartet werden, und führt einen Vorgang über eine bestimmte Zeitdauer hinweg aus. Was der Vorgang genauer ist, ist hier nicht wichtig - man stelle sich vor es handle sich um eine bestimmte Datenbankoperation oder dergleichen.

Weil bestimmte Namen (von DLL, Klasse, Methode etc.) an verschiedenen recht verstreuten Stellen wieder erscheinen, möchte ich zur Veranschaulichung hier folgende Namensgebung verwenden: Wir legen einen neuen Ordner an und legen darin ein

  • neues Projekt an mit dem Namen MyDll an. Das Projekt heißt so, 
    weil der Name der daraus erzeugten kompilierten Datei nachher ja erst einmal sich aus dem Projektnamen ableitet.
  • In diesem Projekt erzeugen wir eine Neue Klasse MyClass mit einer Methode MyMethod.
  • Die Klasse wird abgelegt in die Klassenbibliothek MyClassLib.

Die Methode MyMethod nimmt einen Parameter entgegen für die Anzahl von Sekunden, die sie laufen soll. Sie könnte als Testmethode so aussehen:

    LPARAM lnSec
    LOCAL lnTime,lnTimeStop,lnReturn
    lnTime = DATETIME()
    lnTimeStop = lnTime+lnSec
    lnReturn = 0
    DO WHILE DATETIME()<=lnTimeStop
      lnReturn = lnReturn + 1
    *Anzahl der Durchläufe
    ENDDO
    RETURN lnReturn

Zuerst solle eine als COM-Server angelegte Anwendung trotzdem in VFP getestet werden. Dazu bilden wir eine Instanz von der Klasse und führen die Methode MyMethod aus

    o=NEWOBJ('MyClass','MyClassLib')
    ? o.MyMethod(1)

Der Rückgabewert müsste die Anzahl der Durchläufe unserer DO WHILE-Schleife sein.

Kompilierung als DLL

War der Test unter VFP erfolgreich, kompilieren wir unseren OLE-Server als DLL. Erst danach "kennt" das Projekt seine Server-Klassen. Dies kann angezeigt werden in der Projektinfo.

Unter Projekt-Name wird automatisch der Name Ihres Projekts hineingeschrieben. Die technische Bedeutung von "Projekt-Name" ist jedoch eine andere: Was hier steht, wird später zum Aufruf der COM-Klasse vor dem Punkt verwendet. (d.h. "o=CREATEOBJ('MyDllName.MyClass')"). Zur Veranschaulichung habe ich hier MyDll darum durch MyDllName ersetzt.

Wenn Sie ihre OLE-Klasse umbenennen, erscheint der neue Name der Server-Klasse hier erst, wenn Sie die DLL neu kompiliert haben.

Konfiguration und Registrierung im Netz: MTS

Um nun die von uns erzeugte DLL im Netz zu verwalten, steht uns der Microsoft Transaction Server (MTS) zur Verfügung.

Nebenbei erwähnt: Es gibt auch andere Wege, die aber veraltet sind und jeweils nur mit Mühen zT halbwegs zum Ziel führen: Der Remote Automation Manager (RACMGR32.EXE) in Verbindung mit CLIREG32 (Registrierung auf dem Client). Auch mit dem DCOMCNFG-Konfigurationsmanager brauchen wir uns nicht mühen, wenn wir per MTS arbeiten.

MTS installieren

Der Microsoft Transaction Server muß lediglich auf dem Server installiert sein. Er sorgt dafür, dass die DLL auf dem Server richtig registriert wird und erzeut uns eine EXE, die auf dem Client ausgeführt die Clientregistrierung so vornimmt, dass der Client weiß, auf welchem Server die jeweilige Komponenten ausgeführt werden soll.


 
  • Wenn Sie mit NT4 arbeiten, finden Sie MTS als Teil des Option Packs. Installieren Sie das 
    Option Pack und starten dann den Konsolenmanager.     
  • Wenn Sie mit Win2K arbeiten, ist der Microsoft Transaction Server als COM+ bereits dabei. 
    Sie finden über Systemsteuerung -> Verwaltung -> Komponentendienste die sehr ähnliche Konsole 
    wie unter NT4. Starten Sie diese Konsole.      

MTS einrichten.

Sie finden unter "Komponentendienste" -> "Computer" -> "Arbeitsplatz" (sofern sie auf dem Server arbeiten) dem Üimlt "COM+-Anwendungen". Unter "Anwendung" wird eine Anzahl von Komponenten (also in unserem Fall DLL's) verstanden, die miteinander in Beziehung stehende Funktionalitäten abdecken. Alle Komponenten, die in der gleichen "Anwendung" zusammengefasst sind, werden in demselben MTS-Prozess ausgeführt.

Zuerst müssen wir eine "neue (leere) Anwendung" anlegen. Dann müssen wir diesem leeren Paket die von uns gewünschten Komponenten geben. Die Schritte sind also:

  1. Neue Anwendung hinzufügen

    • Komponentendienste / Arbeitsplatz / Com+ -Anwendungen :
    • Kontextmenü: "Neu" -> "Anwendung"
      • Achtung nicht verwundern: Wenn Sie direkt auf "Com+Anwendungen" mit der rechten Maustaste klicken, bekommen Sie ein falsches Kontextmenü ohne dem Punkt "Neu" (stattdessen "Neues Fenster"). Zuerst mit linker Maustaste auswählen und dann rechts anklicken!
      • Wizard:
          • "Eine leere Anwendung erstellen"
          • Name (hier: MyApplication)
          • "Serverasnwendung"
          • Interaktiver Benutzer (normalerweise)

  2. Komponente hinzufügen:

      • Zuerst neue Anwendung MyApplication auswählen.
      • Kontextmenü auf "Komponenten": "Neu", "Komponente"
      • Wizard
          • "Neue Komponente installieren"
          • Physikalischen Ort der DLL auswählen
          • Im nächsten Dialog werden alle COM-Komponenten, also alle Public-Klassen der DLL angegeben (im Beispiel nur eine)

Ich erkläre hier erst einmal nur die Grundeinstellung - es gibt ziemlich viele Einstellmöglichkeiten, dass man verwirrt sein kann, v.a. wenn etwas nicht richtig funktioniert und man beginnt überall zu suchen.

MTS Verwenden

Um unsere COM-Serveranwendung zu starten müssen wir ein Objekt aus unserer Public-Klasse bilden. Hier bilde ich gleich zwei oder mehr Objekte, um die Reaktion des MTS zu zeigen:

    o1=CREATEOBJ('mydllname.myclass')
    o2=CREATEOBJ('mydllname.myclass')
    o3=CREATEOBJ('mydllname.myclass')

Ergebnis im MTS:

Hier wurde als Ansichtsmodus "Stauts" angegeben, womit der MTS den aktuellen Status einer Komponente verfolgt und angibt. Dreht sich das Symbol für die Komponente, zeigt dies (auch ohne "Status") an, dass die Komponente im Augenblick aktiv ist.

"Der MTS kann mehr"

Ohne darauf hier im Detail einzugehen, soll erwähnt werden, dass mit dem MTS weit mehr möglich ist, als was wir bisher beschrieben haben. Ich will mich hier auf eine Einschränkung aber mit diesem Ausblick begnügen. Für die einzelnen Punkte gibt es ausreichend verschiedene Sekundärliteratur.

Ein Objekt wird stateless (Zustandslos) - ("Just-in-time Activation")

Ein Objekt, das im MTS erzeugt worden ist, kann Zustandslos werden, d.h. es wurde vom Client instanziiert und nicht gelöscht, "verliert aber seinen Zustand", durchläuft seinen Destroy-Event und setzt alle Eigenschaften auf den Standard-Wert zurück. Würden jetzt Eigenschaften abgerufen, würde der Standardwert ausgegeben. Beim nächsten Aufruf einer Methode erhält das Objekt im MTS wieder einen Zustand, nachdem es seinen Init-Event durchlaufen hat. Dies ist es, was sich hinter der oben dargestellten Spalte "aktiviert" befindet. Ein zustandsloses Objekt würde dort als Objekt gezählt, aber unter "aktiviert" nicht mitgezählt. Benutzt man diese Technik ist darauf zu achten, daß im Init und im Destroy nur so wenig wie möglich passiert, da diese oftmals aufgerufen werden.

Verwaltung von Rechten (Rollen)

Wir haben bei der Anlage unserer neuen Anwendung "myApplication" im MTS zwei Unterpunkte gesehen: Komponenten und Rollen. Über Rollen lassen sich detaillierte Zugriffsrechte auf diese spezifische Anwendung vergeben.

Gemeinsame Eigenschaften (Shared Property Manager)

Sie haben über den MTS die Möglichkeit, dort (nicht in der eigenen Anwendung) Eigenschaften anzulegen und zu verwalten. Es geschieht dies durch Instanziierung eines MTS-Objekts innerhalb Ihrer OLE-Public-Klasse.

Transaktions-Verwaltung

Wie der Name "Microsoft Transaction Server" schon sagt, kann der MTS auch Transaktionen verwalten, allerdings leider keine VFP-Transaktionen. Wenn Sie aber als Datenbank beispielsweise MS-SQL-Sever verwenden, haben Sie die Möglichkeit über Methoden des MTS Transaktionen zu beginnen und abzuschließen, so daß der Vorgang, den Ihre Komponente einleitet nur nach gültigem Abschluß bewahrt wird, ansonsten in der Datenbank alle Änderungen zurückgesetzt werden.

Eine gute Einführung in die Verwendung von MTS-Methoden und -Objekten, die für alle diese Funktionen notwendig sind, finden sich im Dokument "Microsoft Transaction Server for Visual FoxPro Developers" von Randy Brown, das ich meinen Unterlagen auf der CD mit beigelegt habe.

vorheriger Vortrag D-STUD

zur Übersicht der Gruppe TIER

nächster Vortrag D-TIER

 

dFPUG c/o ISYS GmbH

Frankfurter Str. 21 b

 

D-61476 Kronberg

per Fax an:

+49-6173-950903

oder per e-Mail an:

konferenz@dfpug.de

© Texte, Grafiken und Inhalt: ISYS GmbH