Ответ
Монолитная архитектура — это традиционный подход, при котором все компоненты приложения (UI, бизнес-логика, доступ к данным) объединены в единую кодовую базу и развертываются как единое целое.
Плюсы:
- Простота разработки и запуска: Единая кодовая база, один процесс сборки и развертывания. Идеально для небольших проектов, MVP и стартапов.
- Надежные транзакции: Легко обеспечить строгую согласованность данных с помощью стандартных ACID-транзакций базы данных, так как все операции происходят в рамках одного процесса.
- Высокая производительность (внутрипроцессная): Взаимодействие между компонентами происходит через вызовы функций, что значительно быстрее и надежнее сетевых запросов.
- Упрощенная отладка и тестирование: Весь контекст выполнения находится в одном приложении, что упрощает трассировку вызовов и end-to-end тестирование.
Минусы:
- Сложность масштабирования: Масштабировать можно только все приложение целиком, даже если нагружена лишь одна его часть (например, сервис обработки изображений).
- Низкая скорость разработки (с ростом проекта): Любое изменение требует пересборки и развертывания всего приложения, что замедляет циклы релиза и увеличивает риски.
- Технологическая привязка (Vendor Lock-in): Сложно внедрять новые технологии или языки программирования, не переписывая значительную часть системы.
- Хрупкость: Ошибка или утечка памяти в одном модуле может привести к отказу всего приложения.
Пример структуры простого монолитного веб-сервиса на Go:
package main
import (
"database/sql"
"fmt"
"log"
"net/http"
// Предполагается наличие драйвера, например: _ "github.com/lib/pq"
)
// App содержит общие зависимости, например, подключение к БД.
type App struct {
DB *sql.DB
}
// handleOrder - метод-обработчик, инкапсулирующий логику.
func (a *App) handleOrder(w http.ResponseWriter, r *http.Request) {
// Вся логика здесь: валидация, работа с БД, формирование ответа.
// Пример: получение пользователя и создание заказа в одной транзакции.
tx, err := a.DB.Begin()
if err != nil {
http.Error(w, "Server error", http.StatusInternalServerError)
return
}
// ... логика работы с транзакцией tx ...
if err := tx.Commit(); err != nil {
http.Error(w, "Failed to commit transaction", http.StatusInternalServerError)
return
}
fmt.Fprintln(w, "Order created successfully!")
}
func main() {
// Инициализация зависимостей в одном месте.
db, err := sql.Open("postgres", "user=... password=... dbname=... sslmode=disable")
if err != nil {
log.Fatal(err)
}
app := &App{DB: db}
// Все роуты регистрируются в одном приложении.
http.HandleFunc("/order", app.handleOrder)
log.Println("Starting server on :8080")
if err := http.ListenAndServe(":8080", nil); err != nil {
log.Fatal(err)
}
}