- Vaša košarica je trenutno prazna
Python aplikacija z WebSocket, SSE in uvicorn
Obvestila v živo, napredek dolgotrajne obdelave, odgovor AI modela, ki se izpisuje sproti: za vse to aplikacije uporabljajo WebSocket ali SSE (ang. Server-Sent Events). Pogosto vprašanje strank je, ali to deluje tudi na spletnem gostovanju.
Kratek odgovor: da, vendar ne prek osnovne postavitve »Setup Python App«. V tem prispevku boste izvedeli, zakaj, in kako aplikacijo postaviti, da WebSocket in SSE delujeta.
Kazalo
- Zakaj osnovna postavitev ne zadošča?
- Rešitev: uvicorn kot samostojen proces
- Katera vrata uporabiti?
- 1. korak: Pripravite aplikacijo in virtualno okolje
- 2. korak: Zaženite uvicorn s PM2
- 3. korak: Posredovanje zahtevkov s .htaccess
- Nasveti za stabilne povezave v živo
- Kaj je primerno za spletno gostovanje?
Zakaj osnovna postavitev ne zadošča?
Python aplikacija, ustvarjena v Setup Python App, komunicira s spletnim strežnikom prek standarda WSGI (za FastAPI prek vmesnika a2wsgi). To pomeni:
- WebSocket ne deluje. WSGI ga ne podpira, strežnik vrne napako 404.
- SSE in pretakanje odgovorov delujeta z zamikom. Odgovor se pošilja v kosih po približno 8 KB, zato kratki dogodki pridejo vsi naenkrat ob koncu.
- Vsaka odprta povezava zaseda enega od največ 8 delovnih procesov aplikacije.
Za navadne API klice to ni težava. Za povezave v živo pa potrebujete aplikacijo, ki teče kot samostojen ASGI strežnik (uvicorn).
Rešitev: uvicorn kot samostojen proces
Postavitev je sestavljena iz treh delov:
- uvicorn teče kot vaš proces na lokalnem naslovu
127.0.0.1in na vratih, ki so dodeljena vašemu računu, - PM2 skrbi, da se uvicorn ob napaki samodejno znova zažene,
- datoteka
.htaccessspletnemu strežniku LiteSpeed naroči, naj zahtevke z vaše domene posreduje uvicornu.
Obiskovalci tako dostopajo do aplikacije prek običajnega naslova https://vasadomena.si/..., uvicorn pa od zunaj ni neposredno dosegljiv.
Pri tej postavitvi deluje vse, kar FastAPI ponuja: WebSocket, SSE brez zamikov, lifespan in startup dogodki ter BackgroundTasks, ki se izvedejo po odgovoru.
Katera vrata uporabiti?
Vsak račun ima dodeljena svoja vrata. Izpišete jih z ukazom:
echo $((20000 + $(id -u)))
Uporabljajte samo ta vrata in vedno naslov 127.0.0.1, nikoli 0.0.0.0.
1. korak: Pripravite aplikacijo in virtualno okolje
V Setup Python App ustvarite aplikacijo (npr. mojaapi) in namestite pakete, kot je opisano v prispevku Python aplikacija na spletnem gostovanju. V requirements.txt naj bo tudi uvicorn[standard].
Aplikacijo v Setup Python App lahko pustite, saj potrebujete njeno virtualno okolje. Njen URL nastavite na naslov, ki ga ne boste uporabljali (npr. /mojaapi-wsgi).
2. korak: Zaženite uvicorn s PM2
PM2 je upravitelj procesov, ki aplikacijo ob napaki samodejno znova zažene. Namestite ga v svojo domačo mapo (prek SSH):
export PATH=/opt/alt/alt-nodejs22/root/usr/bin:$PATH
mkdir -p ~/pm2 && cd ~/pm2
npm install pm2
Zaženite uvicorn (zamenjajte mojaapi, 3.11 in vrata s svojimi):
export PATH=/opt/alt/alt-nodejs22/root/usr/bin:$PATH
export PM2_HOME=~/pm2/.pm2
export OPENBLAS_NUM_THREADS=1 OMP_NUM_THREADS=1
PORT=$((20000 + $(id -u)))
~/pm2/node_modules/.bin/pm2 start ~/virtualenv/mojaapi/3.11/bin/uvicorn \
--name mojaapi \
--interpreter ~/virtualenv/mojaapi/3.11/bin/python \
--cwd ~/mojaapi \
-- main:app --host 127.0.0.1 --port $PORT
~/pm2/node_modules/.bin/pm2 save
Delovanje preverite s ~/pm2/node_modules/.bin/pm2 list in curl http://127.0.0.1:$PORT/.
Da se PM2 samodejno zažene tudi po ponovnem zagonu strežnika, dodajte cron opravilo. Navodila najdete v prispevku Opravila v ozadju, cron in PM2.
3. korak: Posredovanje zahtevkov s .htaccess
V mapo, na kateri bo aplikacija dostopna (npr. public_html/api/ ali koren poddomene), dodajte datoteko .htaccess (zamenjajte vrata s svojimi):
RewriteEngine On
RewriteCond %{HTTP:Upgrade} websocket [NC]
RewriteRule ^(.*)$ ws://127.0.0.1:21073/$1 [P,L]
RewriteRule ^(.*)$ http://127.0.0.1:21073/$1 [P,L]
Prvo pravilo je obvezno za WebSocket. Brez njega se povezava WebSocket ne vzpostavi, čeprav navadni zahtevki delujejo.
Nasveti za stabilne povezave v živo
Za zanesljivo delovanje povezav v živo upoštevajte naslednja priporočila:
- Pošiljajte heartbeat. Povezava, po kateri 10 minut ne potuje noben podatek, se prekine. Pri SSE vsakih 30–60 sekund pošljite komentar
: ping. Pri WebSocket povezavah uvicorn privzeto pošilja ping vsakih 20 sekund. - Poskrbite za ponovno povezavo. Ob vzdrževanju strežnika se odprte povezave lahko prekinejo.
EventSource(SSE) se znova poveže samodejno, pri WebSocket pa mora ponovno povezavo izvesti vaša koda. - SSE v FastAPI:
from fastapi.responses import StreamingResponse
import asyncio
@app.get("/events")
async def events():
async def gen():
while True:
yield "data: novo obvestilo\n\n"
await asyncio.sleep(30)
return StreamingResponse(gen(), media_type="text/event-stream")
Kaj je primerno za spletno gostovanje?
Stalno delujoč uvicorn porablja pomnilnik vašega paketa tudi takrat, ko nihče ne obišče strani, in šteje v omejitve paketa (npr. pri paketu Zeleni 1 GB pomnilnika in 20 sočasnih procesov). Na paketu Zeleni uvicorn s PM2 trajno zaseda približno 130 MB pomnilnika in 16 od 100 dovoljenih procesov in niti.
Za aplikacije, ki morajo teči ves čas, zato priporočamo Turbo gostovanje, ki ima več pomnilnika, procesorskih jeder in sočasnih procesov (npr. paket T1: 4 jedra, 6 GB, 100 procesov).
Primerno:
- obvestila in posodobitve v živo za manjše število uporabnikov,
- prikaz napredka obdelave, izpis odgovorov AI modela,
- API, ki potrebuje
lifespanali opravila v ozadju.
Ni primerno (v skladu s pogoji uporabe za to priporočamo VPS):
- javne klepetalnice (chat strežniki) in spletne igre,
- aplikacije z neprekinjeno porabo procesorja (obdelava podatkov, zbiranje podatkov),
- večje število sočasnih stalnih povezav.
Za take projekte priporočamo VPS strežnik, kjer imate na voljo celoten strežnik in poljubne nastavitve.
KOMENTIRAJTE OBJAVO
Vaš komentar je bil uspešno oddan
Komentar bo viden na strani, ko ga naši moderatorji potrdijo.