Что такое монолитная архитектура приложения?

«Что такое монолитная архитектура приложения?» — вопрос из категории Архитектура, который задают на 10% собеседований QA Тестировщик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Монолитная архитектура — это традиционный подход к построению приложения, при котором все его компоненты (пользовательский интерфейс, бизнес-логика, логика доступа к данным) тесно связаны, собраны в единую кодовую базу и развертываются как одно целое.

Ключевые признаки монолита:

  • Единая кодовая база: Один репозиторий для всего приложения.
  • Единый процесс: Приложение запускается как один процесс или несколько идентичных процессов (реплик).
  • Общая база данных: Все модули приложения обычно работают с одной или несколькими общими БД.
  • Тесное связывание (tight coupling): Изменения в одном модуле могут неожиданно влиять на другие.

Пример структуры монолитного веб-приложения (MVC):

monolith-app/
├── src/
│   ├── controllers/   # Обработчики HTTP-запросов
│   ├── models/        # Сущности бизнес-логики и доступ к БД
│   ├── services/      # Бизнес-логика
│   ├── views/         # Шаблоны (UI)
│   └── utils/         # Общие вспомогательные функции
├── package.json       # Зависимости всего приложения
└── app.js             # Главная точка входа

Преимущества монолита:

  • Простота разработки на старте: Легко начать, не нужно настраивать межсервисное взаимодействие.
  • Простота развертывания: Достаточно собрать и запустить один артефакт (jar, exe, контейнер).
  • Сквозное тестирование: Легче писать интеграционные тесты, так как все компоненты в памяти.
  • Производительность: Вызовы между модулями — это вызовы функций в памяти, без сетевых задержек.

Недостатки, проявляющиеся с ростом:

  1. Сложность поддержки: Кодовая база растет, становится "неподъемной" (big ball of mud).
  2. Замедление разработки: Любое изменение требует пересборки и перезапуска всего приложения.
  3. Проблемы с масштабированием: Можно масштабировать только весь монолит целиком (горизонтально), даже если нагрузка приходится на одну его часть.
  4. Ограничение в технологиях: Вся команда вынуждена использовать единый стек технологий.
  5. Низкая отказоустойчивость: Баг в любом модуле может привести к падению всего приложения.

Пример простого монолита на Python/Flask:

from flask import Flask, request, jsonify
import sqlite3

app = Flask(__name__)

def get_db_connection():
    conn = sqlite3.connect('database.db')
    conn.row_factory = sqlite3.Row
    return conn

# Все в одном файле: и маршруты, и логика, и работа с БД
@app.route('/api/users', methods=['GET'])
def get_users():
    conn = get_db_connection()
    users = conn.execute('SELECT * FROM users').fetchall()
    conn.close()
    return jsonify([dict(user) for user in users])

@app.route('/api/orders', methods=['POST'])
def create_order():
    data = request.get_json()
    # Логика создания заказа, обращение к той же БД
    # ...
    return jsonify({"status": "created"}), 201

if __name__ == '__main__':
    app.run(debug=True)  # Запуск всего приложения одной командой

Когда выбирать монолит: Для небольших проектов, стартапов на ранней стадии или приложений с предсказуемой и простой логикой, где скорость старта критична.