Multi-tenancy v Orchard Core: Architektura, která vám ušetří stovky hodin (i serverů)
Představte si, že máte na starosti 50 různých webových projektů. Pro agenturu nebo SaaS platformu je to běžná realita. Pokud pro každý z nich platíte samostatný hosting a při každé bezpečnostní záplatě aktualizujete 50 různých instancí, vaše provozní náklady a technický dluh rostou raketovým tempem. Jak tento obchodní problém vyřešit elegantně a udržitelně?
Od fragmentace k centralizovanému výkonu
Ať už realizuji tvorbu modulů na míru nebo kompletní modernizaci legacy systémů, často narážím na roztříštěnou infrastrukturu. Starší systémy řešily izolaci klientů tím, že se aplikace zkopírovala a nasadila znovu. To je v dnešní cloudové éře neudržitelné. S Orchard Core zavádím koncept "víceklientské" architektury (Multi-tenancy). Místo 50 aplikací v Azure vám stačí jedna silná, která chytře rozděluje výkon.
Jak si stojí Multi-tenancy proti jiným přístupům?
Abychom pochopili skutečnou hodnotu, podívejme se na srovnání Orchard Core s běžnými alternativami, jako je izolovaný vývoj nebo oblíbený WordPress Multisite.
| Parametr | Orchard Core (Multi-tenancy) | Samostatné aplikace (Single-tenant) | WordPress Multisite |
|---|---|---|---|
| Náklady na server | Extrémně nízké (sdílený App Pool a paměť). | Vysoké (každý web = vlastní proces). | Nízké, ale s rostoucí zátěží PHP nestabilní. |
| Izolace dat | Dokonalá (lze zvolit prefix tabulek nebo i zcela oddělenou DB pro tenanta). | Absolutní. | Slabá (sdílená databáze bez nativní podpory oddělených DB instancí). |
| Nasazení aktualizace | Aktualizujete 1 kódovou základnu -> projeví se u všech. | Nutnost nasadit CI/CD pipelinu 50x. | Aktualizace pluginů často naruší kompatibilitu ostatních webů. |
| Typické využití | SaaS, franšízy, digitální agentury, korporace. | Bankovnictví, systémy s extrémní regulací. | Jednoduché blogovací sítě. |
Výhody a úskalí z pohledu architekta
Výhody: Úspora času i peněz
Největší zbraní je údržba. Když vytvořím nový modul (např. pro fakturaci), jedním nasazením ho mohu zapnout kterémukoliv tenantovi. Spotřeba RAM je dramaticky nižší, protože .NET Assemblies se načítají do paměti pouze jednou.
Architektonická čistota
Orchard Core řeší závislosti na úrovni tenanta. Díky chytrému DI (Dependency Injection) kontejneru má každý tenant vlastní kontext. Můžete tak mít u jednoho klienta zapnutou jinou sadu funkcí než u druhého, ačkoliv běží na stejné instanci.
Nevýhody: Single Point of Failure
Vše má svou cenu. Pokud vaše kódová chyba způsobí pád celé aplikační domény, spadnou všechny weby najednou. Architektura proto vyžaduje seniorní znalost .NET, striktní izolaci chyb a asynchronní programování, aby jeden tenant nezablokoval zdroje ostatním.
Při správě multi-tenant aplikací potřebujete silný "Master Dashboard" pro monitorování všech webů. Místo abych trávil dny psaním složitých tabulek a grafů od nuly, využívám komponenty Syncfusion (Blazor nebo ASP.NET Core). Implementace vysoce výkonného `SfGrid`, který dokáže plynule filtrovat statisíce logů napříč všemi tenanty, nebo programové generování komplexních PDF reportů pro každého klienta zvlášť přes Syncfusion Document Solutions, mi zkracuje vývoj o týdny. Získáváte nepřekonatelný enterprise standard a perfektní UI.
Nahlédnutí pod kapotu: Práce s Tenantem v kódu
Podívejme se, jak elegantně vypadá kód, když v rámci tvorby modulů na míru potřebujete identifikovat aktuálního klienta. Orchard Core poskytuje rozhraní `ShellSettings`, které obsahuje veškerá metadata běžícího tenanta.
using Microsoft.AspNetCore.Mvc;
using OrchardCore.Environment.Shell;
namespace PV.CustomModule.Controllers
{
public class TenantDashboardController : Controller
{
private readonly ShellSettings _shellSettings;
public TenantDashboardController(ShellSettings shellSettings)
{
// DI kontejner automaticky injektne nastavení správného tenanta
_shellSettings = shellSettings;
}
public IActionResult Index()
{
// Můžeme se rozhodovat na základě názvu tenanta nebo jeho stavu
var tenantName = _shellSettings.Name;
var tenantState = _shellSettings.State;
return View(new { Tenant = tenantName, Status = tenantState });
}
}
}
Tato úroveň abstrakce znamená, že vývojář vůbec nemusí řešit složité routování domén – infrastruktura to vyřeší za něj.