Az előadás letöltése folymat van. Kérjük, várjon

Az előadás letöltése folymat van. Kérjük, várjon

WINDOWS COMMUNICATION FOUNDATION Session és példányosítás.

Hasonló előadás


Az előadások a következő témára: "WINDOWS COMMUNICATION FOUNDATION Session és példányosítás."— Előadás másolata:

1 WINDOWS COMMUNICATION FOUNDATION Session és példányosítás

2 PÉLDÁNYOSÍTÁSI MÓDOK 2

3 PÉLDÁNYOSÍTÁS  A WCF felelős egy bejövő üzenet egy adott szolgáltatás példányhoz kötéséért.  Amikor egy kérés érkezik, a WCF eldönti, hogy egy létező szolgáltatás példány fel tudja-e dolgozni a kérést.  Ennek eldöntésére egy döntési mátrixot állít fel. 3

4 PÉLDÁNYKEZELÉS  Minden szolgáltatásnak van egy példánykezelési modellje.  Három ilyen modell létezik: • az „egyke” (single), amelyben egyetlen CLR objektum szolgálja ki az összes klienst; • a „hívásonkénti” (per call), melyben minden egyes klienshívás kiszolgálására új CLR-objektum jön létre; • és a „munkamenetenkénti” (per session), melynél minden egyes munkamenethez egy kiszolgáló CLR objektum jön létre.  A példánykezelési modell kiválasztása függ az alkalmazás által támasztott követelményektől és a szolgáltatás tervezett használatától. 4

5 PÉLDÁNYKEZELÉS 2.  A példányosítás módjának meghatározása a szolgáltatás oldalon történik, azon belül is a szolgáltatás viselkedésének (Service Behavior) leírójában.  Ez azt jelenti, hogy a szolgáltatás összes végpontjában ugyanez a példányosítási mód lesz érvényes. 5

6 HÍVÁSONKÉNTI (PER CALL) MÓD 6

7  Hívásonként módban minden egyes kérésnek saját szolgáltatás példánya van.  A kliens egy proxyn keresztül intéz kéréseket a szolgáltatás felé.  Amikor a kérés megérkezik a szolgáltatás hoszthoz, a hoszt a szolgáltatást implementáló osztályból létrehoz egy új példányt.  Miután a kérés befejeződött és a válasz is visszaküldésre került a kliens felé, a példányra már nincs szükség.  Minden szolgáltatás leíró osztálynak implementálni kell az IDisposable interfészt. Amikor az adott példány elvégezte a dolgát, meghívódik a Dispose metódus. 7

8 HÍVÁSONKÉNTI (PER CALL) MÓD  A WCF-ben a hívásonkénti mód az alapértelmezett.  Ennek egyik oka, hogy így a fejlesztőnek nem kell foglalkoznia a konkurens feldolgozással.  Viszont számos hátránya is van ennek a módnak: • Teljesítmény szempontjából nem előnyös • Ha egy szolgáltatás példány zárol egy erőforrást a teljes életciklusa idejére, akkor az az erőforrás a többi példány számára elérhetetlenné válik. (pl. fájl, adatbázis, stb.)  A problémák kiküszöbölésére léteznek megoldások. 8

9 HÍVÁSONKÉNTI (PER CALL) MÓD  Az egyik megoldás egy proxy objektum rendelése a szolgáltatáshoz.  Az alapértelmezett programozási modell szerint, ha egy adott szolgáltatás példányra nincs szükség, akkor arra meghívódik a Dispose metódus. Ez érvényteleníti a referenciát, ami nem mindig kívánatos.  A WCF-ben a kliens a proxyra tart fent egy referenciát, ami nem szűnik meg minden hívás után.  A proxy feladata az, hogy a szolgáltatás példányt újra létrehozza, ha szükséges. 9

10 HÍVÁSONKÉNTI (PER CALL) MÓD  A példányosítási mód megadási a szolgáltatás oldalán történik: [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)] class UpdateService : IUpdateService {...}  Habár elméletben a kliensnek nem kell tudnia a példányosítás módjáról, a hívásonkénti példányosítási mód azt jelenti, hogy a hívások között nem őrződik meg az állapot.  Ha bármilyen okból mégis szükség van az állapot megőrzésére, a szolgáltatás feladat biztosítani azt. (pl. adatbázisba mentés) 10

11 MUNKAMENETENKÉNTI (PER SESSION) MÓD 11

12 MUNKAMENETENKÉNTI (PER SESSION) MÓD  Az előbbiekben már felmerült az igény a hívások között az állapotok megőrzésére, így létezik egy munkamenetenkénti (per session) példányosítási mód is.  A WCF képes egy privát session-t létesíteni a kliens és a szolgáltatás példány között.  Minden klienshez az első kérésekor hozzárendelődik egy szolgáltatás példány és elkezdődik egy munkamenet.  Minden további kérés ennek a munkamenetnek a része lesz, és ugyanaz a szolgáltatás példány fogja végrehajtani azt. 12

13 MUNKAMENETENKÉNTI (PER SESSION) MÓD  A munkamenetenkénti mód beállításához 2 dolog szükséges:  A szerződés rögzíti, hogy szükséges a munkamenet. Ez azért fontos, mert a kliensnek tartalmazni kell egy azonosítót, hogy megtalálja az adott szolgáltatás objektumot.  A munkamenetenkénti mód beállítása a szolgáltatás oldalon: [ServiceContract(SessionMode = SessionMode.Required)] public interface IUpdateService { // Interface definition code goes here } 13

14 MUNKAMENETENKÉNTI (PER SESSION) MÓD  A másik dolog:  A WCF-nek is meg kell mondani, hogy munkamenetenkénti módot szeretnénk használni, és a szolgáltatás példányt tartsa meg az egész munkamenet alatt.  Ennek megadása a következőképpen történik: [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession)] public class UpdateService : IUpdateService { // Implementation code goes here } 14

15 MUNKAMENETENKÉNTI (PER SESSION) MÓD  A kapcsolat igazából nem a kliens és a szolgáltatás között áll fenn, hanem egy adott proxy példány között, amit a kliens és a szolgáltatás használ.  Amikor a WCF-ben létrehozunk egy proxyt, annak lesz egy azonosítója, amit a szolgáltatás hoszt arra használ, hogy a kéréseket a megfelelő példányokhoz továbbítsa.  Mivel ez az azonosító a proxy példányhoz rendelt, így ha a kliens egy proxyból több példányt is létrehoz, azok nem alkotnak egy munkamenetet. Minden proxynak saját szolgáltatás példánya lesz. 15

16 MUNKAMENETENKÉNTI (PER SESSION) MÓD  Ahogy már korábban említettük, a szolgáltatás példány addig létezik, amíg a kliensnek szüksége van rá.  Egy munkamenet megszűnésének legtermészetesebb módja, amikor a kliens bezárja a proxyt.  Ekkor egy üzenet kerül elküldése a szolgáltatás felé, hogy a munkamenet lezárult.  De mi van akkor, ha valamilyen okból a kliens nem zárja be a proxyt?  Ebben az esetben a munkamenet 10 percnyi inaktivitás után automatikusan megszűnik. Ezután ha a kliens újra használni szeretné a proxyt, CommunicationObjectFaultedException –t kap. 16

17 MUNKAMENETENKÉNTI (PER SESSION) MÓD  Ez a 10 perc csak egy alapértelmezett érték, a kötéstől függően változhat.  Ha a kötés egy megbízható munkamenetet (reliable session) biztosít, akkor az InactivityTimeout tulajdonságot ennek megfelelően átállíthatjuk.  Erre egy példa: NetTcpBinding binding = new NetTcpBinding(); binding.ReliableSession.Enabled = true; binding.ReliableSession.InactivityTimeout = TimeSpan.FromMinutes(60); 17

18 MUNKAMENETENKÉNTI (PER SESSION) MÓD  Ugyanezt a config fájlban is megtehetjük:  Az InactivityTimeout –ot mind a kliens, mind a szolgáltatás oldalán beállíthatjuk, a kettő közül mindig a kisebb érték a mérvadó.  A basicHttpBinding nem támogatja a munkamenetek létrehozását. 18

19 SINGLETON MÓD 19

20 SINGLETON MÓD  Ebben a módban csak egyetlen szolgáltatás példány jön létre.  Ennek az egy példánynak a feladata az összes szolgáltatás felé beérkező kérés feldolgozása.  Az a példány örökké él, és csak akkor szűnik meg, amikor a hoszt processz bezáródik.  Beállítása: [ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)] public class UpdateService : IUpdateService { // Implementation code goes here } 20

21 SINGLETON MÓD  Singleton módban lehetőség nyílik konstruktoron keresztül inicializálni a példányt.  Arra is lehetőség van, hogy létrehozzuk a szolgáltatás példányt, még mielőtt a hoszt elindul. Induláskor átadjuk ezt a példányt a hosztnak.  A ServiceHost osztály egyik konstruktora egy singleton példányt vár paraméterként. Az így létrehozott hoszt az összes kérést a paraméterében megkapott szolgáltatás példányhoz fogja továbbítani.  Ennek megadása: SingletonUpdateService singletonInstance = new SingletonUpdateService(); ServiceHost host = new ServiceHost(singletonInstance); host.Open(); 21

22 SINGLETON MÓD  Ilyen módban más objektumoknak lehetőségük van arra, hogy elérjék a szolgáltatás példány metódusait és beállítsák a paramétereit.  A ServiceHost osztály ehhez biztosít egy SingletonInstance property-t, ami az adott példányra hivatkozik. SingletonUpdateService instance = host.SingletonInstance as SingletonUpdateService; instance.Counter += 50; 22

23 SINGLETON MÓD  Ha a lokális hoszt változó nem elérhető, a példány akkor is elérhető. Az OperationContext osztály biztosít egy readonly Host property-t, amiből ugyanúgy elérhető a példány. ServiceHost host = OperationContext.Current.Host as ServiceHost; if (host != null) { SingletonUpdateService instance = host.SingletonInstance as SingletonUpdateService; if (instance != null) instance.Counter += 1; } 23

24 SINGLETON MÓD  Ha minden kérést egyetlen példány szolgál ki, akkor oda kell figyelni a konkurrens hozzáférésre.  Ha egy szolgáltatáshoz egyszerre több kérés érkezik, ugyanaz a példány fogja őket feldolgozni, csak különböző szálakon.  Ez azt jelenti, hogy az aktuális metóduson kívüli összes változót (az osztály adattagjait) egyszerre több szál is módosíthatja, aminek hatására az értékük nem lesz megfelelő.  Ennek elkerülésére különböző technikákat érdemes használni, mint pl. zárolás. 24

25 MUNKA A PÉLDÁNYOKKAL 25

26 A SZOLGÁLTATÁS MEGVÉDÉSE  Amikor egy szolgáltatás kikerül egy valós közegbe, akarva – akaratlanul is érhetik támadások.  „Denial of Service” (DoS) támadás: kimeríti a szolgáltatás erőforrásait, hogy az több bejövő kérést már ne tudjon feldolgozni.  A WCF az ilyen problémák enyhítésére számos megoldást nyújt: pl. a bejövő kérések lelassításával, gátolásával vagy erőforrás kvótákkal 26

27 BEJÖVŐ KÉRÉSEK GÁTOLÁSA  Ennek a megoldásnak a célja kétszeres.  Először is megvédi a szolgáltatást attól, hogy a kliensek elárasszák kérésekkel.  Másrészt pedig egyenletes terhelés elosztást biztosít a szolgáltatásnak.  Ezt úgy valósítják meg, hogy korlátozzák a szolgáltatáshoz beérkezhető kérések számát azért, hogy azokat a szolgáltatás belátható időn belül fel tudja dolgozni.  A WCF alapbeállítása, hogy nem gátolja a bejövő kéréseket.  Ha a gátolás engedélyezett, akkor a WCF minden egyes bejövő kérésnél ellenőrzi a számlálót. 27

28 BEJÖVŐ KÉRÉSEK GÁTOLÁSA  A WCF alapbeállítása, hogy nem gátolja a bejövő kéréseket.  Ha a gátolás engedélyezett, akkor a WCF minden egyes bejövő kérésnél ellenőrzi a számlálót.  Ha túllépte a beállított értéket, akkor a tovább kéréseket egy várakozó sorra teszi.  Amint a számláló értéket a küszöbérték alá csökken, sorra veszi a következőt a várakozási sorról olyan sorrendben, ahogy a kérések beérkeztek.  Általában ha a szolgáltatás elérte a maximális értékét, akkor a kliens request time out-ot kap. 28

29 BEJÖVŐ KÉRÉSEK GÁTOLÁSA  A szolgáltatás leírójában 3 beállítás kontrollálja a szolgáltatás által egy időben feldolgozható kérések számát.  Ezek mindegyike a config file ServiceThrottlingBehavior részében található.  Ezek a következők: • MaxConcurrentCalls: szabályozza az egyszerre feldolgozható kérések számát. Alapértéke 16. Ez az érték minden típusú kérésre érvényes. • MaxConcurrentSessions: szabályozza a sessiont igénylő csatornák maximális számát. Alapértéke 10. Ezen túli session igénylés TimeoutExepction-t dob. Ha a beérkező kérés típusa nem alkalmas session kezelésre (pl. basicHttpBinding), akkor ennek az értéknek nincs jelentősége. • MaxConcurrentInstances: a szolgáltatás példányok maximális számát adja meg. Alapértéke Int32.MaxValue. Ennek hatása a példányosítás módjától függ. Munkamenetenkénti esetben a MaxConcurrentSession érték a mérvadó, Singleton módban pedig az érték mindig 1. 29

30 BEJÖVŐ KÉRÉSEK GÁTOLÁSA  Beállítása a config fájlban: 30

31 BEJÖVŐ KÉRÉSEK GÁTOLÁSA  Beállítás kódból: ServiceHost host = new ServiceHost( typeof(UpdateService),new Uri("http://localhost:8080/UpdateService")); host.AddServiceEndpoint( "IUpdateService",new WSHttpBinding(), String.Empty); ServiceThrottlingBehavior throttlingBehavior = new ServiceThrottlingBehavior(); throttlingBehavior.MaxConcurrentCalls = 10; throttlingBehavior.MaxConcurrentInstances = 10; throttlingBehavior.MaxConcurrentSessions = 5; host.Description.Behaviors.Add(throttlingBehavior); host.Open(); 31

32 BEJÖVŐ KÉRÉSEK GÁTOLÁSA  A szolgáltatás hoszt megnyitása után lehetőség van a bejövő kérések gátolási beállításainak megtekintésére, de azok módosítására nem.  Ezt a szolgáltatás diszpécserén keresztül tehetjük meg.  A ServiceHost osztály a ChannelDispatchers propertyjében diszpécserek egy kollekcióját biztosítja, amely ChannelDispateched objektumokat tartalmaz.  A ChannelDispatcher objektumnak van egy ServiceThrottle tulajdonsága. Ezen a ServiceThrottle objektumon keresztül elérhetőek az összes beállítások. 32

33 BEJÖVŐ KÉRÉSEK GÁTOLÁSA  A beállítások elérése a következőképpen történik: ChannelDispatcher dispatcher = OperationContext.Current.Host.ChannelDispatchers[0] as ChannelDispatcher; ServiceThrottle throttle = dispatcher.ServiceThrottle; Trace.WriteLine(String.Format("MaxConcurrentCalls = {0}", throttle.MaxConcurrentCalls)); Trace.WriteLine(String.Format("MaxConcurrentSessions = {0}", throttle.MaxConcurrentSessions)); Trace.WriteLine(String.Format("MaxConcurrentInstances = {0}", throttle.MaxConcurrentInstances)); 33

34 KVÓTÁK  A kvóta mechanizmus magában foglalja a szolgáltatás által felhasznált memória menedzselését is.  A DoS lényege, hogy hatalmas mennyiségű memóriát emészt fel, így a szolgáltatás már nem tudja kiszolgálni a további bejövő kéréseket, melyek így OutOfMemoryException vagy StackOverflowException kivételeket kapnak.  Amikor beállítunk egy kvóta értéket, QuotaExceededException keletkezik.  Ahelyett, hogy ilyenkor a szolgáltatás leállna, csak szimplán figyelmen kívül hagyja az üzenetet, és megy tovább. 34

35 KVÓTÁK  Számos beállítás van hatással a kvótára: • MaxReceivedMessageSize: ez közvetlenül a kötésre állítódik be. Megadja, hogy mekkora lehet egy üzenet mérete. Alapértéke 65536 byte. Értékét akár a config fájlból, akár kódból is beállíthatjuk. o Config fájlból: 35

36 KVÓTÁK o Kódból: NetTcpBinding binding = new NetTcpBinding(); binding.MaxReceivedMessageSize = 128000; ServiceHost host = new ServiceHost( typeof(UpdateService), new Uri("net.tcp://localhost:1234/UpdateService")); host.AddServiceEndpoint( "IUpdateService",binding, String.Empty); host.Open(); 36

37 KVÓTÁK • ReaderQuotas: a kötés ezen tulajdonsága a beérkező üzenetek komplexitásának mértékét határozza meg. o Beállítható tulajdonságok: 37 PropertyAlapértékLeírás MaxDepth32Megadja, hogy az üzenet node-jai milyen mélységig mehetnek le. MaxStringContentLength8192Az üzenetben lévő leghosszabb string max értéke. MaxArrayLength16384Maximum hány érték lehet egy tömbben. MaxBytesPerRead4096Max hány byte értékkel térhet vissza a Read. MaxNameTableCharCount16384Táblanév max hossza.

38 MŰVELETEK ELHATÁROLÁSA  Alapértelmezetten egy session csak azt jelenti, hogy a szolgáltatás meg tudja állapítani, hogy melyik klienstől érkezett a kérés.  Azonban vannak esetek, amikor a műveletek végrehajtási sorrendje is számít.  A WCF biztosít erre egy mechanizmust a szerződés tervezőjének, mellyel megadhatja, hogy mely metódusok nem lehetnek elsők, vagy utolsók. Erre az IsInitiating és az IsTerminating propertyk szolgálnak, melyeket a OperationContract attribútumon belül állíthatunk.  Ha egy metódus IsInitiating attribútum értéke true, és még nem jött létre session, a metódus hívásakor, akkor egyből létrejön egy. Ha már létezik session, akkor a metódus azon belül hívódik meg. 38

39 MŰVELETEK ELHATÁROLÁSA  Ha a metódus IsTerminating attribútum értéke true, amikor a metódus befejezi futását, a session lezárul. Ez még nem jelenti azt, hogy megszűnik a szolgáltatás példány, a kliensnek ettől függetlenül még meg kell hívniuk a proxy Close metódusát. Habár minden további utasítás efelé a proxy felé InvalidOperationException-nel tér vissza.  Ezekkel a propertykkel beállítható a műveletek kezdő és végpontja.  Az IsInitiating alapértéke true, az IsTerminating alapértéke false. 39

40 MŰVELETEK ELHATÁROLÁSA  Beállítása: [ServiceContract(SessionMode = SessionMode.Required)] public interface IProcessOrders { [OperationContract] void InitializeOrder(int customerId); [OperationContract(IsInitiating=false)] void AddOrderLine(string productId, int quantity); [OperationContract(IsInitiating=false)] double GetOrderTotal(); [OperationContract(IsInitiating=false, IsTerminating=true)] bool SubmitOrder(); } 40

41 PÉLDÁNY DEAKTIVÁLÁSA 41

42 PÉLDÁNY DEAKTIVÁLÁSA  Ahogy az előző ábrán is látható, egy példány egy Context objektumon belül töltődik be, és a session információk a kliens üzeneteit nem közvetlenül a példányhoz kötik, hanem a Context objektumhoz.  Amikor egy session létrejön, akkor a szolgáltatás hoszt egy új kontextust készít.  Ez a kontextus megszűnik, ha a session megszűnik.  Ez azt jelenti, hogy alapértelmezetten az kontextus addig él, ameddig a benne lévő példány.  A WCF lehetőséget nyújt arra, hogy a két életciklust különválasszuk. 42

43 PÉLDÁNY DEAKTIVÁLÁSA  Létrehozható olyan kontextus is, amiben nincs egyetlen példány sem.  A kontextus deaktiváció menedzselése az OperationBehavior ReleaseInstanceMode propertyjén keresztül történik.  A ReleaseInstanceMode-ban számos érték beállítható: • BeforeCall • AfterCall • BeforeAndAfterCall • None  Az alapértelmezett érték a None. Ez azt jelenti, hogy a szolgáltatás példány azután is létezik, miután feldolgozta a kérést. 43

44 PÉLDÁNY DEAKTIVÁLÁSA  BeforeCall mód esetén minden kérés előtt új példány jön létre. Ha egy példány már eleve létezik, akkor deaktiválódik és meghívódik rá a Dispose metódus. Ezalatt a kliens blokkolódik. Az a mód általában akkor használatos, ha a metódus egy kritikus erőforráshoz szeretne hozzáférni és biztosnak kell lenni abban, hogy az összes előző hozzáférés törlődött.  AfterCall mód esetén a metódus lefutása után az aktuális példány deaktiválódik és meghívódik rá a Dispose metódus. Ezzel azt biztosíthatjuk, hogy a metódus által használt erőforrást azonnal felszabadítjuk, amint nincs már rá szükség, így a következő hívásnál egyből elérhető lesz. 44

45 PÉLDÁNY DEAKTIVÁLÁSA  BeforeAndAfterCall mód esetén a mód az előbbi kettő ötvözése. Gyakorlatilag ugyanaz, mint a hívásonkénti (per call) példányosítási mód. A különbség csak annyi, hogy ezt a módot metódusonként tudjuk beállítani, így minden egyes metódusra más és más lehet a példányosítási mód. • Beállítása: public class UpdateService : IUpdateService { [OperationBehavior(ReleaseInstanceMode=ReleaseInstanceMode. BeforeAndAfterCall)] public void Update() { // Implementation code goes here } 45

46 PÉLDÁNY DEAKTIVÁLÁSA  Lehetőség van az aktuális szolgáltatás példány futásidejű deaktiválására is.  Ehhez az kontextus biztosít egy ReleaseServiceInstance metódust.  Amikor ezt meghívódik, az aktuális példány megjelölésre kerül, hogy rá a deaktiválás vár, miután a metódus befejezte a futását.  Meghívása: OperationContext.Current.InstanceContext.ReleaseServiceInstance(); 46


Letölteni ppt "WINDOWS COMMUNICATION FOUNDATION Session és példányosítás."

Hasonló előadás


Google Hirdetések