我在EC2服务器上托管了一个网站。如果网站在特定时间段(例如60秒)内不可用,我想监视网站端点并重新启动EC2实例。 我在AWS中使用什么工具?如何实现?
答案 0 :(得分:2)
这不是推荐的方法。
首先,如果网站不可用,您可能想调查原因,而不仅仅是重启实例。您的目标应该是通过消除问题的根本原因来运行稳定的系统,而不是通过始终重新启动来忽略问题。
建议的设计应在高度可用配置中运行,并带有:
在此设计中,不健康的实例将被终止(终止并销毁),并使用预定义的磁盘映像和启动脚本创建一个新实例。或者,您可以选择将不良实例移出Auto Scaling组以调查问题,然后启动新实例代替它。
如果您的应用程序需要数据库,则数据库应在实例外部,以便所有实例都可以连接到数据库,并且替换应用程序实例不会造成任何数据丢失。
关于在服务器上发现问题的速度,负载平衡器可以每隔几秒钟执行一次检查。另一方面,Amazon CloudWatch至少需要一分钟来检测问题(由于指标是在一段时间内计算的,而不是“现在”的指标,因此可能需要更长的时间)。
答案 1 :(得分:2)
约翰的方法是正确的,但最简单的方法是
我将留给您编写确定网站是否正常运行的代码并重新启动服务器的工作-但这很简单。您可以在lambda函数中使用python,java,node,go或.net核心-在这种情况下,我认为python是最简单的,但这是一种看法。
答案 2 :(得分:1)
很明显,这不是AWS的最佳做法,但可以说是有道理-例如您正在运行一个需求低的小型个人Web服务器,而可用性比成本要少。
至少那是我为其构建自动化的原因。
lambda代码
import json
import os
import boto3
import time
env_vars = [
'ALARM_NAME',
'REGION',
'INSTANCE_ID',
'OUTPUT_SNS_ARN'
]
ENV = {}
for env_var in env_vars:
ENV[env_var] = os.environ.get(env_var, None)
if not ENV[env_var]:
raise Exception(f"Environment variable {env_var} must be set!")
def reboot_instance(instanceID, regionName) -> "instanceID":
"""
InstanceID
instanceID - ID of instance
regionName - name of region
return InstanceID or False in case of exception
"""
ec2 = boto3.resource('ec2', region_name=regionName)
instance = ec2.Instance(instanceID)
try:
instance.stop()
time.sleep(30)
instance.stop(Force=True)
except:
pass
for i in range(180): # wait 3 minutes
instance = ec2.Instance(instanceID)
if instance.state['Code'] == 80:
break
time.sleep(1)
else:
raise Exception('Unable to stop instance')
instance.start()
return instanceID
def notify_about_reboot(instanceID, snsarn) -> True:
"""
Put SNS message about reboot to snsarn
"""
client = boto3.client('sns', region_name='us-east-1')
client.publish(TopicArn=snsarn, Message=f'EC2 instance {instanceID} was rebooted!')
return True
def lambda_handler(event, context) -> "status about reboot":
"""
event: see events/event.json
"""
print('EVENT:')
print(event)
for record in event.get('Records', None):
sns = record.get('Sns', None)
message = json.loads(sns.get('Message', None))
msgalarm = message.get('AlarmName', None)
msgstatus = message.get('NewStateValue', None)
if not all([sns,message,msgalarm,msgstatus]):
continue
if (msgalarm == ENV['ALARM_NAME']) and (msgstatus == 'ALARM'):
notify_about_reboot(reboot_instance(ENV['INSTANCE_ID'], ENV['REGION']), ENV['OUTPUT_SNS_ARN'])
return 'rebooting'
else:
return 'nothing to do'
return 'no sns record found'
我已经在https://github.com/koss822/misc/tree/master/Aws/route53-healthcheck-instance-reboot
上发布了带有SAM模板和安装说明的经过全面测试的自动化