Programmering

J2EE-gruppering, del 1

Bedrifter velger Java 2, Enterprise Edition (J2EE) for å levere sine oppdragskritiske applikasjoner over Internett. Innenfor J2EE-rammeverket tilbyr klynger oppdragskritiske tjenester for å sikre minimal nedetid og maksimal skalerbarhet. En klynge er en gruppe applikasjonsservere som kjører J2EE-applikasjonen din som om det var en enkelt enhet. For å skalere, bør du inkludere flere maskiner i klyngen. For å minimere nedetid, må du sørge for at alle komponenter i klyngen er overflødige.

I denne artikkelen vil vi få en grunnleggende forståelse av klynging, klyngemetoder og viktige klyngetjenester. Fordi klyngetilnærminger varierer i bransjen, vil vi undersøke fordelene og ulempene med hver tilnærming. Videre vil vi diskutere viktige klyngerelaterte funksjoner å se etter i en applikasjonsserver.

For å bruke vår nyanskaffede klyngekunnskap til den virkelige verden, vil vi se hvordan HP Bluestone Total-e-Server 7.2.1, Sybase Enterprise Application Server 3.6, SilverStream Application Server 3.7 og BEA WebLogic Server 6.0 implementerer klynger.

I del 2 av denne serien vil vi dekke programmering og failover-strategier for klynger, samt teste våre fire applikasjonsserverprodukter for å se hvordan de skaleres og failover.

Klynger definert

J2EE-applikasjonsserverleverandører definerer en klynge som en gruppe maskiner som jobber sammen for å gi transparente tjenester for bedriften (støtte for JNDI, EJB, JSP, HttpSession og komponent failover, og så videre). De lar definisjonen med vilje være vag fordi hver leverandør implementerer klynging forskjellig. I den ene enden av spekteret hviler leverandører som setter en utsender foran en gruppe uavhengige maskiner, hvorav ingen har kjennskap til de andre maskinene i klyngen. I dette skjemaet mottar avsenderen en innledende forespørsel fra en bruker og svarer med en HTTP-viderekoblingshode for å feste klienten til en bestemt medlemsserver i klyngen. I den andre enden av spekteret bor leverandører som implementerer en sammenslutning av tett integrerte maskiner, med hver maskin fullstendig klar over de andre maskinene rundt den sammen med gjenstandene på disse maskinene.

I tillegg til maskiner kan klynger omfatte overflødige og failover-kompatible:

  • Lastbalansere: Enkelt inngangspunkter i klyngen og trafikkdirektører til individuelle web- eller applikasjonsservere
  • Webservere
  • Gateway-rutere: Utgangspunkter fra et internt nettverk
  • Flerlags brytere: Pakke- og rammefiltre for å sikre at hver maskin i klyngen bare mottar informasjon som er relevant for den maskinen
  • Brannmurer: Klyngebeskyttere fra hackere ved å filtrere tilgang på klyngen og det interne nettverket på portnivå
  • SAN-brytere (Storage Area Networking): Koble applikasjonsserverne, webserverne og databasene til et lagringsmedium for backend; administrere hvilken fysisk disk du vil skrive data til; og failover
  • Databaser

Uansett hvordan de implementeres, gir alle klynger to hovedfordeler: skalerbarhet og høy tilgjengelighet (HA).

Skalerbarhet

Skalerbarhet refererer til applikasjonens evne til å støtte økende antall brukere. Klynger lar deg gi ekstra kapasitet ved å legge til ekstra servere, og dermed sikre skalerbarhet.

Høy tilgjengelighet

HA kan oppsummeres i ett ord: redundans. En klynge bruker mange maskiner for å betjene forespørsler. Derfor, hvis en maskin i en klynge mislykkes, kan en annen maskin overta transparent.

En klynge gir bare HA på applikasjonsservernivået. For at et websystem skal vise ekte HA, må det være som Noahs ark i å inneholde minst to av alt, inkludert webservere, gateway-rutere, bytte infrastruktur og så videre. (For mer om HA, se HA-sjekklisten.)

Klyngetyper

J2EE-klynger kommer vanligvis i to smaker: delte ingenting og delt disk. I en klynge med delt ingenting har hver applikasjonsserver sine egne filsystemer med sin egen kopi av applikasjoner som kjører i klyngen. Programoppdateringer og forbedringer krever oppdateringer i hver node i klyngen. Med dette oppsettet blir store klynger mareritt om vedlikehold når kodetrykk og oppdateringer slippes.

I motsetning til dette bruker en delt diskklynge en enkelt lagringsenhet som alle applikasjonsservere bruker for å skaffe applikasjonene som kjører i klyngen. Oppdateringer og forbedringer skjer i et enkelt filsystem, og alle maskiner i klyngen har tilgang til endringene. Inntil nylig var en ulempe ved denne tilnærmingen dens eneste feilpunkt. Imidlertid gir SAN et enkelt logisk grensesnitt til et overflødig lagringsmedium for å gi failover, failback og skalerbarhet. (For mer om SAN, se sidefeltet for lagringsinfrastruktur.)

Når du sammenligner J2EE-applikasjonsserveres klyngeimplementeringer, er det viktig å vurdere:

  • Klyngeimplementering
  • Klynge- og komponent failover-tjenester
  • HttpSession failover
  • Enkelt feilpunkter i en klyngetopologi
  • Fleksibel topologilayout
  • Vedlikehold

Senere vil vi se på hvordan fire populære applikasjonsservere sammenlignes på forskjellige områder. Men først, la oss undersøke hvert element mer detaljert.

Klyngeimplementering

J2EE applikasjonsservere implementerer klynging rundt implementeringen av JNDI (Java Naming and Directory Interface). Selv om JNDI er kjernetjenesten J2EE-applikasjoner er avhengige av, er det vanskelig å implementere i en klynge fordi den ikke kan binde flere objekter til et enkelt navn. Tre generelle klyngemetoder eksisterer i forhold til hver applikasjonsserveres JNDI-implementering:

  • Uavhengig
  • Sentralisert
  • Delt globalt

Uavhengig JNDI-tre

HP Bluestone Total-e-Server og SilverStream Application Server bruker et uavhengig JNDI-tre for hver applikasjonsserver. Medlemsservere i en uavhengig JNDI-treklynge vet ikke eller bryr seg om eksistensen av andre servere i klyngen. Derfor støttes ikke failover eller leveres gjennom formidlingstjenester som omdirigerer HTTP- eller EJB-forespørsler. Disse mellomtjenestene er konfigurert for å vite hvor hver komponent i klyngen ligger og hvordan du kommer til en alternativ komponent i tilfelle feil.

En fordel med den uavhengige JNDI-treklyngen: kortere klyngekonvergens og enkel skalering. Klyngekonvergens måler tiden det tar for klyngen å bli fullstendig klar over alle maskinene i klyngen og tilhørende objekter. Imidlertid er konvergens ikke et problem i en uavhengig JNDI-treklase fordi klyngen oppnår konvergens så snart to maskiner starter opp. En annen fordel med den uavhengige JNDI-treklyngen: skalering krever bare tillegg av ekstra servere.

Imidlertid er det flere svakheter. For det første er failover vanligvis utviklerens ansvar. Det vil si at fordi hver applikasjonsserveres JNDI-tre er uavhengig, blir de eksterne proxyene hentet gjennom JNDI festet til serveren som oppslaget skjedde på. I henhold til dette scenariet, hvis en metodeanrop til en EJB mislykkes, må utvikleren skrive ekstra kode for å koble til en avsender, skaffe seg adressen til en annen aktiv server, gjøre et nytt JNDI-oppslag og ringe den mislykkede metoden igjen. Bluestone implementerer en mer komplisert form av det uavhengige JNDI-treet ved å gjøre hver forespørsel gjennom en EJB-proxy-tjeneste eller Proxy LBB (Load Balance Broker). EJB-proxy-tjenesten sørger for at hver EJB-forespørsel går til en aktiv UBS-forekomst. Denne ordningen gir ekstra ventetid til hver forespørsel, men tillater automatisk failover mellom metodeanrop.

Sentralisert JNDI-tre

Sybase Enterprise Application Server implementerer en sentralisert JNDI-trekluster. Under dette oppsettet bruker sentraliserte JNDI-treklaser CORBAs CosNaming-tjeneste for JNDI. Navneservere huser det sentraliserte JNDI-treet for klyngen og holder rede på hvilke servere som er oppe. Ved oppstart binder hver server i klyngen objektene sine inn i JNDI-treet, samt alle navneserverne.

Å få en referanse til en EJB i en sentralisert JNDI-treklase er en totrinnsprosess. Først slår klienten opp et hjemmeobjekt fra en navneserver, som returnerer en interoperabel objektreferanse (IOR). En IOR peker på flere aktive maskiner i klyngen som har hjemmeobjektet. For det andre velger klienten den første serverplasseringen i IOR og henter hjemmet og fjernkontrollen. Hvis det er en feil mellom påkallelse av EJB-metoden, implementerer CORBA-stubben logikk for å hente et annet hjem eller fjernkontroll fra en alternativ server som er oppført i IOR, returnert fra navnetjeneren.

Navneserverne demonstrerer selv en svakhet ved den sentraliserte JNDI-treklyngen. Spesielt hvis du har en klynge på 50 maskiner, hvorav fem er navneservere, blir klyngen ubrukelig hvis alle fem navneserverne går ned. De andre 45 maskinene kan faktisk være i gang, men klyngen vil ikke betjene en eneste EJB-klient mens navneserverne er nede.

Et annet problem oppstår ved å bringe en ekstra navneserver på nettet i tilfelle total feil i klyngens originale navneservere. I dette tilfellet krever en ny sentralisert navneserver at alle aktive maskiner i klyngen binder objektene sine til den nye navneserverens JNDI-tre. Selv om det er mulig å begynne å motta forespørsler mens bindingsprosessen finner sted, anbefales ikke dette, da bindingsprosessen forlenger klyngens gjenopprettingstid. Videre representerer hvert JNDI-oppslag fra et program eller en applet virkelig to nettverkssamtaler. Den første samtalen henter IOR for et objekt fra navnetjeneren, mens det andre henter objektet klienten ønsker fra en server som er spesifisert i IOR.

Til slutt lider sentraliserte JNDI-treklaser fra økt tid til konvergens ettersom klyngen vokser i størrelse. Når du skalerer klyngen din, må du legge til flere navneservere. Husk at det generelt aksepterte forholdet mellom navneservermaskiner og totale klyngemaskiner er 1:10, med et minimum antall på to navneservere. Derfor, hvis du har en 10-maskinklynge med to navneservere, er det totale antallet bindinger mellom en server og navneserver 20. I en 40-maskinklynge med fire navneservere vil det være 160 bindinger. Hver bind representerer en prosess der en medlemsserver binder alle objektene sine inn i JNDI-treet til en navneserver. Med det i bakhodet har den sentraliserte JNDI-treklyngen den verste konvergenstiden blant alle JNDI-klyngeimplementeringene.

Delt globalt JNDI-tre

Til slutt implementerer BEA WebLogic et delt globalt JNDI-tre. Med denne tilnærmingen, når en server i klyngen starter opp, kunngjør den sin eksistens og JNDI-treet til de andre serverne i klyngen gjennom IP (Internet Protocol) multicast. Hver klyngemaskin binder gjenstandene til det delte globale JNDI-treet, så vel som sitt eget lokale JNDI-tre.

Å ha et globalt og lokalt JNDI-tre innenfor hver medlemsserver gjør at genererte hjem- og eksterne stubber kan failover og gir raske JNDI-oppslag. Det delte globale JNDI-treet deles mellom alle maskiner i klyngen, slik at enhver medlemsmaskin kan vite den nøyaktige plasseringen av alle objekter i klyngen. Hvis et objekt er tilgjengelig på mer enn én server i klyngen, er et spesielt hjemmeobjekt bundet til det delte globale JNDI-treet. Dette spesielle hjemmet kjenner plasseringen til alle EJB-objekter som den er tilknyttet, og genererer eksterne objekter som også vet plasseringen til alle EJB-objekter som den er tilknyttet.

Den delte globale tilnærmingen har store ulemper: den store innledende nettverkstrafikken som genereres når serverne starter opp og klyngens lange konvergenstid. I kontrast, i en uavhengig JNDI-treklase, viser konvergens at det ikke er et problem fordi ingen JNDI-informasjonsdeling forekommer. En delt global eller sentralisert klynge krever imidlertid tid for alle klyngens maskiner å bygge det delte globale eller sentraliserte JNDI-treet. Faktisk, fordi delte globale klynger bruker multicast for å overføre JNDI-informasjon, er tiden det tar å bygge det delte globale JNDI-treet, lineær i forhold til antall påfølgende servere som er lagt til.

De viktigste fordelene med delt global sammenlignet med sentraliserte JNDI-tresamlinger handler om enkel skalering og høyere tilgjengelighet. Med delt global trenger du ikke å fikle med CPUer og RAM på en dedikert navneserver eller stille inn antall navneservere i klyngen. I stedet for å skalere applikasjonen, er det bare å legge til flere maskiner. Hvis en maskin i klyngen går ned, vil klyngen dessuten fortsette å fungere skikkelig. Til slutt krever hvert eksternt oppslag en enkelt nettverksanrop sammenlignet med de to nettverkssamtalene som kreves i den sentraliserte JNDI-treklyngen.

Alt dette bør tas med et saltkorn fordi JSPer, servlets, EJB og JavaBeans som kjører på applikasjonsserveren, kan dra nytte av å være samlokalisert i EJB-serveren. De vil alltid bruke et JNDI-oppslag i prosessen. Husk at hvis du bare kjører applikasjoner på serversiden, er det liten forskjell mellom de uavhengige, sentraliserte eller delte globale klyseimplementeringene. Faktisk vil hver HTTP-forespørsel havne på en applikasjonsserver som vil gjøre et JNDI-oppslag i prosessen for å returnere ethvert objekt som brukes i server-applikasjonen.

Deretter retter vi oppmerksomheten mot den andre viktige hensynet til J2EE-applikasjonsserveren: klyngetjenester og failover-tjenester.

Klyngetjenester og failover-tjenester

$config[zx-auto] not found$config[zx-overlay] not found