#javascript #node.js #mon&odb #mon&oose #nosql
#javascript #node.js #mon&odb #mon&oose #nosql
Вопрос:
Итак, у меня странная проблема, о которой я ломаю голову уже несколько дней, и, похоже, я не могу найти никаких онлайн-решений.
Я разрабатываю службу заказа в мобильном приложении, которая использует уникальные идентификаторы заказа каждый раз, когда размещается заказ.
Каждый день базовое значение идентификатора заказа сбрасывается обратно до 100, а затем, когда заказы размещаются в этот день, оно увеличивается, например: 101, 102, 103, 104 и т.д.
Мой идентификатор заказа рассчитывается на основе количества «активных заказов» в коллекции с именем orders
, 1. Таким образом, если имеется 5 активных заказов, новый идентификатор заказа, возвращаемый клиенту, равен 106. Это работает нормально, за исключением одной проблемы:
- У меня есть 4 экземпляра моего node.js API работает одновременно, чтобы сбалансировать нагрузку.
- Все эти узлы подключены к одной и той же базе данных mon&o.
Итак, если два заказа размещены параллельно, экземпляры 1 и 2 принимают по заказу каждый, оба запрашивают базу данных, сколько существует «активных заказов», и они, очевидно, оба получают одинаковое значение, потому что это происходит практически в одно и то же время. Следовательно, они оба возвращают один и тот же идентификатор заказа, и тогда у нас есть два клиента с одинаковым идентификатором заказа.
Если я сведу свою настройку обратно к одному экземпляру, то это будет работать идеально, поскольку исключает возможность параллельного выполнения заказов. Однако для HA и балансировки нагрузки мне нужно иметь возможность масштабироваться по горизонтали с несколькими экземплярами.
Существует ли стандартная практика, позволяющая избежать такого сценария? Существуют ли лучшие способы отслеживания идентификаторов заказа, подобные этому?
Мы будем очень признательны за любую помощь.
Спасибо.
Ответ №1:
Вы можете использовать блокировки мьютекса, которые используются для одновременного предотвращения доступа к ресурсам. Таким образом, в принципе, процесс получит доступ, когда блокировка будет снята (разблокирована). В противном случае он будет ждать, пока его не станет бесплатным для использования. Вы можете найти один модуль, который делает это за вас здесь: locks
Редактировать:
Другое решение может предотвратить параллельную обработку имеющихся у вас 4 экземпляров. Итак, что вы можете сделать, так это реализовать подход, основанный на очереди, и для этого. Вот модуль, который поможет вам в этом: Mon&oDB-Queue И вы также можете обратиться к этой статье : Medium-Mon&oDB-Queue
Комментарии:
1. Привет, спасибо за ваш ответ — это выглядит хорошо, но во время работы я ожидаю 100 заказов, так будет ли эта «блокировка» противоречить цели моего горизонтального масштабирования и параллельного выполнения заказов?
2. Ну, выполнение одной транзакции за раз не должно занимать так много времени для обработки, поэтому технически параллельный эффект все равно должен быть. Вы все еще можете попробовать это, в противном случае вы можете реализовать свою собственную «Очередь» с использованием подхода FIFO. Я отредактирую свой ответ.
3. Подход, основанный на очереди, — это именно то, что я искал, а также решает другую будущую проблему, с которой, я знаю, я бы столкнулся — так что спасибо!
Ответ №2:
Вы можете добиться балансировки нагрузки, но при этом предотвратить отправку заказа от одного и того же клиента в несколько инстансов, установив пользовательский уровень перед фактическими программами обработки, которые будут направлять запрос конкретного клиента только на определенный узел. Это можно сделать, выполнив операции хэширования и деления по модулю, скажем, с идентификатором клиента, а затем определив узел, на который он должен быть перенаправлен. Поскольку этот уровень «маршрутизатора» в основном является просто пользовательским прокси-сервером и не выполняет дополнительной обработки — это не должно оказывать никакого влияния на производительность.