Išsami „Tornado“ – „Python“ žiniatinklio karkaso ir asinchroninės tinklo bibliotekos – analizė. Sužinokite, kaip kurti mastelio keitimui pritaikytas, didelio našumo programas su išsamiais paaiškinimais, pavyzdžiais ir geriausiomis praktikomis.
Tornado dokumentacija: išsamus vadovas programuotojams visame pasaulyje
„Tornado“ yra „Python“ žiniatinklio karkasas ir asinchroninė tinklo biblioteka, iš pradžių sukurta „FriendFeed“. Ji ypač tinka ilgalaikėms apklausoms (angl. long-polling), „WebSockets“ ir kitoms programoms, kurioms reikalingas ilgalaikis ryšys su kiekvienu vartotoju. Dėl neblokuojančio tinklo įvesties/išvesties (I/O) ji yra ypač pritaikoma mastelio keitimui ir galingas pasirinkimas kuriant didelio našumo žiniatinklio programas. Šis išsamus vadovas supažindins jus su pagrindinėmis „Tornado“ koncepcijomis ir pateiks praktinių pavyzdžių, padėsiančių jums pradėti.
Kas yra „Tornado“?
Iš esmės „Tornado“ yra žiniatinklio karkasas ir asinchroninė tinklo biblioteka. Skirtingai nuo tradicinių sinchroninių žiniatinklio karkasų, „Tornado“ naudoja vienos gijos, įvykių ciklu (angl. event-loop) paremtą architektūrą. Tai reiškia, kad ji gali valdyti daug vienu metu vykstančių ryšių, nereikalaudama atskiros gijos kiekvienam ryšiui, todėl yra efektyvesnė ir labiau pritaikoma mastelio keitimui.
Pagrindinės „Tornado“ savybės:
- Asinchroninis tinklų kūrimas: „Tornado“ pagrindas yra sukurtas aplink asinchroninę įvestį/išvestį (I/O), leidžiančią efektyviai valdyti tūkstančius vienu metu vykstančių ryšių.
- Žiniatinklio karkasas: Jame yra tokios funkcijos kaip užklausų tvarkytuvai, maršrutizavimas, šablonų naudojimas ir autentifikavimas, todėl tai yra pilnavertis žiniatinklio karkasas.
- „WebSocket“ palaikymas: „Tornado“ puikiai palaiko „WebSockets“, įgalindama realaus laiko komunikaciją tarp serverio ir klientų.
- Lengvas ir greitas: Sukurta našumui, „Tornado“ yra lengva ir efektyvi, sumažinanti pridėtines išlaidas ir maksimaliai padidinanti pralaidumą.
- Paprasta naudoti: Nepaisant pažangių funkcijų, „Tornado“ yra santykinai lengva išmokti ir naudoti, su aiškia ir gerai dokumentuota API.
„Tornado“ aplinkos paruošimas
Prieš pradedant kurti su „Tornado“, turėsite paruošti savo aplinką. Štai žingsnis po žingsnio vadovas:
- Įdiekite „Python“: Įsitikinkite, kad turite įdiegtą „Python“ 3.6 ar naujesnę versiją. Ją galite atsisiųsti iš oficialios „Python“ svetainės (python.org).
- Sukurkite virtualią aplinką (rekomenduojama): Naudokite
venv
arbavirtualenv
, kad sukurtumėte izoliuotą aplinką savo projektui:python3 -m venv myenv source myenv/bin/activate # Linux/macOS myenv\Scripts\activate # Windows
- Įdiekite „Tornado“: Įdiekite „Tornado“ naudodami pip:
pip install tornado
Jūsų pirmoji „Tornado“ programa
Sukurkime paprastą „Hello, World!“ programą su „Tornado“. Sukurkite failą pavadinimu app.py
ir pridėkite šį kodą:
import tornado.ioloop
import tornado.web
class MainHandler(tornado.web.RequestHandler):
def get(self):
self.write("Hello, World!")
def make_app():
return tornado.web.Application([
(r"/", MainHandler),
])
if __name__ == "__main__":
app = make_app()
app.listen(8888)
tornado.ioloop.IOLoop.current().start()
Dabar paleiskite programą iš savo terminalo:
python app.py
Atidarykite savo naršyklę ir eikite į http://localhost:8888
. Turėtumėte pamatyti pranešimą „Hello, World!“.
Paaiškinimas:
tornado.ioloop
: Pagrindinis įvykių ciklas, kuris tvarko asinchronines operacijas.tornado.web
: Pateikia žiniatinklio karkaso komponentus, tokius kaip užklausų tvarkytuvai ir maršrutizavimas.MainHandler
: Užklausų tvarkytuvas, kuris apibrėžia, kaip tvarkyti gaunamas HTTP užklausas.get()
metodas yra iškviečiamas GET užklausoms.tornado.web.Application
: Sukuria „Tornado“ programą, susiedama URL šablonus su užklausų tvarkytuvais.app.listen(8888)
: Paleidžia serverį, laukiantį gaunamų ryšių 8888 prievade.tornado.ioloop.IOLoop.current().start()
: Paleidžia įvykių ciklą, kuris apdoroja gaunamas užklausas ir tvarko asinchronines operacijas.
Užklausų tvarkytuvai ir maršrutizavimas
Užklausų tvarkytuvai yra „Tornado“ žiniatinklio programų pagrindas. Jie apibrėžia, kaip tvarkyti gaunamas HTTP užklausas pagal URL. Maršrutizavimas susieja URL su konkrečiais užklausų tvarkytuvais.
Užklausų tvarkytuvų apibrėžimas:
Norėdami sukurti užklausų tvarkytuvą, paveldėkite iš tornado.web.RequestHandler
ir įgyvendinkite atitinkamus HTTP metodus (get
, post
, put
, delete
ir kt.).
class MyHandler(tornado.web.RequestHandler):
def get(self):
self.write("This is a GET request.")
def post(self):
data = self.request.body.decode('utf-8')
self.write(f"Received POST data: {data}")
Maršrutizavimas:
Maršrutizavimas konfigūruojamas kuriant tornado.web.Application
. Jūs pateikiate kortežų sąrašą, kuriame kiekvienas kortežas susideda iš URL šablono ir atitinkamo užklausų tvarkytuvo.
app = tornado.web.Application([
(r"/", MainHandler),
(r"/myhandler", MyHandler),
])
URL šablonai:
URL šablonai yra reguliariosios išraiškos. Galite naudoti reguliariųjų išraiškų grupes, kad užfiksuotumėte URL dalis ir perduotumėte jas kaip argumentus užklausų tvarkytuvo metodams.
class UserHandler(tornado.web.RequestHandler):
def get(self, user_id):
self.write(f"User ID: {user_id}")
app = tornado.web.Application([
(r"/user/([0-9]+)", UserHandler),
])
Šiame pavyzdyje /user/([0-9]+)
atitinka URL, tokius kaip /user/123
. Dalis ([0-9]+)
užfiksuoja vieną ar daugiau skaitmenų ir perduoda juos kaip user_id
argumentą UserHandler
get
metodui.
Šablonų naudojimas
„Tornado“ turi paprastą ir efektyvų šablonų variklį. Šablonai naudojami dinamiškai generuoti HTML, atskiriant pateikimo logiką nuo programos logikos.
Šablonų kūrimas:
Šablonai paprastai laikomi atskiruose failuose (pvz., index.html
). Štai paprastas pavyzdys:
<!DOCTYPE html>
<html>
<head>
<title>My Website</title>
</head>
<body>
<h1>Welcome, {{ name }}!</h1>
<p>Today is {{ today }}.</p>
</body>
</html>
{{ name }}
ir {{ today }}
yra vietos rezervavimo ženklai, kurie bus pakeisti tikrosiomis vertėmis, kai šablonas bus atvaizduotas.
Šablonų atvaizdavimas:
Norėdami atvaizduoti šabloną, naudokite render()
metodą savo užklausų tvarkytuve:
class TemplateHandler(tornado.web.RequestHandler):
def get(self):
name = "John Doe"
today = "2023-10-27"
self.render("index.html", name=name, today=today)
Įsitikinkite, kad jūsų programos nustatymuose teisingai sukonfigūruotas template_path
nustatymas. Pagal numatytuosius nustatymus, „Tornado“ ieško šablonų kataloge pavadinimu templates
tame pačiame kataloge kaip ir jūsų programos failas.
app = tornado.web.Application([
(r"/template", TemplateHandler),
], template_path="templates")
Šablonų sintaksė:
„Tornado“ šablonai palaiko įvairias funkcijas, įskaitant:
- Kintamieji:
{{ variable }}
- Valdymo srautai:
{% if condition %} ... {% else %} ... {% end %}
,{% for item in items %} ... {% end %}
- Funkcijos:
{{ function(argument) }}
- Įtraukimai:
{% include "another_template.html" %}
- Išvengimas (Escaping): „Tornado“ automatiškai išvengia HTML esybių, kad apsisaugotų nuo kryžminio scenarijaus (XSS) atakų. Galite išjungti išvengimą naudodami
{% raw variable %}
.
Asinchroninės operacijos
„Tornado“ stiprybė slypi jos asinchroninėse galimybėse. Asinchroninės operacijos leidžia jūsų programai atlikti neblokuojančią įvestį/išvestį, pagerindamos našumą ir mastelio keitimo galimybes. Tai ypač naudinga užduotims, kurios apima laukimą išorinių išteklių, tokių kaip duomenų bazių užklausos ar tinklo užklausos.
@tornado.gen.coroutine
:
Dekoratorius @tornado.gen.coroutine
leidžia rašyti asinchroninį kodą naudojant yield
raktinį žodį. Tai padaro asinchroninį kodą panašesnį į sinchroninį, pagerindamas skaitomumą ir palaikomumą.
import tornado.gen
import tornado.httpclient
class AsyncHandler(tornado.web.RequestHandler):
@tornado.gen.coroutine
def get(self):
http_client = tornado.httpclient.AsyncHTTPClient()
response = yield http_client.fetch("http://example.com")
self.write(response.body.decode('utf-8'))
Šiame pavyzdyje http_client.fetch()
yra asinchroninė operacija, kuri grąžina Future
objektą. yield
raktinis žodis sustabdo korutinos vykdymą, kol Future
bus išspręstas. Kai Future
yra išspręstas, korutina atnaujina vykdymą ir atsakymo turinys yra rašomas klientui.
tornado.concurrent.Future
:
Future
atspindi asinchroninės operacijos rezultatą, kuris gali būti dar nepasiekiamas. Galite naudoti Future
objektus, kad sujungtumėte asinchronines operacijas ir tvarkytumėte klaidas.
tornado.ioloop.IOLoop
:
IOLoop
yra „Tornado“ asinchroninio variklio širdis. Ji stebi failų deskriptorius ir lizdus dėl įvykių ir perduoda juos atitinkamiems tvarkytuvams. Paprastai jums nereikia tiesiogiai sąveikauti su IOLoop
, bet svarbu suprasti jos vaidmenį tvarkant asinchronines operacijas.
„WebSockets“
„Tornado“ puikiai palaiko „WebSockets“, įgalindama realaus laiko komunikaciją tarp serverio ir klientų. „WebSockets“ idealiai tinka programoms, kurioms reikalinga dvikryptė, mažo delsos laiko komunikacija, pavyzdžiui, pokalbių programoms, internetiniams žaidimams ir realaus laiko informacinėms panelėms.
„WebSocket“ tvarkytuvo kūrimas:
Norėdami sukurti „WebSocket“ tvarkytuvą, paveldėkite iš tornado.websocket.WebSocketHandler
ir įgyvendinkite šiuos metodus:
open()
: Iškviečiamas, kai užmezgamas naujas „WebSocket“ ryšys.on_message(message)
: Iškviečiamas, kai gaunamas pranešimas iš kliento.on_close()
: Iškviečiamas, kai „WebSocket“ ryšys yra uždaromas.
import tornado.websocket
class WebSocketHandler(tornado.websocket.WebSocketHandler):
def open(self):
print("WebSocket opened")
def on_message(self, message):
self.write_message(f"You sent: {message}")
def on_close(self):
print("WebSocket closed")
def check_origin(self, origin):
return True # Įjungti kryžminės kilmės WebSocket ryšius
„WebSockets“ integravimas į jūsų programą:
Pridėkite „WebSocket“ tvarkytuvą į savo programos maršrutizavimo konfigūraciją:
app = tornado.web.Application([
(r"/ws", WebSocketHandler),
])
Kliento pusės įgyvendinimas:
Kliento pusėje galite naudoti „JavaScript“, kad užmegztumėte „WebSocket“ ryšį ir siųstumėte/gautumėte pranešimus:
const websocket = new WebSocket("ws://localhost:8888/ws");
websocket.onopen = () => {
console.log("WebSocket connection established");
websocket.send("Hello from the client!");
};
websocket.onmessage = (event) => {
console.log("Received message:", event.data);
};
websocket.onclose = () => {
console.log("WebSocket connection closed");
};
Autentifikavimas ir saugumas
Saugumas yra kritinis žiniatinklio programų kūrimo aspektas. „Tornado“ teikia keletą funkcijų, padedančių apsaugoti jūsų programas, įskaitant autentifikavimą, autorizavimą ir apsaugą nuo įprastų žiniatinklio pažeidžiamumų.
Autentifikavimas:
Autentifikavimas yra vartotojo tapatybės patvirtinimo procesas. „Tornado“ teikia integruotą palaikymą įvairioms autentifikavimo schemoms, įskaitant:
- Slapukais pagrįstas autentifikavimas: Saugokite vartotojo kredencialus slapukuose.
- Trečiųjų šalių autentifikavimas (OAuth): Integruokitės su populiariomis socialinės medijos platformomis, tokiomis kaip „Google“, „Facebook“ ir „Twitter“.
- API raktai: Naudokite API raktus API užklausų autentifikavimui.
Autorizavimas:
Autorizavimas yra procesas, nustatantis, ar vartotojas turi leidimą pasiekti tam tikrą išteklių. Galite įgyvendinti autorizavimo logiką savo užklausų tvarkytuvuose, kad apribotumėte prieigą pagal vartotojų roles ar leidimus.
Saugumo geriausios praktikos:
- Apsauga nuo kryžminio scenarijaus (XSS): „Tornado“ automatiškai išvengia HTML esybių, kad apsisaugotų nuo XSS atakų. Visada naudokite
render()
metodą šablonams atvaizduoti ir venkite generuoti HTML tiesiogiai savo užklausų tvarkytuvuose. - Apsauga nuo užklausų klastojimo tarp svetainių (CSRF): Įjunkite CSRF apsaugą savo programos nustatymuose, kad apsisaugotumėte nuo CSRF atakų.
- HTTPS: Visada naudokite HTTPS, kad šifruotumėte komunikaciją tarp serverio ir klientų.
- Įvesties tikrinimas: Tikrinkite visą vartotojo įvestį, kad išvengtumėte injekcijos atakų ir kitų pažeidžiamumų.
- Reguliarūs saugumo auditai: Atlikite reguliarius saugumo auditus, kad nustatytumėte ir pašalintumėte galimus pažeidžiamumus.
Diegimas
„Tornado“ programos diegimas apima kelis etapus, įskaitant žiniatinklio serverio konfigūravimą, procesų valdytojo nustatymą ir našumo optimizavimą.
Žiniatinklio serveris:
Galite diegti „Tornado“ už žiniatinklio serverio, tokio kaip „Nginx“ ar „Apache“. Žiniatinklio serveris veikia kaip atvirkštinis tarpinis serveris (angl. reverse proxy), perduodamas gaunamas užklausas „Tornado“ programai.
Procesų valdytojas:
Procesų valdytojas, toks kaip „Supervisor“ ar „systemd“, gali būti naudojamas valdyti „Tornado“ procesą, užtikrinant, kad jis būtų automatiškai paleistas iš naujo, jei sugestų.
Našumo optimizavimas:
- Naudokite produkcijai paruoštą įvykių ciklą: Naudokite produkcijai paruoštą įvykių ciklą, pvz.,
uvloop
, siekiant geresnio našumo. - Įjunkite gzip glaudinimą: Įjunkite gzip glaudinimą, kad sumažintumėte HTTP atsakymų dydį.
- Kaupkite statinius failus (Cache): Kaupkite statinius failus, kad sumažintumėte serverio apkrovą.
- Stebėkite našumą: Stebėkite savo programos našumą naudodami įrankius, tokius kaip „New Relic“ ar „Prometheus“.
Internacionalizacija (i18n) ir lokalizacija (l10n)
Kuriant programas pasaulinei auditorijai, svarbu atsižvelgti į internacionalizaciją (i18n) ir lokalizaciją (l10n). i18n yra programos projektavimo procesas, kad ją būtų galima pritaikyti įvairioms kalboms ir regionams be inžinerinių pakeitimų. l10n yra internacionalizuotos programos pritaikymo procesas konkrečiai kalbai ar regionui, pridedant lokalizacijai būdingus komponentus ir verčiant tekstą.
„Tornado“ ir i18n/l10n
Pats „Tornado“ neturi integruotų i18n/l10n bibliotekų. Tačiau galite lengvai integruoti standartines „Python“ bibliotekas, tokias kaip `gettext`, arba sudėtingesnius karkasus, pvz., „Babel“, kad tvarkytumėte i18n/l10n savo „Tornado“ programoje.
Pavyzdys naudojant `gettext`:
1. **Nustatykite lokalizacijas:** Sukurkite katalogus kiekvienai kalbai, kurią norite palaikyti, su pranešimų katalogais (paprastai `.mo` failais).
locales/
en/LC_MESSAGES/messages.mo
fr/LC_MESSAGES/messages.mo
de/LC_MESSAGES/messages.mo
2. **Išskirkite verčiamas eilutes:** Naudokite įrankį, pvz., `xgettext`, kad išskirtumėte verčiamas eilutes iš savo „Python“ kodo į `.po` failą (Portable Object). Šiame faile bus originalios eilutės ir vietos rezervavimo ženklai vertimams.
xgettext -d messages -o locales/messages.po your_tornado_app.py
3. **Išverskite eilutes:** Išverskite eilutes `.po` failuose kiekvienai kalbai.
4. **Kompiliuokite vertimus:** Kompiliuokite `.po` failus į `.mo` failus (Machine Object), kuriuos `gettext` naudoja vykdymo metu.
msgfmt locales/fr/LC_MESSAGES/messages.po -o locales/fr/LC_MESSAGES/messages.mo
5. **Integruokite į savo „Tornado“ programą:**
import gettext
import locale
import os
import tornado.web
class BaseHandler(tornado.web.RequestHandler):
def initialize(self):
try:
locale.setlocale(locale.LC_ALL, self.get_user_locale().code)
except locale.Error:
# Tvarkykite atvejus, kai lokalizacija nepalaikoma sistemoje
print(f"Locale {self.get_user_locale().code} not supported")
translation = gettext.translation('messages', 'locales', languages=[self.get_user_locale().code])
translation.install()
self._ = translation.gettext
def get_current_user_locale(self):
# Logika vartotojo lokalizacijai nustatyti (pvz., iš Accept-Language antraštės, vartotojo nustatymų ir t.t.)
# Tai supaprastintas pavyzdys - jums reikės patikimesnio sprendimo
accept_language = self.request.headers.get('Accept-Language', 'en')
return tornado.locale.get(accept_language.split(',')[0].split(';')[0])
class MainHandler(BaseHandler):
def get(self):
self.render("index.html", _=self._)
settings = {
"template_path": os.path.join(os.path.dirname(__file__), "templates"),
}
app = tornado.web.Application([
(r"/", MainHandler),
], **settings)
6. **Pakeiskite savo šablonus:** Naudokite `_()` funkciją (susietą su `gettext.gettext`), kad pažymėtumėte eilutes vertimui savo šablonuose.
<h1>{{ _("Welcome to our website!") }}</h1>
<p>{{ _("This is a translated paragraph.") }}</p>
Svarbūs aspektai pasaulinei auditorijai:
- **Simbolių kodavimas:** Visada naudokite UTF-8 kodavimą, kad palaikytumėte platų simbolių spektrą.
- **Datos ir laiko formatavimas:** Naudokite lokalizacijai būdingą datos ir laiko formatavimą. „Python“ `strftime` ir `strptime` funkcijos gali būti naudojamos su lokalizacijos nustatymais.
- **Skaičių formatavimas:** Naudokite lokalizacijai būdingą skaičių formatavimą (pvz., dešimtainius skyriklius, tūkstančių skyriklius). `locale` modulis suteikia funkcijas tam.
- **Valiutos formatavimas:** Naudokite lokalizacijai būdingą valiutos formatavimą. Apsvarstykite galimybę naudoti biblioteką, pvz., `Babel`, sudėtingesniam valiutos tvarkymui.
- **Iš dešinės į kairę (RTL) kalbos:** Palaikykite RTL kalbas, tokias kaip arabų ir hebrajų. Tai gali apimti jūsų svetainės maketo veidrodinį atspindėjimą.
- **Vertimo kokybė:** Naudokite profesionalius vertėjus, kad užtikrintumėte tikslius ir kultūriškai tinkamus vertimus. Mašininis vertimas gali būti gera pradžia, tačiau dažnai reikalauja žmogaus peržiūros.
- **Vartotojo lokalizacijos aptikimas:** Įgyvendinkite patikimą lokalizacijos aptikimą, remiantis vartotojo nuostatomis, naršyklės nustatymais ar IP adresu. Suteikite vartotojams galimybę rankiniu būdu pasirinkti pageidaujamą kalbą.
- **Testavimas:** Kruopščiai išbandykite savo programą su skirtingomis lokalizacijomis, kad įsitikintumėte, jog viskas rodoma teisingai.
Pažangesnės temos
Individualizuoti klaidų puslapiai:
Galite individualizuoti klaidų puslapius, kuriuos „Tornado“ rodo įvykus klaidai. Tai leidžia jums suteikti vartotojui draugiškesnę patirtį ir įtraukti derinimo informaciją.
Individualizuoti nustatymai:
Galite apibrėžti individualizuotus nustatymus savo programos konfigūracijoje ir pasiekti juos savo užklausų tvarkytuvuose. Tai naudinga saugant programai būdingus parametrus, tokius kaip duomenų bazės prisijungimo eilutės ar API raktai.
Testavimas:
Kruopščiai testuokite savo „Tornado“ programas, kad užtikrintumėte, jog jos veikia teisingai ir saugiai. Naudokite vienetų testus, integracijos testus ir „end-to-end“ testus, kad apimtumėte visus savo programos aspektus.
Išvada
„Tornado“ yra galingas ir universalus žiniatinklio karkasas, kuris puikiai tinka kuriant mastelio keitimui pritaikytas, didelio našumo žiniatinklio programas. Dėl jo asinchroninės architektūros, „WebSocket“ palaikymo ir lengvai naudojamos API jis yra populiarus pasirinkimas programuotojams visame pasaulyje. Vadovaudamiesi šiame išsamiame vadove pateiktomis gairėmis ir pavyzdžiais, galite pradėti kurti savo „Tornado“ programas ir pasinaudoti daugeliu jos funkcijų.
Nepamirškite pasikonsultuoti su oficialia „Tornado“ dokumentacija, kad gautumėte naujausią informaciją ir geriausias praktikas. Sėkmingo programavimo!