A Beginner’s Guide to Python Tornado

A web ma már egy nagy hely. Egyszerre több ezer ügyfelet kell támogatnunk, és itt jön a Tornado. A Tornado egy Python webes keretrendszer és aszinkron hálózati könyvtár, amelyet eredetileg a FriendFreednél fejlesztettek ki.

A Tornado nem blokkoló hálózati-io-t használ. Ennek köszönhetően több ezer aktív szerverkapcsolatot képes kezelni. Megmentője azoknak az alkalmazásoknak, ahol hosszú pollingot és nagyszámú aktív kapcsolatot kell fenntartani.

A Tornado nem olyan, mint a legtöbb Python keretrendszer. Nem a WSGI-n alapul, bár a WSGI néhány funkcióját támogatja a `tornado.wsgi` modul segítségével. Eseményhurok kialakítást használ, ami gyorsabbá teszi a Tornado kérések végrehajtását.

Mi az a szinkron program?

Egy függvény blokkol, elvégzi a számítását, és visszatér, ha végzett . Egy függvény több okból is blokkolhat: hálózati I/O, lemez I/O, mutexek stb.

Az alkalmazás teljesítménye attól függ, hogy az alkalmazás milyen hatékonyan használja a CPU-ciklusokat, ezért a blokkoló utasításokat/hívásokat komolyan kell venni. Gondoljunk csak a bcrypt-hez hasonló jelszóhasító függvényekre, amelyek eleve több száz ezredmásodpercnyi CPU-időt használnak, sokkal többet, mint egy tipikus hálózati vagy lemezelérés. Mivel a CPU nincs üresjáratban, nincs szükség aszinkron függvényekre.

Egy függvény lehet blokkoló az egyikben, és nem blokkoló a másikban. A Tornado kontextusában általában a hálózati I/O és a lemez miatti blokkolást tekintjük, bár mindenféle blokkolást minimalizálni kell.

Mi az aszinkron program?

1) Egyszálas architektúra:

Azt jelenti, hogy nem tud számításközpontú feladatokat párhuzamosan elvégezni.

2) I/O párhuzamosság:

Átadhatja az IO feladatokat az operációs rendszernek és folytathatja a következő feladattal a párhuzamosság elérése érdekében.

3) epoll/ kqueue:

Aláhúzza a rendszerrel kapcsolatos konstrukciót, amely lehetővé teszi, hogy egy alkalmazás eseményeket kapjon egy fájlleírón vagy I/O specifikus feladatokon.

4) Eseményhurok:

Az epoll vagy kqueue segítségével ellenőrzi, hogy történt-e bármilyen esemény, és végrehajtja a callback-et, amely ezekre a hálózati eseményekre vár.

Aszinkron vs szinkron webes keretrendszer:

A szinkron modell esetében minden egyes kérés vagy feladat átkerül egy szálra vagy útvonalra, és amint befejeződik, az eredményt átadja a hívónak. Itt a dolgok kezelése egyszerű, de az új szálak létrehozása túl nagy overheadet jelent.

Az aszinkron keretrendszerben, mint például a Node.js, egyszálas modell van, így nagyon kevés a overhead, de komplexitással jár.

Tegyük fel, hogy több ezer kérés érkezik, és egy szerver eseményhurkot és callbacket használ. Most, amíg a kérés feldolgozásra kerül, hatékonyan kell tárolnia és kezelnie a kérés állapotát, hogy a callback eredményét leképezze az aktuális ügyfélhez.

Node.js vs Tornado

A legtöbb ilyen összehasonlítási pont a tényleges programozási nyelvhez és nem a keretrendszerhez kötődik:

  • A Node.js-nek van egy nagy előnye, hogy az összes könyvtára Async. Pythonban rengeteg elérhető csomag van, de nagyon kevés közülük aszinkron
  • Mivel a Node.js JavaScript futtató, és a JS-t használhatjuk front- és back-endhez is, a fejlesztők csak egy kódbázist tarthatnak, és ugyanazt a segédkönyvtárat használhatják
  • A Google V8 motorjának köszönhetően a Node.js gyorsabb, mint a Tornado. De sok Python könyvtár C-ben íródott, és gyorsabb alternatívák lehetnek.

Egy egyszerű ‘Hello World’ példa

CODE: https://gist.github.com/velotiotech/b4d91554b739f2487bf6131ac65ec06d.js

Megjegyzés: Ez a példa nem használ semmilyen aszinkron funkciót.

Az AsyncHTTPClient modul használatával a REST hívást aszinkron módon tudjuk végrehajtani.

CODE: https://gist.github.com/velotiotech/5fe63eb5fd6cf3af9bf353c2fd3b4ca7.js

Mint láthatjuk, a `yield http_client.fetch(url)` coroutine-ként fog futni.

Komplex példa a Tornado Async

Nézzük meg az aszinkron kéréskezelőt.

WebSockets a Tornado használatával:

A Tornado rendelkezik beépített csomaggal a WebSockets számára, amely könnyen használható coroutine-okkal az egyidejűség eléréséhez, íme egy példa:

CODE: https://gist.github.com/velotiotech/34d0a0e0ecd57818ae1db1697c075777.js

Egy WebSocket kliensalkalmazást használhatunk a szerverhez való csatlakozáshoz, az üzenet bármilyen egész szám lehet. A feldolgozás után az ügyfél megkapja az eredményt, hogy az egész szám prím-e vagy sem.
Itt van még egy példa a Tornado tényleges aszinkron funkcióira. Sokan hasonlónak fogják találni a Golang Goroutine-hoz és a csatornákhoz.

Ebben a példában elindíthatjuk a worker(eke)t, és azok a ‘tornado.queue’-t hallgatják. Ez a várólista aszinkron, és nagyon hasonlít az asyncio csomaghoz.

CODE: https://gist.github.com/velotiotech/1477131948ca23879167df0281726d02.js

Következtetés

1) Az aszinkron keretrendszereknek nincs sok haszna, ha a számítások nagy része CPU-központú és nem I/O.

2) A magonkénti egy szálas modellnek és az eseményhuroknak köszönhetően több ezer aktív ügyfélkapcsolatot tud kezelni.

3) Sokan azt mondják, hogy a Django túl nagy, a Flask túl kicsi, a Tornado pedig pont jó:)

Vélemény, hozzászólás?

Az e-mail-címet nem tesszük közzé.