Распределенные блокировки в микросервисной архитектуре

У нас есть настройка архитектуры, в которой у нас есть клиентское приложение, работающее на сервере, и мы хотели бы иметь микросервис, отвечающий за предоставление функций распределенной блокировки/карты/кэша. Эта служба Micro внутри использует Redisson, клиент на основе Java, который может взаимодействовать с Redis. Теперь мы хотели бы обеспечить блокировку API, разблокировку, получение, установку из службы Micro, которую может использовать клиентское приложение. Для связи между приложением и микрослужбой мы будем использовать протокол gRPC.

Как правильно предлагать API блокировки/разблокировки от Microservice клиенту? В настоящее время мы используем Redisson Semap на основе RedissonMap RMap.getLock(..)) и следует спецификации java Lock, поэтому поток, который получает распределенную блокировку, может только разблокироваться. Одна из проблем заключается в том, что поскольку блокировка обрабатывается микрослужбой, клиент должен делать отдельные запросы на блокировку и разблокировку, которые могут обслуживаться или не обслуживаться одним и тем же узлом (микрослужбой) и одним и тем же потоком. это можно обойти с помощью семафора (с 1 разрешением). Итак, по сути, мы используем Rsemaphore redisson для сервера варианта использования взаимного исключения.

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


person M. Shashanka    schedule 05.02.2020    source источник
comment
Я задаюсь вопросом, почему вы хотели бы иметь микросервис, отвечающий за предоставление функций распределенной блокировки/карты/кэша. Вы можете развернуть уже существующие службы координации, которые уже могут предоставить вам такую ​​функциональность, например ZooKeeper или etcd. Что касается асинхронности и синхронизации, это не имеет значения на уровне API, если вы используете gRPC, поскольку gRPC поддерживает оба варианта, и клиент может использовать любой из них.   -  person Mark A    schedule 05.02.2020
comment
когда я говорю, что предлагаю функцию блокировки из микросервиса, я не изобретаю ничего нового. Это просто для того, чтобы избавиться от зависимостей сторонних сервисов от основного приложения. Что касается синхронизации и асинхронности, меня беспокоило, является ли хорошей практикой синхронизация захвата/блокировки API, поскольку она потенциально может дольше удерживать соединение при высоком уровне параллелизма. Отклоняется ли это от стандартных практик микросервисов?   -  person M. Shashanka    schedule 05.02.2020


Ответы (2)


У меня есть аналогичная проблема - в какой-то момент - если это не «опрос», только микросервис должен будет заблокировать клиента, чтобы он дождался завершения семафора. Если блокировка неприемлема, семафор не нужен. Следующая логика должна работать нормально, даже если каждый вызов исходит из другой JVM (возможно, с начальным подключением к redis из этой JVM) — используйте один из объектов RLock или Atomic только временно — достаточно долго, чтобы обновить ключ или карту запись с некоторым уникальным идентификатором (предоставляемым клиентом или микрослужбой). Затем это «безопасно» сохраняется в Redis и указывает на что-то вроде «замка». Если вы используете срок действия ключа, это дает вам TTL для «замка».

Если ваше приложение может блокироваться в микросервисе, ожидая освобождения семафора, тогда вызовы из разных микросервисов должны работать нормально. Это та же самая модель, как если бы у вас было 2 давно работающих JVM, напрямую подключенных к redis/redisson, но каждая из которых использовала семафор только один раз.

Чего вы не можете сделать (легко), так это того, чтобы «блокировка» все еще «удерживалась», пока вы возвращаетесь к клиенту, а затем вызываете (другую JVM) микрослужбу, чтобы снять блокировку.

person DALDEI    schedule 29.03.2020

например, должен ли вызов для получения/освобождения разрешений в микросервисе быть синхронным или асинхронным

Это зависит от логики, применяемой семафором. Используйте асинхронный способ только для асинхронной логики, выполняемой внутри блока получения/выпуска.

person Nikita Koksharov    schedule 07.02.2020