Toto je článek ze světa Pythonu, ale stále je použitelný pro celé programování, i když multithreading nám umožňuje zpracovávat požadavky rychleji, ale existuje i strop, zelená (mikrovlákna) vlákna jsou řešením.
Vývoj vícevláknového softwaru řeší velké množství problémů, zejména u síťově orientovaných aplikací, které vyžadují náročný výkon, aby rychle reagovaly na uživatele. Bohužel multithreading nestačí k řešení velkých škálSouběžnostsexuální problémy.
Řešení těchto problémů vyžaduje změnu programovacích modelů, používání asynchronních událostí a mechanismů založených na zpětném volání. V Druva jsme vytvořili knihovnu založenou na pythonu nazvanou Dhaga, která řeší rozsáhlé problémySouběžnost, zatímco programovací model nevyžaduje významné změny.
Softwaroví vývojáři žijí v jednéSouběžnostsvět. Vlákna jsou dnes prvotřídní občané, zejména během vývoje, zvlášť když vaše aplikace provádí intenzivní síťové operace, jako je systém inSync (produkt pro synchronizaci síťové bezpečnosti) jako Druva. Vícevláknové zpracování pomáhá jednoduchým a uspořádaným plynulým procesem programování kódu pro síťové operace. Když naše aplikace potřebuje zlepšení nebo zlepšení výkonu, lze ji zlepšitPružnost, můžeme zvýšit počet vláken.
Ale pokud jde o tisíce škálSouběžnostŽádosti, vlákna nestačí.
Zjistili jsme, že vícevláknové zpracování má následující nevýhody: 1. Systémový klient inSync musí zálohovat velké množství souborů na server prostřednictvím síťových RPC volání. Typický způsob, jak vývojáři urychlují práci, je použití vláken. Výkon multithreadingu však zvyšuje náklady na paměť a CPU; Vývojáři musí udržovat rovnováhu mezi rychlostí a počtem vláken.
2. Naše servery musí zvládat vztah mezi systémem inSync a tisíci zákazníkůSouběžnostPřipojení a oznámení. Pro efektivní zpracování spojení používáme vlákna pro zpracování požadavků. Ale rostoucí počet zákazníků systému inSync také znamená, že musíme stále zvyšovat počet vláken, což spotřebovává hodně serverové paměti a CPU.
3. Náš webový server musí zpracovat tisíce paralelních HTTP požadavků. Většina práce je na síťových socketech, které přijímají a odesílají data a předávají je na backend systému inSync. Způsobí, že většina vláken čeká na síťové operace. Příčinou problému C10K je, že když jsou tisíce synchronních požadavků na webový server, generování vlákna pro každý požadavek je poměrně neškálovatelné (Scale).
Omezení asynchronních rámců Mnoho asynchronních frameworků, včetně Twisted, Tornado Tornado a asyncore, může vývojářům pomoci opustit populární způsoby používání vláken. Tyto rámce spoléhají na neblokující sockety a mechanismy callbacku (podobné Node.js). Pokud tyto frameworky použijeme tak, jak jsou, hlavní části našeho Druva kódu budou muset být refaktorovány. To není to, co chceme dělat. Refaktorování kódu prodlužuje vývojové a testovací cykly, což nám brání splnit požadavky na škálování. Vzhledem k tomu, že více částí produktu musí být masivních, každý z nás je bude muset refaktorovat – proto je snaha zdvojnásobit nebo ztrojnásobit.
Abychom se vyhnuli tolika změnám kódu, museli jsme se vzdálit od přímého používání stávajícího frameworku. Naštěstí jsme našli užitečné nástroje.
Protože chceme řídit provádění kódu na síťovém I/O, potřebujeme způsob, jak rozdělit vlákno na mikrovlákna. ZjistímeGreenlets。 Poskytuje neimplicitní mikrovláknové plánování nazývané korutina korutiny. Jinými slovy. Je to užitečné, když chcete ovládat běh kódu. Můžete vytvářet mikrovlákna pro vlastní plány, protože můžete ovládat, kdy greenlety přinášejí pauzy. To je pro nás ideální, protože nám to dává plnou kontrolu nad plánovaním našeho kódu.
Tornado je jednoduchý, neblokující rámec webového serveru napsaný v Pythonu, navržený tak, aby zvládl tisíce asynchronních požadavků. Používáme jeho základní komponentu, IOLoop IOStream. IOLoop je neblokující socketová I/O event smyčka; Používá epoll (na Linuxu) nebo fronty (BSD a Mac OS X), jinak vybere (na Windows), pokud jsou dostupné. IOStream poskytuje neblokující sockety, jako je pohodlné balení pro čtení a zápis. Všechny operace se sockety delegujeme na Tornado a pak používáme callbacky k vyvolání kódových operací k dokončení (poznámka k banq: velmi podobné mechanismu Node.js).
Je to dobrý začátek, ale potřebujeme víc. Pokud použijeme výše uvedený modul přímo v našem kódu, bude se muset změnit spousta našeho RPC kódu – plánování RPC přes greenlety, zajištění, že greenlety neblokují (pokud se greenlety ucpávají, zablokují celé vlákno i všechny ostatní), a zvládáme callback funkce z Tornado.
Potřebujeme abstrakci pro správu a uspořádání greenletů, abychom je nezahlcovali externími voláními, a tato abstrakce může být výrazně škálovatelná i mimo vlákna. Tato abstrakce je Dhaga, která umožňuje programovat tok aplikačního kódu jako tradiční synchronní sekvenci, ale provádění je asynchronní.
Dhaga (z hindštiny, což znamená vlákno) je rámec pro provádění lehkého vlákna, které abstrahujeme. Třída Dhaga je odvozena z greenletů a používá přepínání zásobníků k provádění více kódových toků v jednom vlákně operačního systému. Vlákna jednoho operačního systému vykonávají více dhagas pomocí kolaborativního plánování. Kdykoli dhaga čeká (hlavně čeká, až se vrátí volání RPC), předává řízení na úroveň rodiče (tj. kontext vykonání vlákna na úrovni OS, které ji vytvořilo). Nadřazená úroveň pak naplánuje další dhagu, aby byla připravena k provozu. RPC volání bude předáno tornado webovému serveru, aby socket asynchronně zapsal, a poté zaregistruje zpětné volání při návratu, a když se toto RPC vrátí, čekající dhaga bude přidána do fronty spustitelného souboru a poté přijata rodičovským vláknem. (Poznámka Banq: podobně jako node.js principu)
Dhaga můžeme použít místo vláken pro operace s vysokou latencí a v jednom vlákně používáme 512 dhag, když počet vláken překročí rozumný limit propustnosti.
|