Sdílet prostřednictvím


Zlepšení výkonu a spolehlivosti služby Azure Functions

Tento článek obsahuje pokyny ke zlepšení výkonu a spolehlivosti aplikací bezserverových funkcí. Obecnější sadu osvědčených postupů azure Functions najdete v osvědčených postupech azure Functions.

Níže jsou uvedené osvědčené postupy při vytváření a navrhování bezserverových řešení pomocí Azure Functions.

Vyhněte se dlouhotrvajícím funkcím

Velké dlouhotrvající funkce můžou způsobit neočekávané problémy s vypršením časového limitu. Další informace o časových limitech pro daný plán hostování najdete v tématu Doba trvání časového limitu aplikace funkcí.

Funkce může být velká kvůli mnoha Node.js závislostem. Import závislostí mohou také způsobit zvýšené doby načítání, které vedou k neočekávaným výpadkům. Závislosti se načítají explicitně i implicitně. Jeden modul načtený vaším kódem může načíst vlastní další moduly.

Kdykoli je to možné, refaktorujte velké funkce na menší sady funkcí, které spolupracují a vracejí odpovědi rychle. Například funkce webhooku nebo HTTP trigger funkce může vyžadovat potvrzující odpověď do určitého časového limitu; webhooky obvykle vyžadují okamžitou odpověď. Datovou část triggeru HTTP můžete předat do fronty, kterou zpracuje funkce triggeru fronty. Tento přístup umožňuje odložit skutečnou práci a vrátit okamžitou odpověď.

Ujistěte se, že úkoly na pozadí jsou dokončené.

Když vaše funkce spustí jakékoli úlohy, zpětná volání, vlákna, procesy, musí se dokončit před vrácením kódu funkce. Vzhledem k tomu, že funkce tyto vlákna na pozadí nesleduje, může dojít k vypnutí webu bez ohledu na stav vlákna na pozadí, což může způsobit nezamýšlené chování ve vašich funkcích.

Pokud například funkce spustí úlohu na pozadí a vrátí úspěšnou odpověď před dokončením úkolu, modul runtime Služby Functions považuje provedení za úspěšné dokončení bez ohledu na výsledek úlohy na pozadí. Pokud tato úloha na pozadí provádí nezbytnou práci, může být vyřazena vypnutím webu a zůstane v neznámém stavu.

Komunikace mezi funkcemi

Durable Functions a Azure Logic Apps jsou vytvořené pro správu přechodů stavu a komunikace mezi několika funkcemi.

Pokud k integraci s více funkcemi nepoužíváte Durable Functions nebo Logic Apps, je nejlepší použít fronty úložiště pro komunikaci mezi funkcemi. Hlavním důvodem je, že fronty úložiště jsou levnější a mnohem jednodušší zřizovat než jiné možnosti úložiště.

Jednotlivé zprávy ve frontě úložiště jsou omezené na 64 kB. Pokud potřebujete předávat větší zprávy mezi funkcemi, můžete frontu služby Azure Service Bus použít k podpoře velikostí zpráv o velikosti až 256 kB na úrovni Standard a až 100 MB na úrovni Premium.

Témata služby Service Bus jsou užitečná, pokud před zpracováním vyžadujete filtrování zpráv.

Centra událostí jsou užitečná pro podporu vysoké objemové komunikace.

Napište funkce, které mají být bezstavové

Pokud je to možné, měly by být funkce bezstavové a idempotentní. Přidružte ke svým datům všechny požadované informace o stavu. Například zpracovávaná objednávka by pravděpodobně měla přidruženého state člena. Funkce může zpracovat pořadí na základě tohoto stavu, zatímco samotná funkce zůstává bezstavová.

Zejména u triggerů časovače se doporučují idempotentní funkce. Pokud máte například něco, co se musí spouštět jednou denně, napište ho, aby se mohl spustit kdykoli během dne se stejnými výsledky. Funkce může skončit, když pro daný den není k dispozici žádná práce. Pokud se předchozí spuštění nepovedlo dokončit, mělo by další spuštění pokračovat tam, kde skončilo. To je zvlášť důležité pro vazby založené na zprávách, které se zkouší znovu při selhání. Další informace najdete v tématu Návrh služby Azure Functions pro stejný vstup.

Psaní defenzivních funkcí

Předpokládejme, že se vaše funkce může kdykoli setkat s výjimkou. Navrhněte funkce s možností pokračovat z předchozího bodu selhání během dalšího spuštění. Představte si scénář, který vyžaduje následující akce:

  1. Dotaz na 10 000 řádků v databázi
  2. Vytvořte zprávu pro frontu pro každý z těchto řádků k dalšímu zpracování.

V závislosti na tom, jak složitý je váš systém, můžete mít: zapojené podřízené služby, které se chovají špatně, výpadky sítě nebo dosažení limitů kvót atd. Všechny tyto možnosti můžou mít vliv na vaši funkci kdykoli. Potřebujete navrhnout funkce tak, aby byly pro ně připravené.

Jak váš kód reaguje, pokud dojde k selhání po vložení 5 000 těchto položek do fronty ke zpracování? Sledujte položky v sadě, kterou jste dokončili. Jinak je můžete příště vložit znovu. Toto dvojité vložení může mít závažný dopad na pracovní tok, takže udělejte vaše funkce idempotentní.

Pokud již byla položka fronty zpracována, povolte, aby vaše funkce byla no-op.

Využijte defenzivní opatření, která už poskytujete pro komponenty, které používáte na platformě Azure Functions. Podívejte se například na téma Zpracování zpráv z nebezpečné fronty v dokumentaci pro triggery a vazby fronty Azure Storage.

U funkcí založených na protokolu HTTP zvažte strategie správy verzí rozhraní API pomocí služby Azure API Management. Pokud například potřebujete aktualizovat aplikaci funkcí založenou na protokolu HTTP, nasaďte novou aktualizaci do samostatné aplikace funkcí a pomocí revizí nebo verzí služby API Management nasměrujte klienty na novou verzi nebo revizi. Jakmile všichni klienti začnou používat verzi nebo revizi a v předchozí funkční aplikaci nebude probíhat žádné další spuštění, můžete zrušit nasazení předchozí funkční aplikace.

Osvědčené postupy organizace funkcí

V rámci vašeho řešení můžete vyvíjet a publikovat více funkcí. Tyto funkce se často kombinují do jedné aplikace funkcí, ale můžou se spouštět i v samostatných aplikacích funkcí. V prémiových a vyhrazených plánech hostování (App Service) může několik funkčních aplikací také sdílet stejné prostředky tím, že běží ve stejném plánu. Způsob seskupení funkcí a aplikací funkcí může mít vliv na výkon, škálování, konfiguraci, nasazení a zabezpečení celkového řešení. Pro každý scénář neplatí žádná pravidla, proto při plánování a vývoji funkcí zvažte informace v této části.

Uspořádání funkcí pro výkon a škálování

Každá funkce, kterou vytvoříte, má nároky na paměť. I když je tato stopa obvykle malá, může příliš mnoho funkcí v jedné funkční aplikaci vést k pomalejšímu spuštění této aplikace na nových instancích. Také to znamená, že celkové využití paměti vaší aplikace funkcí může být vyšší. Je těžké říci, kolik funkcí by mělo být v jedné aplikaci, což závisí na konkrétní úloze. Pokud ale vaše funkce ukládá velké množství dat do paměti, zvažte méně funkcí v jedné aplikaci.

Pokud spouštíte více aplikací funkcí v jednom plánu Premium nebo vyhrazeném plánu (App Service), všechny tyto aplikace sdílejí stejné prostředky přidělené plánu. Pokud máte jednu aplikaci funkcí, která má mnohem vyšší požadavek na paměť než ostatní, používá v každé instanci, do které je aplikace nasazená, nepřiměřeně velké množství paměťových prostředků. Vzhledem k tomu, že by to mohlo ponechat méně paměti pro ostatní aplikace v každé instanci, můžete chtít spustit aplikaci funkcí s vysokým využitím paměti, jako je tato, v samostatném samostatném plánu hostování.

Poznámka:

Při použití plánu Consumption doporučujeme vždy umístit každou aplikaci do vlastního plánu, protože aplikace se škálují nezávisle na sobě. Další informace najdete v tématu Více aplikací ve stejném plánu.

Zvažte, jestli chcete seskupit funkce s různými profily zatížení. Pokud máte například funkci, která zpracovává mnoho tisíc zpráv fronty a další, která se volá jen občas, ale má vysoké požadavky na paměť, můžete je nasadit v samostatných aplikacích funkcí, aby získaly vlastní sady prostředků a škálovaly se nezávisle na sobě.

Uspořádání funkcí pro konfiguraci a nasazení

Aplikace funkcí mají host.json soubor, který slouží ke konfiguraci pokročilého chování triggerů funkcí a modulu runtime Azure Functions. Změny v host.json souboru platí pro všechny funkce v aplikaci. Pokud máte některé funkce, které potřebují vlastní konfigurace, zvažte jejich přesun do vlastní aplikace funkcí.

Všechny funkce v místním projektu se nasadí společně jako sada souborů do vaší aplikace funkcí v Azure. Možná budete muset nasadit jednotlivé funkce samostatně nebo používat funkce, jako jsou sloty nasazení pro některé funkce, a ne jiné. V takových případech byste tyto funkce měli nasadit (v samostatných projektech kódu) do různých aplikací funkcí.

Uspořádání funkcí podle oprávnění

Připojovací řetězce a další přihlašovací údaje uložené v nastavení aplikace poskytují všem funkcím v aplikaci funkcí stejnou sadu oprávnění v přidruženém prostředku. Zvažte minimalizaci počtu funkcí s přístupem ke konkrétním přihlašovacím údajům přesunutím funkcí, které tyto přihlašovací údaje nepoužívají do samostatné aplikace funkcí. K předávání dat mezi funkcemi v různých aplikacích funkcí můžete použít techniky, jako je například řetězení funkcí.

Osvědčené postupy škálovatelnosti

Existuje řada faktorů, které ovlivňují škálování instancí vaší aplikace funkcí. Podrobnosti najdete v dokumentaci pro škálování funkcí. Následuje několik osvědčených postupů pro zajištění optimální škálovatelnosti aplikace funkcí.

Sdílení a správa připojení

Kdykoli je to možné, znovu použijte připojení k externím prostředkům. Zjistěte , jak spravovat připojení ve službě Azure Functions.

Vyhněte se sdílení účtů úložiště

Když vytvoříte aplikaci funkcí, musíte ji přidružit k účtu úložiště. Připojení účtu úložiště se udržuje v nastavení aplikace AzureWebJobsStorage.

Pokud chcete maximalizovat výkon, použijte pro každou aplikaci funkcí samostatný účet úložiště. Tento přístup je zvlášť důležitý v případě, že máte aktivované funkce Durable Functions nebo Event Hubs, které generují velký objem transakcí úložiště. Pokud logika aplikace komunikuje se službou Azure Storage, ať už přímo (pomocí sady SDK služby Storage), nebo prostřednictvím některé z vazeb úložiště, měli byste použít vyhrazený účet úložiště. Pokud máte například funkci aktivovanou centrem událostí, která zapisuje některá data do úložiště objektů blob, použijte dva účty úložiště: jeden pro aplikaci funkcí a druhý pro objekty blob, které funkce ukládá.

Nemíchejte testovací a produkční kód ve stejné aplikaci funkcí

Funkce v rámci aplikace funkcí sdílejí prostředky. Například sdílená paměť. Pokud používáte aplikaci funkcí v produkčním prostředí, nepřidávejte do ní funkce a prostředky související s testováním. Může způsobit neočekávanou režii při provádění produkčního kódu.

Dávejte pozor, co načítáte v produkčních funkčních aplikacích. Paměť se průměruje napříč jednotlivými funkcemi v aplikaci.

Pokud máte sdílené sestavení odkazované ve více funkcích .NET, vložte ho do společné sdílené složky. Jinak byste mohli omylem nasadit více verzí stejného binárního souboru, které se mezi funkcemi chovají odlišně.

Nepoužívejte podrobné protokolování v produkčním kódu, které má negativní dopad na výkon.

Používejte asynchronní kód, ale vyhněte se blokování volání

Asynchronní programování je doporučeným postupem, zejména při blokování vstupně-výstupních operací.

V jazyce C# se vždy vyhněte odkazování na Result vlastnost nebo volání Wait metody v Task instanci. Tento přístup může vést k vyčerpání vláken.

Návod

Pokud plánujete používat vazby HTTP nebo WebHook, naplánujte, aby se zabránilo vyčerpání portů, které může být způsobeno nesprávnou instancí HttpClient. Další informace najdete v tématu Správa připojení ve službě Azure Functions.

Použijte více pracovních procesů

Ve výchozím nastavení používá každá instance hostitele pro Functions jeden pracovní proces. Pokud chcete zvýšit výkon, zejména u modulů runtime s jedním vláknem, jako je Python, použijte FUNCTIONS_WORKER_PROCESS_COUNT ke zvýšení počtu pracovních procesů na hostitele (až 10). Azure Functions se pak pokusí rovnoměrně distribuovat souběžné vyvolání funkcí napříč těmito pracovními procesy.

Nastavení FUNCTIONS_WORKER_PROCESS_COUNT se vztahuje na všechny hostitele, které služba Functions vytvoří při škálování vaší aplikace na více instancí podle poptávky.

Přijímejte zprávy v dávkách, kdykoli je to možné

Některé triggery, jako je centrum událostí, umožňují přijímat dávku zpráv při jediném vyvolání. Dávkový proces zpracování zpráv přináší mnohem lepší výkon. Maximální velikost dávky v host.json souboru můžete nakonfigurovat podle podrobných informací v referenční dokumentaci khost.json.

U funkcí jazyka C# můžete změnit typ na silně typované pole. Místo podpisu metody může být EventData[] sensorEventnapříklad EventData sensorEvent . V případě jiných jazyků budete muset explicitně nastavit vlastnost kardinality, function.json aby many bylo možné povolit dávkování , jak je znázorněno zde.

Konfigurace chování hostitelů pro lepší zpracování souběžnosti

Soubor host.json v function aplikaci umožňuje konfiguraci runtime modulu hostitele a chování triggerů. Kromě dávkového chování můžete spravovat souběžnost pro řadu triggerů. Často úpravou hodnot v těchto možnostech může každá instance odpovídajícím způsobem škálovat podle požadavků vyvolaných funkcí.

Nastavení v souboru host.json platí pro všechny funkce v aplikaci v rámci jedné instance funkce. Pokud byste například měli aplikaci funkcí se dvěma funkcemi HTTP a maxConcurrentRequests požadavky nastavenými na 25, požadavek na trigger HTTP se počítá do sdílených 25 souběžných požadavků. Když se tato aplikace funkcí škáluje na 10 instancí, deset funkcí efektivně umožňuje 250 souběžných požadavků (10 instancí × 25 souběžných požadavků na instanci).

Další možnosti konfigurace hostitele najdete v článku o konfiguracihost.json.

Další kroky

Další informace najdete v následujících zdrojích informací: