Django au Flask: Ipi bora kwa VPS ndogo ya 1GB?
Chambua matumizi ya RAM ya kila Gunicorn worker kwenye Django na Flask. Jifunze idadi halisi ya workers inayoweza kuendeshwa kwenye VPS ya 1GB hadi 2GB bila mfumo kukwama.
Gharama za Django na Flask kwenye VPS ndogo
Kulinganisha Django na Flask kwenye VPS ndogo ni suala la kumbukumbu (RAM) kwanza. Django hupakia ORM (object relational mapper) yake, mfumo wake wa migration, na tovuti ya admin (ukiiwasha), kwenye kila worker process unayoanzisha. Flask hupakia router na request object pekee. Kwenye seva ya 1 GB, tofauti hiyo huamua ni idadi ngapi ya workers inayoweza kutoshea, na idadi ya workers huamua ni maombi mangapi unaweza kuhudumia kwa wakati mmoja.
Gharama hiyo humgharimu Django tu ikiwa hutajenga upya kile ambacho kimekuandalia. Programu yenye akaunti za watumiaji, sessions, na admin panel inahitaji Django: RAM inayotumiwa na kila worker ni bei ya msimbo (code) ambayo hutaandika wewe mwenyewe. JSON API iliyo mbele ya datastore unayoiendesha tayari inahitaji Flask, kwa sababu vipengele vyote vya ziada vya Django havitalazimika kupakiwa. Hili ni suala la kufaa kwa mahitaji. Vipimo vilivyo hapa chini vitakuonyesha upande ambao programu yako inafaa zaidi.
Mfanyakazi mmoja wa gunicorn hutumia kumbukumbu kiasi gani?
The data behind this chart
[
{
"label": "Bare Python 3.12 process",
"rss_mb": 14,
"pss_mb": 9
},
{
"label": "Flask, one route",
"rss_mb": 42,
"pss_mb": 26
},
{
"label": "Flask + SQLAlchemy",
"rss_mb": 58,
"pss_mb": 38
},
{
"label": "Django, admin disabled",
"rss_mb": 78,
"pss_mb": 47
},
{
"label": "Django, admin enabled",
"rss_mb": 96,
"pss_mb": 58
}
]Hizo ni takwimu za kawaida zilizochapishwa kwa programu ya "hello world" ya kila aina kwenye Ubuntu 24.04 ikiwa na Python 3.12, wafanyakazi watatu wa gunicorn, na kipengele cha preload kimewashwa. Zichukulie kama kiwango cha chini kabisa, kwa sababu imports zako mwenyewe huongezeka juu ya msingi huo. Mfanyakazi wa Django mwenye admin iliyowashwa huonyesha 96 MB ya resident memory, huku sehemu yake ya uwiano wa kumbukumbu ikiwa ni 58 MB. Tofauti kati ya namba hizo mbili ndiyo mada kuu ya sehemu inayofuata.
Fanya vipimo hivyo hivyo kwenye seva yako mwenyewe.
sudo apt update && sudo apt install -y python3-venv
python3 -m venv /srv/site1/.venv
/srv/site1/.venv/bin/pip install django gunicorn setproctitleSakinisha setproctitle. Ikiwa imewekwa, gunicorn hubadilisha majina ya michakato yake kuwa gunicorn: master [site1] na gunicorn: worker [site1], jambo linaloruhusu amri zinazofuata kupata wafanyakazi kwa jina badala ya kubahatisha.
pgrep -af gunicorn
ps -o pid,rss,args -p $(pgrep -d, -f 'gunicorn: worker')Safu ya rss ni resident set size katika kilobytes: kila ukurasa wa kumbukumbu ambao mchakato unashikilia kwa sasa kwenye RAM. Kujumlisha namba hizi kwa wafanyakazi wote hutoa namba kubwa mno, kwa sababu mfanyakazi aliyegawanywa (forked worker) hushiriki kurasa na mzazi wake na ndugu zake, hivyo ukurasa mmoja huhesabiwa mara nyingi. Iombe kernel proportional set size (PSS) badala yake, ambayo hugawanya kila ukurasa ulioshirikiwa kwa michakato inayoutumia.
for pid in $(pgrep -f 'gunicorn: worker'); do awk -v p="$pid" '/^Pss:/ {printf "%s %d MB\n", p, $2/1024}' /proc/$pid/smaps_rollup; doneIendeshe kama mtumiaji anayemiliki wafanyakazi hao, au kwa kutumia sudo. PSS ndiyo safu ya kutumia kwa ajili ya bajeti, kwa sababu PSS hujumlisha kwa usahihi wakati RSS haifanyi hivyo.
Django ni kubwa zaidi kwa sababu ya kile ambacho django.setup() hufanya. Inafanya import ya kila ingizo katika INSTALLED_APPS, inajenga sajili ya programu, na kuunda kila darasa la model pamoja na kitu cha Python kwa kila field iliyomo. Kuongeza django.contrib.admin huendesha utambuzi wa kiotomatiki wa admin, ambao hufanya import ya moduli ya admin ya kila programu na kuvuta tabaka za forms na templates nyuma yake. Mfanyakazi wa Flask hufanya import ya Werkzeug na Jinja2, kisha huishia hapo.
Onyo moja la kweli: mfumo (framework) mara nyingi ni sehemu ndogo tu. Mfanyakazi anayefanya import ya cloud SDK au kitu chochote cha namba hubeba uzito mkubwa zaidi kuliko Django. Pima programu yako halisi kabla ya kuamua kuwa mfumo ndio tatizo.
Copy on write, na kwa nini preload inabadilisha namba
Mchakato mkuu (master process) wa Gunicorn hufanya fork ya wafanyakazi (workers). Mara tu baada ya fork(), mchakato mwana (child) hushiriki kila ukurasa wa kumbukumbu (memory page) na mzazi, na kernel hunakili ukurasa pale tu upande mmoja unapoandika kwenye ukurasa huo. Kwa hivyo, kama sajili ya modeli ya Django ipo mara moja au mara nne kwenye seva inategemea upande upi wa fork ilipojengwa.
Ikiwa preload_app imezimwa, kila mfanyakazi hu-import programu yako baada ya kufanyiwa fork, hivyo kila mmoja hujenga nakala yake binafsi. Ikiwa imewashwa, mchakato mkuu hu-import programu mara moja na wafanyakazi hurithi kurasa hizo.
import gc
bind = "unix:/run/site1/gunicorn.sock"
umask = 0o007
workers = 3
timeout = 30
preload_app = True
max_requests = 500
max_requests_jitter = 50
def when_ready(server):
gc.freeze()CPython inafanya kazi kinyume na copy on write. Kila kichwa cha kitu (object header) kina hesabu ya marejeleo (reference count), na kugusa kitu chochote huandika kwenye kichwa hicho, hivyo kurasa zilizoshirikiwa hunakiliwa moja baada ya nyingine wakati mkusanyaji taka (garbage collector) anapopitia heap. gc.freeze() huhamisha kila kitu kilichotengwa hadi sasa kwenye kizazi cha kudumu ambacho mkusanyaji hatakitembelea tena, jambo linalosaidia kurasa nyingi zaidi kubaki zikiwa zimeshirikiwa. when_ready ndicho kiunganishi (hook) sahihi kwa sababu kinafanya kazi baada ya preload na kabla ya mfanyakazi wa kwanza kufanyiwa fork. Pima PSS kabla na baada ya kuiongeza, kwa sababu akiba ya kumbukumbu inategemea kiasi gani cha programu yako ni hali ya wakati wa import.
Preload ina gharama moja inayowashangaza watu siku ya deploy. systemctl reload hutuma HUP, na tabia ya Gunicorn iliyoandikwa kwenye nyaraka kuhusu HUP ni kupakia upya usanidi wake na kuanzisha wafanyakazi wapya. Wakati programu imefanyiwa preload, haifanyi re-import ya msimbo wako, kwa hivyo toleo lako jipya halifanyi kazi hata kama michakato ya wafanyakazi ni mipya. Tumia systemctl restart baada ya mabadiliko ya msimbo, au mfuatano wa USR2 kisha WINCH ikiwa unahitaji wafanyakazi wa zamani wamalize kazi zao kwanza.
Ni wafanyakazi wangapi VPS ya 1 GB inaweza kuendesha kwa uhalisia?
The data behind this chart
[
{
"label": "Ubuntu 24.04 base",
"ram_mb": 190
},
{
"label": "nginx",
"ram_mb": 12
},
{
"label": "PostgreSQL, default config",
"ram_mb": 120
},
{
"label": "Headroom you must leave",
"ram_mb": 150
},
{
"label": "Left for gunicorn workers",
"ram_mb": 550
}
]Hizo ni takwimu za hali ya kutofanya kazi (idle) kwenye seva isiyohudumia chochote. Takriban 550 MB zimebaki kwa ajili ya wafanyakazi wa programu (application workers), na hiyo ni kabla ya ombi la kwanza kufika.
Sasa gawanya, na uwe na mtazamo wa tahadhari. Ombi hutumia kumbukumbu linapokuwa linafanya kazi: queryset inayopakia safu chache elfu, kisha utoaji wa template. Kilele cha matumizi kwa kila mfanyakazi mara nyingi ni karibu mara mbili ya takwimu ya idle, kwa hivyo panga bajeti kwa kuzingatia mara mbili ya kiasi hicho. Django ikiwa na admin katika 58 MB ya idle inakupa wafanyakazi wanne kwenye seva hii. Flask ikiwa na SQLAlchemy katika 38 MB inakupa saba.
Pendekezo la (2 x cores) + 1 la Gunicorn linadhani kuwa CPU ndiyo rasilimali adimu na RAM siyo. Kwenye VPS ndogo, hiyo ni kinyume. vCPU moja iliyoshirikiwa pia inakupa chini ya uwezo wa core moja wakati mwenyeji (host) ana shughuli nyingi, jambo ambalo ni muhimu kulielewa kabla ya kulaumu msimbo wako: CPU steal time kutoka kwa jirani mwenye kelele huonekana katika top kama takwimu ya st.
Ikiwa views zako nyingi husubiri database au API ya juu, threads ni bora kuliko processes hapa. --worker-class gthread --workers 2 --threads 4 inatoa maombi nane ya wakati mmoja kwa gharama ya kumbukumbu ya wafanyakazi wawili, kwa sababu threads hushiriki nakala moja iliyopakiwa ya interpreter na framework. Global interpreter lock inamaanisha kuwa threads hazisaidii view inayotumia CPU nyingi.
Ipe seva swap. VPS ya 1 GB isiyo na swap hugeuza ongezeko la ghafla la kumbukumbu kuwa mchakato uliouawa (killed process), wakati swapfile hugeuza ongezeko hilo kuwa ombi la polepole.
sudo fallocate -l 1G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile
echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab
echo 'vm.swappiness = 10' | sudo tee /etc/sysctl.d/99-swappiness.conf
sudo sysctl --systemKisha weka kikomo kwa programu yenyewe. MemoryMax=600M kwenye unit ya gunicorn inamaanisha kuwa kernel itachukua kumbukumbu kutoka kwa cgroup ya programu yako badala ya kuchagua mwathiriwa kutoka kwenye seva nzima, kwa hivyo ombi linalotoka nje ya udhibiti halitakugharimu session yako ya SSH.
Tabia ya kuanza na kuanzisha upya (Cold start and restart)
The data behind this chart
[
{
"label": "Flask, one route",
"cold_start_ms": 90
},
{
"label": "Flask + SQLAlchemy",
"cold_start_ms": 260
},
{
"label": "Django, admin disabled",
"cold_start_ms": 480
},
{
"label": "Django, admin enabled",
"cold_start_ms": 720
}
]Gharama ya boot hulipwa mara mbili: wakati wa kila deploy, na wakati wa kila restart ya kiotomatiki baada ya crash. Programu ndogo ya Flask huwa tayari ndani ya takriban 90 ms, na Django ikiwa na admin imewezeshwa huchukua takriban 720 ms kwenye vCPU ileile ya pamoja. Hizi ni takwimu za kawaida zilizochapishwa. Pima zako mwenyewe, kwa sababu dependencies zako ndizo zinazoathiri zaidi.
cd /srv/site1
DJANGO_SETTINGS_MODULE=site1.settings /srv/site1/.venv/bin/python -X importtime -c "import django; django.setup()" 2>&1 | tail -20Mistari ya mwisho huorodhesha imports za polepole zaidi kwa kutumia microseconds limbikizi. Kwa Flask, tumia flag ileile dhidi ya moduli yako: python -X importtime -c "import app".
Ikiwa preload imewashwa, master hulipa gharama hiyo mara moja na kila worker aliyefork huanza papo hapo. Ikiwa preload imezimwa, kila worker hulipa gharama hiyo, na timeout ya gunicorn hufunika boot pamoja na ombi. Worker ambaye hajajiripoti ndani ya sekunde timeout huuwawa na kubadilishwa, kwa hivyo programu nzito kwenye vCPU ya polepole ya pamoja inaweza kukwama kwenye mzunguko wa restart ambao hautoi huduma yoyote. Log inasema:
[2026-08-09 09:14:02 +0000] [981] [CRITICAL] WORKER TIMEOUT (pid:1004)Migrations ni za kitengo (unit), si za msimbo wa kuanzisha programu (application startup code). ExecStartPre huendeshwa mara moja kabla ya worker yeyote kuwepo. Kuweka migrate ndani ya programu yako inamaanisha kuwa workers watatu watashindana dhidi ya lock ileile ya schema.
Muundo wa deployment ni karibu sawa
Meneja wa mchakato
Framework zote mbili huendeshwa chini ya gunicorn, na gunicorn huendeshwa chini ya systemd.
[Unit]
Description=gunicorn for site1
After=network.target
[Service]
User=site1
Group=www-data
WorkingDirectory=/srv/site1
RuntimeDirectory=site1
Environment="PATH=/srv/site1/.venv/bin"
ExecStartPre=/srv/site1/.venv/bin/python manage.py migrate --noinput
ExecStart=/srv/site1/.venv/bin/gunicorn -c /srv/site1/gunicorn.conf.py site1.wsgi:application
Restart=on-failure
RestartSec=3
MemoryMax=600M
[Install]
WantedBy=multi-user.targetRuntimeDirectory=site1 hutengeneza /run/site1 wakati wa kuanza na kuifuta wakati wa kusimama, hivyo njia ya socket ipo kila wakati ikiwa na mmiliki sahihi. Mstari wa umask = 0o007 katika usanidi wa gunicorn ndio unaofanya socket hiyo iweze kuandikwa na kundi la www-data, ambayo ndiyo njia ambayo nginx huitumia kuifikia.
Unit ya Flask ni faili lilelile likiwa na mstari mmoja uliobadilishwa: ExecStart=... gunicorn -c /srv/site1/gunicorn.conf.py app:app, na hakuna ExecStartPre. Hoja ya app:app ni moduli ikifuatiwa na callable, kwa hivyo kosa la Failed to find attribute 'app' in 'app'. linamaanisha kuwa moduli yako haijafafanua variable kwa jina hilo. Kazi zilizopangwa hufuata muundo uleule, na systemd timer inachukua nafasi ya cron kwa amri ya usimamizi ya Django bila kuongeza foleni ya kazi kwenye seva ya ukubwa huu.
Faili tuli (Static files)
Django ikiwa na DEBUG = False haihudumii faili zozote tuli. Weka STATIC_ROOT, endesha python manage.py collectstatic, na uelekeze seva ya wavuti kwenye saraka ya matokeo. Ukiruka hatua hiyo, admin itapakia bila mtindo wowote huku logi ikijaa Not Found: /static/admin/css/base.css.
Kuna njia mbili zinazofaa za kuzihudumia. Block ya nginx ya alias haigharimu programu yako chochote. WhiteNoise, iliyoongezwa kama middleware, huhudumia faili kutoka kwa worker na kukuokoa block ya nginx, kwa gharama ya muda kidogo wa worker kwa kila faili. Flask huhudumia folda yake ya static/ wakati wa maendeleo, na katika uzalishaji unaelekeza proxy kwenye folda hiyo kwa sababu hiyo hiyo.
Reverse proxy
server {
listen 80;
server_name example.com;
location /static/ {
alias /srv/site1/static/;
expires 30d;
}
location / {
proxy_pass http://unix:/run/site1/gunicorn.sock;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}Nyuma ya proxy yoyote, Django inahitaji kuambiwa kuwa ombi la asili lilikuwa HTTPS, vinginevyo ukaguzi wake wa cross site request forgery (CSRF) utakataa fomu zako.
ALLOWED_HOSTS = ["example.com"]
CSRF_TRUSTED_ORIGINS = ["https://example.com"]
SECURE_PROXY_SSL_HEADER = ("HTTP_X_FORWARDED_PROTO", "https")Ikiwa seva tayari inaendesha containers, Traefik mbele ya programu kadhaa za Docker Compose hufanya kazi hiyo hiyo kwa kutumia lebo kwenye container badala ya faili moja kwa kila tovuti.
Database ipi
SQLite inafaa kabisa kwa seva moja ya programu yenye kiwango cha uandishi kinachopimwa kwa chache kwa sekunde, na huondoa daemon nzima kutoka kwa bajeti ya kumbukumbu. Washa write ahead logging (WAL) na upe driver muda wa kusubiri (busy timeout).
DATABASES = {
"default": {
"ENGINE": "django.db.backends.sqlite3",
"NAME": BASE_DIR / "db.sqlite3",
"OPTIONS": {
"timeout": 20,
"init_command": "PRAGMA journal_mode=WAL;",
},
}
}Bila chaguzi hizo mbili utakutana na django.db.utils.OperationalError: database is locked mara ya kwanza wafanyakazi wawili wanapoandika kwa wakati mmoja, kwa sababu hali ya default ya journal huzuia wasomaji wakati wa uandishi na muda wa default wa kusubiri huacha mara moja. Hoja ndefu zaidi, ikijumuisha mahali ambapo SQLite inaacha kuwa jibu sahihi, iko katika kuendesha SQLite katika uzalishaji kwenye VPS.
PostgreSQL kwenye seva ileile ya 1 GB inagharimu 120 MB katika bajeti hapo juu, pamoja na mchakato mmoja wa backend kwa kila muunganisho wa kudumu. CONN_MAX_AGE ya Django huweka muunganisho wazi kwa kila worker, kwa hivyo wafanyakazi wanne wanamaanisha backends wanne. Hiyo kawaida ni biashara nzuri. Ihesabu tu kabla ya kuweka idadi ya wafanyakazi. Ikiwa ungependelea kuweka database kwenye container kando ya programu, kuendesha Docker kwenye VPS ni biashara ileile kwa gharama ya juu zaidi, kwa kuwa daemon na kila container huongeza mzigo ambao ni muhimu kwa ukubwa huu.
Faida za Django na gharama zake
Megabytes za ziada za Django ni mkusanyiko wa vipengele ambavyo tayari vipo na vinafanya kazi pamoja: ORM yenye uwezo wa migrations, mfumo wa session na authentication, muundo wa ruhusa (permission model), safu ya fomu yenye ulinzi wa CSRF, injini ya template, amri za usimamizi (management commands), na sehemu ya admin. Sehemu ya admin ni kipengele ambacho watu hukidharau. Ni kihariri cha database kinachofanya kazi kwa ajili ya models zako, kikiwa na utafutaji na vichujio, kwa mstari mmoja tu wa msimbo katika INSTALLED_APPS.
Flask ni kinyume chake. Unapata routing, request object, Jinja2 templates, na config object. Kila kitu kingine ni chaguo lako, jambo ambalo ni thamani halisi wakati programu ni ndogo, kwa sababu hakuna ORM inayopakiwa ikiwa hutaiingiza (import).
Mtego upo katika njia ya kati. Ukiongeza SQLAlchemy kwa ajili ya models, Alembic kwa ajili ya migrations, Flask-Login kwa ajili ya sessions, Flask-WTF kwa ajili ya fomu na CSRF, na extension ya admin kwa ajili ya ofisi ya nyuma, utakuwa umeunda kitu chenye matumizi ya kumbukumbu (RAM) sawa na ya Django lakini bila mshikamano wake. Kila kipengele kina mzunguko wake wa releases na mtazamo wake kuhusu jinsi programu inapaswa kuunganishwa. Hapo ndipo Django inapokuwa jibu la bei nafuu, katika matumizi ya RAM na katika saa unazotumia kufanya upgrades.
Django dhidi ya Flask: kanuni ya uamuzi
Tumia Django wakati programu ina akaunti, maudhui yanayoweza kuhaririwa, schema inayobadilika mara kwa mara, na mfumo wa usimamizi (back office) ambao utatumiwa na watu. Tumia Flask wakati programu ni interface ya JSON juu ya datastore iliyopo, au mpokeaji wa webhook asiye na HTML yoyote.
Kigezo cha mwisho cha uamuzi ni orodha iliyoandikwa. Andika kila package utakayoisakinisha kwenye Flask ili kufikia seti ya vipengele unavyohitaji. Ikiwa orodha hiyo ina ORM na zana ya migration, tayari umechagua Django na unalipa gharama za ziada ili kufika huko kwa mwendo wa polepole.
Kuna kisa kimoja ambacho kwa kweli kinapendelea Flask kwenye vifaa vidogo: huduma kadhaa ndogo kwenye seva moja. Kila huduma ya Flask ni mchakato wake wa bei nafuu chini ya unit yake binafsi. Tovuti tatu za Django kwenye VPS ya 1 GB inamaanisha nakala tatu za framework hiyo zikifanya kazi kwa wakati mmoja, na hesabu iliyotajwa hapo juu inashindwa kufanya kazi. Ikiwa rasilimali zinaendelea kuwa chache, mpango mkubwa zaidi mara nyingi ndio suluhisho la kweli, na gharama halisi ya VPS kwa mwezi ni mazungumzo mafupi zaidi kuliko kuandika upya programu inayofanya kazi.
Njia za hitilafu na ujumbe utakaouona
Wafanyakazi (workers) hupotea na kurudi. Gunicorn huchapisha [ERROR] Worker (pid:1234) was sent SIGKILL! Perhaps out of memory?. Ujumbe huu hutokea pale inapoua mfanyakazi aliyepitiliza muda wa heartbeat, au pale kernel inapoua mchakato huo. Tofautisha matukio haya mawili kwa kutumia dmesg -T | grep -i "killed process". Mstari hapo unaoashiria kumbukumbu (memory) unamaanisha kuwa unahitaji kupunguza idadi ya wafanyakazi au kuongeza swap.
Kila ukurasa unarudisha 400 na logi inasema Invalid HTTP_HOST header. Ujumbe kamili ni Invalid HTTP_HOST header: 'example.com'. You may need to add 'example.com' to ALLOWED_HOSTS.. Django hukataa ombi kabla halijafika kwenye msimbo wako, kwa sababu ALLOWED_HOSTS haina kitu au haijajumuisha jina ambalo proxy imepitisha kwenye Host.
Fomu zinashindwa kufanya kazi na kuleta Origin checking failed. Ukurasa unasema uthibitisho wa CSRF umefeli. Hili hutokea nyuma ya proxy inayofanya TLS termination: programu huona HTTP ya kawaida, hutengeneza http:// origin, na kuilinganisha na ombi lililofika kupitia https://. Weka SECURE_PROXY_SSL_HEADER na CSRF_TRUSTED_ORIGINS, kisha thibitisha kuwa proxy inatuma X-Forwarded-Proto.
nginx inarudisha 502 mara moja. Logi ya makosa inaeleza sababu: connect() to unix:/run/site1/gunicorn.sock failed (2: No such file or directory) inamaanisha unit haifanyi kazi, na (13: Permission denied) inamaanisha socket ipo lakini nginx haiwezi kuifungua, jambo linalotokana na mipangilio ya umask na group.
Ukurasa wa admin hauna muonekano (styling). collectstatic haijatekelezwa, au njia ya alias hailingani na STATIC_ROOT. Logi ya ufikiaji (access log) inaonyesha 404 chini ya /static/admin/.
Uandikaji unashindwa hata kwenye mzigo mdogo. database is locked kutoka SQLite inamaanisha WAL imezimwa au busy timeout ni fupi mno kwa wafanyakazi wawili kuandika kwa wakati mmoja.
FAQ
Je, Django ni nzito sana kwa VPS ya 1 GB?
Hapana. Django ikiwa na idadi ndogo ya workers, nginx mbele, na SQLite nyuma hufanya kazi vizuri kwenye 1 GB. Mambo huwa magumu unapoongeza PostgreSQL yenye mipangilio yake ya kawaida, cache, background worker, na Docker kwenye seva hiyo hiyo. Pima proportional set size ya worker mmoja, zidisha mara mbili ili kuruhusu ongezeko la maombi, kisha linganisha jumla hiyo na kile kilichobaki baada ya mfumo wa uendeshaji na database.
Ni gunicorn workers wangapi ninaopaswa kuendesha kwenye vCPU moja?
Anza na watatu kisha upime. Kumbukumbu (RAM) kwa kawaida ndiyo kizuizi kikuu kwenye VPS ndogo, kwa hivyo gawanya RAM iliyobaki baada ya mfumo wa uendeshaji na database kwa mara mbili ya proportional set size ya worker mmoja. Ikiwa views zako nyingi husubiri database au upstream API, badilisha na utumie gthread worker class yenye idadi ndogo ya workers na threads kadhaa kila mmoja, kwa sababu threads hushiriki nakala moja ya framework iliyopakiwa na hutumia kumbukumbu kidogo sana kuliko processes za ziada.
Je, ninahitaji PostgreSQL, au SQLite inatosha?
SQLite inatosha kwa seva moja ya programu yenye kiwango kidogo cha uandishi, na huondoa daemon nzima kwenye bajeti ya kumbukumbu. Washa write ahead logging na uweke busy timeout, vinginevyo uandishi wa wakati mmoja utafeli kwa database is locked. Hamia PostgreSQL wakati mashine zaidi ya moja inahitaji kuandika, au unapohitaji kitu ambacho SQLite haitoi, kama vile waandishi wengi wenye mzigo mkubwa au udhibiti wa ufikiaji kwa kila role.
Je, ninapaswa kuendesha uvicorn badala ya gunicorn?
Fanya hivyo tu ikiwa una async views na kitu halisi cha kusubiri. Flask ni programu ya WSGI, kwa hivyo async view huendeshwa kwenye event loop mpya ndani ya worker thread na kumalizika kabla ya ombi linalofuata kuanza, jambo ambalo haliongezi concurrency yoyote. Django async views zinahitaji ASGI server ili kusaidia kwa vyovyote vile. Matoleo ya hivi karibuni ya uvicorn yamehamisha gunicorn worker class yao kwenye package tofauti, kwa hivyo soma nyaraka za sasa za uvicorn badala ya kunakili flag ya zamani ya worker class kutoka kwenye mafunzo ya zamani.
Kwa nini worker wangu alitoweka bila traceback?
Process iliyouawa na kernel kupitia out of memory killer hupokea SIGKILL na haiwezi kuandika chochote kwenye log wakati inafungwa, kwa hivyo log ya programu yako huacha tu. Gunicorn hutambua pengo hilo na kuchapisha Worker (pid:1234) was sent SIGKILL! Perhaps out of memory?. Thibitisha hili kwa dmesg -T | grep -i "killed process". Suluhisho ni kupunguza idadi ya workers, au kutumia swapfile ili ongezeko la ghafla la matumizi ya kumbukumbu lisababishe ombi la polepole badala ya process kufa.