Olen tässä tutustunut hieman J2EE arkkitehtuuriin, ja nyt ajattelin "nipottaa" eräästä ykityiskohdasta.
-Jsp -sivun pn oltava nk. thread safe, koska palvelin luo servlet oliosta vain muutaman (yleensä yhden) ilmentymän. Tätä ilmentymää kierrätetään sitten monessa sessiossa, joita jokaista ajetaan omassa threadissään.
-Tämä on loogista, sillä mikäli palvelimen annettaisiin vapaasti luoda aina uusi ilmentymä, niin koneen muisti/stack saattaisi loppua, ja tästä aiheutuisi turvariski.
-Useinhan palvelinarkkitehtuureissa esim. yhteydet (serversocket) poolataan taulukkoon, eikä jokaista yhteyttä varten perusteta näin aina omaa uutta säiettä. Näitä sitten kierrätetään, ja mikäli kaikki on käytössä, loput pyynnöt laitetaan joko jonoon odottamaan, tai sitten ne hylätään. Tämä juuri yllämainitusta syystä.
-Nyt esim. jsp:ssä, jos olio käyttää metodeissaan instanssimuuttujia, ne täytyy synkronoida. --> pullonkaula. Pullonkaulan välttämiseksi tarvittavista metodiparametreista voidaan luoda oma luokkansa, ja parametrit välitetään metodille luomalla luokasta aina uusi ilmentymä. Ratkaisu on "thread safe".
esim.
public void foo(Fooparameters foodata){
//do something with the foodata
}
%>
-Ok, siinä lyhyesti teoria. Toivottavasti siitä tajuaakin jotain. Sitten kritiikkiin...
-On ymmärrettävää että säieturvallisia ratkaisuja tarvitaan. Silti tuntuu siltä, että tässä kierretään alkuperäinen syy luoda olioista vain yksi instanssi, ja synnytetään taas uudelleen riski pinon täyttymiselle.
-Mikäli instanssi kerran laitenaan luomaan aina uuden olion (jokainen sessio luo oman dataolionsa), niin mitä järkeä oli alunperin rajoittaa jsp-instanssit yhteen/muutamaan?
-Ok, tuollaiset dataioliot ovat lyhytaikaisia, mikäli roskienkeruu toimii kunnolla ja kooltaan usein pienempiä kuin esim. koko servletin muodostama uusi instanssi , mutta silti niiden käyttäminen jättää meille turva-aukon, jota alunperin yrittiin välttää rajoittamalla servlet-instanssien määrää. Ohjelmoijan pitäisi siis tällöin itse raknetaa kontrolli /pooli/factory itseluomilleen instansseille. Tämä on toki mahdollista, mutta miksi näin on, kun kerran j2ee containereiden pitäisi nimenomaan huolehtia tällaisista asioista automaattisesti?
-Eli käsittääkseni servletolioiden määrän rajoittaminen ei poista ongelmaa, se vain siirtää mahdollisesti aihetuvaa ylivuototilannetta tuonnemmaksi --> virheen etsiminen hankaloituu.
-En mene vannomaan etteikö asiaa olisi jollain tavalla hoidettu. Olen myös saattanut ymmärtää koko asian väärin. Jos joku tietää enemmän tästä, niin kuulisin mielelläni siitä.
-Jsp -sivun pn oltava nk. thread safe, koska palvelin luo servlet oliosta vain muutaman (yleensä yhden) ilmentymän. Tätä ilmentymää kierrätetään sitten monessa sessiossa, joita jokaista ajetaan omassa threadissään.
-Tämä on loogista, sillä mikäli palvelimen annettaisiin vapaasti luoda aina uusi ilmentymä, niin koneen muisti/stack saattaisi loppua, ja tästä aiheutuisi turvariski.
-Useinhan palvelinarkkitehtuureissa esim. yhteydet (serversocket) poolataan taulukkoon, eikä jokaista yhteyttä varten perusteta näin aina omaa uutta säiettä. Näitä sitten kierrätetään, ja mikäli kaikki on käytössä, loput pyynnöt laitetaan joko jonoon odottamaan, tai sitten ne hylätään. Tämä juuri yllämainitusta syystä.
-Nyt esim. jsp:ssä, jos olio käyttää metodeissaan instanssimuuttujia, ne täytyy synkronoida. --> pullonkaula. Pullonkaulan välttämiseksi tarvittavista metodiparametreista voidaan luoda oma luokkansa, ja parametrit välitetään metodille luomalla luokasta aina uusi ilmentymä. Ratkaisu on "thread safe".
esim.
public void foo(Fooparameters foodata){
//do something with the foodata
}
%>
-Ok, siinä lyhyesti teoria. Toivottavasti siitä tajuaakin jotain. Sitten kritiikkiin...
-On ymmärrettävää että säieturvallisia ratkaisuja tarvitaan. Silti tuntuu siltä, että tässä kierretään alkuperäinen syy luoda olioista vain yksi instanssi, ja synnytetään taas uudelleen riski pinon täyttymiselle.
-Mikäli instanssi kerran laitenaan luomaan aina uuden olion (jokainen sessio luo oman dataolionsa), niin mitä järkeä oli alunperin rajoittaa jsp-instanssit yhteen/muutamaan?
-Ok, tuollaiset dataioliot ovat lyhytaikaisia, mikäli roskienkeruu toimii kunnolla ja kooltaan usein pienempiä kuin esim. koko servletin muodostama uusi instanssi , mutta silti niiden käyttäminen jättää meille turva-aukon, jota alunperin yrittiin välttää rajoittamalla servlet-instanssien määrää. Ohjelmoijan pitäisi siis tällöin itse raknetaa kontrolli /pooli/factory itseluomilleen instansseille. Tämä on toki mahdollista, mutta miksi näin on, kun kerran j2ee containereiden pitäisi nimenomaan huolehtia tällaisista asioista automaattisesti?
-Eli käsittääkseni servletolioiden määrän rajoittaminen ei poista ongelmaa, se vain siirtää mahdollisesti aihetuvaa ylivuototilannetta tuonnemmaksi --> virheen etsiminen hankaloituu.
-En mene vannomaan etteikö asiaa olisi jollain tavalla hoidettu. Olen myös saattanut ymmärtää koko asian väärin. Jos joku tietää enemmän tästä, niin kuulisin mielelläni siitä.
Vastaukset 1
Vanhimmat
> -Nyt esim. jsp:ssä, jos olio käyttää
> metodeissaan instanssimuuttujia, ne täytyy
> synkronoida. --> pullonkaula.
Instanssimuuttujien tekeminen servleteissä on yleensä aina huono idea(tm) ja logiikka tulisi aina sijoittaa erillisiin luokkiin, ei näkymän luovaan JSP-sivuun. Myös synkronointia tulisi välttää jos vain mahdollista.
Servlettejä voi kuitenkin ajaa myös instansseittain säikeistettynä:
http://java.sun.com/products/servlet/2.2/javadoc/javax/servlet/SingleThreadModel.html
Tai JSP-sivulla asetuksella:
Ennen kuin jatkan eteenpäin, kannattaa tutustua Sunin J2EE blueprinttiin JSP:n virheistä:
http://java.sun.com/blueprints/guidelines/designing_enterprise_applications_2e/web-tier/web-tier3.html#1097924
Eli JSP-sivulle pystyy kyllä kirjoittamaan Java-koodia, mutta sitä tulisi välttää kuin ruttoa. Hyviä syitä löytyy ylläolevasta dokumentista. JSP sivu on vain MVC:n näkymäosa, eikä sen pitäisi sisältää mitään logiikkaa.
Lyhennettynä seuraavanlaisia merkkijonoja tulisi välttää JSP-sivulla:
> -Mikäli instanssi kerran laitenaan luomaan aina
> uuden olion (jokainen sessio luo oman
> dataolionsa), niin mitä järkeä oli alunperin
> rajoittaa jsp-instanssit yhteen/muutamaan?
Servletit monesti toteuttavat niin simppeliä logiikkaa ja niitä pyydetään jatkuvalla syötöllä, että useimmiten tuosta poolaamisesta on hyötyä. Tietysti jos jokainen servletin http-kutsu johtaa johonkin jättipäivityksiin tietokantojen puolella, niin silloin siitä ei niin suurta hyötyä olekaan.
> -Ok, tuollaiset dataioliot ovat lyhytaikaisia,
> mikäli roskienkeruu toimii kunnolla ja kooltaan
> usein pienempiä kuin esim. koko servletin
> muodostama uusi instanssi , mutta silti niiden
> käyttäminen jättää meille turva-aukon, jota
> alunperin yrittiin välttää rajoittamalla
> servlet-instanssien määrää.
Tarkoitit varmaankin juuri toisinpäin? Eli että instanssien jako aiheuttaa instanssimuuttujien näkymistä muillekin servletin kutsujille?
Ratkaisu on simppeli: Älä käytä luokka- tai instanssimuuttujia servleteissä. Muistinkäytöllisesti metodin sisäiset oliot ovat lyhytaikaisia ja ne kerätään tehokkaasti gc:n toimesta, siitä ei kannata huolestua.
> -Eli käsittääkseni servletolioiden määrän
> rajoittaminen ei poista ongelmaa, se vain
> siirtää mahdollisesti aihetuvaa
> ylivuototilannetta tuonnemmaksi --> virheen
> etsiminen hankaloituu.
Ylivuoto-ongelma on Javassa varsin olematon, JVM pitää tästä huolen. Jos taas tarkoitat muistivuotoa, niin sekään ei ole ongelma niin kauan, kun kysymys on metodin sisäisistä lyhytaikaisista olioista, jotka siivotaan heti seuraavan keruun aikana.
Jos oikeasti olet kiinnostunut tutkimaan hyviä tapoja toteuttaa web kerros J2EE-maailmassa, niin suosittelen seuraaviin ratkaisuihin tutustumista:
Komponenttipohjainen ratkaisu (3 sukupolvi):
- Jakarta Tapestry
- Sun JavaServer Faces & JSTL
Tapahtuma-pohjainen ratkaisu (2 sukupolvi):
- Jakarta Struts
- OpenSymphony WebWork & SiteMesh