Laden...

WebService-Lastverteilung

Erstellt von tom-essen vor 17 Jahren Letzter Beitrag vor 17 Jahren 3.518 Views
tom-essen Themenstarter:in
1.820 Beiträge seit 2005
vor 17 Jahren
WebService-Lastverteilung

Hallo!

Ich habe folgendes Problem:
Ich habe einen WebService, welcher Anfragen an ein Programm (welches auch auf einem anderen Rechner laufen kann) weiterleitet. Nun soll der WebService diese Anfragen zur Lastverteilung auf mehrere Programme (und somit evtl. mehrere Rechner) verteilen können.

Da bei jeder Anfrage an den WebService einen neue Instanz von diesem im WebServer erstellt wird, und auch die Möglichkeit besteht, dass mehrere Instanzen aufgrund der Anfragen nahezu zeitgleich erzeugt werden, bräuchte ich eine Komponente, auf welche alle Instanzen gleichermassen Zugriff haben und die gleichzeitig auch threadsicher ist.

Dann könnte in dieser Komponente im einfachsten Fall ein Zähler laufen, wobei nur getestet wird, ob die aktuelle Anfrage bei einem graden oder ungraden Zählerstand erfolgt.

Eine Möglichkeit wäre natürlich eine Datei zu erstellen, aber dies erscheint mir zu ressourcenhungrig.

Weiss jemand eine Lösung, bzw. hab' ich mich überhaupt verständlich genug ausgedrückt ...?

Nobody is perfect. I'm sad, i'm not nobody 🙁

I
256 Beiträge seit 2005
vor 17 Jahren

Also wenn es auf mehreren Rechner laufen soll, dann nimmst am besten eine DB wo jeder Recher zugriff hat.

Ansonsten eine Service, dass allen Rechner zugriff gibt.

tom-essen Themenstarter:in
1.820 Beiträge seit 2005
vor 17 Jahren

@Ifoko:
Db ist sogar 'ne interessante idee, werd' ich mal als alternative behalten.
Das einzige, was mich dabei ein wenig stört, ist die Tatsache, dafür eine DB aufzubauen (ok, geht mit mysql super schnell).

Mein Wunsch läge eigentlich in einer dll oder einem dienst, welche(r) einmal im speicher vorliegt, und von allen WebService-Instanzen gleichermassen aufgerufen werden könnte. vorteil wäre, dass weder ein zugriff der komponenten auf das dateisystem oder ein db-system erfolgen muss. es wird einfach ein zähler erhöht und zurückgegeben.

kann man da evtl. was über die Windows-Mitteilungen machen, und wenn, wie erhält der webservice die antwort???

eine andere möglichkeit, die mir grade noch einfällt, wäre die möglichkeit über tcp-verbindungen: auf demselben rechner, auf dem auch der webserver läuft, läuft ein dienst im hintergrund, welcher auf einem port auf anfragen wartet (da lokal, kann ja sogar die firewall unberührt bleiben).
ist aber auch schon ein wenig so wie mit kanonen auf spatzen zu schiessen gg. aber ist noch 'ne alternative.

hoffentlich hat hier noch jemand eine bessere lösung ....

Nobody is perfect. I'm sad, i'm not nobody 🙁

S
8.746 Beiträge seit 2005
vor 17 Jahren

Original von tom-essen
Da bei jeder Anfrage an den WebService einen neue Instanz von diesem im WebServer erstellt wird, und auch die Möglichkeit besteht, dass mehrere Instanzen aufgrund der Anfragen nahezu zeitgleich erzeugt werden, bräuchte ich eine Komponente, auf welche alle Instanzen gleichermassen Zugriff haben und die gleichzeitig auch threadsicher ist.

Das schreit nach Sessions. Damit kannst du sorgen, dass mehrere Aufrufe ein und die gleiche Service-Instanz nutzen. Für Threadsicherheit musst du selbst sorgen. Damit kannst du auch leicht zustandsbehaftete WS basteln.

Load Balacing würde aber die Last auf verschiedene Rechner verteilen. So kannst du natürlich klassisches HTTP-Load Balancing machen (verschiedenen URLs werden zu verschiedenen Rechnern geroutet). Dort hängt dann jeweils ein WCF-Server.

So richtig automatisch geht da aber noch nix. Ich würde erwarten dass da was mit Vista-Server kommt. Applikationsseitiges Load Balancing ist zwar leistungsfähig, aber auch kompliziert. Eigentlich will man ja nur einen LoadBalancer konfigurieren, der dann die Services automatisch verteilen und zugleich die Hosts instanziiert, ohne dass man dafür was tun muss (außer konfigurieren).

Sessions und Load Balancing sind natürlich in Kombination nicht möglich oder sinnvoll, da eine Session performant zur einem Server zugeordnet werden kann. Load Balacing ist also zustandslosen Diensten vorbehalten.

3.170 Beiträge seit 2006
vor 17 Jahren

Wie meinst Du das mit der neuen Instanz?
Wenn es sich um einen ASP.NET Webservice handelt, laufen die alle unter dem aspnet-workerprozess, und der wird nicht beendet. Dann reicht dir ein statischer Member in deiner Webservice-Klasse oder ein Eintrag in der Application[]-Collection. Im Konstruktor kannst Du dann diesen dann durch lock() threadsafe für weitere Auswertungen puffern.

class MyWebService: System.Web.Services.WebService
{
  int selector = 0;
  MyWebService()
  {
     if(Application["Selector"]==null)
     {
        Application["Selector"] = selector;
     }
     else
     {
        lock(Application["Selector"])
        {
          selector = (int)Application["Selector"];
          selector  ++;
          Application["Selector"] = selector;
        }
     }
  }
  /*
  WebMethods
  */
}

Oder hab ich Dich jetzt völlig falsch verstanden?

Non quia difficilia sunt, non audemus, sed quia non audemus, difficilia sunt! - Seneca

I
256 Beiträge seit 2005
vor 17 Jahren

Die Frage ist:

Gibts 1 Server oder mehrere Server wo die Services laufen.

1 Server dann alles kp

meherer Server dann brauchst 1 zentrale DB oder Ähnliches.

lg

3.170 Beiträge seit 2006
vor 17 Jahren

Wenns mehrere Server gibt, kann man einen zentralen Webservice zur Verfügung stellen, der nichts anderes als mein Beispiel von oben tut und dann "selector" per WebMethod zurückgibt. An den können sich dann die verteilten Server wenden 🙂

Non quia difficilia sunt, non audemus, sed quia non audemus, difficilia sunt! - Seneca

tom-essen Themenstarter:in
1.820 Beiträge seit 2005
vor 17 Jahren

Also:
Es gibt einen Rechner, auf dem der IIS läuft.
Dort ist ein WebService hinterlegt.
Wenn nun z.B. zwei externe Rechner zur gleichen Zeit Anfragen an diesen WebService richten, werden doch auch zwei Instanzen des WebService erstellt, oder?

Funktioniert das dann trotzdem mit der statischen Instanz. Es ist doch eher so, als wenn ich zweimal dasselbe Programm starte, oder?

Nobody is perfect. I'm sad, i'm not nobody 🙁

3.170 Beiträge seit 2006
vor 17 Jahren

Wenn das alles auf einem IIS läuft, kannst du so vorgehen, wie ich oben gepostet habe. Der asp.net-Prozess stellt dem Webservice die Appliation-Collection zur Verfügung. So eine Collection gibts einmal für jeden Webservice im IIS. Da der asp-Prozess weiterlebt und nicht beendet wird ausser wenn Du den IIS beendest, ist diese Collection dann quasi für alle Threads statisch.

Andersrum gesagt: Es werden zwar 2 Instanzen des Webservice erdtellt, diese laufen aber im selben Prozesss. Dies ist der ASP-Prozess (aspwp.exe), der weiterlebt un damit Applikationsdaten für den gesamten Webservice halten kann.

Non quia difficilia sunt, non audemus, sed quia non audemus, difficilia sunt! - Seneca

tom-essen Themenstarter:in
1.820 Beiträge seit 2005
vor 17 Jahren

@All:
Erstmal ein grosses Dankeschön für die vielen Tipps und Anregungen.
Ich werd's aber heute nicht mehr ausprobieren, bin irgendwie total fertig.

@MarsStein:
Wenn das hinhaut, ist's genau das, was ich gesucht habe.

Ich melde mich, sobald ich getestet habe 🙂

Nobody is perfect. I'm sad, i'm not nobody 🙁

1.274 Beiträge seit 2005
vor 17 Jahren

Der IIS unterstützt Clustering ab Version 6, out-of-the-box. Dafür werden Anfragen auf verschiedenen Threads ausgelagert, d.h. mehrere Workerprozesse. Man muss halt nur mit dem Sassions aufpassen.

"Das Problem kennen ist wichtiger, als die Lösung zu finden, denn die genaue Darstellung des Problems führt automatisch zur richtigen Lösung." Albert Einstein

I
256 Beiträge seit 2005
vor 17 Jahren

1 Server -> wie MarcStein oder so Ähnlich (unlock nicht vergessen)

3.170 Beiträge seit 2006
vor 17 Jahren

lock(var){...} ist eine Blockanweisung, wenn die geschweifte Klammer geschlossen wird, ist die Variable wieder frei. Ein "unlock" gibts meines Wissens nicht.

Non quia difficilia sunt, non audemus, sed quia non audemus, difficilia sunt! - Seneca

I
256 Beiträge seit 2005
vor 17 Jahren

wieder was dazu gelernt ^^ 😉