去年我接手了一套跑在 AWS Elastic Beanstalk(EB)上的生产环境,App 层、Worker 层加起来十几个环境,平时看着挺稳。直到某天大促流量上来,用户在群里开始反馈页面转圈,我打开 CloudWatch 一看,某台 t3.medium 的 CPU 已经顶着 100% 跑了快二十分钟,AutoScaling 组里新实例还在 Initializing 的状态没转起来。更尴尬的是,那个时段我们没有任何告警进来——不是告警没触发,而是压根没给这个 AutoScaling 组配置过自定义告警。
这个问题的根子在于,EB 环境里的 AutoScaling 组虽然是标准的 EC2 Auto Scaling 资源,但它对用户来说是个“托管黑盒”,不会像你自己用控制台创建 ASG 那样顺手就能点几个按钮把告警配好。这篇文章就围绕“AWS EB 环境为 AutoScaling 组添加告警”这件事,完整梳理一遍我的实操过程:EB 里 ASG 的托管机制、如何定位 ASG、指标怎么选、内置 trigger 和自定义 CloudWatch 告警两条路径怎么取舍、SNS 通知链路怎么搭,以及上线后我踩过的几个坑。适合正在用 EB 做生产环境的开发或运维同学参考。
1. 为什么在 EB 里“加告警”不是点一个按钮那么简单
很多人第一次接触 EB,都会觉得它就是一个“自动帮你建 EC2、ELB、ASG”的工具,那告警直接去 EC2 Auto Scaling 控制台配不就行了?实际操作后你就会发现,事情没那么简单。
1.1 EB 环境里的 AutoScaling 组其实是一个“黑盒”
EB 环境本质上是一个 CloudFormation 栈,栈里包含一个名为 AWSEBAutoScalingGroup 的 AutoScaling Group、一个或多个 Launch Template、一个 Load Balancer,以及安全组、实例角色等一堆资源。这个 CloudFormation 栈由 EB 平台托管,EB 对环境配置的每一次变更,都可能触发栈更新,进而修改 ASG 的容量、实例类型、扩缩策略等。
问题就在这里:如果你绕过 EB 的配置体系,直接跑到 Auto Scaling 控制台去改这个 ASG 的扩展策略、告警策略,EB 下一次环境更新时很可能把你手动改的东西覆盖掉。原因很简单,EB 会以自己维护的配置为“唯一事实来源”,它认为用户不应该直接操作底层的 ASG。
所以,给 EB 的 ASG 添加告警,首先要想清楚一个原则:哪些告警应该用 EB 的内置配置项来声明,哪些告警必须通过 CloudWatch 自定义告警来做,而且要做好“环境更新后告警可能丢失”的心理准备。后面第 6 节我会再展开讲这个坑。
1.2 默认告警和手动告警的边界
EB 控制台的环境页面里,有一个“监控”页签,能看到 CPU、网络、磁盘 I/O 等基础指标,但这些只是“看板”,不是“告警”。EB 默认的告警能力非常基础,它主要依赖环境健康状态(Health Status)来判断是否异常,比如 ELB 的 5xx 比例过高、实例状态检查失败等,会反映在 EB 环境的 Overall Health 上。但如果你设置了 healthy 阈值太宽松,或者应用进程自己出了问题但 ELB 还认为后端健康,那 EB 的健康检查可能根本不会告警。
另外,EB 的“环境健康”是环境级别的,不是实例级别或 ASG 级别的。你无法通过 EB 健康状态快速感知“某一台实例内存吃满但整体还撑得住”这种情况。所以需要额外配置自定义告警,把监控粒度下探到 ASG 维度,甚至实例维度。
1.3 EB 内置 trigger 的限制:能配什么、不能配什么
EB 的配置文件里其实有一个专门的命名空间,叫 aws:autoscaling:trigger,它负责定义基于 CloudWatch 指标的伸缩触发规则,例如:
yaml复制option_settings:
aws:autoscaling:trigger:
MeasureName: CPUUtilization
Statistic: Average
Unit: Percent
Period: "300"
EvaluationPeriods: "2"
UpperThreshold: "80"
LowerThreshold: "20"
UpperBreachScaleIncrement: "1"
LowerBreachScaleIncrement: "-1"
这套配置的实质,就是让 EB 自动在 CloudWatch 里创建一个告警,并挂到 ASG 的扩容/缩容策略上。注意,它只能使用 EC2 的标准指标,比如 CPUUtilization、NetworkIn、NetworkOut、DiskReadBytes、DiskWriteBytes 等。想用内存使用率、磁盘使用率这类自定义指标,它做不到。
所以我的结论是:如果是监控 CPU 这类基础指标,优先用 EB 内置 trigger;如果需要内存、磁盘、应用层自定义指标,就必须走自定义 CloudWatch 告警 + CloudWatch Agent 采集的路线。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 先锁定目标:找出 EB 环境背后的那个 ASG
不管是走 EB 内置 trigger,还是自定义 CloudWatch 告警,你都得先搞清楚当前 EB 环境对应的 ASG 叫什么名字、在哪个区域。这个步骤看着简单,但在多环境多区域场景下,特别容易搞混。
2.1 控制台三分钟定位 ASG
最简单的方法:进入 EB 控制台,打开具体环境页面,左侧菜单找到“配置”,然后点击“容量”板块的“修改”。弹出的界面里会显示 Auto Scaling 组的名称,通常长这样:
code复制awseb-e-xxxxx-stack-AWSEBAutoScalingGroup-XXXXXXXXXXXX
记下这个名字,后续配置 CloudWatch 告警、SNS 通知都要用到。还有另一个办法:打开 EC2 Auto Scaling 控制台,筛选出 ASG 名称里包含 awseb-e- 前缀的组,再对照环境 ID 判断是哪一个。
2.2 用 CLI 反查 ASG 名称
如果环境太多,或者你在写自动化脚本,建议用 CLI 反查。先通过 EB 的 API 拿环境 ID:
bash复制aws elasticbeanstalk describe-environments \
--environment-names my-production-env \
--region us-east-1 \
--query "Environments[0].EnvironmentId" \
--output text
拿到 EnvironmentId 后,可以用 CloudFormation 的接口反查这个环境栈里的 ASG 物理 ID。EB 环境对应的 CloudFormation 栈名格式是 awseb-e-{EnvironmentId}-stack:
bash复制aws cloudformation list-stack-resources \
--stack-name awseb-e-{EnvironmentId}-stack \
--region us-east-1 \
--query "StackResourceSummaries[?LogicalResourceId=='AWSEBAutoScalingGroup'].PhysicalResourceId" \
--output text
这里有一点要留意:EB 环境的 CloudFormation 栈不是每次都叫 awseb-e-{EnvironmentId}-stack,早期版本可能是 awseb-{EnvironmentName}-stack。如果 list-stack-resources 查不到,可以先 aws cloudformation describe-stacks 列出所有栈名,再确认。
2.3 多环境/多区域下的命名陷阱
ASG 名称里的那串随机字符是 CloudFormation 生成的物理 ID,每个环境都不一样。同一套代码部署到不同环境、不同区域,ASG 名称都不同,所以脚本里不能写死名称,一定得通过查询动态获取。
还有一点容易被忽略:如果 EB 环境做过“Platform upgrade”或“Configuration update”导致底层 ASG 被替换,ASG 名称会变。这种情况在手动运维的多环境场景下尤其危险,因为告警维度里写的是旧的 ASG 名称,一旦 ASG 被替换,告警条件永远匹配不到新实例,直接失效。
3. 指标选型:给 AutoScaling 组告警,到底该盯哪些数据
定位到 ASG 之后,下一步是确定告警哪些指标。我的经验是分三层:第一层是免费的实例标准指标,第二层是需要装 Agent 的自定义指标,第三层是告警维度设计层面的问题。
3.1 CPU、网络和状态检查:免费的必配项
EC2 免费的基础指标包括 CPUUtilization、NetworkIn、NetworkOut、DiskReadBytes、DiskWriteBytes、StatusCheckFailed_Instance、StatusCheckFailed_System 等。在 ASG 维度做告警时,最常用的是:
- CPUUtilization:应用负载的直接体现,适合做扩缩容触发和异常告警。
- StatusCheckFailed_Instance:实例内部系统崩溃或网络栈异常,需要立刻人工介入。
- StatusCheckFailed_System:底层硬件或 AWS 侧问题,通常需要重启实例或迁移。
网络指标我一般不做告警,只做看板。因为网络流量波动大,阈值难定,而且网络打满时 CPU 大概率已经出问题了。真正需要关注的是“丢包率”或者“ELB 5xx”,但这些在 ASG 维度没有,得看 ELB 维度。
3.2 内存和磁盘使用率:默认不采集,需要 CloudWatch Agent
这是新手最容易踩的坑:你在 CloudWatch 里选了 AWS/EC2 命名空间,然后搜 MemoryUtilization,会发现根本搜不到。因为 EC2 默认不采集内存指标,必须安装 CloudWatch Agent 并通过配置开启内存、磁盘指标采集。
对于 EB 环境,推荐的做法是在 .ebextensions 里写一个配置文件,负责安装 CloudWatch Agent、写入采集配置并启动服务。一个最简配置如下:
yaml复制# .ebextensions/cloudwatch-agent.config
files:
/etc/amazon/amazon-cloudwatch-agent.json:
mode: "000644"
owner: root
group: root
content: |
{
"metrics": {
"append_dimensions": {
"AutoScalingGroupName": "${aws:autoscaling:groupName}",
"InstanceId": "${aws:instanceId}"
},
"metrics_collected": {
"mem": {
"measurement": [
{ "name": "mem_used_percent", "unit": "Percent" }
],
"metrics_collection_interval": 60
},
"disk": {
"measurement": [
{ "name": "disk_used_percent", "unit": "Percent" }
],
"resources": [ "/", "/var/log" ],
"metrics_collection_interval": 60
}
}
}
}
commands:
install_cloudwatch_agent:
command: yum install -y amazon-cloudwatch-agent || apt-get install -y amazon-cloudwatch-agent
ignoreErrors: true
start_cloudwatch_agent:
command: /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl -a fetch-config -m ec2 -c file:/etc/amazon/amazon-cloudwatch-agent.json -s
配置好之后,过几分钟,CloudWatch 里就会出现 CWAgent 命名空间下的 mem_used_percent 和 disk_used_percent 指标,并且维度里带了 AutoScalingGroupName 和 InstanceId。这个 append_dimensions 自动加上 ASG 名称的做法是关键,后面建告警的时候就方便多了。
3.3 告警维度别用错:按 ASG 聚合而不是逐个实例
这个问题容易被忽略。CloudWatch 中 EC2 指标有两种常见用法:
- 按
InstanceId维度建告警,比如CPUUtilization+ 具体实例 ID; - 按
AutoScalingGroupName维度建告警,此时 CloudWatch 会把组内所有实例的指标做聚合,默认取平均值。
对 ASG 这种弹性资源来说,按实例 ID 建告警毫无意义:实例可能随时被替换,告警会失联。正确的做法是选择 AutoScalingGroupName 维度,这样新实例加入 ASG 后,指标自动包含进来,不需要手动维护实例列表。
但要注意,“组内平均”会掩盖单点故障。比如 4 台实例里 1 台内存溢出,其他 3 台正常,平均值可能只有 25%,告警不会触发。这种情况下,建议对内存和磁盘这类容易“某一台率先爆掉”的指标,使用 Maximum 而不是 Average 做统计。对 CPU 这种整体负载型指标,Average 更合适。
3.4 一个可参考的指标阈值表
给大家一个我在生产里用过的初始阈值模板,实际要根据业务压测结果调整:
| 指标 | 命名空间 | 统计 | 周期 | 连续周期 | 阈值 | 通知级别 |
|---|---|---|---|---|---|---|
| CPUUtilization | AWS/EC2(ASG维度) | Average | 5分钟 | 3 | > 80% | 警告 |
| CPUUtilization | AWS/EC2(ASG维度) | Average | 5分钟 | 3 | > 95% | 严重 |
| StatusCheckFailed_Any | AWS/EC2(ASG维度) | Maximum | 5分钟 | 2 | > 0 | 严重 |
| mem_used_percent | CWAgent(ASG维度) | Maximum | 1分钟 | 3 | > 85% | 严重 |
| disk_used_percent | CWAgent(ASG维度) | Maximum | 1分钟 | 3 | > 85% | 严重 |
需要说明的是,告警周期的长短要跟你对故障的容忍度挂钩。如果你希望扩缩容更快,CPU 告警可以用 1 分钟周期、连续 2 次;但如果不想被短暂尖峰打扰,5 分钟周期更稳。
4. 两条主流配置路径:EB 内置 trigger 和 CloudWatch 自定义告警
这一节是全文的核心操作部分。我根据不同的告警目标,分三条路线来讲:内置 trigger、控制台自定义告警、CLI 批量操作。
4.1 路径 A:修改 EB 配置里的 aws:autoscaling:trigger
如果你只需要 CPU 类告警,并且希望告警能和 ASG 的伸缩策略联动(CPU 高时扩容,CPU 低时缩容),那直接用 EB 内置 trigger 是最省心的方案。
你可以通过 EB 控制台:环境 -> 配置 -> 容量 -> 修改,找到“扩展”相关配置。也可以直接改 .ebextensions 或 option_settings 配置文件:
yaml复制option_settings:
aws:autoscaling:asg:
MinSize: "2"
MaxSize: "8"
aws:autoscaling:trigger:
MeasureName: CPUUtilization
Statistic: Average
Unit: Percent
Period: "300"
EvaluationPeriods: "2"
UpperThreshold: "80"
LowerThreshold: "20"
UpperBreachScaleIncrement: "1"
LowerBreachScaleIncrement: "-1"
改动部署后,EB 会自动在 CloudWatch 里创建两条告警(一条扩容、一条缩容),并自动绑定到 ASG 的扩展策略上。这里的好处是,你不需要手动管理告警和 ASG 的关系,EB 环境更新后它自己会维护。
要注意的是:这套配置只能指定一个指标。如果你想“CPU 和内存都触发扩容”,内置 trigger 就无能为力了,只能转自定义告警,并通过 ASG 的 scaling policy 或 EB 配置来配合。
4.2 路径 B:CloudWatch 控制台创建自定义告警
先明确一点:在 EB 相关的场景里,只要你是用 CloudWatch 控制台建告警,就一定不要选错指标来源。针对 EC2 标准指标,路径是:CloudWatch -> 所有告警 -> 创建告警 -> 选择指标 -> 浏览指标 -> 选择 AWS/EC2 命名空间 -> 按 AutoScalingGroupName 维度找对应的 ASG。
创建告警时需要设置的关键参数:
- 指标:
CPUUtilization - 条件:大于 80,连续 3 个周期(每个周期 5 分钟)
- 通知:选择已有的 SNS 主题,或新建一个
- 告警名称:建议带上环境和 ASG 标识,例如
prod-api-asg-cpu-high
我通常会把“告警名称”命名为这种格式:{环境名}-{模块}-{指标}-{条件},比如 prod-api-asg-mem-max-high。方便后续在脚本里批量维护。
4.3 路径 C:CLI 批量创建和更新告警的脚本思路
如果环境多、告警多,控制台操作效率太低。CLI 是更可靠的方式。下面是一个创建 CPU 高负载告警的示例:
bash复制export AWS_REGION=us-east-1
export ASG_NAME=$(aws cloudformation list-stack-resources \
--stack-name awseb-e-xxxxxxxxx-stack \
--query "StackResourceSummaries[?LogicalResourceId=='AWSEBAutoScalingGroup'].PhysicalResourceId" \
--output text)
aws cloudwatch put-metric-alarm \
--alarm-name "prod-api-asg-cpu-high" \
--alarm-description "Alert when average CPU of prod-api ASG exceeds 80% for 15 minutes" \
--metric-name CPUUtilization \
--namespace AWS/EC2 \
--statistic Average \
--period 300 \
--evaluation-periods 3 \
--threshold 80 \
--comparison-operator GreaterThanThreshold \
--dimensions Name=AutoScalingGroupName,Value="$ASG_NAME" \
--alarm-actions "arn:aws:sns:us-east-1:123456789012:eb-alerts" \
--ok-actions "arn:aws:sns:us-east-1:123456789012:eb-alerts"
注意这里我同时加了 --alarm-actions 和 --ok-actions,也就是告警时通知,恢复时也通知。很多人只配了前者,出故障时确实收到了告警,但恢复时没人知道,团队会一直处于恐慌状态。我建议恢复通知一定要配。
对于内存和磁盘告警,把 --namespace 改成 CWAgent,--metric-name 改成 mem_used_percent,统计方式改成 Maximum 即可。另外,如果要用 Terraform 或 CloudFormation 管理告警,记得 ASG 名称是动态的,需要通过数据源动态获取,不能写死。Terraform 里常见做法是先 data 获取 EB 环境的 CloudFormation 栈,再解析 ASG 名称,虽然略麻烦,但至少可复现。
5. 通知链路:从 SNS 主题到钉钉/企业微信/邮箱的分级触达
告警配置好了,如果通知链路不通,告警等于白配。EB 本身没有独立的告警通知模块,通常需要借助 SNS 来完成:CloudWatch 告警触发 -> 发送到 SNS 主题 -> SNS 推送给订阅的邮件、Lambda、HTTP 等。
5.1 创建 SNS 主题并接入邮箱
创建方式很简单,在 SNS 控制台新建一个主题,比如 eb-alerts-prod。然后创建订阅,协议选 Email,输入接收告警的邮箱地址。SNS 会向该邮箱发送一封确认邮件,必须先点击确认订阅,后续才能收到告警。
如果你在国内,邮箱服务商对 SNS 这类境外邮件的投递有一定概率进垃圾箱,所以看到告警邮件在垃圾箱时不要惊讶。这里给一个建议:生产环境的告警邮件,最好用一个独立的告警邮箱,并配置邮箱规则自动标记为重点,避免被大量系统通知淹没。
5.2 用 Lambda 把告警转成 Webhook 消息
纯粹邮件通知的短板是时效性差、格式不可控。我把钉钉/企业微信的 Webhook 也接进来,做法是:创建一个 Lambda 函数,订阅同一个 SNS 主题,解析 SNS 消息里的 NewStateValue、OldStateValue、AlarmName、Trigger.Metrics 等字段,然后拼成一条带颜色的文本消息,POST 到钉钉机器人或企业微信机器人的 Webhook 地址。
Lambda 函数核心逻辑示意如下:
python复制import json
import urllib3
http = urllib3.PoolManager()
def lambda_handler(event, context):
for record in event['Records']:
sns = json.loads(record['Sns']['Message'])
alarm_name = sns['AlarmName']
new_state = sns['NewStateValue']
old_state = sns['OldStateValue']
reason = sns['NewStateReason']
metric = sns['Trigger']['MetricName']
namespace = sns['Trigger']['Namespace']
if new_state == 'ALARM':
text = f"[告警] {alarm_name}\n指标: {metric}\n说明: {reason}"
elif new_state == 'OK':
text = f"[恢复] {alarm_name}\n指标: {metric}\n说明: {reason}"
else:
text = f"[数据不足] {alarm_name}\n指标: {metric}"
msg = {"msgtype": "text", "text": {"content": text}}
http.request("POST",
"https://oapi.dingtalk.com/robot/send?access_token=xxxx",
body=json.dumps(msg),
headers={"Content-Type": "application/json"})
return {"statusCode": 200}
这里提醒一个细节:SNS 消息里 NewStateValue 只有三种状态:ALARM、OK、INSUFFICIENT_DATA。你不要只在 ALARM 时发消息,OK 状态也必须发一条“恢复”消息,否则团队只知道挂的瞬间,不知道啥时候好的。
5.3 对标 alertmanager:告警也要分级别和分对象
如果你用过 k8s 的监控体系,对 Prometheus + Alertmanager 应该不陌生。Alertmanager 的特色是路由、分组、抑制、静默,可以把不同级别的告警发给不同的人。AWS 这套体系里,类似的实现思路是:
- 创建多个 SNS 主题,比如
eb-alerts-critical、eb-alerts-warning、eb-alerts-info; - 不同严重程度的 CloudWatch 告警,
alarm-actions指向不同的 SNS 主题; - 每个 SNS 主题再分别接邮箱、Lambda、短信等,做到分级触达。
不需要强行模仿 k8s 那套,但“分级”这个思路一定要有。比如磁盘使用率到 70% 先发警告给运维群,到 85% 再发严重告警给运维和研发负责人。如果所有告警都发给所有人,很快就会出现告警疲劳,真正的大故障反而没人看。
5.4 告警恢复通知:不要等到出故障才想起来
我在第 4 节已经提过,创建告警时一定把 --ok-actions 也配到 SNS。这是因为你排查问题、处理完故障后,需要确认“恢复”这件事是系统自动确认的,而不是靠人肉看到监控曲线回归正常。恢复通知不仅能收尾一次故障,还能帮你判断告警是否被误触发:如果恢复得特别快,通常只是抖动,后续可以调阈值或周期。
6. 上线之后我踩过的坑:ASG 被重建、部署误报、阈值风暴
告警系统上线前,我带着团队做了挺多测试,但真正跑起来之后,还是踩了几个坑。挑几个有代表性的说一下,希望能帮后来人少走弯路。
6.1 EB 环境更新会重建 ASG,固定 ARN/名称的告警会失联
这是最隐蔽的一个坑。EB 环境的某些配置变更或平台版本升级,会触发底层 CloudFormation 栈更新。如果修改了可能会影响 ASG 定义的配置(比如实例类型、VPC 设置、密钥对等),CloudFormation 可能会直接替换 ASG,生成一个新的 ASG 名称。
问题来了:你之前创建的 CloudWatch 告警,维度里写的是旧 ASG 名称。新 ASG 起来后,旧 ASG 被删除,告警的维度找不到任何匹配指标,状态会变成 INSUFFICIENT_DATA,持续一段时间后告警就算“失联”了。但 CloudWatch 告警本身不会自动删除,也不会自动帮你改成新 ASG 名称。
我的解决思路是:告警配置也要“基础设施化”。我写了一个小脚本,每天晚上扫描所有 EB 环境,动态获取当前 ASG 名称,然后比对 CloudWatch 里域名包含 asg- 的告警,如果维度里的 ASG 名称不对,就重新 put-metric-alarm 覆盖。虽然粗暴,但很有效。如果你用 Terraform,也建议用 data source 动态获取 ASG 名称并创建告警,而不是写死。
6.2 不可变更新期间的“假告警”
EB 支持不可变更新(Immutable Update),这种部署方式会先启动一批新实例,确认健康后再把流量切过去、销毁旧实例。这个过程中不可避免会出现“新实例 CPU 从 0 到 100 再回落”的过程,CPU 告警非常容易被触发。
应对办法有两种。如果你用的是 EB 内置 trigger,它天生考虑到了这种场景,因为 trigger 挂在 EB 的扩容策略上,EB 自己的部署流程会暂时抑制相关操作。但如果你用的是自定义 CloudWatch 告警,就需要注意了:可以在部署前通过脚本禁用告警的 actions,部署完成后再启用:
bash复制aws cloudwatch disable-alarm-actions --alarm-names "prod-api-asg-cpu-high"
# 部署完成后执行
aws cloudwatch enable-alarm-actions --alarm-names "prod-api-asg-cpu-high"
如果不想这么麻烦,另一个思路是给 CPU 告警设置更长的评估期,比如连续 3 个 5 分钟周期,大部分部署导致的短暂 CPU 尖峰不会持续那么久。
6.3 阈值拍脑袋的后果:告警风暴和告警疲劳
我刚开始给 ASG 配内存告警时,阈值定的 70%。结果上线第一天晚上,告警微信群直接炸了,十几条 ALARM 消息,第二天一查基本都是夜间定时任务导致的正常内存波动。后来我把阈值从 70% 调到 85%,并加上“连续 3 次周期”的条件,告警量瞬间就正常了。
这里的教训是:阈值不能凭感觉定,一定要结合业务负载曲线和实际监控数据来定。建议先让告警系统“只记录不通知”跑两周,收集历史指标分布,再根据 P90 或 P99 分位数定阈值。AWS 的 CloudWatch 告警可以先创建一个不带 action 的告警,观察触发频率,确认稳定后再绑定 SNS。
6.4 内存/磁盘数据“永远没有”:Agent 配置的几个坑
如果你按照我前面第 3 节的 .ebextensions 配置装了 CloudWatch Agent,但还是看不到 mem_used_percent 指标,通常有以下几种原因:
- EB 环境的实例没有外网访问权限,或 VPC 终端节点缺失,导致 CloudWatch Agent 无法上报指标。确认实例角色里有
CloudWatchAgentServerPolicy,以及网络能到达 CloudWatch 的服务端点。 append_dimensions里的变量没用对。如果用EC2模式,变量写${aws:autoscaling:groupName}是对的,但不同版本的 Agent 对变量名前缀的解析可能有差异,建议在 Agent 日志里确认。- 修改
.ebextensions后没有让它滚动部署,导致只有新实例安装了 Agent,旧实例还在裸奔。
如果你测试时发现指标偶尔有、偶尔没有,多半是 Agent 进程崩溃或被 OOM Killer 杀了,可以登录实例看 /var/log/amazon/amazon-cloudwatch-agent 下的日志。
6.5 定期巡检:用脚本核对 ASG 与告警的绑定关系
因为 EB 环境太“善变”,我这边最终沉淀了一套巡检逻辑,定期自动检查:
bash复制aws cloudwatch describe-alarms --namespace AWS/EC2 \
--query "MetricAlarms[?contains(AlarmName,'asg-')].{Name:AlarmName,Dimensions:Dimensions}" \
--output json
然后和当前所有 EB 环境的 ASG 名称做比对,不一致就重新生成。你也可以把这一步集成到 CI/CD 里,在每次部署后触发一次告警同步任务。
最后说一句个人体会:给 EB 的 AutoScaling 组配告警,重点不在于“配几条告警”,而在于理解 EB 平台的托管属性。告警配置不能是一次性的控制台操作,它应该跟着环境走、跟着部署流程走,甚至可以作为 IaC 的一部分纳入版本管理。CloudWatch 的指标体系本身不复杂,复杂的是在 EB 这种托管环境里,怎么让你的告警能在 ASG 被替换、实例被滚动、配置被更新之后仍然生效。把这套逻辑理顺了,不管是 CPU、内存还是磁盘告警,都只是同一个套路的不同参数而已。
