AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Netzwerke Delphi Sinnvolle Threadverwendung bei Server Monitor???
Thema durchsuchen
Ansicht
Themen-Optionen

Sinnvolle Threadverwendung bei Server Monitor???

Ein Thema von Piro · begonnen am 30. Sep 2008 · letzter Beitrag vom 30. Sep 2008
Antwort Antwort
Benutzerbild von Piro
Piro

Registriert seit: 14. Jul 2003
Ort: Flintbek
810 Beiträge
 
Delphi XE2 Professional
 
#1

Sinnvolle Threadverwendung bei Server Monitor???

  Alt 30. Sep 2008, 18:48
Hi Leute,

ich bin in unserer Firma ein Tool "Server Monitor" programmiert für ca. 70 Server. Die Aufgaben sind:
1. Online Check
2. Informationen mit Hilfe von WMI sammeln pro Server
3. Dienste von verschiedenen Server überwachen (mit Hilfe von WMI)

Das Programm läuft schon wunderbar. Ich habe nur das Problem, dass sich das Programm aufhängt nach ca. 2 Tagen. Nichts reagiert mehr.

Folgendes läuft im Hintergrund:
1. Alle 10 Sekunden werden die Server auf ihren Status geprüft ==> 70 Threads werden dazu erzeugt (Ping Funktion)...Dauer aller Threads = 5 Sekunden
2. Alle 20 Sekunden werden die Dienste überprüft ==> 20 Threads (WMI Abfrage)... Dauer aller Threads = 10 Sekunden
3. Alle 5 Minuten werden alle möglichen Daten (z.B.: Seriennummer, CPU, RAM, etc.) abgefragt ==> 70 Threads werden erzeugt (WMI Abfragen)...Dauer aller Threads = 1 Minute

Mir ist aufgefallen, dass die Ping Threads sich sauber beenden und keiner übrig bleibt. Bei den anderen kommt es vor, dass sie vereinzelt stehen bleiben und sich sogar vermehren.

Ich habe nur eine Thread Unit. Ich benutze TThread. Muss ich eventuell meine Logik ändern? Wie würdet ihr soetwas realsieren?

Aufruf der Threads durch den Timer am Beispiel der Diensteüberwachung:
Delphi-Quellcode:
procedure Tfrm_main.CheckServiceStatusThreadTerminate(Sender: TObject);
begin
 if ThreadCount_ServiceCheck = ThreadMax_ServiceCheck then
 begin
   ThreadsRunning_ServiceCheck := False;
   lbl_overview_servicecheck.Caption := FormatDateTime('dd. mmmm yyyy hh:nn:ss', now);
   if cb_setup_servicestatusactive.Checked = True then
     timer_checkservicestatus.Enabled := True;
 end;
 ThreadCount_ServiceCheck := ThreadCount_ServiceCheck + 1;
end;

procedure Tfrm_main.timer_checkservicestatusTimer(Sender: TObject);
var
 i : Integer;
 Thread : MyThread;
begin
 while ThreadsRunning_ServerInfoToXML = True do
   Application.ProcessMessages;

 ThreadMax_ServiceCheck := lv_service.Items.Count - 1;
 ThreadsRunning_ServiceCheck := True;
 ThreadCount_ServiceCheck := 0;

 for i := 0 to ThreadMax_ServiceCheck do
 begin
   timer_checkservicestatus.Enabled := False;
   ThreadsRunning_ServiceCheck := True;
   Thread := MyThread.Create(True);
   Thread.art := 'CheckServiceStatus';
   Thread.user := edt_setup_user.Text;
   Thread.pwd := edt_setup_password.Text;
   Thread.lvid := i;
   Thread.service := lv_service.Items[i].SubItems[0];
   Thread.servicerestart := lv_service.Items[i].SubItems[2];
   Thread.server := lv_service.Items[i].SubItems[3];
   Thread.lastStatus := lv_service.Items[i].SubItemImages[4];
   Thread.OnTerminate := CheckServiceStatusThreadTerminate;
   Thread.FreeOnTerminate := True;
   Thread.Resume;
 end;
end;
Thread Unit:
Delphi-Quellcode:
unit uThread;

interface

uses
  Classes, SysUtils, MSXML2_TLB, ActiveX, Dialogs, uMain, uServer,
  ComCtrls, uHostAlive, WbemScripting_TLB, Variants;

type
  MyThread = class(TThread)
  private
    { Private-Deklarationen }
  protected
    procedure Execute; override;
    procedure CheckServerStatus;
    procedure ServerStatusToListView;
    procedure CheckServiceStatus;
    procedure ServiceStatusToListView;
    procedure ServerInformationToXML;
  public
    { Public-Deklarationen }
    art : String;
    lvid : Integer;
    lastStatus : Integer;
    server : String;
    sid : String;
    curStatus : String;
    user : String;
    pwd : String;
    service : String;
    servicerestart : String;
  end;


implementation

uses uHostSocketAlive, DateUtils;

{ Wichtig: Methoden und Eigenschaften von Objekten in visuellen Komponenten dürfen
  nur in einer Methode namens Synchronize aufgerufen werden, z.B.

      Synchronize(UpdateCaption);

  und UpdateCaption könnte folgendermaßen aussehen:

    procedure MyThread.UpdateCaption;
    begin
      Form1.Caption := 'Aktualisiert in einem Thread';
    end; }


{ MyThread }

procedure MyThread.Execute;
begin
 CoInitialize(nil);
 try
   if art = 'CheckServerStatusthen
     CheckServerStatus;

   if art = 'CheckServiceStatusthen
     CheckServiceStatus;

   if (art = 'ServerInformationToXML') and (lastStatus = 1) then
       ServerInformationToXML;

 except
    on e: exception do begin
      // mache hier irgendetwas mit dem Fehler.
    end;
 end;
 CoUnInitialize();
end;

procedure MyThread.CheckServerStatus;
var
 i : Integer;
 max : Integer;
begin
 // Verbindungsversuche
 max := 3;

 for i := 0 to max - 1 do
 begin
   if IsHostAlive(Server) = True then
   begin
     curStatus := '1'; //Server Online
     break;
   end
   else
     curStatus := '2'; //Server Offline
 end;

   Synchronize(ServerStatusToListView);
end;

procedure MyThread.ServerStatusToListView;
begin
 with frm_main.lv_server do
 begin
   case lastStatus of
     1 : begin
           if curStatus = '2then
           begin
             Items[lvid].ImageIndex := 2;
             if frm_main.FirstStart = False then
               Items[lvid].SubItems[1] := 'off';
           end;
         end;
     2 : begin
           if curStatus = '1then
           begin
             Items[lvid].ImageIndex := 1;
             if frm_main.FirstStart = False then
               Items[lvid].SubItems[1] := 'on';
           end;
         end;
   end;
 end;
end;

procedure MyThread.CheckServiceStatus;
var
 SWbemLocator1 : ISWbemLocator;
 aSrv : ISWbemServices;
 vNVS : OleVariant;
 aObjSet : ISWbemObjectSet;
 aNVSDummy : IDispatch;
 pEnum : IEnumVARIANT;
 vOut : OleVariant;
 dwRetrieved : LongWord;
 hRes : HResult;
begin
 try
   SWbemLocator1 := CoSWbemLocator.Create;
   // Für lokale Computer darf kein Benutzer und Passwort verwendet werden
   if UpperCase(server) <> UpperCase(GetEnvironmentVariable('COMPUTERNAME')) then
     aSrv := SWbemLocator1.ConnectServer(server,'root\cimv2',user, pwd,'','',0,vNVS)
   else
     aSrv := SWbemLocator1.ConnectServer(server,'root\cimv2','','','','',0,vNVS);

   aObjSet := aSrv.ExecQuery('Select * from Win32_Service Where Name = "' +service+'"','WQL', 0, aNVSDummy);
   pEnum := aObjSet.Get__NewEnum as IEnumVARIANT;
   hRes := pEnum.Next(1, vOut, dwRetrieved);
   if hRes = S_OK then
     curStatus := VarToStr(vOut.State);

   Free;
 Except
   curStatus := '';
 end;

 Synchronize(ServiceStatusToListView);
end;

procedure MyThread.ServiceStatusToListView;
begin
 with frm_main.lv_service do
 begin
   case lastStatus of
     16 : begin
            if curStatus <> 'Runningthen
            begin
              Items[lvid].SubItemImages[4] := 17;
              if frm_main.FirstStart = False then
                //Items[lvid].SubItems[6] := 'down';
            end;
          end;
     17 : begin
            if curStatus = 'Runningthen
            begin
              Items[lvid].SubItemImages[4] := 16;
              if frm_main.FirstStart = False then
                //Items[lvid].SubItems[6] := 'up';
            end;
          end;
     0,18 : begin
              if curStatus = 'Runningthen
                Items[lvid].SubItemImages[4] := 16
              else
                Items[lvid].SubItemImages[4] := 17;
              end;
            end;
 end;
end;

// Gekürzter Quellcode
procedure MyThread.ServerInformationToXML;
var
...
begin
...
 try
   SWbemLocator1 := CoSWbemLocator.Create;
   // Für lokale Computer darf kein Benutzer und Passwort verwendet werden
   if UpperCase(server) <> UpperCase(GetEnvironmentVariable('COMPUTERNAME')) then
     aSrv := SWbemLocator1.ConnectServer(server,'root\cimv2',user, pwd,'','',0,vNVS)
   else
     aSrv := SWbemLocator1.ConnectServer(server,'root\cimv2','','','','',0,vNVS);

   //*** System Summary ***
   aObjSet := aSrv.ExecQuery('Select * from Win32_ComputerSystem','WQL', 0, aNVSDummy);
   ...

   //*** Operation System ***
   aObjSet := aSrv.ExecQuery('Select * from Win32_OperatingSystem','WQL', 0, aNVSDummy);
   ...

   //*** Prozessor Information ***
   aObjSet := aSrv.ExecQuery('Select * from Win32_Processor','WQL', 0, aNVSDummy);
   ...

   //*** Memory Information ***
   aObjSet := aSrv.ExecQuery('Select * from Win32_PhysicalMemory','WQL', 0, aNVSDummy);
   ...

   //*** Network Information ***
   aObjSet := aSrv.ExecQuery('Select * from Win32_NetworkAdapterConfiguration where IPEnabled = true','WQL', 0, aNVSDummy);
   ...

   //*** Storage Information ***
   aObjSet := aSrv.ExecQuery('Select * from Win32_LogicalDisk Where DriveType = 3','WQL', 0, aNVSDummy);
   ...

 Except
   //
 end;
end;

end.
  Mit Zitat antworten Zitat
Apollonius

Registriert seit: 16. Apr 2007
2.325 Beiträge
 
Turbo Delphi für Win32
 
#2

Re: Sinnvolle Threadverwendung bei Server Monitor???

  Alt 30. Sep 2008, 20:20
So oft so viele Threads zu erzeugen ist nicht gut. Du hast hier einen klassischen Anwendungsfall für Thread Pools. Implementationen davon gibt es hier in der DP und seit Windows 2000 direkt im Betriebssystem.
Wer erweist der Welt einen Dienst und findet ein gutes Synonym für "Pointer"?
"An interface pointer is a pointer to a pointer. This pointer points to an array of pointers, each of which points to an interface function."
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 22:59 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