Un selector de proxy round-robin compartido en Go
Mantén vivo un selector de proxy de Go entre peticiones, protege el estado de selección compartido y distingue elegir una ruta de observar su salida.
Un selector puede rotar perfectamente y aun así seguir eligiendo el primer proxy. El fallo está en crear accidentalmente un selector nuevo por cada petición, lo que reinicia su contador antes de que pueda hacer una segunda elección.
Construye el selector una vez y consérvalo con el transporte. La lista de proxies HTTP puede aportar candidatos HTTP públicos para el conjunto de URL cuando las peticiones permiten intermediarios públicos. Empieza con una lista de URL de proxy ya validada y no vacía:
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
}
}
La aplicación circundante debe rechazar una lista vacía, validar las URL y usar las importaciones normales net/http, net/url y sync. La lista debería permanecer inmutable mientras este selector la usa, o bien sustituirse mediante un diseño sincronizado por separado.
Adjunta la función devuelta a un único http.Transport retenido. El mutex protege la secuencia de selección entre devoluciones de llamada concurrentes. No exige mantener un bloqueo mientras se completa una petición de red lenta.
No consumas una ruta solo para imprimirla
Volver a llamar al selector para un mensaje de diagnóstico avanza el contador otra vez. Esa salida puede describir el siguiente candidato en lugar del candidato que usó la petición que estás investigando. Registra la selección dentro de la devolución de llamada real con un identificador de extremo seguro.
Una invocación de devolución de llamada no prueba que una petición se haya entregado correctamente. Las redirecciones o los intentos de transporte adicionales pueden complicar una suposición simple de «una llamada de la aplicación, una elección». Si un flujo de trabajo debe conservar una ruta durante varias operaciones, elige esa ruta en el límite del flujo de trabajo en lugar de usar una devolución de llamada rotatoria global.
El round-robin tampoco promete salidas públicas distintas. Programa extremos. La identidad final sigue siendo una propiedad de la ruta que aporta cada extremo.