如何按指定顺序启动EC2实例并完成Linux服务前置健康检查
顺序启动EC2实例+服务健康检查实现方案
核心逻辑梳理
要实现你的需求,我们按如下逻辑改造代码:
- 提前按启动优先级整理好实例ID列表,列表顺序就是启动顺序
- 逐台启动实例,启动后先等待EC2实例进入运行状态
- 对该实例上运行的Linux服务做健康检查,检查通过后再启动下一台
- 任意实例启动或健康检查失败,立即触发SNS告警,终止启动流程
现有代码问题修正
你提供的参考代码存在几个基础问题,先修正:
- 导入库名错误:
import request应为import requests - 缩进错误:
lambda_handler函数缩进错误,不应该嵌套在Ec2Instance1函数内 - 逻辑重复:两个判断条件都是
r.status_code == 200,无实际意义 - 启动逻辑错误:调用
start_instances时传入了所有实例ID,会同时启动全部实例,不符合顺序启动要求
完整可运行代码
import boto3 import requests import time # --------------- 可配置参数 --------------- # 实例所在区域 REGION = 'ap-southeast-1' # 按启动顺序填写实例ID和对应健康检查地址,顺序靠前的先启动 ORDERED_INSTANCES = [ {"instance_id": "i-xxxxxx1", "health_check_url": "http://实例1的内网IP/health"}, {"instance_id": "i-xxxxxx2", "health_check_url": "http://实例2的内网IP/health"}, {"instance_id": "i-xxxxxx3", "health_check_url": "http://实例3的内网IP/health"} ] # SNS告警主题ARN SNS_TOPIC_ARN = 'arn:aws:sns:ap-southeast-1:123:sample' # 健康检查最大重试次数 HEALTH_CHECK_RETRY = 10 # 健康检查间隔(秒) CHECK_INTERVAL = 15 # ------------------------------------------ ec2_client = boto3.client('ec2', region_name=REGION) sns_client = boto3.client('sns', region_name=REGION) def start_single_instance(instance_id): """启动单台EC2实例""" ec2_client.start_instances(InstanceIds=[instance_id]) print(f"已触发启动实例:{instance_id}") # 等待实例进入running状态 waiter = ec2_client.get_waiter('instance_running') waiter.wait(InstanceIds=[instance_id]) print(f"实例{instance_id}已进入运行状态,等待服务启动") # 预留服务初始化时间,可根据实际情况调整 time.sleep(30) def check_service_health(check_url): """检查服务健康状态,返回布尔值""" for _ in range(HEALTH_CHECK_RETRY): try: # 如果是https自签名证书可以加verify=False resp = requests.get(check_url, timeout=5, verify=False) if resp.status_code == 200: print(f"健康检查通过:{check_url}") return True except Exception as e: print(f"健康检查请求失败:{str(e)}") time.sleep(CHECK_INTERVAL) print(f"健康检查超过最大重试次数,检查失败:{check_url}") return False def send_alert(message, subject): """发送SNS告警""" sns_client.publish( TopicArn=SNS_TOPIC_ARN, Subject=subject, Message=message ) def lambda_handler(event, context): for instance_conf in ORDERED_INSTANCES: instance_id = instance_conf['instance_id'] check_url = instance_conf['health_check_url'] try: # 启动当前实例 start_single_instance(instance_id) # 检查服务健康 health_ok = check_service_health(check_url) if not health_ok: alert_msg = f"实例{instance_id}服务健康检查失败,终止后续实例启动" send_alert(alert_msg, "EC2顺序启动失败告警") print(alert_msg) return except Exception as e: alert_msg = f"实例{instance_id}启动失败,错误信息:{str(e)},终止后续实例启动" send_alert(alert_msg, "EC2顺序启动失败告警") print(alert_msg) return print("所有实例按顺序启动完成,服务全部健康")
注意事项说明
- 依赖处理:Lambda默认没有集成
requests库,你可以直接将代码中的requests请求替换为Python自带的urllib实现,或者将requests打包为Lambda层上传使用 - 权限配置:Lambda执行角色需要添加
ec2:StartInstances、ec2:DescribeInstances、sns:Publish权限 - 网络配置:如果实例的健康检查地址是私网地址,需要将Lambda部署到和实例相同的VPC下,配置对应的安全组放通访问
- 无HTTP接口的服务健康检查:如果你的服务没有暴露HTTP健康检查接口,可以通过SSM Agent在实例内执行命令检查服务状态,只需安装SSM Agent并给Lambda添加SSM相关权限即可
- 超时配置:Lambda的默认超时时间是3秒,需要根据你实例启动+健康检查的总时长调整超时时间,最大可设置为15分钟
内容的提问来源于stack exchange,提问作者Mohsin Ijaz
相关产品推荐
相关产品推荐

