Avatar billede jespersahner Nybegynder
26. juni 2008 - 16:09 Der er 10 kommentarer og
1 løsning

Multiple threads og server-requests håndtering

Jeg har en applikation, som anvender multiple threads, der foretager requests mod en server (via SOAP interface). Serveren tillader kun et vist antal requests pr. min, så jeg har behov for at sætte mine requests i kø. Hvordan gør jeg det bedst? Jeg kan godt lave noget selv, men jeg tænker, at der en almindelig/vedtagen måde at gøre det på.

Lidt overordnet:
Er det ualmindeligt, at funktionaliteten foretages på server-siden, altså at serveren sørger for at blokere indkomne kald og først returnerer, når kaldene er igennem? - det ville alt andet lige i den her situation gøre livet lettere på klient-siden, tænker jeg.
Avatar billede arne_v Ekspert
26. juni 2008 - 17:18 #1
Jeg mener at Tomcat konfiguration indeholder N tråde der processer requests og M requests
der venter i kø.

http://tomcat.apache.org/tomcat-5.5-doc/config/http.html

acceptCount   

The maximum queue length for incoming connection requests when all possible request processing threads are in use. Any requests received when the queue is full will be refused. The default value is 100.

maxThreads   

The maximum number of request processing threads to be created by this Connector, which therefore determines the maximum number of simultaneous requests that can be handled. If not specified, this attribute is set to 200.
Avatar billede arne_v Ekspert
26. juni 2008 - 17:20 #2
Hvis du skal styre det client side, så skal du have en kø.

Hvis du er på nyere Java version, så er der en masse goodies i java.util.concurrent
package.
Avatar billede arne_v Ekspert
26. juni 2008 - 17:25 #3
Hvis jeg skulle skyde fra hoften på et design så:

2 queues
en med requests der venter
en med requests der er behandlet

en thread som fjerner fra færdig køen når de er mere end 1 minut gamle

et antal tråde som hvis
  udestående requests + antal elementer i færdig køen < N
henter en fra vente køen, laver kald og putter i færdig køen med timestamp
Avatar billede jespersahner Nybegynder
26. juni 2008 - 23:15 #4
->arne_v: I mit tilfælde må det blive noget med BlockingQueue. Men jeg er lidt i tvivl om designet. Hvis serveren kaldes uden styr på frekvensen, risikerer requests at blive afvist af serveren, fordi serveren kun tillader et vist antal requests pr. min. Ok, man kan så etablere en kø (sluse) på klient-siden for at undgå dette, men denne løsning begrænser sandsynligvis frekvensen unødigt for at undgå afvisning af requests. En bedre løsning vil være at foretage blocking kald til serveren.

Min applikation involverer Axis2, så jeg tænker, om jeg på klient-siden kan vælge mellem non-blocking/asynkront kald hhv. blocking/synkront kald til serveren?
Avatar billede arne_v Ekspert
27. juni 2008 - 02:33 #5
Det var en løsning til det jeg skitserede 26/06-2008 17:25:13 !

Man kan ikke lave et ægte asynkront web service kald. Man kan lave et kald der sender
request og så bede en tråd der venter på svar om at kalde en metode når den har svaret.
Avatar billede jespersahner Nybegynder
27. juni 2008 - 07:58 #6
->arne_v: Jeg skal lige være sikker på, at jeg forklarer mig rigtigt. I mit tilfælde er serveren en ekstern server, som jeg ikke kan konfigurere. Hvis jeg kalder serveren lidt for hidsigt, bliver jeg afvist. Jeg kan så etablere en kø-løsning på klient-siden, som kompenserer for dette, men måske udnyttes serveren ikke optimalt på denne måde. Selv om det enkelte kald til serveren er blocking, hindrer det ikke afvisningen ved for mange kald. I forhold til blocking/non-blocking er der altså 2 niveauer: det enkelte kald og det samlede antal kald. Det er i forhold til det sidste jeg ønsker blocking-kald - altså hvor serveren blokerer kaldet (holder det tilbage et vist stykke tid, indtil der er grønt lys i forhold til antallet af kald) i stedet for at afvise det.
Avatar billede arne_v Ekspert
28. juni 2008 - 02:57 #7
Det tror jeg at jeg har forstået.

Det jeg skitserer 26/06-2008 17:25:13 er også til client side.

Og det bør sikre at:

antal udenstående requests + antal afsluttede requests indenfor det sidste minut < N

hvilket må sikre at:

antal requests per minut < N
Avatar billede jespersahner Nybegynder
28. juni 2008 - 09:34 #8
->arne_v: Ja, den løsning virker fint på klient-siden. Løsningen udnytter dog ikke nødvendigvis serveren optimalt, idet klienten måske venter med kald, hvor serveren er ledig. Det optimale ville være, hvis køen var på server-siden, så serveren administrerer de indkomne requests og holder dem i stedet for at afvise dem. Jeg kan ikke etablere køen på server-siden, men jeg tænker, om man via kaldet kan fortælle serveren, at den skal holde svaret i stedet for at afvise det?
Avatar billede arne_v Ekspert
28. juni 2008 - 17:26 #9
Forudsat at request processing tid er rimelig lille i forhold til 1 minut, så vil
den ligge ret tæt på de N/minut som er max..

Men det er en kludge. Men sådan er det ligesom givet. Hvis du kontrollerer serveren
kan du lave en masse smart. Har du ingen kontrol over serveren kan du ikke lave
noget. Der er ikke noget i HTTP eller SOAP som giver mulighed for at fortælle
serveren noget om hvad den skal.
Avatar billede jespersahner Nybegynder
28. juni 2008 - 19:30 #10
->arne_v: Ok, fint at få afklaret det sidste, du skriver. Løsningen fungerer fint på klient-siden, og koden bliver i øvrigt ret smidig med java.util.concurrent: Trådene fylder køen med requests uden at tænke på, hvordan køen afvikles, og en selvstændig tråd afvikler køen uden at tænke på, hvordan den er blevet fyldt - fin adskillelse af funktionalitet.

Tak for hjælpen, smid gerne et svar.
Avatar billede arne_v Ekspert
28. juni 2008 - 20:19 #11
svar
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester