Какую архитектуру (микросервисы или монолит) вы использовали в последнем проекте?

Ответ

В последнем проекте использовалась микросервисная архитектура на Spring Boot.

Реализация:

  • Сервисы (user, order, payment) были выделены в отдельные приложения.
  • Синхронное взаимодействие через REST API.
  • Асинхронная коммуникация через брокер сообщений RabbitMQ (для событий и фоновых задач).

Пример REST-контроллера (user-service):

@RestController
@RequestMapping("/api/users")
public class UserController {
    @GetMapping("/{id}")
    public ResponseEntity<UserDTO> getUser(@PathVariable Long id) {
        UserDTO user = userService.findUserById(id);
        return ResponseEntity.ok(user);
    }
}

Преимущества: Независимое масштабирование и развертывание сервисов, технологическая гибкость. Сложности: Усложнение мониторинга, необходимость управления межсервисными коммуникациями и консистентностью данных.

Ответ 18+ 🔞

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

Вот смотри, в прошлом проекте мы сделали так: взяли всю эту хуйню — пользователей, заказы, платежи — и раскидали по отдельным коробочкам, каждая на своём Spring Boot. Каждая живёт своей жизнью, как сука независимая республика.

Как это всё общалось, спросишь? А по-разному, ёпта!

  • Синхронно: Когда нужно было быстро и прямо сейчас, сервисы орали друг на друга через REST API. Типа «эй, user-service, дай-ка мне данные этого юзера, а то щас впендюрю!».
  • Асинхронно: А когда можно было не торопиться или нужно было что-то сделать «на потом», кидали событие в RabbitMQ. Это как оставить записку на холодильнике: «заказ создан, разберитесь». Другие сервисы подходили, забирали её и делали свои дела — отправляли уведомление, списывали деньги. Все довольны, очередь не простаивает.

Вот, например, как выглядел кусок кода в сервисе пользователей, когда к нему приставали за данными:

@RestController
@RequestMapping("/api/users")
public class UserController {
    @GetMapping("/{id}")
    public ResponseEntity<UserDTO> getUser(@PathVariable Long id) {
        UserDTO user = userService.findUserById(id);
        return ResponseEntity.ok(user);
    }
}

Что в итоге получилось хорошего? Ну, сервисы можно масштабировать по отдельности. Если пользователей стало овердохуища, накинули мощностей только на user-service, а payment-service пусть себе в ус не дует. И технологии в каждом можно свои пихать, хоть на ассемблере писать, если начальство разрешит.

А что за пиздец начался? О, тут веселье. Мониторить эту паутину — тот ещё квест. Один сервис лег — и пошла цепная реакция, все остальные начали падать как домино, потому что ждут ответа. А ещё эта ебля с консистентностью данных... Один сервис говорит «заказ оплачен», а другой в это время уже отменил его. И сиди, разбирайся, кто из них тут мудак. В общем, волнение ебать, терпения ноль.