ird meg azt az 5 soros java progit ami felhuz 1000 thread-et, es nezd meg, tenyleg annyira eroforras zabalo-e? ... mondjuk megirtad es megnezted, ugye hogy nem? :) Persze az marlehet az, hogy mit csinalnak azok a thread-ek, mit hogy programoz bele az ember. De onmagaban az 1k-10k thread nem sok. A sok akkor lesz, ha ezek egyszerre akarnak valamit csinalni, es nyilvan nem fognak egyszerre idot kapni a proci-tol, es a processzor fugvenyeben x thread tud elfutni parhuzamosan, a tobbi meg sorra kerul, ahogy utemezesre kerult. ennyi.
az rettento okos megoldas, es vegulis par ora alatt monjuk vegez is 1 uzenet kikuldesevel :) Es akkor jon a kovetkezo problema, de hat nem csak napi 1-2 uzenetet szeretnenk kikuldeni, es azt szerentnenk hogy a kikuldes idejeben kapja meg mindenki, ne reggel az 1ik, delutan a masik :) Te sem orulnel, ha elmennel jegyet venni vhova, es mivel a Te arusod nem kapna meg az uzit, hogy dehat mar nincs hely, ezert eladna neked ;) Szoval az otleted szuper, csak mindenen oldalrol verzik, es onmagaban is rossz, raadasul nem megoldas a problemara, hanem a labtorlo ala sepres tipukus esete. (jooooolesssszazjozsikam)
ha az lenne a probléma, hogy az 1000 kliens a saját feje után bármikor kérdezgetheti a szervert, akár egyszerre is, és ez okoz a szerveren torlódást, arra pont megoldást jelent ha nem a kliens szólítja a szervert hanem fordítva, és nem külön szálakról hanem 1 szálról, egymás után, így egyszerre mindig 1 klienssel kommunikál
előferdülhet olyan szituáció, hogy nem kell a változásról minden klienst értesíteni, hanem csak mondjuk 10-et, a többi 990-nek ez a konkrét változás nem kell, viszont kell másik változásról infó, ilyenkor lehet hogy mégis jobb ha a szerver hívja a klienst
Azonban ez nem muproblema. Lattam, hogy SE-ben RMI-vel megy a dolog, EE-ben is szertettem volna implementalni, elvezve az ejb kontener adta elonyoket. Erre kerdeztem ra. Talan az aszinkron hivasu webservice lesz a megoldas. Nem is tudom hogyan lehetne kivitelezni enlkul. Talan lenne egy frissites gomb, amit kelloen gyakran kene nyomogatni a kliensen? Vagy pl 5 masodpercenket kerdezne a klens a szervert, hogy van e valami ujdonsag? Ezt ereztem eroltetettnek. Ha maskeppen nem tudom megcsinalni ez lesz. Ez esetben is talan az 5s-es kerdezgetes. Ez van.
egyaltalan nem akarlak lebeszelni arrol, hogy a szerver hivja a kliens. arra akarok ramutatni, hogy sok kliens eseten olyan hogy realtime nincs. olyan hogy 10sec-en belul garantaltan, olyan sincs. olyan hogy altalaban par masodpercen belul, olyan letezhet, de partiz kliens felett komoly problemakat kell megoldani, es ezek a problemak a ki hiv kit tematol fuggetlenek.
ha csak partiz kliens van, akkor tenyleg hotmindegy.
muproblemakon meg nem szeretek agyalni, mert letukbol eredoen aluldefinialtak, es a felveto menetkozben ugy valtoztatja oket, hogy az o szaja ize szerinti valasz szulessen.
en is pont ezt irtam az elobb a hagyomanyos szerver-kliens architektura sem oldja meg az 1000 kliens problemajat, raadasul elveszik a realtime lehetosege. A a tul sok konnekt a hagyomanyos szerver-kliens esten is eloall. (ezt kezeltetned te a webkontenerrel, ha jol ertem)
Valoban nem foglalkoztam azzal, hogy mi van akkor, ha tul sok a konnekt, de az a helyzet, hogy ha jol tervezem a kodot nagyon-nagyon keves adatot kell lekernie a kliensnek, ha valtozas van a szerveren. (par boxnak a koordinatajat)
Le akarsz beszelni arrol, hogy a szerver hivja a klienst, a sok kliens problemaja miatt. De nekem legalabb annyira fontos a realtime frissules. Ragaszkodnom kell, a par masodperces (jo, legyen 10s :) ) klienoldali frissuleshez. Ezt a lehetoseget nem adja a szerver-kliens rendszer. Megnezem az aszinkron webservice-os dolgot, hatha o az en emberem.
1. ez fontos szempont, nem abban a tekintetben, hogy "sok" kliensre szamitok, hanem mert tanulom az EE-t, es szeretnem kiprobalni klaszteren is a kodot? Nagyon nagy pofatlansag lenne a reszemrol, ha megkernelek, hogy reszletezd egy kicsit, miert nem klaszterezheto ekkor az alkalmazas? :))) (nagyon bizonytalan vagyok meg ezen a teruleten. elkepzelem most a stateful bean-eket, amikkel kiszolgalnam a klienseket, esetleg lenne valami egyke POJO, ami meg beekelodne a beanek, es a kliens koze.... Miert veszitenem el ekkor a custer lehetoseget?)
2. Pl egy chatszervert szeretnek EE-n kesziteni. :) Egyebkent nem azt akarok. :)
Az "A" kliensnek, mikozben dolgozik a szerverrel, a munkaja soran fontos lenne, hogy ha "B" kliens hozzanyul az "A" kliens szamara erdekes objektumhoz, akkor arrol "azonnal" ertesuljon, mert befolyassal van a munkajara az adott objektumban bekovetkezo valtozas. Egyszerre dolgozna az adott objektumon (persze most nem a JAVA nyelv objektumara gondolok), annak egyik reszen az egyik kliens, masik reszen a masik, de "latniuk" kell real time egymas munkajat
(Azt saccolom, par masodperce keslekedes belefer, de pl egyperces mar nem)
3. vastag kliensek lesznek. Teljes a kod a tulterheleses problemaval kapcsolatban. Nem tudom ezt hogyan kellne kezelnem, de webkontener - azt gondolom - nem lesz a rendszerben.
"A lényeg a lényeg: ilyen megoldást akkor érdemes választani"
Az a baj, hogy van itt egy kenyszer. Realtime kozeli kliensoldali frissules. Szoval a klienseknek "azonnal" latniuk kell a szerveren tortent valtozast.
azt akarod, hogy mind az 1000 kliens 10 masodpercen belul megtudja hogy van valtozas, es 10 masodpercen belul le is toltse a frissitest.
Ehhez masodpercenkent legalabb 100 klienst kell tudj ertesits, es szinten masodpercenkent 100 klienst ki is kell szolgalj a frissitessel.
Ha a frissites csak 10kByte, akkor is 8Mbit/sec-cel kell tolj _atlag_.
Ha egy kliens kiszolgalasa csak 100msec, akkor ha idealisan el vannak osztva a 10masodpercbe, akkor 10-et kell egyszerre kiszolgalj. De ha ok dontik el hogy mikor kernek frissitest, valamint a sok konkurrens kerestol lelassulsz, akkor elougorhat a szituacio, hogy sok szaz konkurrens kerest kell kezelj. Es ennek nullarol nekiugorva kicsi az eselye hogy jo lesz. Nagyon igaza van Angyalhentesnek, hogy pl egy HTTP, annak a kliens es szerver oldali implementacioi pont jol megoldjak ezt a kerdest.
En most ugy csinalnam, hogy csinalnek egy egyszeru szervletet. Ezt hivja a kliens, es a szervlet nem valaszol semmit. Ha eltimeoutol, akkor a kliens ujrahivja es kesz. Igy minden kliensnek van egy elo kapcsolata a szerverhez allandoan, amin nem tortenik semmi. Ha a szerveren valtozas van, akkor errol ertesitjuk a fuggo szervleteket, akik osszeszedik a frissitest, es visszaadjak a kliensnek. A kliens megeszi a gombocot, es kezdi elolrol. Igy a szervlet kontener problemaja lesz kezelni a sok konneksont, eldonteni hogy hanyat varakoztat, hanyat szolgal ki egyszerre. Es nem kellett kulon a notification, meg utanna a refresh, hanem a notification egyben a refresh es kesz.
1. Egy normális kliens-szerver felállásban ha sok a kliens, be lehet rakni még egy szervert clusterbe. (Normálisan megírt applikációk esetén.) Na, ennek helyből búcsút inthetsz, ha a kliens hívja a szervert.
2. Miért is olyan fontos, hogy a kliens azonnal tudjon minden változásról? Valójában az esetek 99.9%-ában egyáltalán nem fontos. Egyáltalán, mit jelent az, hogy azonnal?
3. Ha a szerver túl van terhelve, akkor ha rendes HTTP-t használsz, akkor maga a container gondoskodik a megfelelő várakoztatásról, és még ha azon is túlcsúszol, a kliensnek amúgy is tudnia kell kezelni azt, amikor a szerver visszautasítja egy-egy kérését. A másik esetben viszont ezt neked kell megoldanod, és jó eséllyel a barkács megoldás gyengébb lesz.
A lényeg a lényeg: ilyen megoldást akkor érdemes választani, ha a felek valóban egyenrangúak (klasszikus peer-to-peer), vagy ha korlátozott (leginkább fix) számú kliensed van. Például amikor két, clusterbe kötött szerver kommunikál egymással vagy egy virtuális POS terminálnál, amikor a bank és a bolt szervere a háttérben cseveg, miközben a klienseket az egyikről a másikra irányítják, majd vissza.
szerintem van egy kis logikai ficam abban amit irsz. a problemat (1000=tulSok kliens problemaja) abbol eredezteted, hogy a "szerver hivja a klienst"(tovabbiakban SZHK), es igy "egyszerre" kell kiszolgalnia tul sok klienst.
Na de en pont azert eroltetnem ezt az SZHK-t, hogy azonnal tudjon rola a kliens, ha valtozas van a szerveren. Rendben, akkor ne SZHK legyen, hanem hagyomanyos szerver-kliens megoldas. Na akkor azt, hogy a kliens "gyorsan" ertesuljon arrol, ha a szerveren valtozas van, ugy lehet megoldani, hogy nagyon pici "pihenoidokkel" kerdezgeti a szervert, hogy valtozott e valami. A nagyon pici idointervallumok miatt megintcsak ott vagyunk, hogy "egyszerre" hivja az 1000 kliens a szervert, amikor valtozott a szerveren valami, es a szervernek ki kell szolgalnia a klienseket a valtozas miatt!!! Raadasul meg a kliensek folyamatosan bombazzak a "valtozott valami a szerveren?" kerdeseikkel a szervert.
az a helyzet, hogy a kommunikacio eszkoze egy megoldando es megoldhato kerdes. skalazasilag az az igazi problema, hogy ha van 1000 kliens beregisztralva, es tortenik egy valtozas, amirol mindet ertesiteni kell, es netalantan utanna mindegyiknek frissitenie kell 500K adatot, akkor azt hogyan csinalod meg hogy ne legyen torlodas, dugulas, memoriaproblemak, szinkronizalasi problemak.
ha egy kliens ertesitese 50msec, akkor is 50sec ha egy threaded sorban hivogatod oket. es meg igy is ha azok azonnal visszajonnek a friss adataikert, es egy ilyen adatot 100msec kiadnod neki, akkor az elso 50sec-ben csak 500-at tudsz kiszolgalni, az 50-edik masodpercben lesz 500 konkurrens keresed folyamatban. ha ettol a 100msec nem 100 hanem 400, akkor meg szebb a helyzet...
De en nem tokolnek itt socket-ekkel. Itt ez a nagyszeru RMI, pont az lenne a lenyeg, hogy szepen transzparensen hivhatja a kliens a szervert es vissza. Nemi nemu elokeszulet utan ugy hivhatjak egymas metodisait, mintha egyazon JVM-en futnanak. Persze a visszafele valo hivasnak feltetele, hogy a kliens csinaljon egy ilyet: UnicastRemoteObject.exportObject(this, 0);
Koszi a kodot. Sajnos a hangsuly nem azon van, hogy hogyan lehet egy remote interface-es szerver EJB-jet tavolrol megszolitani, bar mint kezdo, szivesen latom ezt a kodot is, hanem, hogy hogyan hivhatja vissza a szerver a klienst. (es nem is arrol van szo, hogy a szervetoldali metodus visszaad erteket, hanem hogy meghiv egy kliensoldali metodust. A referenciat a kliensoldali objektumra a szerver akkor szerzi meg a klienstol, amikor a kliens hivja a szerveroldali metodust, parameterkent kuldve egy kliensoldali objektum referenciajat. Legalabbis SE "alatt" RMI-vel ez igy mukodik.)
Par evvel ezelott pontosan ilyen dolgot csinaltam. Roviden osszefoglalva a tapasztalataim:
- A kliens meghivja a szervert, beregisztral es onnantol azon a csatornan keresztul kommunikalnak.
Ettol eltero megoldas eseten biztos lehetsz benne, hogy a skalazhatosag ugrik vmint a szerver registry-nek a karbantartasa nagyon macerassa valik.
- Amennyiban a szervernek nagy teljesitmennyell kell megbirkoznia (100+ request / masodperc), akkor csak is az io multiplexing johet szoba.
Ha nincs kedved a java.nio-val implementalni (ha vmi sajat dolgot csinalsz szerintem egyszer mindenkepp megeri, hogy tudd, hogyan mukodik), akkor egy jo alternativa lehet a netty. Vmint a java7-es nio2 minden bizonyara erdekes lehet, bar en meg nem hasznaltam.
- Ha szerver oldalrol kezdemenyezett adatkuldeseket szeretnel, akkor megint csak io multiplexing a non-blocking tulajdonsaga miatt.
Emellett van egy eleg kozismert megvalositasa ennek a http stateless protokollon keresztul: comet. Egyik legismertebb esete ennek az ajax.
halaloszto emlitette ezt az asszinkron webservice-os megoldast? Nem lenne megoldas erre a problemara, ha a szerver is asszinron modon hivna a klienst. Raadasul a szerver csupan annyi infot kozolne a klienssel, hogy frissitse az adatait, tehat valami olyan tavoli metodusat hivna a kliensnek, aminek nem lenne visszateresi erteke, azonnal visszaterne, esetleg a kliens egy masik szalon kezdemenyezne a szervertol a friss adatok lekereset.