У меня есть веб-сайт, размещенный на сервере EC2. Я хочу отслеживать конечную точку веб-сайта и перезапускать экземпляр EC2, если веб-сайт недоступен в течение определенного периода времени (скажем, 60 секунд). Какие инструменты я использую в AWS и как это сделать?
перезапустить без вмешательства человека
Вы используете Route 53 для DNS и / или ELB для балансировки нагрузки?
почему вам нужно перезапускать весь сервер, а не искать процесс или службу, которые отвечают за обеспечение доступности конечной точки веб-сайта?
Нет. Мы не используем Route53 или ELB. У нас есть эластичный IP-адрес, настроенный для сервера. Мы знаем, что проблема требует расследования и устранения основной причины. На это потребуется время. Нам нужно немедленное решение, которое перезапускает сервер.
хорошо. Что вы имеете в виду под перезагрузкой? вам нужна простая команда reboot или stop ec2 instance and start the ec2 instance functionality like doing it in the aws console? Возможно, вы захотите создать дополнительные ресурсы aws, такие как лямбда-сигналы и сигналы облачного наблюдения, чтобы полностью автоматизировать процесс перезапуска без вмешательства человека, если вам нужен более поздний тип перезапуска.





Это не рекомендуемый подход.
Во-первых, если веб-сайт недоступен, вы, вероятно, захотите исследовать причину, а не просто перезапустить экземпляр. Ваша цель должна состоять в том, чтобы запустить стабильную систему, устраняя основные причины проблем, а не просто игнорировать проблему путем постоянного перезапуска.
Рекомендуемый дизайн - запуск в конфигурации Высокая доступность с:
В этой схеме неработоспособным экземпляром будет прекращено (остановлен и уничтожен), а новый экземпляр будет создан с заранее определенным образом диска и сценарием запуска. В качестве альтернативы вы можете удалить плохие экземпляры из группы Auto Scaling для исследования проблемы, запустив новый экземпляр, чтобы занять его место.
Если вашему приложению требуется база данных, база данных должна быть внешней по отношению к экземплярам, чтобы все экземпляры могли подключаться к базе данных и замена экземпляров приложения не вызывала потери данных.
Что касается скорости обнаружения проблем на сервере, балансировщик нагрузки может выполнять проверки каждые несколько секунд. Amazon CloudWatch, с другой стороны, потребуется не менее минуты для обнаружения проблем (возможно, дольше, поскольку метрики рассчитываются за период, а не являются метриками «сейчас»).
Мы бы вовремя внедрили конфигурацию с высокой доступностью. Однако пока нам нужно, чтобы служба работала в текущей конфигурации. Отсюда и это решение перезапуска сервера.
Подход Джона правильный, но самый простой:
Я оставлю вам работу по написанию кода, который определяет, работает ли веб-сайт, и перезапуску сервера, но это довольно просто. Вы можете использовать ядро python, java, node, go или .net в своей лямбда-функции - я бы подумал, что python будет самым простым в этом случае, но это мое мнение.
Понятно, что это не лучшая практика в AWS, но может иметь некоторый смысл - например, вы используете небольшой персональный веб-сервер с низким спросом, где доступность - меньшая проблема, чем затраты.
По крайней мере, это была моя причина, по которой я построил для него автоматизацию.
лямбда-код
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'
Я выпустил полностью протестированную автоматизацию с шаблоном SAM и инструкциями по установке также на https://github.com/koss822/misc/tree/master/Aws/route53-healthcheck-instance-reboot
вы хотите перезапустить его вручную или с помощью скрипта?