Ответ
Прокси-сервер — это посредник между клиентом и сервером. Основные типы прокси и их реализация в Go:
1. Reverse Proxy (Обратный прокси)
Назначение: Принимает запросы от клиентов и перенаправляет их на один или несколько бэкенд-серверов. Используется для балансировки нагрузки, SSL-терминации, кэширования и сокрытия внутренней архитектуры.
Реализация в Go: Очень проста благодаря пакету net/http/httputil
.
import (
"log"
"net/http"
"net/http/httputil"
"net/url"
)
func main() {
// URL бэкенд-сервера, на который будут проксироваться запросы
target, err := url.Parse("http://localhost:8081")
if err != nil {
log.Fatal(err)
}
// Создаем reverse proxy
proxy := httputil.NewSingleHostReverseProxy(target)
// Запускаем HTTP-сервер, который будет использовать прокси как обработчик
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
log.Printf("Proxying request for: %s", r.URL.Path)
proxy.ServeHTTP(w, r)
})
log.Println("Reverse proxy server started on :8080")
log.Fatal(http.ListenAndServe(":8080", nil))
}
2. Forward Proxy (Прямой прокси)
Назначение: Принимает запросы от клиентов из внутренней сети и перенаправляет их во внешнюю сеть (интернет). Используется для обхода блокировок, фильтрации трафика, анонимизации.
Реализация в Go: Можно написать вручную, реализовав интерфейс http.Handler
. Приведенный ниже пример — упрощенный и не обрабатывает HTTPS-трафик (метод CONNECT
).
func handleHTTP(w http.ResponseWriter, r *http.Request) {
// Создаем новый запрос на основе оригинального
proxyReq, err := http.NewRequest(r.Method, r.URL.String(), r.Body)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
proxyReq.Header = r.Header
// Выполняем запрос
client := &http.Client{}
resp, err := client.Do(proxyReq)
if err != nil {
http.Error(w, err.Error(), http.StatusBadGateway)
return
}
defer resp.Body.Close()
// Копируем заголовки и тело ответа клиенту
for key, values := range resp.Header {
for _, value := range values {
w.Header().Add(key, value)
}
}
w.WriteHeader(resp.StatusCode)
io.Copy(w, resp.Body)
}
Готовые решения
Помимо самостоятельной реализации, в экосистеме Go популярны готовые прокси-серверы, написанные на Go:
- Traefik: Современный reverse proxy и балансировщик нагрузки, который легко интегрируется с Docker и Kubernetes.
- Caddy: Веб-сервер с автоматической поддержкой HTTPS, который также может работать как мощный reverse proxy.
- Envoy / Nginx: Хотя они написаны не на Go, для них существуют Go-библиотеки и SDK для управления и расширения их функциональности.