Как создать общую очередь в Go? - PullRequest
0 голосов
/ 26 сентября 2019

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

server = spq[0]
serverNumber = server.value

updatedPriority = server.priority + 1 // Increment connection count for server

spq.update(server, serverNumber, updatedPriority)

targetUrl, err := url.Parse(configuration.Servers[serverNumber])
if err != nil {
    log.Fatal(err)
}

// Send the request to the selected server
httputil.NewSingleHostReverseProxy(targetUrl).ServeHTTP(w, r)

updatedPriority = server.priority - 1 // Decrement connection count for server
spq.update(server, serverNumber, updatedPriority)

, где spq - моя очередь с приоритетами.

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

Я уверен, что это как-то связано с синхронизацией и блокировкой очереди между запросами.Но я не уверен, каков правильный подход в данном конкретном случае.

1 Ответ

1 голос
/ 26 сентября 2019

Если это действительно ваш код, который выполняется в нескольких программах, то у вас явно есть расы.

Я не понимаю spq.update.Сначала это выглядит так, как будто это функция, которая переупорядочивает очередь, чтобы сервер имел минимальное количество вызовов в элементе 0, но тогда зачем ему и server, и serverNumber?serverNumber представляется уникальным идентификатором для сервера, и, поскольку у вас уже есть сервер, зачем он вам нужен?

В любом случае у вас должен быть sync.Mutex, общий для всех программ, и заблокируйтеmutex перед первой строкой и разблокировка после spq.update, также вы должны снова заблокировать его после вызова прокси и разблокировать, когда все будет сделано.Строка, которая вычитает 1 из server.priority, будет работать, только если server является указателем.Если это не указатель, вы теряете все обновления сервера, произошедшие во время разговора.

...