Ответы пользователя по тегу Сервис-ориентированная архитектура
  • Как правильнее реализовать consumer'a rabbitmq в микросервисе grpc на go?

    2ord
    @2ord
    Если я верно понял, вопрос о том как сделать так, чтобы можно было слушать gRPC и RabbitMQ с одного сервиса.
    Тогда можно в теле main.go
    app := NewApp()
    app.Start()

    в структуре App можно декларировать ссылки на хэндлеры соединений для gRPC, RabbitMQ.

    func (a *App) Start() {
      go listenGRPC()
      go listenMQ()
    }


    Микросервис запустит 2 горутины, каждая из которых будет слушать и обрабатывать свои соединения независимо.
    Ответ написан
    Комментировать
  • Как подбирать недообработанные длительные задания?

    2ord
    @2ord
    Необходимо, чтобы приложения могли обрабатывать сигнал SIGTERM и по окончанию обработки задачи могли завершиться нормально.
    Ответ написан
    Комментировать
  • Как задизайнить job queue?

    2ord
    @2ord
    Думаю, при получении сообщений необходимо сохранить в СУБД тело сообщения, id (UUID?), timestamp. При наличии существующего id просто обновить timestamp.
    Некоторый сервис может с частотой 1 Гц проверять наличие записей, у которых timestamp подпадает под условие "которое находится в очереди как минимум 10 минут" и всех их отправлять в брокер сообщений и удалять/помечать как удалённые.
    Таким образом, обработчики очереди берут из очереди только сообщения, для которых пришло время обработки.
    Если темп отправки брокеру сообщений умеренный, нет смысла использовать Kafka. Возможно, достаточно и RabbitMQ. Главное, чтобы очередь не росла и обработчики успевали опустошать её.
    Ответ написан
    Комментировать
  • Как обращаться к микросервисам по именам? Нужен DNS?

    2ord
    @2ord
    Попробуй внешний DNS резолвер https://nip.io/
    Тогда нигде и ничего не нужно будет прописывать, а только обращаться к сервису по адресу типа
    serviceName.127.0.0.1.nip.io:5001
    Но без доступа к интернету не будет работать.
    Ответ написан
    Комментировать
  • Правильно ли под каждый микросервис запускать сервер базы данных?

    2ord
    @2ord
    Имеется в виду одна БД не для каждого отдельного экземпляра микросервиса, а для всех экземпляров некоторого микросервиса. Скажем, 10 контейнеров микросервиса с одним DB connection string. Соответственно, 1 балансировщик на эту группу.
    Ответ написан
    Комментировать
  • Архитектура сервиса для сбора и обработки текстовых данных. Нужна здоровая критика. /?

    2ord
    @2ord
    Моя схема:

    Запись данных: Клиенты --> LB --> API --> MQ брокер --> обработчики очереди --> СУБД
    То есть API получает данные от клиента, отправляет MQ брокеру (RabbitMQ/Apache Kafka) и сразу отвечает со статусом 200/202.
    API и обработчики очереди масштабировать по необходимости. Запись в материализованном представлении данных. СУБД с репликацией master-slave.

    Чтение данных: LB --> API --> кэш/СУБД
    Здесь можно взять даже какой-нибудь фреймворк типа RoR/Django.
    Ответ написан
  • MicroMQ и RabbitMQ очередь запросов внутри сервиса?

    2ord
    @2ord
    Хотел бы понять что означает
    намертво вешает систему.
    в контексте микросервисов? И почему это является проблемой?

    Тот получает кучу одинаковых заданий
    А почему нужно обрабатывать одинаковые URL повторно?
    Если, конечно, сильно надо, то можно проверять в K/V хранилище на наличие ключа с таким URL , у которого ограничено время жизни. Тогда при повторном событии просто игнорировать его.

    Ну а, вообще, микросервис "Браузер" может работать только в качестве обработчика очереди, получая сообщения, отправленные REST API. Сам же просто складывать в своем темпе результаты сканирования URL в СУБД, а REST API будет проверять наличие в той же СУБД и сообщать результаты клиенту, если готово.
    Ответ написан
  • Как приложениям лучше работать с общими данными в БД?

    2ord
    @2ord
    Когда несколько приложений обращаются к одной СУБД, то это усложняет поддержку этих приложений:
    • приходится изменять код во всех приложениях при любых изменениях в схеме СУБД
    • нужно отслеживать как влияют изменения на другие приложения из-за возможной регрессии.
    • проводить мониторинг соединений и того как запросы одного приложения влияют на другие (timeout, deadlock).

    Если все приложения должны писать в одну БД, то лучше добавить прослойку для обращения к ней.
    DB <= service A
    service A <= service B
    service A <= service C

    Кроме того так будет легче управлять, дебажить и масштабировать в случае нужды. Зона ответственности будет находиться у одного сервиса.
    Ответ написан
    3 комментария
  • Верна ли архитектура приложения сбора статистики онлайн пользователей используя Prometheus?

    2ord
    @2ord
    Мне показалось, что архитектура переусложнена. Может, чего-то недопонял. Prometheus метрики забирает (scraping) со всех узлов самостоятельно через http: //apiendpoint/metrics .

    То есть схема такова (data flow):
    [api 1..N] => Prometheus scraper => Prometheus TSDB

    Не понял зачем весь огород с очередями и воркерами. Какую задачу он призван решить?
    Прометей не может обращаться напрямую к узлам? А даже если нет, то можно предоставить ему доступ через прокси-сервер.

    Клиент моего продукта получает крайние справа данные за сутки/неделю/месяц по названию группы (group_name) в виде графика
    Для получения данных есть язык запросов PromQL по API.

    В конфигурации Prometheus можно переопределить интервал сбора метрик с узлов. Каждый узел должен уметь отдавать метрики в заданном формате. Благо, есть библиотеки. Средствами библиотеки пишем метрики (новый запрос к АПИ от клиента - делаем increment группе), которые автоматически агрегируются необходимым образом для Prometheus и выдаются по запросу скрэпера. Ответственность за тайминг сбора метрик лежит на Прометее.

    Данные временных серий хранятся в БД Prometheus в оптимальном виде. Или в совместимой с ней VictoriaMetrics, если того мало.

    Prometheus для хранения двух метрик users_amount{group=} и users_online{group=}
    Вроде бы OK.

    тысячи лэйблов в Prometheus - это ок?
    А зачем тысячи меток? Из-за кол-ва групп?
    Цититрую:
    CAUTION: Remember that every unique combination of key-value label pairs represents a new time series, which can dramatically increase the amount of data stored. Do not use labels to store dimensions with high cardinality (many different label values), such as user IDs, email addresses, or other unbounded sets of values.
    То есть не рекомендуют.

    если в Prometheus настроена pull модель для двух метрик, то он меня будет пинать раз в 5 минут делая два запроса по каждой метрике и я ему отдаю пачкой данные для тысяч лэйблов, у меня верное понимание?
    Метрики собираются одинажды для узла (endpoint), который должен представлять из себя отдельную группу со своими парами users_amount, users_online. Если так нельзя, то тогда Прометей тогда, наверное, не подходит. По крайней мере, я так себе представляю.

    Если по каким-то причинам Прометей не устроит, тогда можете рассмотреть ClickHouse, куда данные нужно отправлять пачками (с воркеров или как хотите). Но тогда всю логику сами разгребать будете. Redis'ом или как хотите.
    Ответ написан
  • Как правильно организовать микросервисную архитектуру средствами языка Golang?

    2ord
    @2ord
    Не нужно смешивать все вопросы в кучу. Отвечаю на вопрос в заголовке.

    Как правильно - зависит от масштаба проекта. Если он малый, то не нужно распыляться на много сервисов.

    В архитектуре описывают задачи сервисов.

    Вариант А (простой).
    Процесс-демон сканера-парсера сайтов, пишущий в СУБД (реляционную или документо-ориентированную). Обновляет новые страницы. Можно использовать очереди (тот же Redis) для обработки парсинга.
    cron-задача по очистке неактуальных записей.
    Телеграм-бот, читающий с СУБД подготовленную информацию.

    Вариант Б (сложнее).
    Процесс-демон сканера сайтов. Занимается сканированием страниц и кладет сообщение в очередь контент страниц. Потенциально держит много соединений со сканируемыми сайтами, обрабатывает ошибки получения страниц и пробует повторно.
    Процесс-демон парсера страниц. Занимается обработкой сообщений из очереди с контентом страниц, извлекает нужный контент и кладет в СУБД (upsert).
    cron-задача по очистке неактуальных записей.
    REST API для обработки запросов от Телеграм-бота, читающий с СУБД подготовленную информацию. Потенциально может потребоваться их большее количество.
    Телеграм-бот обращается к REST API за получением информации и других действий.

    В этом случае можно масштабировать каждый сервис отдельно, в зависимости от нагрузки. Само собой, вместо Go можно использовать любой подходящий язык XYZ.

    Не претендую на правильность. Это больше размышления на тему как можно сделать.
    Ответ написан
    Комментировать
  • Правильно ли копировать данные между микросервисами?

    2ord
    @2ord
    Каждому микро-сервису необходима разная информация по фильму.
    Возможно, через брокер сообщений нужно отправлять достаточное количество информации, необходимой для работы каждого сервиса. Тогда не нужно обращаться за данными к другому.

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

    Паттерн Event Sourcing говорит о том, что все изменения состояния приложения должны быть представлены как последовательность событий.
    Я не знаю какой брокер сообщений используете вы, но для возможности реконструировать всю последовательность изменений заново в каждом микросервисе, нужно изначально хранить их в каком-то центральном журнале событий. Apache Kafka весьма подходит для этих целей.
    Если не Kafka, то нужно обеспечить возможность отправлять одно и то же событие по нескольким каналам, чтобы каждый из микросервисов смог получить всю необходимую информацию.
    Изменения в СУБД должны происходить атомарно, чтобы избежать несогласованности данных.

    Шаблон источников событий
    https://martinfowler.com/eaaDev/EventSourcing.html
    https://microservices.io/patterns/data/event-sourc...
    Ответ написан
  • Как правильно организовать очереди?

    2ord
    @2ord
    А в чём проблема отправлять из сервис_1 в брокер и идентификатор пользователя и идентификатор сервиса (экземпляра), к которому он подключен? Тогда каждый экземпляр сервис_2 будет знать кому предназначена команда. Не вижу смысла плодить очереди на каждого пользователя (и тем более заниматься их управлением) и даже для каждого экземпляра сервис_1.
    Так что я за более простой вариант:
    Или это все одна очередь и каждое сообщение должно быть вычитано каждым инстансом сервиса_1 а затем отфильтровано?
    Ответ написан
  • Какой стэк выбрать для микросервисов на Golang?

    2ord
    @2ord
    1. Сначала нужно иметь подробное ТЗ с описанием всех функций продукта фронт-офис и минимальный бэк-офис для управления бизнес процессами. Продумать роли пользователей и доступ к разным функциям.
    2. Затем нужно построить схему с потоками данных.
    3. Построить архитектуру сервисов, разделив их по назначению.
    4. Продумать БД, очереди и т.д.
    5. Языки и фреймворки выбираются из задачи и различных критериев.
    Ответ написан
    Комментировать
  • Как организовать микросервис для биллинга?

    2ord
    @2ord
    Сразу предупреждаю что не работал с системами биллинга вплотную.

    Микросервисы
    Микросервисы помимо всего привносят дополнительную модульность к общей архитектуре. Система биллинга вряд ли может быть представлена микросервисом. На микросервисах лежит малое количество функций, иначе они не микро.

    Архитектура
    ... если делать в лоб, то перед каждым запросом юзера нужно будет делать запрос в БД, чтобы определить, доступно ли по тарифу этому юзеру действие. То есть увеличится количество запросов к БД существенно. А можно держать какой-то кеш в памяти, и для определения параметров тарифа обращаться к нему. Но процессов-бекендов у меня много (бекенд на ноде), а этот кеш должен быть один. Это либо какое-то хранилище использовать (Redis, memcache и т.д.), либо выделить все в один процесс и внутри него организовать кеш. В первом случае все равно нужно как-то управлять кешем, с помощью какого-то процесса. Вот я и остановился на втором варианте - сделать сервис, который будет отвечать на вопросы биллинга. Но кеш же нужно своевременно обновлять (например, когда оплата прошла), поэтому логично и оплату вносить через этот сервис - он сразу сможет обновить данные по нужному клиенту. А где оплата, там и счета и все остальное.

    Конечно нельзя по любому запросу пользователя лезть в БД и всё заново. Можно периодически отложенно считать стоимость услуг и сливать результаты в кэш.

    Иван Шумов верно заметил, стоит подумать о процессах и от этого отталкиваться.
    Материал почитать...
    Designing for SaaS: Next-Generation Software Deliv...
    Ответ написан