Ответ
L7-балансировщик — это балансировщик нагрузки, работающий на седьмом, прикладном уровне модели OSI (Application Layer). В отличие от L4-балансировщика, который оперирует на уровне транспортных протоколов (TCP/UDP) и видит только IP-адреса и порты, L7-балансировщик "понимает" протоколы прикладного уровня, такие как HTTP, HTTPS, gRPC.
Ключевые отличия от L4
- L4 (Транспортный уровень): Маршрутизирует трафик на основе IP-адреса и порта источника/назначения. Он не анализирует содержимое пакетов. Работает быстро, но с ограниченной гибкостью.
- L7 (Прикладной уровень): Анализирует содержимое запроса (URL, HTTP-заголовки, cookies, тело запроса) и принимает решение о маршрутизации на основе этих данных. Это позволяет реализовать более сложную логику.
Основные возможности и преимущества L7
- Content-Based Routing: Маршрутизация на разные группы серверов в зависимости от пути (
/api/v1
,/users
) или поддомена (api.example.com
). - Sticky Sessions (Прилипчивые сессии): Возможность направлять все запросы от одного клиента на один и тот же бэкенд-сервер, используя cookies.
- SSL/TLS Termination: L7-балансировщик может расшифровывать HTTPS-трафик, снимая эту нагрузку с бэкенд-серверов. Сервера за балансировщиком могут общаться по обычному HTTP.
- Перезапись URL и заголовков: Модификация запросов "на лету" перед отправкой на бэкенд.
Пример на Go (Reverse Proxy)
В Go L7-балансировщик можно реализовать с помощью httputil.ReverseProxy
. В этом примере трафик, идущий на /api
, направляется на API-сервис, а весь остальной — на веб-сервис.
package main
import (
"log"
"net/http"
"net/http/httputil"
"net/url"
"strings"
)
// director определяет, на какой бэкенд отправить запрос
func director(req *http.Request) {
// Парсим URL целевых сервисов
apiBackend, _ := url.Parse("http://api-backend:8080")
webBackend, _ := url.Parse("http://web-backend:8081")
// Если путь начинается с /api, отправляем на API-сервис
if strings.HasPrefix(req.URL.Path, "/api") {
req.URL.Scheme = apiBackend.Scheme
req.URL.Host = apiBackend.Host
} else {
// Иначе — на веб-сервис
req.URL.Scheme = webBackend.Scheme
req.URL.Host = webBackend.Host
}
}
func main() {
proxy := &httputil.ReverseProxy{Director: director}
log.Println("Starting L7 reverse proxy on :80")
if err := http.ListenAndServe(":80", proxy); err != nil {
log.Fatal(err)
}
}