基于SQS队列深度的Auto Scaling Group扩容异常排查求助
Terraform配置ASG基于SQS队列深度扩容无触发问题排查
我用Terraform实现以下流程:创建S3存储桶及事件通知,配置S3触发的Lambda函数将消息发送到SQS队列;同时创建基于SQS队列深度(公式:消息数/实例数)的Auto Scaling Group(ASG),最大实例数设为5。我已经创建了对应的自动扩容策略,知道这类目标追踪策略无需告警即可自行触发,但执行terraform apply成功后,向SQS发送消息时ASG并没有新增实例。请问我哪里出错或者遗漏了什么?
初始代码
resource "aws_sqs_queue" "file_checker_sqs_queue" { name = var.sqs_queue_name max_message_size = 256000 message_retention_seconds = 86400 visibility_timeout_seconds = 30 receive_wait_time_seconds = 10 } data "aws_availability_zones" "available" { state = "available" # Only retrieve the main AZs, no local zones. filter { name = "opt-in-status" values = ["opt-in-not-required"] } } data "aws_ami" "audio_ami" { most_recent = true filter { name = "image-id" values = ["ami-067d1e60475437ey2"] } } resource "aws_launch_configuration" "audio_asg_launch_config" { name_prefix = var.launch_config_name_prefix image_id = data.aws_ami.audio_ami.id instance_type = "t2.micro" lifecycle { create_before_destroy = true } } resource "aws_autoscaling_group" "audio_auto_scaling_group" { availability_zones = data.aws_availability_zones.available.names name = var.asg_name max_size = 5 min_size = 0 health_check_grace_period = 300 health_check_type = "EC2" force_delete = true launch_configuration = aws_launch_configuration.audio_asg_launch_config.name } resource "aws_autoscaling_policy" "asg_audio_scale_up_policy" { autoscaling_group_name = var.asg_name name = var.asg_policy_name policy_type = "TargetTrackingScaling" depends_on = [ aws_autoscaling_group.audio_auto_scaling_group ] target_tracking_configuration { target_value = 1 customized_metric_specification { metrics { label = "Get the queue size (the number of messages waiting to be processed)" id = "m1" metric_stat { metric { namespace = "AWS/SQS" metric_name = "ApproximateNumberOfMessagesVisible" dimensions { name = "QueueName" value = var.sqs_queue_name } } stat = "Sum" } return_data = false } metrics { label = "Get the group size (the number of InService instances)" id = "m2" metric_stat { metric { namespace = "AWS/AutoScaling" metric_name = "GroupInServiceInstances" dimensions { name = "AutoScalingGroupName" value = var.asg_name } } stat = "Average" } return_data = false } metrics { label = "Calculate the backlog per instance" id = "e1" expression = "IF(m2 == 0, m1, m1 / m2)" return_data = true } } } }
更新后代码
resource "aws_launch_template" "audio_asg_launch_template" { name_prefix = var.launch_config_name_prefix image_id = data.aws_ami.audio_ami.id instance_type = "t2.micro" } resource "aws_autoscaling_group" "audio_auto_scaling_group" { availability_zones = data.aws_availability_zones.available.names name = var.asg_name max_size = var.asg_max_size min_size = var.asg_min_size desired_capacity = 0 health_check_grace_period = var.asg_health_check_grace_period health_check_type = "EC2" force_delete = true launch_template { id = aws_launch_template.audio_asg_launch_template.id version = "$Latest" } } resource "aws_autoscaling_policy" "asg_audio_scale_up_policy" { autoscaling_group_name = aws_autoscaling_group.audio_auto_scaling_group.name name = var.asg_policy_name policy_type = "TargetTrackingScaling" target_tracking_configuration { target_value = 1 customized_metric_specification { metrics { label = "Get the queue size (the number of messages waiting to be processed)" id = "m1" metric_stat { metric { namespace = "AWS/SQS" metric_name = "ApproximateNumberOfMessagesVisible" dimensions { name = "QueueName" value = aws_sqs_queue.file_checker_sqs_queue.name } } stat = "Sum" } return_data = false } metrics { label = "Get the group size (the number of InService instances)" id = "m2" metric_stat { metric { namespace = "AWS/AutoScaling" metric_name = "GroupInServiceInstances" dimensions { name = "AutoScalingGroupName" value = aws_autoscaling_group.audio_auto_scaling_group.name } } stat = "Average" } return_data = false } metrics { label = "Calculate the backlog per instance" id = "e1" expression = "IF(m2 == 0, m1, m1 / m2)" return_data = true } } } }
可能的问题及排查方向
- 指标计算逻辑缺陷:当前表达式
IF(m2 == 0, m1, m1 / m2)在实例数为0时,计算值等于队列消息数。而你的target_value=1,如果队列只有1条消息,计算值刚好等于目标值,不会触发扩容。建议调整表达式为IF(m2 == 0, 100, m1/m2),这样只要队列有消息,计算值就会远大于目标值,触发ASG扩容到至少1个实例。 - CloudWatch指标延迟:CloudWatch指标默认的统计周期是5分钟,目标追踪策略需要等待指标聚合完成后才会执行扩缩容判断。发送消息后需等待至少5分钟再观察ASG状态。
- ASG权限缺失:检查ASG关联的IAM角色是否具备读取CloudWatch指标、执行EC2实例创建的权限。虽然Terraform默认会创建基础权限,但如果有自定义IAM策略,可能遗漏了
cloudwatch:GetMetricStatistics、ec2:RunInstances等关键权限。 - 启动模板配置不全:你的启动模板未配置安全组、密钥对等必要参数,可能导致实例无法成功启动。即使ASG触发扩容,实例启动失败也不会显示在ASG的实例列表中。需补充安全组(允许必要的网络访问)和密钥对配置。
- 策略关联状态异常:登录AWS控制台,进入ASG详情页查看自动扩缩容策略是否已成功关联,以及策略是否有报错信息(比如指标无法读取)。
- 目标值设置不合理:
target_value=1意味着每个实例只处理1条消息,这个阈值过于严格。可以根据实际处理能力调整为更高的值(比如5或10),避免频繁扩缩容,同时确保触发逻辑更符合预期。
内容的提问来源于stack exchange,提问作者dnd1993
相关产品推荐
相关产品推荐

