הגדרת איזון עומסים עם AWS ALB/ELB
האתר קורס תחת עומס? שגיאות 502 בזמן תנועה שיווקית בשיא? נתקלנו בזה בפרויקטים עם 100k+ RPS. איזון עומסים עם AWS ALB הוא הפתרון הסטנדרטי לפרויקטים בעלי עומס גבוה. אנו מגדירים ALB/ELB במפתח מלא: קבוצות יעד, חוקי מאזין, SSL, אינטגרציה עם Auto Scaling. ניסיון של 7+ שנים, 50+ מאזני עומסים שהוגדרו. הגדרת ALB נכונה היא קריטית לזמינות האתר ולמהירותו — חיסכון משמעותי בתשתית עם כוונון מוסמך.
AWS מספקת מאזני עומסים מנוהלים ללא צורך בתחזוקת שרת משלך. Application Load Balancer (ALB) פועל ברמת HTTP/HTTPS עם ניתוב לפי נתיב וכותרים. Network Load Balancer (NLB) — L4 TCP/UDP עם זמן השהיה מינימלי. Classic ELB מיושן ואינו מומלץ לפרויקטים חדשים.
למה לבחור ב-ALB על פני NLB?
ALB עדיף על NLB עבור HTTP/HTTPS: הוא תומך בניתוב חכם, אינטגרציה עם WAF, ואספקת תוכן סטטי. NLB חיוני לשירותי TCP הדורשים כתובות IP סטטיות וזמן השהיה מינימלי. אם יש לך יישום web מבוסס React/Vue או API של Node.js — בחר ב-ALB. עבור GameServer או VoIP — בחר ב-NLB. לעיתים קרובות אנו משלבים ביניהם: ALB ל-web, NLB ל-WebSocket.
| מאפיין | ALB (L7) | NLB (L4) |
|---|---|---|
| פרוטוקולים | HTTP/HTTPS/gRPC | TCP/UDP/TLS |
| ניתוב | לפי נתיב, כותרת, מארח | אין |
| אינטגרציה עם WAF | כן | לא |
| כתובת IP סטטית | לא | כן (באמצעות Elastic IP) |
| זמן השהיה | ~2-5 ms | <1 ms |
| קבוצות יעד | EC2, ECS, Lambda, IP | EC2, IP, ALB |
איך ALB עובד עם Auto Scaling?
חבר קבוצת יעד של ALB לקבוצת Auto Scaling. בעת קנה מידה, מופעים חדשים נרשמים אוטומטית ומתחילים לקבל תנועה. בדיקת הבריאות של ALB (נתיב /health, סף של 2 תגובות מוצלחות) קובעת מתי המופע מוכן לקבל בקשות. זה מבטיח פריסה ללא זמן השבתה. עבור שירותים קריטיים אנו משתמשים בקבוצות יעד עם deregistration_delay של 30 שניות כדי לאפשר לבקשות בתהליך להסתיים.
הגדרת ALB שלב אחר שלב באמצעות Terraform
- צור ALB עם קבוצות אבטחה ו-subnets.
- הגדר מאזין HTTPS עם תעודת ACM והפניה מ-HTTP.
- הגדר קבוצות יעד עם בדיקת בריאות ו-stickiness.
- הוסף חוקי מאזין לניתוב לפי נתיבים, כותרים או מארחים.
- חבר קבוצת יעד לשירות שלך (EC2, ECS, Lambda).
- הפעל יומני גישה וניטור.
דוגמת תצורה מלאה למטה.
Application Load Balancer
ALB הוא הבחירה הסטנדרטית ליישומי web. מנתב לפי נתיב, מארח, כותרות HTTP, שיטה, מחרוזת שאילתה. משתלב עם ECS, EKS, Lambda, קבוצות Auto Scaling. להלן תצורה מלאה עם AWS ALB, ניתוב ו-ACM.
# Terraform: полная конфигурация ALB + routing + ACM
resource "aws_lb" "main" {
name = "myapp-alb"
internal = false
load_balancer_type = "application"
security_groups = [aws_security_group.alb.id]
subnets = aws_subnet.public[*].id
enable_deletion_protection = true
enable_cross_zone_load_balancing = true
drop_invalid_header_fields = true
access_logs {
bucket = aws_s3_bucket.alb_logs.bucket
prefix = "alb"
enabled = true
}
tags = {
Name = "myapp-alb"
}
}
# HTTPS Listener
resource "aws_lb_listener" "https" {
load_balancer_arn = aws_lb.main.arn
port = 443
protocol = "HTTPS"
ssl_policy = "ELBSecurityPolicy-TLS13-1-2-2021-06"
certificate_arn = aws_acm_certificate.main.arn
default_action {
type = "forward"
target_group_arn = aws_lb_target_group.web.arn
}
}
# HTTP → HTTPS redirect
resource "aws_lb_listener" "http" {
load_balancer_arn = aws_lb.main.arn
port = 80
protocol = "HTTP"
default_action {
type = "redirect"
redirect {
port = "443"
protocol = "HTTPS"
status_code = "HTTP_301"
}
}
}
# Target Group для веб-приложения
resource "aws_lb_target_group" "web" {
name = "myapp-web-tg"
port = 8080
protocol = "HTTP"
vpc_id = aws_vpc.main.id
target_type = "ip" # для ECS Fargate
health_check {
enabled = true
path = "/health"
healthy_threshold = 2
unhealthy_threshold = 3
timeout = 5
interval = 10
matcher = "200"
}
deregistration_delay = 30
stickiness {
type = "lb_cookie"
cookie_duration = 86400
enabled = false
}
}
# API Target Group
resource "aws_lb_target_group" "api" {
name = "myapp-api-tg"
port = 3000
protocol = "HTTP"
vpc_id = aws_vpc.main.id
health_check {
path = "/api/health"
matcher = "200"
}
}
# Правила маршрутизации
resource "aws_lb_listener_rule" "api" {
listener_arn = aws_lb_listener.https.arn
priority = 10
action {
type = "forward"
target_group_arn = aws_lb_target_group.api.arn
}
condition {
path_pattern {
values = ["/api/*"]
}
}
}
# Маршрут по заголовку (версионирование API)
resource "aws_lb_listener_rule" "api_v2" {
listener_arn = aws_lb_listener.https.arn
priority = 5
action {
type = "forward"
target_group_arn = aws_lb_target_group.api_v2.arn
}
condition {
http_header {
http_header_name = "X-API-Version"
values = ["2", "2.0"]
}
}
}
# Weighted forwarding для Canary deployments
resource "aws_lb_listener_rule" "canary" {
listener_arn = aws_lb_listener.https.arn
priority = 20
action {
type = "forward"
forward {
target_group {
arn = aws_lb_target_group.web_stable.arn
weight = 95
}
target_group {
arn = aws_lb_target_group.web_canary.arn
weight = 5
}
stickiness {
enabled = true
duration = 3600
}
}
}
condition {
path_pattern {
values = ["/*"]
}
}
}
# Сертификат ACM
resource "aws_acm_certificate" "main" {
domain_name = "example.com"
subject_alternative_names = ["*.example.com"]
validation_method = "DNS"
lifecycle {
create_before_destroy = true
}
}
resource "aws_route53_record" "cert_validation" {
for_each = {
for dvo in aws_acm_certificate.main.domain_validation_options : dvo.domain_name => {
name = dvo.resource_record_name
record = dvo.resource_record_value
type = dvo.resource_record_type
}
}
zone_id = aws_route53_zone.main.zone_id
name = each.value.name
type = each.value.type
ttl = 60
records = [each.value.record]
}
resource "aws_acm_certificate_validation" "main" {
certificate_arn = aws_acm_certificate.main.arn
validation_record_fqdns = [for record in aws_route53_record.cert_validation : record.fqdn]
} ALB + WAF
אנו משלבים WAF להגנה מפני OWASP top-10 והגבלת קצב.
resource "aws_wafv2_web_acl_association" "alb" {
resource_arn = aws_lb.main.arn
web_acl_arn = aws_wafv2_web_acl.main.arn
}
resource "aws_wafv2_web_acl" "main" {
name = "myapp-waf"
scope = "REGIONAL"
default_action {
allow {}
}
rule {
name = "AWSManagedRulesCommonRuleSet"
priority = 1
override_action {
none {}
}
statement {
managed_rule_group_statement {
name = "AWSManagedRulesCommonRuleSet"
vendor_name = "AWS"
}
}
visibility_config {
cloudwatch_metrics_enabled = true
metric_name = "CommonRuleSet"
sampled_requests_enabled = true
}
}
rule {
name = "RateLimit"
priority = 2
action {
block {}
}
statement {
rate_based_statement {
limit = 2000
aggregate_key_type = "IP"
}
}
visibility_config {
cloudwatch_metrics_enabled = true
metric_name = "RateLimit"
sampled_requests_enabled = true
}
}
visibility_config {
cloudwatch_metrics_enabled = true
metric_name = "MyAppWAF"
sampled_requests_enabled = true
}
}
ALB + ECS Fargate
דוגמה לאינטגרציה של ALB עם Fargate: השירות נרשם אוטומטית בקבוצת היעד.
resource "aws_ecs_service" "app" {
name = "myapp-web"
cluster = aws_ecs_cluster.main.id
task_definition = aws_ecs_task_definition.app.arn
desired_count = 3
launch_type = "FARGATE"
network_configuration {
subnets = aws_subnet.private[*].id
security_groups = [aws_security_group.app.id]
assign_public_ip = false
}
load_balancer {
target_group_arn = aws_lb_target_group.web.arn
container_name = "web"
container_port = 8080
}
deployment_circuit_breaker {
enable = true
rollback = true
}
deployment_controller {
type = "ECS"
}
depends_on = [aws_lb_listener.https]
} Network Load Balancer
NLB עבור TCP/UDP עם כתובות IP סטטיות וזמן השהיה מינימלי.
resource "aws_lb" "nlb" {
name = "myapp-nlb"
internal = false
load_balancer_type = "network"
subnets = aws_subnet.public[*].id
enable_cross_zone_load_balancing = true
}
resource "aws_lb_listener" "nlb_tls" {
load_balancer_arn = aws_lb.nlb.arn
port = 443
protocol = "TLS"
ssl_policy = "ELBSecurityPolicy-TLS13-1-2-2021-06"
certificate_arn = aws_acm_certificate.main.arn
default_action {
type = "forward"
target_group_arn = aws_lb_target_group.nlb_tcp.arn
}
}
resource "aws_lb_target_group" "nlb_tcp" {
name = "myapp-nlb-tg"
port = 8080
protocol = "TCP"
vpc_id = aws_vpc.main.id
health_check {
protocol = "HTTP"
path = "/health"
healthy_threshold = 2
unhealthy_threshold = 2
interval = 10
}
} ניטור ALB
מדדי CloudWatch מרכזיים: # Terraform: полная конфигурация ALB + routing + ACM resource "aws_lb" "main" { name = "myapp-alb" internal = false load_balancer_type = "application" security_groups = [aws_security_group.alb.id] subnets = aws_subnet.public[*].id enable_deletion_protection = true enable_cross_zone_load_balancing = true drop_invalid_header_fields = true access_logs { bucket = aws_s3_bucket.alb_logs.bucket prefix = "alb" enabled = true } tags = { Name = "myapp-alb" } } # HTTPS Listener resource "aws_lb_listener" "https" { load_balancer_arn = aws_lb.main.arn port = 443 protocol = "HTTPS" ssl_policy = "ELBSecurityPolicy-TLS13-1-2-2021-06" certificate_arn = aws_acm_certificate.main.arn default_action { type = "forward" target_group_arn = aws_lb_target_group.web.arn } } # HTTP → HTTPS redirect resource "aws_lb_listener" "http" { load_balancer_arn = aws_lb.main.arn port = 80 protocol = "HTTP" default_action { type = "redirect" redirect { port = "443" protocol = "HTTPS" status_code = "HTTP_301" } } } # Target Group для веб-приложения resource "aws_lb_target_group" "web" { name = "myapp-web-tg" port = 8080 protocol = "HTTP" vpc_id = aws_vpc.main.id target_type = "ip" # для ECS Fargate health_check { enabled = true path = "/health" healthy_threshold = 2 unhealthy_threshold = 3 timeout = 5 interval = 10 matcher = "200" } deregistration_delay = 30 stickiness { type = "lb_cookie" cookie_duration = 86400 enabled = false } } # API Target Group resource "aws_lb_target_group" "api" { name = "myapp-api-tg" port = 3000 protocol = "HTTP" vpc_id = aws_vpc.main.id health_check { path = "/api/health" matcher = "200" } } # Правила маршрутизации resource "aws_lb_listener_rule" "api" { listener_arn = aws_lb_listener.https.arn priority = 10 action { type = "forward" target_group_arn = aws_lb_target_group.api.arn } condition { path_pattern { values = ["/api/*"] } } } # Маршрут по заголовку (версионирование API) resource "aws_lb_listener_rule" "api_v2" { listener_arn = aws_lb_listener.https.arn priority = 5 action { type = "forward" target_group_arn = aws_lb_target_group.api_v2.arn } condition { http_header { http_header_name = "X-API-Version" values = ["2", "2.0"] } } } # Weighted forwarding для Canary deployments resource "aws_lb_listener_rule" "canary" { listener_arn = aws_lb_listener.https.arn priority = 20 action { type = "forward" forward { target_group { arn = aws_lb_target_group.web_stable.arn weight = 95 } target_group { arn = aws_lb_target_group.web_canary.arn weight = 5 } stickiness { enabled = true duration = 3600 } } } condition { path_pattern { values = ["/*"] } } } # Сертификат ACM resource "aws_acm_certificate" "main" { domain_name = "example.com" subject_alternative_names = ["*.example.com"] validation_method = "DNS" lifecycle { create_before_destroy = true } } resource "aws_route53_record" "cert_validation" { for_each = { for dvo in aws_acm_certificate.main.domain_validation_options : dvo.domain_name => { name = dvo.resource_record_name record = dvo.resource_record_value type = dvo.resource_record_type } } zone_id = aws_route53_zone.main.zone_id name = each.value.name type = each.value.type ttl = 60 records = [each.value.record] } resource "aws_acm_certificate_validation" "main" { certificate_arn = aws_acm_certificate.main.arn validation_record_fqdns = [for record in aws_route53_record.cert_validation : record.fqdn] } , resource "aws_wafv2_web_acl_association" "alb" { resource_arn = aws_lb.main.arn web_acl_arn = aws_wafv2_web_acl.main.arn } resource "aws_wafv2_web_acl" "main" { name = "myapp-waf" scope = "REGIONAL" default_action { allow {} } rule { name = "AWSManagedRulesCommonRuleSet" priority = 1 override_action { none {} } statement { managed_rule_group_statement { name = "AWSManagedRulesCommonRuleSet" vendor_name = "AWS" } } visibility_config { cloudwatch_metrics_enabled = true metric_name = "CommonRuleSet" sampled_requests_enabled = true } } rule { name = "RateLimit" priority = 2 action { block {} } statement { rate_based_statement { limit = 2000 aggregate_key_type = "IP" } } visibility_config { cloudwatch_metrics_enabled = true metric_name = "RateLimit" sampled_requests_enabled = true } } visibility_config { cloudwatch_metrics_enabled = true metric_name = "MyAppWAF" sampled_requests_enabled = true } } , resource "aws_ecs_service" "app" { name = "myapp-web" cluster = aws_ecs_cluster.main.id task_definition = aws_ecs_task_definition.app.arn desired_count = 3 launch_type = "FARGATE" network_configuration { subnets = aws_subnet.private[*].id security_groups = [aws_security_group.app.id] assign_public_ip = false } load_balancer { target_group_arn = aws_lb_target_group.web.arn container_name = "web" container_port = 8080 } deployment_circuit_breaker { enable = true rollback = true } deployment_controller { type = "ECS" } depends_on = [aws_lb_listener.https] } (p50/p95/p99), resource "aws_lb" "nlb" { name = "myapp-nlb" internal = false load_balancer_type = "network" subnets = aws_subnet.public[*].id enable_cross_zone_load_balancing = true } resource "aws_lb_listener" "nlb_tls" { load_balancer_arn = aws_lb.nlb.arn port = 443 protocol = "TLS" ssl_policy = "ELBSecurityPolicy-TLS13-1-2-2021-06" certificate_arn = aws_acm_certificate.main.arn default_action { type = "forward" target_group_arn = aws_lb_target_group.nlb_tcp.arn } } resource "aws_lb_target_group" "nlb_tcp" { name = "myapp-nlb-tg" port = 8080 protocol = "TCP" vpc_id = aws_vpc.main.id health_check { protocol = "HTTP" path = "/health" healthy_threshold = 2 unhealthy_threshold = 2 interval = 10 } } , RequestCount, ActiveConnectionCount. אנו מגדירים התראות על 5xx וזמן השהיה גבוה.
resource "aws_cloudwatch_metric_alarm" "target_5xx" {
alarm_name = "alb-5xx-errors"
comparison_operator = "GreaterThanThreshold"
evaluation_periods = 2
metric_name = "HTTPCode_Target_5XX_Count"
namespace = "AWS/ApplicationELB"
period = 60
statistic = "Sum"
threshold = 10
alarm_actions = [aws_sns_topic.alerts.arn]
dimensions = {
LoadBalancer = aws_lb.main.arn_suffix
}
}
resource "aws_cloudwatch_metric_alarm" "latency" {
alarm_name = "alb-high-latency"
comparison_operator = "GreaterThanThreshold"
evaluation_periods = 3
metric_name = "TargetResponseTime"
namespace = "AWS/ApplicationELB"
period = 60
extended_statistic = "p95"
threshold = 2.0
alarm_actions = [aws_sns_topic.alerts.arn]
dimensions = {
LoadBalancer = aws_lb.main.arn_suffix
}
} מה כלול בעבודה
- תכנון איזון עומסים: בחירת סוג (ALB/NLB), תכנית רשת.
- קוד Terraform עם קבוצות יעד, חוקי מאזין, ACM, WAF.
- הגדרת ניטור והתראות.
- אינטגרציה עם CI/CD ו-Auto Scaling.
- תיעוד תפעולי והדרכת צוות.
לוחות זמנים ליישום
| תצורה | לוח זמנים |
|---|---|
| ALB + קבוצת יעד + HTTPS | 1–2 ימים |
| ניתוב לפי נתיב/כותרת | +יום אחד |
| WAF + הגבלת קצב | +1–2 ימים |
| פריסת Canary באמצעות העברת משקלים | +יום אחד |
| תצורת Terraform מלאה עם ניטור | 3–5 ימים |
טעויות תצורה נפוצות
- בדיקת בריאות לא מוגדרת — מופעים מקבלים תנועה לפני שהם מוכנים.
- הגנת מחיקה חסרה — מחיקת ALB בשוגג.
- מדיניות SSL שגויה — פרצות אבטחה.
- אי-הפעלת WAF — כללים מנוהלים לא מופעלים.
אנו מבטיחים יציבות וביצועים. קבל ייעוץ על הגדרת ALB לפרויקט שלך. צור קשר — נעריך לוחות זמנים למקרה שלך. תיעוד AWS ALB יכול לעזור להעמיק ביכולות.







