Общий циклический селектор прокси на Go
Поддерживайте селектор прокси Go живым между запросами, защищайте общее состояние выбора и отличайте выбор маршрута от наблюдения за его выходом.
Селектор может идеально чередоваться и всё равно выбирать первый прокси. Ошибка в том, что для каждого запроса случайно создаётся новый селектор, который сбрасывает свой счётчик ещё до того, как появится второй вариант выбора.
Создайте селектор один раз и храните его вместе с транспортом. Список HTTP-прокси может предоставить публичных HTTP-кандидатов для набора URL, когда запросы допускают публичных посредников. Начните с уже проверенного, непустого списка URL прокси:
func rotatingProxy(urls []*url.URL) func(*http.Request) (*url.URL, error) {
var mu sync.Mutex
next := 0
return func(*http.Request) (*url.URL, error) {
mu.Lock()
selected := urls[next]
next = (next + 1) % len(urls)
mu.Unlock()
return selected, nil
}
}
Окружающее приложение должно отклонять пустой список, проверять URL и использовать обычные импорты net/http, net/url и sync. Список должен оставаться неизменным, пока этот селектор его использует, либо заменяться через отдельно синхронизированный дизайн.
Прикрепите возвращённую функцию к одному сохраняемому http.Transport. Мьютекс защищает последовательность выбора при одновременных обратных вызовах. Он не требует удерживать блокировку, пока завершается медленный сетевой запрос.
Не расходуйте маршрут только для того, чтобы его напечатать
Повторный вызов селектора для диагностического сообщения снова продвигает счётчик. Этот вывод может описывать следующего кандидата вместо кандидата, использованного исследуемым запросом. Фиксируйте выбор внутри настоящего обратного вызова с безопасным идентификатором конечной точки.
Вызов обратного вызова не является доказательством того, что запрос был успешно доставлен. Перенаправления или дополнительные попытки транспорта могут усложнить простое допущение «один вызов приложения — один выбор». Если рабочему процессу нужно сохранять один маршрут на протяжении нескольких операций, выбирайте этот маршрут на границе рабочего процесса, а не используйте глобальный вращающийся обратный вызов.
Циклическое чередование также не обещает различных публичных выходов. Оно планирует конечные точки. Итоговая идентичность остаётся свойством пути, который предоставляет каждая конечная точка.