В чем разница между микросервисной и сервис-ориентированной архитектурой

Ответ

Микросервисная архитектура (MSA) и сервис-ориентированная архитектура (SOA) — это два разных подхода к декомпозиции монолитных приложений на сервисы. Основные различия с точки зрения разработки и тестирования:

Критерий SOA MSA
Гранулярность Крупные, многофункциональные сервисы (например, «Сервис заказов»). Мелкие, автономные сервисы, отвечающие за одну бизнес-возможность (например, «Сервис расчета стоимости доставки»).
Способ коммуникации Часто через централизованную шину (ESB), которая управляет маршрутизацией и трансформацией данных. Легковесные протоколы (HTTP/REST, gRPC, асинхронные сообщения). Сервисы общаются напрямую или через простой брокер сообщений.
Управление данными Общая база данных или несколько тесно связанных БД. Каждый сервис владеет своей собственной базой данных (принцип bounded context из DDD).
Связность и независимость Сервисы тесно связаны через общие контракты и ESB. Сервисы слабо связаны, могут разрабатываться, развертываться и масштабироваться независимо.

Для QA это означает разный подход к тестированию:

  • В SOA фокус на интеграционное тестирование через ESB, проверку сложных бизнес-процессов и контрактов (XSD, WSDL).
  • В MSA критически важны:
    1. Изолированные модульные тесты для каждого сервиса.
    2. Контрактное тестирование (например, с Pact) для проверки взаимодействия между сервисами.
    3. Тестирование устойчивости (resilience testing) — как сервисы ведут себя при отказе соседних сервисов.
    4. Сквозное (E2E) тестирование ключевых пользовательских сценариев, проходящих через несколько сервисов.

Пример теста для микросервиса на Python (с использованием pytest и requests):

import pytest
import requests

SERVICE_URL = "http://user-service:8080"

def test_user_creation_and_retrieval():
    """E2E-сценарий: создание пользователя и получение его данных."""
    # 1. Создание пользователя
    create_payload = {"username": "test_user", "email": "test@example.com"}
    create_resp = requests.post(f"{SERVICE_URL}/users", json=create_payload)
    assert create_resp.status_code == 201
    user_id = create_resp.json()["id"]

    # 2. Получение созданного пользователя
    get_resp = requests.get(f"{SERVICE_URL}/users/{user_id}")
    assert get_resp.status_code == 200
    user_data = get_resp.json()
    assert user_data["username"] == "test_user"
    assert user_data["email"] == "test@example.com"

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

Ответ 18+ 🔞

Давай разжую тебе эту тему, как будто объясняю за бутылкой пива после тяжёлого дебага. Сиди, слушай.

Представь себе две стратегии, как раздолбать здоровенный, неповоротливый монолит на куски. Первая — это SOA, такая солидная, корпоративная тётя в пиджаке. Вторая — MSA, это уже орава шустрых, дерзких пацанов, которые носятся по серверной. Разница между ними — просто овердохуища.

SOA — это когда ты берёшь монолит и режешь его на крупные, основательные куски. Типа «Сервис Заказов», который внутри себя делает всё: от проверки кредитки до отправки письма курьеру. Эти куски общаются через центральную диспетчерскую — ESB (Enterprise Service Bus). Это такая жирная, навороченная шина, которая всё знает, всем рулит и данные преобразует. Представь себе главного по складу, который каждую коробку лично проверяет и ставит штампик. База данных у них часто одна на всех, или несколько, но так тесно переплетённых, что если один сервис накосячил, то всем остальным — хиросима и нигерсраки. Тестировать тут — это сплошное интеграционное веселье. Весь фокус на проверке этих здоровенных бизнес-процессов, которые плетутся через ESB, и на контрактах (этих ваших WSDL), которые по сложности как инструкция к космическому кораблю.

А теперь смотри сюда. MSA — это полная противоположность, ёпта. Ты дробишь монолит до состояния, когда каждый сервис — это хитрая жопа, отвечающая за одну мелкую, но чёткую задачу. «Сервис расчёта доставки», «Сервис отправки смс», «Сервис генерации аватарки котика». Каждый из этих мелких пацанов абсолютно автономен: у него своя база данных (принцип bounded context), свой код, и он может развернуться или упасть, не потревожив соседей. Общаются они между собой налегке: HTTP, gRPC или кидаются асинхронными сообщениями через простого брокера вроде Kafka. Никакой жирной шины ESB — хуй с горы, общаются почти напрямую.

И вот что это значит для нас, для QA. Если в SOA мы бздели в основном про интеграцию, то в мире микросервисов у нас терпения ноль ебать, потому что фокус смещается.

Вот на что надо орать и тыкать пальцем:

  1. Изолированные модульные тесты для каждого сервиса. Каждый пацан должен сам за себя отвечать.
  2. Контрактное тестирование (Pact). Это чтобы, когда один сервис говорит «я жду от тебя вот такие данные», а другой отвечает «ок, братан», — они не обманывали друг друга. Иначе получится манда с ушами, когда всё вроде работает по отдельности, а вместе — пизда рулю.
  3. Тестирование устойчивости (Resilience). Это святое. Надо проверять, как сервис ведёт себя, если его сосед, на которого он завязан, внезапно накрылся медным тазом. Выдерживает ли он? Или тоже падает, устраивая цепную реакцию?
  4. Сквозное (E2E) тестирование ключевых сценариев. Ну, это классика. Создал пользователя → он сделал заказ → получил уведомление. Весь путь должен работать, даже если он проходит через пяток разных микросервисов.

Смотри, какой простой тестик на Python для микросервиса пользователей. Всё прозрачно, как слеза ребёнка.

import pytest
import requests

SERVICE_URL = "http://user-service:8080"

def test_user_creation_and_retrieval():
    """E2E-сценарий: создание пользователя и получение его данных."""
    # 1. Создание пользователя
    create_payload = {"username": "test_user", "email": "test@example.com"}
    create_resp = requests.post(f"{SERVICE_URL}/users", json=create_payload)
    assert create_resp.status_code == 201
    user_id = create_resp.json()["id"]

    # 2. Получение созданного пользователя
    get_resp = requests.get(f"{SERVICE_URL}/users/{user_id}")
    assert get_resp.status_code == 200
    user_data = get_resp.json()
    assert user_data["username"] == "test_user"
    assert user_data["email"] == "test@example.com"

Итог, чувак. SOA — это для больших, неповоротливых корпораций с legacy, где всё должно быть по регламенту и с кучей бумажек. MSA — для современных, быстрых облачных штук, где команды работают независимо, а масштабировать нужно быстро и гибко. Выбирай, что тебе ближе: размеренная работа диспетчера на шине или весёлая гонка на картинге с кучей мелких, но юрких болидов.