Микросервисы на Flask и PostgreSQL — пошаговое руководство
Зачем нужен этот материал
Дизайн программного обеспечения сильно влияет на скорость разработки, масштабируемость и сопровождение проекта. Монотонные монолиты удобны для небольших проектов, но быстро становятся проблемой с ростом команды и нагрузки. Микросервисы предлагают альтернативу: набор небольших, автономных сервисов, каждый из которых решает узкую задачу.
Кратко: микросервис — это независимое приложение, выполняющее одну бизнес-функцию, способное к самостоятельному развёртыванию и масштабированию.

Архитектура микросервисов
Архитектура микросервисов подразумевает разбиение большого приложения на независимые сервисы. Каждый сервис отвечает за конкретную бизнес-область и обычно имеет собственные ресурсы: базу данных, очереди сообщений, процессорные ресурсы.
Такой подход снижает связность между частями системы: сервисы общаются по стандартным протоколам (HTTP/REST, gRPC) или через брокеры сообщений (например, RabbitMQ, Kafka). В распределённой системе серверные узлы запускают сервисы в отдельных процессах или контейнерах.

Архитектура даёт гибкость и автономию командам: отдельные сервисы можно разворачивать, обновлять и масштабировать независимо.
Что мы реализуем
В этом руководстве вы создадите простой микросервис пользователей на Flask, который сохраняет и читает данные из PostgreSQL. Далее мы покажем, как контейнеризовать сервис в Docker и дадим рекомендации по тестированию, безопасности и внедрению.
Установка PostgreSQL
Для начала потребуется PostgreSQL. Установите его локально или используйте облачный/удалённый экземпляр.
Если вы хотите быстро получить удалённую базу данных, можно воспользоваться бесплатным тарифом Render (пример). Шаги по развёртыванию на Render:
- Зарегистрируйтесь и войдите в аккаунт. Перейдите на страницу панель управления.

- В списке сервисов выберите сервис PostgreSQL.

- На странице настроек базы заполните поля, выберите бесплатный тариф, затем нажмите Create database.

Скопируйте внешний URL базы данных (external database URL) с панели Render — он понадобится для подключения из вашего сервиса.
Примечание: на проде используйте управляемые базы или собственную кластеризацию с бэкапами и мониторингом.
Создание микросервиса на Flask
Ниже приведён практический пример: структура проекта, установка виртуального окружения, зависимости, модель данных и API.
Подготовка рабочего каталога
Откройте терминал и выполните:
mkdir flask-microservice
cd flask-microserviceУстановите virtualenv и создайте виртуальное окружение:
pip install virtualenv
virtualenv venvАктивируйте окружение:
# Windows:
.\venv\Scripts\activate
# Unix или macOS:
source venv/bin/activateУстановка зависимостей
Создайте файл requirements.txt в корне проекта с такими строками:
flask
psycopg2-binary
sqlalchemyУстановите зависимости:
pip install -r requirements.txtСоздание сервера Flask
Создайте файл service.py в корне и добавьте код, приведённый ниже. Код реализует простую модель User, создание таблицы и два эндпоинта: POST /api/user и GET /api/user.
Начальные импорты:
from flask import Flask, request, jsonify
from sqlalchemy import create_engine, Column, Integer, String
from sqlalchemy.orm import sessionmaker
from sqlalchemy.ext.declarative import declarative_base
import psycopg2Создаём приложение и подключение к базе. Замените строку подключения на URL вашей базы данных (формат: postgresql+psycopg2://user:password@host/dbname):
app = Flask(__name__)
engine = create_engine("postgresql+psycopg2://flask_service_fe0v_user:4785MhjfkdjfhjfjyUx67O2Nuzjchb2MQIP@dpg-chffjfjdkgfk54d6mb7860-a.oregon-postgres.render.com/flask_service_fe0v")Важно: не храните секреты в коде. На практике используйте переменные окружения или секрет-менеджер.
Модель данных и создание таблицы:
Base = declarative_base()
class User(Base):
__tablename__ = 'users'
id = Column(Integer, primary_key=True)
name = Column(String(50))
Base.metadata.create_all(engine)
print("Table 'users' created successfully.")
Session = sessionmaker(engine)Роуты API:
@app.route("/api/user", methods=["POST"])
def create_user():
data = request.get_json()
name = data["name"]
try:
session = Session()
new_user = User(name=name)
session.add(new_user)
session.commit()
return {"id": new_user.id, "name": new_user.name, "message": f"User {name} created."}, 201
except Exception as e:
print(f"The error '{e}' occurred.")
return {"error": "An error occurred while creating the user."}, 500
@app.route("/api/user", methods=["GET"])
def get_all_users():
try:
session = Session()
users = session.query(User).all()
if users:
result = []
for user in users:
result.append({"id": user.id, "name": user.name})
return jsonify(result)
else:
return jsonify({"error": f"Users not found."}), 404
except Exception as e:
print(f"The error '{e}' occurred.")
return {"error": "An error occurred while getting all users."}, 500
if __name__ == "__main__":
app.run(debug=True, host="0.0.0.0")Объяснение: код использует SQLAlchemy ORM для моделирования таблицы users и сессий для транзакций. При ошибках сервис возвращает 500 и логирует исключение в консоль.
Управление конфигурацией
Рекомендуемый шаблон использования переменных окружения — хранить URL базы и секреты в .env или системных переменных. Пример файла .env (не коммитить в репозиторий):
DATABASE_URL=postgresql+psycopg2://user:password@host:port/dbname
FLASK_ENV=development
SECRET_KEY=changemeВ коде считывайте их через os.environ или библиотеку python-dotenv.
Тестирование микросервиса
Запустите сервер разработки:
flask --app service runВ Postman или curl выполните POST для добавления пользователя (Content-Type: application/json):
POST http://localhost:5000/api/user
{
"name": "Иван"
}После добавления можно сделать GET:
GET http://localhost:5000/api/user
Советы по тестированию:
- Покрывайте юнитами слой бизнес-логики, мокайте внешние зависимости (базы, брокеры).
- Пишите интеграционные тесты с тестовой БД (например, временная база в Docker) и откатывайте транзакции после теста.
- Настройте CI, чтобы тесты выполнялись при каждом коммите.
Контейнеризация с Docker
Контейнеры упрощают развёртывание и масштабирование микросервисов. Ниже — пример простого Dockerfile для нашего сервиса.
Создайте Dockerfile в корне проекта:
FROM python:3.9-alpine
WORKDIR /app
COPY requirements.txt ./
RUN pip install -r requirements.txt
COPY . .
EXPOSE 5000
CMD ["python", "./service.py"]Постройте образ:
docker build -t flask-microservice .Запустите контейнер (проброс портов):
docker run -p 5000:5000 flask-microserviceВажно: в проде используйте правильно настроенный WSGI-сервер (например, gunicorn), а не встроенный в Flask, и не забудьте обеспечить ротацию логов и управление процессами.
Когда микросервисы не подходят
Микросервисы дают гибкость, но не всегда они оправданы. Примеры случаев, когда микросервисы — не лучший выбор:
- Небольшие проекты с ограниченным набором функций. Монолит быстрее разработать и проще поддерживать.
- Команда из 1–3 человек: накладные расходы на инфраструктуру и коммуникации могут превышать выгоды.
- Сильная взаимозависимость данных: если функциональные части часто требуют атомарных транзакций над общими таблицами, разбиение усложнит логику.
Если вы видите частые потребности в корреляции данных и сложные распределённые транзакции, подумайте о гибридном подходе.
Альтернативы и гибридные стратегии
- Модульный монолит: кодовая база остаётся монолитной, но логически разделена на модули с чёткими границами. Позволяет отложить сетевую сложность.
- Мини-сервисы: несколько крупных автономных сервисов, вместо множества мелких.
- Функции (Serverless): функции как сервис (FaaS) подходят для событийно-ориентированных задач с непостоянной нагрузкой.
Выбор зависит от зрелости команды, требований к SLA и бюджета на поддержку инфраструктуры.
Мини-методология внедрения микросервисов
- Выделите границы контекстов (bounded contexts) по бизнес-логике.
- Определите API контракт (OpenAPI/Swagger) для каждого сервиса.
- Начните с одного сервиса: настроьте CI/CD, мониторинг и логирование.
- Интегрируйте сервисы через стабильные интерфейсы и брокеры сообщений, если нужно.
- Настройте централизованный мониторинг (метрики, трассировки — e.g., Prometheus + Jaeger) и alerting.
- Автоматизируйте развертывания и откаты (blue/green, canary).
Роль-ориентированные чеклисты
- Для разработчика:
- Чёткий контракт API (OpenAPI).
- Тесты: unit + integration.
- Переменные окружения для конфигурации, секреты вне репозитория.
- Для DevOps:
- CI/CD для сборки образов и развёртывания.
- Мониторинг, логирование, алерты.
- Бэкапы БД и политка ретенции логов.
- Для QA:
- Автотесты сценариев на уровне API.
- Контроль регрессий при развёртывании.
- Для архитектора:
- План границ сервисов и модель данных.
- Стратегия версии API и обратная совместимость.
Критерии приёмки
- Сервис корректно создаёт и возвращает пользователей через API.
- Все тесты в CI проходят успешно.
- Развёртывание в контейнере прошло без ошибок, сервис доступен по указанному порту.
- Пароль и URL БД не хранится в коде, используются переменные окружения.
Безопасность и приватность
- Секреты: используйте секрет-менеджеры (Vault, cloud secrets) или сервисы провайдера.
- Соединение с БД должно быть по TLS, где это возможно.
- Ограничьте доступ к базе (белый список IP/секьюрные сети).
- Логи не должны содержать PII. Для GDPR/DSA соблюдайте минимальную необходимость хранения персональных данных.
- Настройте ограничение прав для учетной записи БД: принцип наименьших привилегий.
Оценка затрат и эффект × усилия
- Малый проект: высокая стоимость микросервисов из-за накладных расходов (инфраструктура, оркестрация).
- Средний/крупный проект: микросервисы дают выигрыш в автономии команд, масштабировании и удержании SLA.
Решение принимается, исходя из: числа разработчиков, требований к масштабированию и частоты релизов.
Миграция и совместимость версий
- Версионируйте API (например, /api/v1/user).
- Совмещайте старые и новые версии в течение периода миграции.
- Используйте тесты контрактов, чтобы убедиться в обратной совместимости.
Примеры отказов и способы их предотвращения
- Проблема: сервис не может подключиться к БД на проде — причина: неверный URL или сеть. Решение: проверка переменных окружения в CI, health-check и readiness probe.
- Проблема: утечки соединений — решение: настройка пула соединений, мониторинг использования.
- Проблема: неконсистентные данные между сервисами — решение: проектирование событийной согласованности (event sourcing, saga patterns).
Полезные шаблоны и сниппеты
.env (пример):
DATABASE_URL=postgresql+psycopg2://user:password@host:5432/dbname
FLASK_ENV=production
SECRET_KEY=supersecretПростейший systemd unit для запуска контейнера (пример):
[Unit]
Description=Flask Microservice
After=docker.service
[Service]
Restart=always
ExecStart=/usr/bin/docker run --rm -p 5000:5000 --env-file /opt/micro/.env flask-microservice
ExecStop=/usr/bin/docker stop flask-microservice
[Install]
WantedBy=multi-user.targetКак принять решение: диаграмма
flowchart TD
A[Небольшой проект, 1–3 разработчика?] -->|Да| B[Монолит или модульный монолит]
A -->|Нет| C[Требуется масштабирование/частые релизы?]
C -->|Да| D[Микросервисы]
C -->|Нет| B
D --> E{Есть экспертиза в DevOps?}
E -->|Да| F[Микросервисы с CI/CD и мониторингом]
E -->|Нет| G[Подготовить команду, начать с мини-сервисов]Краткое резюме
Микросервисы дают гибкость и масштабируемость, но требуют дисциплины в управлении конфигурацией, мониторинге и развертывании. Для демонстрации мы реализовали простой сервис на Flask с PostgreSQL и показали как контейнеризовать и тестировать его. Прежде чем переходить на микросервисы, оцените зрелость команды и требования к системе.
Важное: начните с одной сервисной единицы, настройте CI/CD, мониторинг и секреты, затем масштабируйте архитектуру по потребности.
Если нужна версия руководства с примерами CI/CD, production-grade Dockerfile (gunicorn + healthcheck) или готовыми тестами pytest — сообщите вашу целевую среду, и я подготовлю дополнение.
Похожие материалы
Запланировать отправку письма в Gmail
Удаление старых драйверов Windows
Как установить Windows 11 на Mac с Parallels Desktop
Установка Node.js и npm на Ubuntu
Продлить срок службы SD‑карт на Raspberry Pi