Эксперименты с микросервисами

Недавно на работе меня попросили сделать мини-проект: динамическую страницу со слайдами для одного из настенных проекторов. Они развешаны по всему офису, и показывают на стенах разную актуальную информацию: статистики по клиентам, задержки при передаче пакетов от одного сервера к другому, кто над чем работает, и т. п. Мне же нужно было добавить статистику по релизам и билдам: сколько времени занимает билд, какие тесты упали, какие нестабильные, и что там еще может мотивировать разработчиков на подвиг. Вся эта информация лежит в Google BigQuery, и её нужно просто собрать и грамотно представить. Ничего сложного.

А я с недавних пор живо интересуюсь распределенными приложениями и микросервисами. Вместо того, чтобы делать большое монолитное приложение, мы дробим его на логические единицы-сервисы, которые работают независимо друг от друга и общаются по какому-нибудь легковесному протоколу. Например, HTTP. И эта задача оказалась просто создана для того, чтобы с ней поиграть в микросервисы, потому что:

  • запрашивать данные напрямую из BigQuery медленно и неудобно, так что нужно сделать какой-нибудь кэш-агрегатор, который будет снабжать данными страницу со слайдами;
  • очень может быть, что сервис с данными будет полезен и для других внутренних проектов, так что хорошо бы сделать его более или менее автономным и независимым от вэб-проекта;
  • серверный язык, понятный всем на конторе, — C#, так что сервис данных должен быть на .NET или .NET Core;
  • вэб-страница должна быть закрыта для посторонних, например, логином и паролем. Быстрее всего я могу это сделать на Nodejs.

То есть в приложении автоматически вырисовываются два сотрудничающих сервиса — сервис данных и сервис представления, у них разные требования к языку и среде выполнения, и по крайней мере один из сервисов может быть использован кем-то еще. Микросервисы в чистом виде.

Вот к какой архитектуре я по итогу пришёл:

Микросервис-архитектура

В Ubuntu-машине на 80-м порту сидит Nginx и маршрутизирует запросы либо к вэб-, либо к сервису данных, которые живут на портах 8080 и 5000. Конфигурировать Nginx в качестве reverse proxy — одно удовольствие:

UI-сервис на Node.js просто раздаёт html и javascript. После того, как я убрал из него авторизацию и вместо неё добавил IP-фильтр в Nginx, не осталось ни одной веской причины, зачем Node.js вообще нужен. Контент может раздавать как сам Nginx, так и какой-нибудь IIS, Apache или даже python -m SimpleHTTPServer . Остальным компонентам приложения это побоку. Вот она, свобода!

Сервис-данных написан на ASP.NET Core. Он общается напрямую с BigData, держит локальный кэш, и отдаёт данные миру через RESTful API. Например, GET /build , GET /build/master . И да, .NET Core действительно работает на linux.

Я в восторге от эффекта. Во-первых, UI-кусок приложения не ожидает, что сервис с данными будет постоянно доступен — это ведь разные сервисы. Из-за этого приложение запросто работает и в оффлайн, и с дата-сервисом, который рухнул. Оно просто показывает последние доступные результаты.

Во-вторых, я могу запросто увести Node.js в оффлайн чтобы что-то исправить, и сервису данных это побоку. Никакого downtime, никаких тормозов из-за пересоздания кэша — сервис продолжает работать. И это разумно — если нужно обслужить какой-то кусок приложения, не обязательно выключать его целиком.

В-третьих, я наделал кучу ошибок в дата-сервисе, и, пока не исправил, должен его время от времени перезапускать. И никто не заметил. Потому что UI часть приложения как работает, так и работала.

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

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *