En delad round-robin-proxyväljare i Go
Håll en Go-proxyväljare levande mellan förfrågningar, skydda delat valtillstånd och skilj valet av en rutt från att observera dess utgång.
En väljare kan rotera perfekt och ändå fortsätta att välja den första proxyn. Felet är att av misstag skapa en ny väljare för varje förfrågan, vilket nollställer räknaren innan den har ett andra val att göra.
Konstruera väljaren en gång och behåll den med transporten. HTTP-proxylistan kan leverera offentliga HTTP-kandidater för URL-uppsättningen när förfrågningarna tillåter offentliga mellanhänder. Börja med en redan validerad, icke-tom lista med proxy-URL:er:
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
}
}
Den omgivande applikationen måste avvisa en tom lista, validera URL:erna och använda de vanliga importerna net/http, net/url och sync. Listan bör förbli oföränderlig medan denna väljare använder den, eller ersättas genom en separat synkroniserad design.
Koppla den returnerade funktionen till en behållen http.Transport. Mutexen skyddar valsekvensen mellan samtidiga återanrop. Den kräver inte att ett lås hålls medan en långsam nätverksförfrågan slutförs.
Förbruka inte en rutt bara för att skriva ut den
Att anropa väljaren igen för ett diagnostikmeddelande flyttar räknaren framåt igen. Den utskriften kan beskriva nästa kandidat i stället för kandidaten som förfrågan du undersöker använde. Registrera valet inne i det riktiga återanropet med en säker slutpunktsidentifierare.
Ett återanrop är inte bevis på att en förfrågan levererades framgångsrikt. Omdirigeringar eller ytterligare transportförsök kan komplicera ett enkelt antagande om ”ett applikationsanrop, ett val”. Om ett arbetsflöde måste behålla en rutt genom flera operationer, välj den rutten vid arbetsflödets gräns i stället för att använda ett globalt roterande återanrop.
Round-robin lovar inte heller olika offentliga utgångar. Det schemalägger slutpunkter. Den slutliga identiteten förblir en egenskap hos den väg varje slutpunkt tillhandahåller.