Client.Transport를 변경하지 않고 Go HTTP 프록시 경로 전환하기
동기화된 RoundTripper 래퍼를 사용해 실행 중인 http.Client 필드를 바꾸지 않고 새로 구성한 프록시 전송체를 게시합니다.
http.Client가 이미 동시 요청에 공유되고 있다면 Transport 필드를 안정적으로 유지하세요. 래퍼는 이후 각 왕복이 어떤 완전히 구성된 전송체를 받을지 동기화할 수 있습니다:
type routeSlot struct {
mu sync.RWMutex
current http.RoundTripper
}
func (s *routeSlot) RoundTrip(r *http.Request) (*http.Response, error) {
s.mu.RLock()
current := s.current
s.mu.RUnlock()
return current.RoundTrip(r)
}
func (s *routeSlot) Set(next http.RoundTripper) {
s.mu.Lock()
s.current = next
s.mu.Unlock()
}net/http와 sync를 사용해 클라이언트를 게시하기 전에 초기화하세요:
slot := &routeSlot{current: initialTransport}
client := &http.Client{Transport: slot}
slot.Set(nextTransport)initialTransport와 nextTransport는 non-nil이어야 하고, 완전히 구성되어야 하며, 동시성에 안전해야 합니다. 각 프록시 전송체는 게시 전에 만들고, 요청이 사용하는 동안에는 그 구성을 바꾸지 마세요.
잠금은 포인터 스냅숏만 보호하므로 느린 요청이 전체 네트워크 교환 동안 라우팅 잠금을 붙잡지 않습니다. 이전 스냅숏을 사용하는 요청은 그 전송체에서 계속 진행합니다. 전환은 그 요청을 다시 실행하지 않고 연결을 옮기지도 않습니다.
오래된 전송체는 애플리케이션의 제한된 수명 주기 안에서 유지하고 폐기하며, 진행 중인 작업이 끝나도록 하고 필요할 때 유휴 풀을 닫으세요. 리디렉션은 전환 후 또 다른 RoundTrip을 일으킬 수 있습니다. 워크플로 전체가 하나의 경로를 필요로 한다면, 이 공유 선택기를 중간에 바꾸지 말고 워크플로 경계에서 그 경로를 지정하세요.