Перейти до змісту

Урок: Мережевий фундамент — від проводу до Python

Перш ніж вивчати Django, потрібно зрозуміти, де живе твій код. Django — це лише один шар у великому стеку. Цей документ описує всі шари нижче.


Навіщо це вивчати?

Коли ти пишеш python manage.py runserver і відкриваєш браузер — відбуваються десятки операцій: DNS-запит, TCP-з'єднання, HTTP-переговори, парсинг запиту. Більшість розробників не знають, що відбувається до того, як запит досягає їхнього Python-коду. Це і є причина більшості помилок у продакшні.


1. Що таке мережа?

Мережа — це система, де два або більше комп'ютери можуть обмінюватися даними. Фізично це дроти, оптоволокно, Wi-Fi сигнал. Логічно — це набір протоколів (домовленостей про мову).

Рівні абстракції (OSI-модель — спрощено)

Рівень Що робить Приклад
Фізичний Передає біти Кабель, Wi-Fi
Канальний Адресує в локальній мережі MAC-адреса
Мережевий Маршрутизація між мережами IP
Транспортний Надійна передача TCP, UDP
Прикладний Протоколи для програм HTTP, DNS, SSH

Ключова ідея: Кожен рівень вирішує одну задачу і не знає деталей інших рівнів.


2. IP-адреса — де живе комп'ютер

IP-адреса (Internet Protocol Address) — унікальний числовий ідентифікатор кожного пристрою в мережі.

IPv4

192.168.1.105

Чотири числа (0–255), розділені крапками. Всього ~4 мільярди адрес. Майже вичерпано.

IPv6

2001:0db8:85a3:0000:0000:8a2e:0370:7334

128-бітна адреса. Практично необмежений простір.

Публічна vs Приватна IP

Тип Приклад Видима з Інтернету
Публічна 104.21.14.55 Так
Приватна 192.168.1.x, 10.0.0.x Ні (тільки в локальній мережі)

Коли ти відкриваєш localhost:8000 — ти звертаєшся до 127.0.0.1, адреси самого себе (loopback).


3. DNS — телефонна книга Інтернету

Комп'ютери спілкуються через IP-адреси. Але люди запам'ятовують google.com, а не 142.250.74.46.

DNS (Domain Name System) — розподілена система, яка перекладає домени в IP-адреси.

Як відбувається DNS-резолюція

  1. Ти вводиш github.com у браузер
  2. Браузер перевіряє локальний кеш (чи не знає вже цю адресу)
  3. Якщо немає — запитує DNS Resolver (зазвичай від інтернет-провайдера або 8.8.8.8)
  4. Resolver запитує Root DNS Server (знає лише TLD-сервери)
  5. Root сервер вказує на TLD сервер (для .com — Verisign)
  6. TLD сервер вказує на Authoritative DNS (де зберігаються реальні записи github.com)
  7. Authoritative DNS повертає IP: 140.82.121.4
  8. Браузер кешує відповідь і з'єднується з сервером

DNS-записи

Тип Що робить Приклад
A Домен → IPv4 github.com → 140.82.121.4
AAAA Домен → IPv6
CNAME Аліас на інший домен www.example.com → example.com
MX Де email-сервер
TXT Довільний текст (SPF, верифікація)

Реальний бекенд: При деплої Django-проєкту ти купуєш домен і додаєш A-запис, що вказує на IP твоєї хмарної VM.

Чому браузер завантажується швидше вдруге? — DNS-відповідь кешується на час TTL (Time To Live). Повторний запит іде прямо з кешу.


4. Порти — квартири в будинку

IP-адреса доставляє пакет до потрібного комп'ютера. Але на одному комп'ютері може бути десятки програм. Порт вказує, до якої саме програми надходить трафік.

192.168.1.100:80   ← веб-сервер (Nginx)
192.168.1.100:5432 ← PostgreSQL
192.168.1.100:22   ← SSH
192.168.1.100:8000 ← Django runserver

Відомі порти

Порт Протокол Використання
80 HTTP Веб (без шифрування)
443 HTTPS Веб (з TLS)
22 SSH Безпечний доступ до сервера
5432 PostgreSQL База даних
6379 Redis Кеш / брокер
25 SMTP Email
53 DNS DNS-запити

Реальний бекенд: Якщо ти запускаєш два Django-проєкти одночасно на порту 8000 — другий виведе Address already in use. ОС не може прив'язати один порт до двох процесів.


5. TCP — надійна доставка

TCP (Transmission Control Protocol) забезпечує гарантовану та впорядковану доставку даних.

Як це працює

Дані розбиваються на пакети (chunks). Кожен пакет: - має порядковий номер - може йти різними маршрутами через Інтернет - може прийти не в тому порядку

TCP на стороні отримувача: - перевіряє порядкові номери - запитує повторну відправку втрачених пакетів - збирає пакети у правильному порядку

TCP Three-Way Handshake

Перш ніж відправити будь-які дані, TCP встановлює з'єднання:

Клієнт → Сервер: SYN         (Привіт, можемо поговорити?)
Сервер → Клієнт: SYN-ACK     (Так, я готовий)
Клієнт → Сервер: ACK         (Чудово, починаємо)
         [З'єднання встановлено]
Клієнт → Сервер: HTTP GET /  (Тепер надсилаємо дані)

Аналогія: Уяви, що відправляєш 300-сторінкову книгу по пошті посторінково. Поштова служба (IP) може відправити сторінки різними шляхами. Друг (TCP) дивиться на номери сторінок, збирає книгу по порядку і просить надіслати повторно сторінку 47, якщо вона загубилася.

UDP — швидка, ненадійна альтернатива

UDP (User Datagram Protocol) надсилає пакети без підтвердження. Використовується там, де втрата пакету краща за затримку: відеозв'язок, онлайн-ігри, DNS.


6. HTTP — мова вебу

HTTP (HyperText Transfer Protocol) — текстовий протокол прикладного рівня. Описує формат запитів і відповідей між браузером і сервером.

Структура HTTP-запиту

GET /api/users/42/ HTTP/1.1
Host: example.com
Accept: application/json
Authorization: Bearer eyJhbGc...
Content-Type: application/json

{"name": "Alice"}
Частина Що це
GET Метод (дія)
/api/users/42/ Шлях (ресурс)
HTTP/1.1 Версія протоколу
Host, Accept... Заголовки (метадані)
{"name": "Alice"} Тіло (тільки для POST/PUT/PATCH)

HTTP-методи

Метод Призначення Ідемпотентний
GET Отримати ресурс Так
POST Створити ресурс Ні
PUT Повністю замінити Так
PATCH Частково оновити Ні
DELETE Видалити Так

Структура HTTP-відповіді

HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 48
Set-Cookie: sessionid=abc123; HttpOnly

{"id": 42, "name": "Alice", "email": "alice@mail.com"}

Коди статусу

Діапазон Значення Приклади
2xx Успіх 200 OK, 201 Created, 204 No Content
3xx Редирект 301 Moved Permanently, 302 Found
4xx Помилка клієнта 400 Bad Request, 401 Unauthorized, 404 Not Found
5xx Помилка сервера 500 Internal Server Error, 503 Service Unavailable

7. HTTPS та TLS

HTTPS = HTTP + TLS (Transport Layer Security). TLS шифрує дані між клієнтом і сервером.

Навіщо це потрібно?

Без HTTPS будь-який вузол між клієнтом і сервером (маршрутизатор у кав'ярні, провайдер) може прочитати твій запит — включно з паролями та токенами.

TLS Handshake (спрощено)

  1. Клієнт: "Я підтримую TLS 1.3, ось мій рандомний ключ"
  2. Сервер: "Ок, ось мій SSL-сертифікат і публічний ключ"
  3. Клієнт: "Перевірив сертифікат (підписаний довіреним CA). Генерую session key."
  4. Обидві сторони: "Тепер шифруємо все сесійним ключем"

SSL-сертифікат видається довіреними організаціями (Certificate Authorities): Let's Encrypt, DigiCert тощо. Nginx зберігає сертифікат і виконує TLS-handshake до того, як запит дійде до Python.


8. Sockets — фундамент мережевого програмування

Socket — це двонаправлена точка з'єднання між двома програмами. Це низькорівневий API, який надає операційна система.

Як Python відкриває мережеве з'єднання (низький рівень)

import socket

# Сервер
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind(('0.0.0.0', 8080))   # Прив'язуємо до порту
server.listen(5)                  # Чекаємо підключень
conn, addr = server.accept()      # Блокує, поки клієнт не підключиться
data = conn.recv(1024)            # Читаємо дані
conn.send(b"HTTP/1.1 200 OK\r\n\r\nHello")
conn.close()
# Клієнт
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.connect(('127.0.0.1', 8080))
client.send(b"GET / HTTP/1.1\r\nHost: localhost\r\n\r\n")
response = client.recv(4096)

Django, Flask, FastAPI — всі вони зрештою використовують саме цей механізм, просто з великою кількістю абстракцій зверху.

Unix Domain Sockets

У продакшні Nginx і uWSGI часто спілкуються через Unix socket (файл у файловій системі, напр. /run/django.sock) замість мережевого. Це швидше, бо не проходить через мережевий стек.


9. Stateless протокол та стан сесій

HTTP за своєю природою stateless — без пам'яті. Кожен запит повністю незалежний. Сервер не пам'ятає, що ти вже робив запит секунду тому.

Як тоді сайт знає, що ти залогінений?

Через cookies і sessions:

Схема: 1. Ти відправляєш POST /login/ з логіном/паролем 2. Сервер перевіряє дані, створює session в базі даних з унікальним ID 3. Сервер відправляє відповідь із заголовком Set-Cookie: sessionid=abc123 4. Браузер зберігає cookie і автоматично додає його до кожного наступного запиту: Cookie: sessionid=abc123 5. Сервер читає sessionid, знаходить сесію в БД і знає, хто ти

Атрибут Що робить
HttpOnly JavaScript не може читати (захист від XSS)
Secure Надсилається тільки через HTTPS
SameSite Захист від CSRF
Expires Коли cookie стає недійсним

10. Client/Server архітектура

У класичній архітектурі є дві ролі:

Роль Хто Що робить
Client Браузер, мобільний додаток Ініціює запит, відображає результат
Server Nginx, Django, PostgreSQL Пасивно чекає, обробляє, відповідає

Повний lifecycle запиту (від URL до HTML)

1. Користувач вводить https://shop.example.com/products/
2. DNS: shop.example.com → 203.0.113.10
3. TCP Handshake з сервером 203.0.113.10:443
4. TLS Handshake (шифрування)
5. HTTP GET /products/ відправлено
6. Nginx отримує запит
7. Nginx пересилає до uWSGI через Unix socket
8. uWSGI перетворює HTTP в Python dict (WSGI environ)
9. Django URL Dispatcher: /products/ → ProductListView
10. Middleware: SecurityMiddleware → SessionMiddleware → AuthMiddleware
11. View: Product.objects.all() → SQL SELECT → Python objects
12. Template: рендеринг HTML з даними
13. HttpResponse 200 OK з HTML
14. Nginx відправляє відповідь клієнту
15. Браузер парсить HTML, завантажує CSS/JS

11. REST API архітектура

REST (Representational State Transfer) — архітектурний стиль для проектування API.

Принципи REST

Принцип Пояснення
Stateless Кожен запит містить усю потрібну інформацію
Resource-based URL описує ресурс (/users/, /products/42/)
HTTP Verbs Дія виражена методом (GET, POST, PUT, DELETE)
Uniform Interface Стандартна поведінка для всіх ресурсів

REST URL-конвенції

GET    /api/products/         → список всіх продуктів
POST   /api/products/         → створити продукт
GET    /api/products/42/      → отримати продукт #42
PUT    /api/products/42/      → повністю оновити продукт #42
PATCH  /api/products/42/      → частково оновити продукт #42
DELETE /api/products/42/      → видалити продукт #42

12. Як бекенд отримує запит — під капотом

Що відбувається на рівні ОС коли приходить HTTP-запит:

1. NIC (мережева карта) отримує електричний сигнал → перетворює в байти
2. ОС: TCP/IP stack обробляє пакети → збирає HTTP-запит
3. ОС: дивиться, яка програма слухає порт 80 → це Nginx
4. ОС: копіює дані в буфер Nginx через системний виклик recv()
5. Nginx: парсить HTTP-заголовки
6. Nginx: дивиться на location rules у nginx.conf
7. Nginx: proxy_pass → відправляє до unix:/run/django.sock
8. uWSGI: читає з сокету → парсить HTTP → будує WSGI environ dict
9. uWSGI: викликає Django application(environ, start_response)
10. Django: решта — це Python

Ключовий інсайт: Весь шлях — це серія перетворень байтів між різними програмами через буфери ОС. Python-код — це останній рядок у ланцюжку.


Типові помилки — мережевий рівень

1. Блокуючі запити в синхронному коді

# ПОГАНО: блокує весь процес на час HTTP-запиту
import requests

def my_view(request):
    response = requests.get("https://slow-api.example.com/data")  # чекає 5 сек
    return JsonResponse(response.json())
# ДОБРЕ: async view (Django 3.1+)
import httpx

async def my_view(request):
    async with httpx.AsyncClient() as client:
        response = await client.get("https://slow-api.example.com/data")
    return JsonResponse(response.json())

2. Неправильне розуміння stateless

Не зберігай стан у глобальних змінних Python — при кількох workers кожен має свою пам'ять. Стан повинен бути в БД або Redis.

3. Відсутність HTTPS

Ніколи не деплой продакшн без TLS. Пам'ятки, паролі, токени — все йде відкритим текстом.


Питання для самоперевірки

  1. Що відбувається, якщо DNS-сервер недоступний? Чи дійде запит до сайту?
  2. Навіщо потрібен TCP handshake, якщо можна просто надіслати дані одразу?
  3. Чому 127.0.0.1 і localhost — це одне і те ж?
  4. Як сервер дізнається, що ти залогінений, якщо HTTP stateless?
  5. Чому python manage.py runserver не підходить для продакшну?