Sdílet prostřednictvím


Domény aplikací

Poznámka:

Tento článek je specifický pro rozhraní .NET Framework. Nevztahuje se na novější implementace .NET, včetně .NET 6 a novějších verzí.

Operační systémy a běhová prostředí obvykle poskytují určitou formu izolace mezi aplikacemi. Systém Windows například používá procesy k izolaci aplikací. Tato izolace je nezbytná k zajištění toho, aby kód spuštěný v jedné aplikaci nemohl nepříznivě ovlivnit jiné nesouvisející aplikace.

Domény aplikací poskytují hranici izolace pro zabezpečení, spolehlivost, správu verzí a odpojování sestavení. Domény aplikací se obvykle vytvářejí hostiteli modulu runtime, kteří zodpovídají za spouštění modulu CLR (Common Language Runtime) před spuštěním aplikace.

Výhody izolace aplikací

V minulosti se hranice procesů používaly k izolaci aplikací běžících na stejném počítači. Každá aplikace se načte do samostatného procesu, který izoluje aplikaci od ostatních aplikací spuštěných na stejném počítači.

Aplikace jsou izolované, protože adresy paměti jsou relativní vzhledem k procesu; ukazatel paměti předaný z jednoho procesu do druhého nelze v cílovém procesu použít smysluplným způsobem. Kromě toho není možné provádět přímá volání mezi dvěma procesy. Místo toho musíte použít proxy servery, které poskytují úroveň nepřímosti.

Před spuštěním spravovaného kódu je nutné provést ověřovací proces (pokud správce nepovolil oprávnění k vynechání ověření). Proces ověření určuje, jestli se kód může pokusit o přístup k neplatným adresům paměti, nebo provést nějakou jinou akci, která by mohla způsobit, že proces, ve kterém běží, nebude správně fungovat. Kód, který projde ověřovacím testem, se považuje za typově bezpečný. Možnost ověřit kód jako typově bezpečný umožňuje modulu CLR (Common Language Runtime) poskytovat stejně velkou úroveň izolace jako hranice procesu s mnohem nižšími náklady na výkon.

Domény aplikací poskytují bezpečnější a všestrannější jednotku zpracování, kterou může modul CLR (Common Language Runtime) použít k zajištění izolace mezi aplikacemi. V jednom procesu můžete spustit několik domén aplikace se stejnou úrovní izolace, která by existovala v samostatných procesech, ale bez dalších režijních nákladů na provádění volání mezi procesy nebo přepínání mezi procesy. Schopnost spouštět více aplikací v rámci jednoho procesu výrazně zvyšuje škálovatelnost serveru.

Izolace aplikací je také důležitá pro zabezpečení aplikací. Ovládací prvky z několika webových aplikací můžete například spouštět v jednom procesu prohlížeče tak, aby ovládací prvky nemohly přistupovat k datům a prostředkům ostatních.

Izolace poskytovaná doménami aplikací má následující výhody:

  • Chyby v jedné aplikaci nemohou ovlivnit jiné aplikace. Protože typově bezpečný kód nemůže způsobit chyby paměti, použití domén aplikace zajišťuje, že kód spuštěný v jedné doméně nemůže ovlivnit jiné aplikace v procesu.

  • Jednotlivé aplikace je možné zastavit bez zastavení celého procesu. Použití domén aplikací umožňuje uvolnit kód spuštěný v jedné aplikaci.

    Poznámka:

    Nelze vyložit jednotlivé sestavení nebo typy. Uvolnit lze pouze úplnou doménu.

  • Kód spuštěný v jedné aplikaci nemůže přímo přistupovat k kódu nebo prostředkům z jiné aplikace. Modul CLR (Common Language Runtime) tuto izolaci vynucuje tím, že brání přímým voláním mezi objekty v různých doménách aplikace. Objekty předávané mezi doménami se buď zkopírují, nebo se k nim přistupuje přes proxy. Pokud je objekt zkopírován, volání objektu je místní. To znamená, že volající i objekt, na který se odkazuje, jsou ve stejné doméně aplikace. Pokud se k objektu přistupuje přes proxy server, volání objektu je vzdálené. V tomto případě se volající a objekt, na který odkazuje, nacházejí v různých doménách aplikace. Volání mezi doménou používají stejnou infrastrukturu vzdáleného volání jako volání mezi dvěma procesy nebo mezi dvěma počítači. Proto musí být metadata odkazovaného objektu dostupná pro obě domény aplikace, aby bylo možné správně zkompilovat volání metody JIT. Pokud volající doména nemá přístup k metadatům pro objekt, který je volána, kompilace může selhat s výjimkou typu FileNotFoundException. Další informace naleznete v tématu Vzdálené objekty. Mechanismus pro určení přístupu k objektům napříč doménami je určen objektem. Další informace najdete v tématu System.MarshalByRefObject.

  • Chování kódu je vymezeno aplikací, ve které běží. Jinými slovy, doména aplikace poskytuje nastavení konfigurace, jako jsou zásady verze aplikace, umístění všech vzdálených sestavení, ke kterým přistupuje, a informace o tom, kde najít sestavení načtená do domény.

  • Oprávnění udělená kódu můžou být řízena doménou aplikace, ve které je kód spuštěný.

Domény a sestavení aplikací

Tato část popisuje vztah mezi doménami aplikace a sestaveními. Před spuštěním kódu, který obsahuje, je nutné načíst sestavení do domény aplikace. Spuštění typické aplikace způsobí načtení několika sestavení do aplikační domény.

Způsob načtení sestavení určuje, zda může být jeho běhový kompilovaný kód (JIT) sdílen více aplikačními doménami v rámci procesu, a zda může být sestavení z procesu uvolněno.

  • Pokud je sestavení načteno v doméně neutrálním režimu, mohou všechny aplikační domény, které sdílejí stejnou sadu bezpečnostních práv, sdílet stejný kód kompilovaný pomocí JIT, což sníží paměť vyžadovanou aplikací. Sestavení však nelze nikdy vyložit z procesu.

  • Pokud sestavení není načteno neutrální vůči doméně, musí být JIT zkompilováno v každé doméně aplikace, ve které je načteno. Sestavení však může být uvolněno z procesu uvolněním všech domén aplikace, ve kterých je načten.

Hostitel runtime určuje, zda se mají sestavení načítat jako neutrální z hlediska domény, když načte prostředí runtime do procesu. U spravovaných aplikací použijte LoaderOptimizationAttribute atribut na metodu vstupního bodu pro proces a zadejte hodnotu z přidruženého LoaderOptimization výčtu. Pro nespravované aplikace, které hostují modul CLR (Common Language Runtime), zadejte příslušný příznak při volání CorBindToRuntimeEx – metoda funkce .

Existují tři možnosti načítání doménově neutrálních sestavení.

  • LoaderOptimization.SingleDomain nenačítá žádná sestavení jako doménově neutrální, s výjimkou knihovny Mscorlib, která je vždy načtena jako doménově neutrální. Toto nastavení se nazývá jedna doména, protože se běžně používá, když hostitel spouští v procesu pouze jednu aplikaci.

  • LoaderOptimization.MultiDomain načte všechna sestavení jako doménově neutrální. Toto nastavení použijte, pokud v procesu existuje více domén aplikace, z nichž všechny běží stejný kód.

  • LoaderOptimization.MultiDomainHost načte silně pojmenovaná sestavení jako doménově neutrální, pokud jsou společně se všemi jejich závislostmi nainstalována v globální mezipaměti sestavení. Jiná sestavení jsou načtena a JIT kompilována nezávisle pro každou doménu aplikace, ve které jsou načteny, a proto je lze z procesu odstranit. Toto nastavení použijte při spuštění více než jedné aplikace ve stejném procesu nebo pokud máte kombinaci sestavení, která jsou sdílena mnoha doménami aplikace a sestaveními, které je potřeba z procesu uvolnit.

Zkompilovaný kód JIT nelze sdílet pro sestavení načtená do načítacího kontextu, použitím metody LoadFrom třídy Assembly nebo načtených z obrazů pomocí přetížených metod Load, které specifikují pole bajtů.

Sestavení, která byla zkompilována do nativního kódu pomocí Ngen.exe (Generátor nativních imagí), mohou být sdílena mezi doménami aplikací, pokud jsou při prvním načtení do procesu načtena jako doménově neutrální.

Kód zkompilovaný JIT pro sestavení, které obsahuje vstupní bod aplikace, je sdílen pouze v případě, že lze sdílet všechny její závislosti.

Sestavení neutrální domény může být JIT přeloženo vícekrát. Pokud jsou například sady grantů zabezpečení dvou domén aplikace odlišné, nemůžou sdílet stejný kód zkompilovaný JIT. Každou kopii JIT kompilovaného sestavení lze však sdílet s jinými doménami aplikace, které mají stejnou sadu oprávnění.

Když se rozhodnete, jestli se mají sestavení načítat jako doménově neutrální, musíte učinit kompromis mezi snížením využití paměti a dalšími faktory výkonu.

  • Přístup ke statickým datům a metodám je pro doménově neutrální sestavení pomalejší, protože sestavení musí být izolována. Každá doména aplikace, která přistupuje k sestavení, musí mít samostatnou kopii statických dat, aby se zabránilo odkazům na objekty ve statických polích překračovat hranice domény. Modul runtime proto obsahuje další logiku pro směrování volajícího na příslušnou kopii statických dat nebo metody. Tato další logika zpomaluje volání.

  • Všechny závislosti sestavení musí být umístěny a načteny neutrálně vůči doméně, protože závislost, kterou nelze načíst neutrálně vůči doméně, brání načtení sestavení tímto způsobem.

Domény aplikací a vlákna

Doména aplikace tvoří hranici izolace pro zabezpečení, správu verzí, spolehlivost a uvolnění spravovaného kódu. Vlákno je struktura operačního systému používaná modulem CLR ke spuštění kódu. Za běhu se veškerý spravovaný kód načte do domény aplikace a spouští se jedním nebo více spravovanými vlákny.

Mezi doménami aplikací a vlákny neexistuje korelace 1:1. V každém okamžiku se může v jedné doméně aplikace spustit několik vláken a konkrétní vlákno se neomezuje na jednu doménu aplikace. To znamená, že vlákna mohou volně překračovat hranice domén aplikace; pro každou doménu aplikace se nevytváří nové vlákno.

V každém okamžiku se každé vlákno spustí v doméně aplikace. V libovolné doméně aplikace může probíhat nula, jedno nebo více vláken. Modul runtime sleduje, která vlákna běží ve kterých doménách aplikace. Doménu, ve které se vlákno spouští, můžete kdykoli vyhledat voláním Thread.GetDomain metody.

Domény aplikací a kultury

Kultura, která je reprezentována objektem CultureInfo, je přidružena k vláknům. Můžete získat kulturu přidruženou k aktuálně spuštěnému vláknu pomocí CultureInfo.CurrentCulture vlastnosti a získat nebo nastavit kulturu přidruženou k aktuálně spuštěnému vláknu pomocí Thread.CurrentCulture vlastnosti. Pokud byla kultura přidružená k vláknu explicitně nastavena pomocí vlastnosti Thread.CurrentCulture, bude nadále přidružena k tomuto vláknu i po překročení hranic aplikační domény. V opačném případě je kultura přidružená k vláknu v daném okamžiku určena hodnotou CultureInfo.DefaultThreadCurrentCulture vlastnosti v doméně aplikace, ve které vlákno je spuštěno:

  • Pokud hodnota vlastnosti není null, kulturní nastavení vrácené vlastností je přidruženo k vláknu (a proto vráceny Thread.CurrentCulture vlastnostmi a CultureInfo.CurrentCulture vlastnostmi).

  • Pokud je null hodnota vlastnosti, aktuální systémové nastavení je přidruženo k vláknu.

Programování s doménami aplikací

Domény aplikací se obvykle vytvářejí a manipulují programově hostiteli modulu runtime. Někdy se ale může stát, že aplikace bude chtít pracovat i s doménami aplikací. Například aplikační program by mohl načíst komponentu aplikace do domény, aby mohla uvolnit doménu (a komponentu), aniž by bylo nutné zastavit celou aplikaci.

Jedná se AppDomain o programové rozhraní pro domény aplikací. Tato třída obsahuje metody pro vytváření a uvolnění domén, vytváření instancí typů v doménách a registraci pro různá oznámení, jako je například uvolnění domény aplikace. Následující tabulka uvádí běžně používané AppDomain metody.

AppDomain – metoda Popis
CreateDomain Vytvoří novou doménu aplikace. Doporučuje se použít přetížení této metody, která určuje AppDomainSetup objekt. Toto je upřednostňovaný způsob nastavení vlastností nové domény, jako je základ aplikace nebo kořenový adresář pro aplikaci; umístění konfiguračního souboru pro doménu; a cestu hledání, kterou modul CLR (Common Language Runtime) používá k načtení sestavení do domény.
ExecuteAssembly a ExecuteAssemblyByName Spustí sestavení v doméně aplikace. Jedná se o metodu instance, takže ji můžete použít ke spuštění kódu v jiné doméně aplikace, na kterou máte odkaz.
CreateInstanceAndUnwrap Vytvoří instanci zadaného typu v aplikační doméně a vrátí proxy. Tuto metodu použijte, chcete-li zabránit načtení sestavení obsahujícího vytvořený typ do volajícího sestavení.
Unload Provede řádné vypnutí domény. Doména aplikace není uvolněna, dokud všechna vlákna spuštěná v doméně neskončí nebo se nepřestanou nacházet v doméně.

Poznámka:

Modul CLR (Common Language Runtime) nepodporuje serializaci globálních metod, takže delegáty nelze použít ke spouštění globálních metod v jiných doménách aplikace.

Nespravovaná rozhraní popsaná ve specifikaci rozhraní hostování common language runtime také poskytují přístup k doménám aplikace. Hostitelé modulu runtime můžou k vytvoření a získání přístupu k doménám aplikace v rámci procesu používat rozhraní z nespravovaného kódu.

Proměnná prostředí COMPLUS_LoaderOptimization

Proměnná prostředí, která nastavuje výchozí zásady optimalizace zavaděče spustitelné aplikace.

Syntaxe

COMPLUS_LoaderOptimization = 1

Poznámky

Typická aplikace před spuštěním kódu, který obsahují, načte do domény aplikace několik sestavení.

Způsob, jakým je sestavení načteno, určuje, zda může být jeho za běhu zkompilovaný kód (JIT) sdílen více doménami aplikace v procesu.

  • Pokud je sestavení načteno jako neutrální vůči doméně, můžou všechny domény aplikace, které sdílejí stejnou sadu udělení zabezpečení, sdílet stejný just-in-time kompilovaný kód. Tím se sníží paměť vyžadovaná aplikací.

  • Pokud sestavení není načteno jako neutrální vůči doméně, musí být zkompilováno metodou JIT v každé aplikační doméně, ve které je načteno, a zavaděč nesmí sdílet interní prostředky napříč aplikačními doménami.

Pokud je nastaven na hodnotu 1, příznak prostředí COMPLUS_LoaderOptimization vynutí, aby hostitel modulu runtime načetl všechna sestavení v nedoménově neutrálním režimu, známém jako SingleDomain. SingleDomain nenačte žádná sestavení jako doménově neutrální, s výjimkou Mscorlib, která je vždy načtena jako doménově neutrální. Toto nastavení se nazývá jedna doména, protože se běžně používá, když hostitel spouští v procesu pouze jednu aplikaci.

Upozornění

Příznak prostředí COMPLUS_LoaderOptimization byl navržen tak, aby se používal v diagnostických a testovacích scénářích. Zapnutí vlajky může způsobit výrazné zpomalení a zvýšenou spotřebu paměti.

Příklad kódu

Chcete-li vynutit, aby žádné sestavení nebylo načteno jako doménově neutrální pro službu IISADMIN, můžete toho dosáhnout připojením COMPLUS_LoaderOptimization=1 k vícestrunné hodnotě prostředí v klíči HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\IISADMIN.

Key = HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\IISADMIN
Name = Environment
Type = REG_MULTI_SZ
Value (to append) = COMPLUS_LoaderOptimization=1

Viz také