лучший подход для хранения в памяти (мультирегион в GCP / облачном хранилище) - PullRequest
0 голосов
/ 23 января 2020

Я создаю чат-приложение на реагирующем языке с nodejs бэкэндом. Я использую облачную платформу Google.

Я использую веб-сокеты для создания непрерывного соединения между приложением и серверной частью. Поскольку пользователи могут отправлять сообщения указанным c клиентам, я сохраняю сокеты в nodejs:

var sockets = {}
io.on('connection', socket => {
    console.log('user connected')
    let userId = socket.handshake.query.userId
    sockets[userId] = socket
    socket.on('message', msgData => {
        let msg = JSON.parse(msgData)
        sockets[msg.userId].emit('message', JSON.stringify(msg.message))
    }
    socket.on('disconnect', () => {
        console.log('user disconnected')
        delete sockets[userId]
    }
})

Обратите внимание, что это упрощенный пример.

Проблема заключается в том, что Я планирую иметь несколько экземпляров в разных регионах за балансировщиком нагрузки. Когда вы подключаетесь к указанному c экземпляру, другие экземпляры не могут достичь объекта сокетов. Поэтому, когда два разных пользователя подключены к двум разным экземплярам, ​​они не могут общаться друг с другом.

Чтобы решить эту проблему, я думал о сохранении сокетов в кэше redis (облачном хранилище памяти). Но экземпляр redis должен находиться в том же регионе, что и экземпляр VM. Но, как я уже сказал, у меня есть несколько экземпляров виртуальных машин в нескольких регионах.

Мои вопросы:

1) Является ли это решение лучшим решением для go? Или есть ли другие возможности, например, просто хранить сокеты в базе данных?

2) Как решить проблему невозможности подключения экземпляров виртуальной машины к экземпляру redis, если они не находятся в одном регионе , Должен ли я создать экземпляр redis для каждого региона, который я использую (asia-east1, europe-north1, us-central1), и отразить эти 3 экземпляра redis, чтобы они все имели одинаковое содержимое?

Если вы на другом стороны имеют совершенно другой подход, пожалуйста, дайте мне знать! Я все еще изучаю nodejs и облачную платформу Google, и я открыт для нового ввода.

Редактировать: Все экземпляры (группы экземпляров) имеют c в одном и том же VP C.

Редактировать 2: Что если я создам виртуальную машину в том же регионе, что и экземпляр redis, и использую ее в качестве прокси? Будут ли проблемы с производительностью?

Редактировать 3: Я заработал, создав прокси-сервер с использованием haproxy. Экземпляр находится в том же регионе, что и экземпляр Redis. Один вопрос: будут ли проблемы с производительностью? И действительно ли это путь к go?

1 Ответ

1 голос
/ 24 января 2020

Сосредоточив внимание на вашем первом вопросе, я бы сказал, что эта архитектура - не лучший способ реализации приложения чата. Облачная платформа Google предоставляет очень мощную службу обмена сообщениями - Pub / Sub . Используя этот сервис, все вопросы, касающиеся балансировки нагрузки, параллелизма, соединений и эффективности, будут решаться по умолчанию.

Здесь вы можете найти действительно хорошую статью о том, как создать приложение для чата. с Cloud Pub / Sub. Он основан на C#, но идея та же, но с использованием Nodejs клиентских библиотек Посмотрите общую схему работы Pub / Sub:

enter image description here

Архитектура этого приложения будет иметь следующие преимущества:

  • один-к-одному (прямой) и один-ко-многим функциональность обмена сообщениями

  • Метод передачи, при котором не требуется, чтобы полный сервер был
    разработан

В случае, если вы не хотите использовать Pub / Sub, я бы все-таки подумал, что вам понадобится централизованное серверное приложение, которое сможет общаться с пользователями, обрабатывать их сообщения и отправлять их по назначению и обратно.

Что касается вашего второго вопроса, это может сработать, но я думаю, что это может повлиять на производительность и, что более важно, на четкость самой системы. Поддерживать, отлаживать что-то вроде этого было бы кошмаром.

...