SSD Nodes Learn 🎉 VPS $5.50/నెల నుండి
మార్గదర్శకాలు Matt Connorద్వారా Matt Connor · అప్‌డేట్ చేయబడింది 2026-08-13

చిన్న VPSపై Django vs Flask: RAM, workers పోలిక

1 నుంచి 2 GB VPSలో Django, Flaskకు gunicorn workerకు ఎంత resident memory పడుతుందో, చిన్న server నిజంగా ఎన్ని workers నడపగలదో కొలతలతో తెలుసుకోండి.

చిన్న VPSపై Django మరియు Flask వనరుల ఖర్చు

చిన్న VPSపై Django మరియు Flask మధ్య ఎంపికలో మొదటి ప్రశ్న memory గురించినదే. మీరు ప్రారంభించే ప్రతి worker processలో Django తన object relational mapper (ORM), migration వ్యవస్థను, అలాగే enable చేస్తే admin siteను load చేస్తుంది. Flask ఒక routerను, request objectను load చేస్తుంది. 1 GB ఉన్న serverలో ఈ తేడా ఎన్ని workers సరిపోతాయో నిర్ణయిస్తుంది. Worker count ఒకేసారి ఎన్ని requestsను అందించగలరో నిర్ణయిస్తుంది.

Django అందించే భాగాలను మీరు మళ్లీ స్వయంగా నిర్మించకపోతేనే ఆ ఖర్చు Djangoకు ప్రతికూలంగా మారుతుంది. User accounts, sessions, admin panel ఉన్న అప్లికేషన్‌కు Django సరైన ఎంపిక. ప్రతి workerకు అవసరమయ్యే RAM, మీరు రాయకుండా మిగిలే codeకు చెల్లించే ధర. మీరు ఇప్పటికే నడుపుతున్న datastore ముందు పనిచేసే JSON APIకి Flask సరైనది. ఎందుకంటే ఆ batteriesలో ఏదీ load కావాల్సిన అవసరం ఉండదు. ఇది సరైన సరిపోలికను నిర్ణయించే ప్రశ్న. దిగువ measurements మీ అప్లికేషన్ ఏ వైపుకు చెందుతుందో చూపిస్తాయి.

ఒక gunicorn worker ఎంత memory ఉపయోగిస్తుంది?

ChartMemory per gunicorn worker, minimal app, three workers with preload on
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
  }
]

ఇవి Ubuntu 24.04లో Python 3.12, మూడు gunicorn workers మరియు preload ప్రారంభించి, ప్రతి రకమైన hello world app కోసం సాధారణంగా ప్రచురించే గణాంకాలు. వీటిని కనిష్ఠ పరిమితిగా పరిగణించండి, ఎందుకంటే మీ స్వంత imports వాటికి అదనంగా memory ఉపయోగిస్తాయి. admin ప్రారంభించిన Django worker resident memoryగా 96 MB చూపిస్తుంది. దాని proportional share of memory 58 MB ఉంటుంది. ఈ రెండు సంఖ్యల మధ్య తేడానే తరువాతి section మొత్తం విషయంగా ఉంటుంది.

మీ స్వంత boxలో ఇదే measurement రూపొందించండి.

sudo apt update && sudo apt install -y python3-venv
python3 -m venv /srv/site1/.venv
/srv/site1/.venv/bin/pip install django gunicorn setproctitle

setproctitle ను install చేయండి. ఇది అందుబాటులో ఉంటే, gunicorn తన processes పేర్లను gunicorn: master [site1] మరియు gunicorn: worker [site1] గా మార్చుతుంది. అందువల్ల తరువాతి commands workers ను అంచనా వేయకుండా, పేరుతో కనుగొనగలవు.

pgrep -af gunicorn
ps -o pid,rss,args -p $(pgrep -d, -f 'gunicorn: worker')

rss column resident set size ను kilobytesలో చూపిస్తుంది. అంటే process ప్రస్తుతం RAMలో ఉంచుకున్న ప్రతి memory page. Workersలో దీన్ని మొత్తం చేస్తే సంఖ్య ఎక్కువగా వస్తుంది. కారణం, fork చేసిన worker తన parentతో మరియు ఇతర workersతో pages share చేస్తుంది. అందువల్ల అదే page అనేకసార్లు లెక్కించబడుతుంది. దానికి బదులుగా kernel నుంచి proportional set size (PSS) అడగండి. ఇది shared pageను దాన్ని map చేసిన processes మధ్య విభజిస్తుంది.

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; done

Workersకు owner అయిన userగా లేదా sudoతో దీన్ని run చేయండి. Budget నిర్ణయించడానికి PSS columnనే ఉపయోగించాలి. PSS సరైన మొత్తం ఇస్తుంది; RSS ఇవ్వదు.

django.setup() చేసే పనివల్ల Django ఎక్కువ memory ఉపయోగిస్తుంది. ఇది INSTALLED_APPS లోని ప్రతి entryను import చేస్తుంది, application registryని రూపొందిస్తుంది, ప్రతి model classను instantiate చేస్తుంది. అలాగే ప్రతి fieldకు ఒక Python objectను సృష్టిస్తుంది. django.contrib.admin జోడిస్తే admin autodiscovery నడుస్తుంది. ఇది ప్రతి appలోని admin moduleను import చేసి, forms మరియు template layersను కూడా load చేస్తుంది. Flask worker Werkzeug మరియు Jinja2ను import చేసి అక్కడితో ఆగుతుంది.

ఒక ముఖ్యమైన పరిమితి ఉంది: framework తరచుగా చిన్న భాగమే. cloud SDK లేదా ఏదైనా numeric libraryని import చేసే worker, Djangoకన్నా వాటికే ఎక్కువ memory ఉపయోగించవచ్చు. Frameworkనే సమస్యగా నిర్ణయించేముందు మీ నిజమైన appను measure చేయండి.

copy-on-write మరియు preload సంఖ్యను ఎందుకు మారుస్తుంది

Gunicorn యొక్క master process workers ను fork చేస్తుంది. fork() వెంటనే child, parent లోని ప్రతి memory page ను share చేస్తుంది. ఆ రెండు వైపులలో ఏదైనా page కు write చేసినప్పుడు మాత్రమే kernel ఆ page ను copy చేస్తుంది. అందువల్ల సర్వర్‌లో Django model registry ఒకసారి ఉందా లేదా నాలుగు సార్లు ఉందా అనేది అది fork కు ముందు ఏ వైపున నిర్మించబడిందనే దానిపై ఆధారపడి ఉంటుంది.

preload_app నిలిపివేస్తే, ప్రతి worker fork అయిన తర్వాత మీ application ను import చేస్తుంది. అందువల్ల ప్రతి worker తనకు స్వంత private copy ని నిర్మిస్తుంది. preload_app ప్రారంభించి ఉంటే, master application ను ఒకసారి import చేస్తుంది. Workers ఆ pages ను inherit చేసుకుంటాయి.

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 copy-on-write విధానానికి అనుకూలంగా పనిచేయదు. ప్రతి object header లో reference count ఉంటుంది. Object ను తాకినప్పుడు ఆ header కు write జరుగుతుంది. అందువల్ల garbage collector heap ను పరిశీలిస్తున్నప్పుడు shared pages ఒక్కొక్కటిగా copy అవుతాయి. gc.freeze() ఇప్పటివరకు allocate చేసిన ప్రతిదాన్ని collector ఇకపై సందర్శించని permanent generation లోకి తరలిస్తుంది. దీనివల్ల ఆ pages లో ఎక్కువ భాగం shared గా కొనసాగుతుంది. when_ready సరైన hook. ఎందుకంటే ఇది preload తర్వాత, మొదటి worker fork కావడానికి ముందు అమలవుతుంది. when_ready జోడించే ముందు మరియు తర్వాత PSS ను కొలవండి. ఎందుకంటే ఆదా అయ్యే memory, import సమయంలో మీ application లో ఎంత state నిర్మించబడిందో దానిపై ఆధారపడి ఉంటుంది.

Deploy సమయంలో చాలామందికి preload కు ఉన్న ఒక ఖర్చు అనూహ్యంగా కనిపిస్తుంది. systemctl reload, HUP ను పంపుతుంది. HUP పై gunicorn యొక్క documented behaviour configuration ను reload చేసి కొత్త workers ను ప్రారంభించడం. Application preload అయి ఉంటే అది మీ code ను మళ్లీ import చేయదు. అందువల్ల worker processes కొత్తవైనా మీ కొత్త release అమలులో ఉండదు. Code మారిన తర్వాత systemctl restart ఉపయోగించండి. పాత workers ముందుగా పూర్తయ్యే వరకు వేచి ఉండాల్సి వస్తే USR2 తరువాత WINCH క్రమాన్ని ఉపయోగించండి.

1 GB VPS నిజంగా ఎన్ని workers ను నడపగలదు?

ChartWhere a 1 GB VPS goes, typical idle figures before any traffic
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
  }
]

ఏ సేవా పనీ చేయని server లో ఇవి idle గణాంకాలు. Application workers కోసం సుమారు 550 MB మాత్రమే మిగులుతుంది. ఇది మొదటి request రాకముందు ఉన్న పరిమితి.

ఇప్పుడు ఆ memory ను విభజించండి. అంచనాను జాగ్రత్తగా, తక్కువ వైపున ఉంచండి. Request నడుస్తున్న సమయంలో memory వినియోగిస్తుంది. ఉదాహరణకు, కొన్ని వేల rows ను లోడ్ చేసే queryset, ఆ తరువాత template render. ఒక్క worker యొక్క peak వినియోగం సాధారణంగా idle figure కు దాదాపు రెట్టింపు ఉంటుంది. కాబట్టి రెట్టింపు memory ఆధారంగా budget చేయండి. Admin తో Django idle గా 58 MB వినియోగిస్తే, ఈ server లో నాలుగు workers నడపవచ్చు. SQLAlchemy తో Flask 38 MB వినియోగిస్తే, ఏడు workers నడపవచ్చు.

Gunicorn యొక్క (2 x cores) + 1 సూచనలో CPU పరిమిత వనరు అని, RAM పరిమితి కాదని భావిస్తారు. చిన్న VPS లో పరిస్థితి దీనికి విరుద్ధంగా ఉంటుంది. Host busy గా ఉన్నప్పుడు ఒక shared vCPU కూడా పూర్తి core సామర్థ్యానికి తక్కువ పని మాత్రమే అందిస్తుంది. Code ను తప్పుపట్టే ముందు దీన్ని అర్థం చేసుకోవాలి: పక్క server అధిక వనరులు వినియోగించడం వల్ల కలిగే CPU steal time top లో st figure గా కనిపిస్తుంది.

మీ views ఎక్కువగా database లేదా upstream API కోసం వేచి ఉంటే, ఇక్కడ processes కంటే threads మెరుగ్గా ఉంటాయి. --worker-class gthread --workers 2 --threads 4 రెండు workers కు అవసరమైన memory తో ఎనిమిది concurrent requests ను అందిస్తుంది. దీనికి కారణం threads interpreter మరియు framework యొక్క ఒకే loaded copy ను పంచుకోవడం. Global interpreter lock కారణంగా CPU ను ఎక్కువగా వినియోగించే view కు threads సహాయం చేయవు.

Server కు swap ఇవ్వండి. Swap లేని 1 GB VPS లో memory spike వల్ల process terminate అవుతుంది. Swapfile ఉంటే అదే spike ఒక slow request గా మారుతుంది.

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 --system

తరువాత application కు కూడా పరిమితి విధించండి. Gunicorn unit లో MemoryMax=600M ఉపయోగిస్తే, మొత్తం server లో ఏ process ను terminate చేయాలో ఎంచుకునే బదులు kernel మీ app యొక్క cgroup నుంచి memory ను తిరిగి తీసుకుంటుంది. అందువల్ల అదుపు తప్పిన request కారణంగా మీ SSH session నిలిచిపోదు.

Cold start మరియు restart ప్రవర్తన

ChartImport to ready, minimal app, one shared vCPU
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
  }
]

ప్రతి deploy సమయంలో ఒకసారి, crash తర్వాత జరిగే ప్రతి automatic restart సమయంలో మరోసారి boot ఖర్చు అవుతుంది. కనిష్ఠ Flask app సుమారు 90 ms లో సిద్ధమవుతుంది. అదే shared vCPU పై admin enabled చేసిన Django కు సుమారు 720 ms పడుతుంది. ఇవి సాధారణంగా ప్రచురించబడిన గణాంకాలు. మీ dependencies ప్రభావం ఎక్కువగా ఉంటుంది కాబట్టి మీ స్వంత వ్యవస్థలో కొలవండి.

cd /srv/site1
DJANGO_SETTINGS_MODULE=site1.settings /srv/site1/.venv/bin/python -X importtime -c "import django; django.setup()" 2>&1 | tail -20

చివరి పంక్తులు cumulative microseconds ఆధారంగా అత్యంత నెమ్మదైన imports ను చూపిస్తాయి. Flask కోసం మీ module పై అదే flag నడపండి: python -X importtime -c "import app".

preload enabled గా ఉంటే, master ఆ ఖర్చును ఒక్కసారి మాత్రమే భరిస్తుంది. ప్రతి forked worker వెంటనే ప్రారంభమవుతుంది. preload disabled గా ఉంటే, ప్రతి worker ఆ ఖర్చును భరిస్తుంది. gunicorn యొక్క timeout boot సమయాన్నీ request సమయాన్నీ కలుపుతుంది. timeout seconds లోపు check in చేయని worker ను terminate చేసి దాని స్థానంలో కొత్త worker ను ప్రారంభిస్తారు. అందువల్ల నెమ్మదైన shared vCPU పై heavy app నిరంతర restart loop లో చిక్కుకుని, ఏదీ serve చేయకపోవచ్చు. Log ఇలా చూపిస్తుంది:

[2026-08-09 09:14:02 +0000] [981] [CRITICAL] WORKER TIMEOUT (pid:1004)

Migrations ను unit లో ఉంచాలి. వాటిని application startup code లో ఉంచకూడదు. ఏ worker ప్రారంభం కాకముందే ExecStartPre ఒక్కసారి నడుస్తుంది. మీ app లో migrate ఉంచితే, మూడు workers ఒకే schema lock కోసం పరస్పరం పోటీ పడతాయి.

వినియోగ నిర్మాణం దాదాపు ఒకేలా ఉంటుంది

ప్రాసెస్ మేనేజర్

రెండు frameworks కూడా gunicorn కింద నడుస్తాయి. gunicorn 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.target

ప్రారంభించినప్పుడు RuntimeDirectory=site1, /run/site1 ను సృష్టిస్తుంది. ఆపినప్పుడు దాన్ని తొలగిస్తుంది. అందువల్ల socket path సరైన owner తో ఎల్లప్పుడూ అందుబాటులో ఉంటుంది. gunicorn config లోని umask = 0o007 లైన్ ఆ socket ను www-data group కు writable గా చేస్తుంది. అందుకే nginx దాన్ని చేరుకోగలదు.

Flask unit ఇదే file. ఒక లైన్ మాత్రమే మారుతుంది: ExecStart=... gunicorn -c /srv/site1/gunicorn.conf.py app:app. ఇందులో ExecStartPre ఉండదు. app:app argument లో ముందుగా module, తరువాత callable వస్తాయి. అందువల్ల Failed to find attribute 'app' in 'app'. error అంటే మీ module లో ఆ పేరుతో variable నిర్వచించబడలేదని అర్థం. Scheduled work కూడా ఇదే విధానాన్ని అనుసరిస్తుంది. ఈ పరిమాణంలోని box కు task queue జోడించకుండా, Django management command కోసం systemd timer cron ను భర్తీ చేస్తుంది.

Static files

DEBUG = False తో Django static files ఏవీ అందించదు. STATIC_ROOT ను సెట్ చేసి, python manage.py collectstatic నడపండి. తరువాత web server ను output directory కు point చేయండి. ఈ దశను వదిలేస్తే admin styling లేకుండా లోడ్ అవుతుంది. Log లో Not Found: /static/admin/css/base.css సందేశాలు వరుసగా చేరతాయి.

వాటిని అందించడానికి రెండు సరైన మార్గాలు ఉన్నాయి. nginx alias block మీ app పై అదనపు భారం వేయదు. Middleware గా జోడించిన WhiteNoise worker నుంచే files ను అందిస్తుంది. దాంతో nginx block అవసరం ఉండదు. అయితే ప్రతి file కు కొంత worker సమయం ఖర్చవుతుంది. Flask development లో తన static/ folder ను తానే అందిస్తుంది. Production లో అదే కారణంతో proxy ను ఆ folder కు point చేయాలి.

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;
    }
}

ఏ proxy వెనుక ఉన్నా, అసలు request HTTPS ద్వారా వచ్చిందని Django కు తెలియజేయాలి. లేకపోతే దాని cross site request forgery (CSRF) checks మీ స్వంత forms ను తిరస్కరిస్తాయి.

ALLOWED_HOSTS = ["example.com"]
CSRF_TRUSTED_ORIGINS = ["https://example.com"]
SECURE_PROXY_SSL_HEADER = ("HTTP_X_FORWARDED_PROTO", "https")

ఆ box లో ఇప్పటికే containers నడుస్తుంటే, అనేక Docker Compose apps ముందు Traefik ను ఉంచడం ప్రతి site కు ఒక్కో file బదులుగా container పై labels ఉపయోగించి ఇదే పని చేస్తుంది.

ఏ database

సెకనుకు కొన్ని writes మాత్రమే ఉండే single application server కు SQLite నిజంగా సరిపోతుంది. ఇది memory budget నుంచి ఒక పూర్తి daemon ను తొలగిస్తుంది. write ahead logging (WAL) ను enable చేసి, driver కు busy timeout ఇవ్వండి.

DATABASES = {
    "default": {
        "ENGINE": "django.db.backends.sqlite3",
        "NAME": BASE_DIR / "db.sqlite3",
        "OPTIONS": {
            "timeout": 20,
            "init_command": "PRAGMA journal_mode=WAL;",
        },
    }
}

ఈ రెండు options లేకపోతే, రెండు workers ఒకేసారి write చేసినప్పుడు మొదటిసారే django.db.utils.OperationalError: database is locked ను ఎదుర్కొంటారు. కారణం, default journal mode write జరుగుతున్నప్పుడు readers ను block చేస్తుంది. Default timeout కూడా దాదాపు వెంటనే ప్రయత్నాన్ని నిలిపివేస్తుంది. SQLite సరైన ఎంపికగా ఉండటం ఎప్పుడు ఆగుతుందో సహా విస్తృత వివరణ VPS లో SQLite ను production లో నడపడం లో ఉంది.

అదే 1 GB box పై PostgreSQL కు పై budget లో 120 MB ఖర్చవుతుంది. అదనంగా ప్రతి persistent connection కు ఒక backend process అవసరం. Django యొక్క CONN_MAX_AGE ప్రతి worker కు ఒక connection ను open గా ఉంచుతుంది. అందువల్ల నాలుగు workers అంటే నాలుగు backends. ఇది సాధారణంగా సముచితమైన మార్పిడి. అయితే worker సంఖ్యను సెట్ చేసే ముందు ఈ వినియోగాన్ని లెక్కించండి. Database ను app పక్కనే ఒక container లో ఉంచాలనుకుంటే, VPS లో Docker ను నడపడం అదే మార్పిడి, కానీ అధిక కనిష్ఠ overhead తో ఉంటుంది. ఈ పరిమాణంలో daemon మరియు ప్రతి container జోడించే overhead ప్రాముఖ్యంగా ఉంటుంది.

అదనపు పరిమాణం ఏం ఇస్తుంది, దానికి అయ్యే ఖర్చు ఏమిటి

Django యొక్క అదనపు megabytes అంటే ఇప్పటికే ఉన్న మరియు పరస్పరం పనిచేసే భాగాల సమాహారం: migrations తో కూడిన ORM, session మరియు authentication వ్యవస్థ, permission model, CSRF protection తో కూడిన form layer, template engine, management commands, అలాగే admin. ప్రజలు తక్కువగా అంచనా వేసే భాగం admin. INSTALLED_APPS లోని ఒక పంక్తి కోసం, ఇది మీ models కు search మరియు filters ఉన్న పనిచేసే database editor ను అందిస్తుంది.

Flask దీనికి పూర్తి విరుద్ధం. మీకు routing, request object, Jinja2 templates మరియు config object లభిస్తాయి. మిగతావన్నీ మీరు ఎంచుకోవాలి. అప్లికేషన్ చిన్నదిగా ఉన్నప్పుడు ఇది నిజమైన ప్రయోజనం, ఎందుకంటే మీరు ORM ను ఎప్పుడూ import చేయకపోతే అది load కాదు.

మధ్యస్థ పరిస్థితే సమస్య. models కోసం SQLAlchemy, migrations కోసం Alembic, sessions కోసం Flask-Login, forms మరియు CSRF కోసం Flask-WTF, back office కోసం admin extension జోడిస్తే, Django కు సమానమైన memory profile ఉన్నప్పటికీ దాని సమగ్రత లేని వ్యవస్థను మీరు నిర్మించినట్టవుతుంది. ప్రతి భాగానికీ ప్రత్యేక release cycle ఉంటుంది. అప్లికేషన్‌ను ఎలా wire చేయాలనే దానిపై ప్రతి భాగానికీ ప్రత్యేక అభిప్రాయం ఉంటుంది. ఆ దశలో Django తక్కువ ఖర్చుతో కూడిన ఎంపిక అవుతుంది—RAM పరంగా, అలాగే upgrades కోసం మీరు వెచ్చించే సమయం పరంగా.

Django vs Flask: నిర్ణయం తీసుకునే నియమం

అప్లికేషన్‌లో accounts, మార్చగల content, తరచుగా మారే schema, అలాగే ఎవరైనా నిజంగా ఉపయోగించే back office ఉంటే Django ను ఉపయోగించండి. ఇప్పటికే ఉన్న datastore పై JSON interface గా పనిచేసే అప్లికేషన్‌కి లేదా HTML లేని webhook receiver కి Flask ను ఉపయోగించండి.

చివరి నిర్ణయానికి రాతపూర్వక జాబితాను ఉపయోగించండి. అవసరమైన feature set ను Flask లో పొందడానికి install చేయాల్సిన ప్రతి package ను రాసుకోండి. ఆ జాబితాలో ORM మరియు migration tool ఉంటే, మీరు ఇప్పటికే Django ను ఎంచుకున్నట్టే. అదే స్థితికి నెమ్మదిగా చేరడానికి అదనపు శ్రమ చేస్తున్నారు.

చిన్న hardware పై Flask కు నిజంగా అనుకూలమైన ఒక పరిస్థితి ఉంది: ఒకే box పై అనేక చిన్న సేవలు నడపడం. ప్రతి Flask సేవ తన స్వంత unit కింద స్వల్ప వనరులు ఉపయోగించే ప్రత్యేక process గా నడుస్తుంది. 1 GB VPS పై మూడు Django sites నడిపితే framework యొక్క మూడు resident copies ఒకేసారి మెమరీలో ఉంటాయి. అప్పుడు పై లెక్క వర్తించదు. లెక్క మళ్లీ మళ్లీ సరిపోకపోతే, పెద్ద plan తీసుకోవడమే తరచుగా నిజాయితీగల పరిష్కారం. పనిచేస్తున్న అప్లికేషన్‌ను మళ్లీ రాయడం కంటే VPS కు నెలకు వాస్తవంగా ఎంత ఖర్చవుతుంది అనే విషయంపై చర్చించడం సులభం.

మీరు చూసే strings‌తో వైఫల్య పరిస్థితులు

Workers కనిపించకుండా పోయి మళ్లీ వస్తారు. Gunicorn [ERROR] Worker (pid:1234) was sent SIGKILL! Perhaps out of memory? ను చూపిస్తుంది. Timeout heartbeat కోల్పోయిన worker ను terminate చేసినప్పుడు, అలాగే kernel ఆ process ను terminate చేసినప్పుడు కూడా ఇది కనిపిస్తుంది. ఈ రెండు పరిస్థితులను వేరు చేయడానికి dmesg -T | grep -i "killed process" ను ఉపయోగించండి. అక్కడ ఒక line కనిపిస్తే memory కొరత ఉందని అర్థం; worker సంఖ్యను తగ్గించండి లేదా swap జోడించండి.

ప్రతి page 400 ను తిరిగి ఇస్తుంది, అలాగే log లో Invalid HTTP_HOST header అని కనిపిస్తుంది. పూర్తి message Invalid HTTP_HOST header: 'example.com'. You may need to add 'example.com' to ALLOWED_HOSTS.. మీ code వరకు request చేరకముందే Django దాన్ని reject చేస్తుంది. కారణం ALLOWED_HOSTS ఖాళీగా ఉండటం లేదా proxy Host లో పంపిన name ను అది కలిగి లేకపోవడం.

Forms Origin checking failed తో విఫలమవుతాయి. Page లో CSRF verification failed అని కనిపిస్తుంది. TLS terminating proxy వెనుక ఇది జరుగుతుంది: app కు plain HTTP కనిపిస్తుంది, అందువల్ల అది http:// origin ను నిర్మిస్తుంది. తరువాత దాన్ని https:// పై వచ్చిన request తో పోలుస్తుంది. SECURE_PROXY_SSL_HEADER మరియు CSRF_TRUSTED_ORIGINS ను సెట్ చేయండి. Proxy నిజంగా X-Forwarded-Proto ను పంపుతున్నదని నిర్ధారించండి.

nginx వెంటనే 502 ను తిరిగి ఇస్తుంది. Error log కారణాన్ని చూపిస్తుంది: connect() to unix:/run/site1/gunicorn.sock failed (2: No such file or directory) అంటే unit నడుస్తూ లేదని అర్థం. (13: Permission denied) అంటే socket ఉన్నప్పటికీ nginx దాన్ని open చేయలేకపోతోందని అర్థం. దీనికి కారణం umask మరియు group setting.

Admin కు styling కనిపించదు. collectstatic run కాలేదు లేదా alias path, STATIC_ROOT తో సరిపోలడం లేదు. Access log లో /static/admin/ కింద 404లు కనిపిస్తాయి.

తక్కువ load లో writes విఫలమవుతాయి. SQLite నుంచి వచ్చే database is locked అంటే WAL off లో ఉందని లేదా అదే సమయంలో రెండు workers రాస్తున్నప్పుడు busy timeout చాలా తక్కువగా ఉందని అర్థం.

FAQ

Django 1 GB VPS కు చాలా భారమా?

కాదు. తక్కువ సంఖ్యలో workers, ముందు భాగంలో nginx, వెనుక SQLite ఉన్న Django 1 GBలో సౌకర్యంగా నడుస్తుంది. అదే serverలో PostgreSQL ను default settingsతో, cache, background worker మరియు Docker ను జోడించినప్పుడు memory పరిమితి త్వరగా ఎదురవుతుంది. ఒక worker యొక్క proportional set size ను కొలవండి. Request peaks కోసం దాన్ని రెండింతలు చేయండి. తరువాత operating system మరియు database కోసం ఉపయోగించిన memory తీసివేసిన తర్వాత మిగిలిన memoryతో మొత్తం అవసరాన్ని పోల్చండి.

ఒక vCPUపై ఎన్ని gunicorn workers నడపాలి?

మూడు workersతో ప్రారంభించి కొలవండి. చిన్న VPSలో సాధారణంగా memory ప్రధాన పరిమితిగా ఉంటుంది. అందువల్ల operating system మరియు database తర్వాత మిగిలిన RAM ను ఒక worker యొక్క proportional set size కు రెండింతలతో భాగించండి. మీ views ఎక్కువగా database లేదా upstream API కోసం వేచి ఉంటే, తక్కువ సంఖ్యలో workersతో, ప్రతి workerకు అనేక threadsతో gthread worker class కు మారండి. Threads ఒకే loaded framework copyని పంచుకుంటాయి. అదనపు processes కంటే వాటికి చాలా తక్కువ memory అవసరం.

నాకు PostgreSQL అవసరమా, లేక SQLite సరిపోతుందా?

మితమైన write rate ఉన్న ఒక application serverకు SQLite సరిపోతుంది. ఇది memory budget నుంచి మొత్తం daemon అవసరాన్ని తొలగిస్తుంది. write ahead logging ను enable చేసి, busy timeout ను సెట్ చేయండి. లేకపోతే concurrent writes database is locked తో విఫలమవుతాయి. ఒకటి కంటే ఎక్కువ machines రాయాల్సి వచ్చినప్పుడు PostgreSQLకు మారండి. SQLite అందించని concurrent heavy writers లేదా per-role access control వంటి సామర్థ్యాలు అవసరమైనప్పుడు కూడా PostgreSQLను ఉపయోగించండి.

gunicorn బదులుగా uvicorn నడపాలా?

మీకు async views మరియు వేచి ఉండాల్సిన నిజమైన asynchronous పని ఉంటే మాత్రమే. Flask ఒక WSGI application. అందువల్ల async view worker threadలో కొత్త event loopలో నడిచి, తదుపరి request ప్రారంభమయ్యేలోపు పూర్తవుతుంది. దీనివల్ల అదనపు concurrency లభించదు. Django async viewsకు సహాయం అందించాలంటే ASGI server అవసరం. ఇటీవలి uvicorn releases తమ gunicorn worker class ను ప్రత్యేక packageలోకి మార్చాయి. కాబట్టి పాత tutorialలోని పాత worker class flag ను కాపీ చేయకుండా, ప్రస్తుత uvicorn documentation చదవండి.

traceback లేకుండా నా worker ఎందుకు కనుమరుగైంది?

Kernel out of memory killer ఒక processను ముగించినప్పుడు, అది SIGKILL అందుకుంటుంది. బయటకు వెళ్లే సమయంలో ఏదీ log చేయలేడు. అందువల్ల మీ application log అకస్మాత్తుగా ఆగిపోతుంది. Gunicorn ఈ అంతరాన్ని గుర్తించి Worker (pid:1234) was sent SIGKILL! Perhaps out of memory? ను ముద్రిస్తుంది. dmesg -T | grep -i "killed process" తో దీన్ని నిర్ధారించండి. తక్కువ workers నడపడం పరిష్కారం. లేదా swapfile ఉపయోగించండి. అప్పుడు memory spike వల్ల process ముగియకుండా, request నెమ్మదిగా పూర్తవుతుంది.

#django#flask#python#gunicorn#deployment#vps