使用OpenAPI自动化处理ECS系统事件

本文涉及的产品
轻量应用服务器 2vCPU 1GiB,适用于搭建电商独立站
轻量应用服务器 2vCPU 4GiB,适用于网站搭建
轻量应用服务器 4vCPU 16GiB,适用于搭建游戏自建服
简介: 什么是系统事件 当您将业务系统部署到阿里云ECS后,阿里云保证ECS计算服务的高可用。在极少情况下,比如探测到ECS实例所在的硬件发生故障,会产生有计划的维护事件并通知您。 深入了解系统事件,请参考: 实例系统事件 让运维更高效:关于ECS系统事件 监控和应对系统事件的方式 为了业务的平稳运行,您需要监控ECS系统事件并及时合理地应对系统事件。

什么是系统事件

当您将业务系统部署到阿里云ECS后,阿里云保证ECS计算服务的高可用。在极少情况下,比如探测到ECS实例所在的硬件发生故障,会产生有计划的维护事件并通知您。

深入了解系统事件,请参考:

监控和应对系统事件的方式

为了业务的平稳运行,您需要监控ECS系统事件并及时合理地应对系统事件。

从控制台处理ECS主动运维事件请参考 ECS主动运维事件--让你HOLD住全场

相对于收到通知后登陆ECS控制台人工处理系统事件,通过程序自动化监控和处理系统事件,能够提高您的运维效率,消除遗漏或出错的可能性,让您的运维人员不用再为半夜的故障通知而烦恼。如果您保有较多的ECS实例,自动化程序的优点将会更加突出。

ECS为您提供了两个OpenAPI来监控实例的健康状态和系统事件。

1. DescribeInstancesFullStatus 查询实例的全状态信息

ECS实例全状态信息包括:

  • 实例的生命周期状态,比如实例处于Running还是Stopped状态
  • 实例的健康状态,比如您的实例处于Ok还是Warning状态
  • 处于待执行状态(Scheduled)的所有系统事件

这个OpenAPI关注实例的当前状态,它不会返回已经完结的历史事件。对于事前运维来说,我们只需要关注Scheduled状态的事件。事件处于Scheduled状态意味着现在仍处在用户操作窗口期。在事件的计划执行时间NotBefore之前,我们可以通过程序处理来避免事件执行。

首先,我们调用DescribeInstancesFullStatus OpenAPI来查询当前是否存在待执行的SystemMaintenance.Reboot事件。

def build_instance_full_status_request():
    request = DescribeInstancesFullStatusRequest()
    request.set_EventType('SystemMaintenance.Reboot')
    return request


# send open api request
def _send_request(request):
    request.set_accept_format('json')
    try:
        response_str = client.do_action_with_exception(request)
        logging.info(response_str)
        response_detail = json.loads(response_str)
        return response_detail
    except Exception as e:
        logging.error(e)


# only_check=True时仅检查是否存在SystemMaintenance.Reboot事件,为False时对SystemMaintenance.Reboot事件进行处理
def check_scheduled_reboot_events(only_check=False, instance_id=None):
    request = build_instance_full_status_request()
    if instance_id:
        request.set_InstanceIds([instance_id])
    response = _send_request(request)
    if response.get('Code') is None:
        instance_full_status_list = response.get('InstanceFullStatusSet').get('InstanceFullStatusType')
        # 因为指定了事件类型查询,无SystemMaintenance.Reboot系统事件的实例不会返回
        exist_reboot_event = len(instance_full_status_list) > 0
        if not exist_reboot_event:
            print "No scheduled SystemMaintenance.Reboot event found"
        if only_check:
            return exist_reboot_event
        for instance_full_status in instance_full_status_list:
            instance_id = instance_full_status.get('InstanceId')
            scheduled_reboot_events = instance_full_status.get('ScheduledSystemEventSet').get(
                'ScheduledSystemEventType')
            for scheduled_reboot_event in scheduled_reboot_events:
                handle_reboot_event(instance_id, scheduled_reboot_event)
    else:
        logging.error(str(response))
AI 代码解读

Tip:主动运维系统事件会留出足够长的用户操作窗口期,一般以天为单位。所以并不需要频繁的去轮询待执行的系统事件。未来我们将会提供基于消息队列的系统事件消费接口

如果发现存在SystemMaintenance.Reboot系统事件,您应该根据实例上运行的业务类型来决定是否需要自行处理。

Tip:即使由ECS系统执行重启,对您的重要数据进行提前备份也是一个好主意。

如果实例重启对业务有影响,你可能需要选择一个NotBefore之前的更合适的业务低谷时间点。您需要设定一个定时任务,在这个时间点执行重启操作。


def handle_reboot_event(instance_id, reboot_event):
    not_before_str = reboot_event.get('NotBefore')
    not_before = datetime.strptime(not_before_str, '%Y-%m-%dT%H:%M:%SZ')
    print "Instance %s has a SystemMaintenance.Reboot event scheduled to execute at %s" % (instance_id, str(not_before))
    # 根据你的业务特性选择not_before之前的影响最小的时间点
    # 使用定时任务在该时间点进行实例重启

    # 示例中简化为立即重启
    pre_reboot(instance_id)
    reboot_instance(instance_id)
    post_reboot(instance_id)


def reboot_instance(instance_id):
    print "Reboot instance %s now..." % instance_id
    reboot_request = RebootInstanceRequest()
    reboot_request.set_InstanceId(instance_id)
    _send_request(reboot_request)


def pre_reboot(instance_id):
    # 重启前做backup等等准备工作
    print "Do pre-reboot works..."


def post_reboot(instance_id):
    # 重启后做健康检查等等善后工作
    # 检查重启是否成功
    print "Do post-reboot works..."

    # 一般情况下重启成功后几秒后SystemMaintenance.Reboot事件将变为Avoided状态
    # 再次查询DescribeInstancesFullStatus确认SystemMaintenance.Reboot事件无法查询到
    wait_event_disappear(instance_id)
AI 代码解读

重启成功完成后,系统事件将在短时间内变为Avoided状态。

def wait_event_disappear(instance_id):
    wait_sec = 0
    while wait_sec < TIME_OUT:
        exist = check_scheduled_reboot_events(only_check=True, instance_id=instance_id)
        if not exist:
            print "SystemMaintenance.Reboot system event is avoided"
            return
        time.sleep(10)
        wait_sec += 10
AI 代码解读

您的自动化处理程序需要妥善处理各种异常情况,保证定时重启的及时性和稳定性。尤其注意的是,在事件状态变化前不要重复处理,以避免不必要的重启。

2. DescribeInstanceHistoryEvents 查询实例的历史事件

查询指定ECS实例的系统事件,默认查询已经处于非活跃状态的历史事件。如果指定全部的事件状态,可以查询包含活跃事件在内的所有事件。

此API默认只查询历史事件,它的用途是对实例的历史事件进行分析、复盘,追溯问题原因。某些事件类型比如SystemFailure.Reboot发生时,不一定会留出用户操作窗口期。比如非预期的紧急故障发生后,阿里云立刻进行了恢复并重启了您的实例。此类事件可以在历史事件中查询到。

总结

  1. 使用DescribeInstancesFullStatus来查询实例状态和Scheduled状态的系统事件
  2. 使用DescribeInstanceHistoryEvents对历史事件进行复盘。如果指定系统事件状态,也可以查询未结束的系统事件(Scheduled和Executing状态)。
  3. 使用自动化程序对Scheduled状态的系统事件进行处理
  4. 如果只需要查询系统事件,推荐使用DescribeInstanceHistoryEvents接口,性能更好。

未来我们将会发布更多类型的ECS实例和存储相关系统事件,覆盖更多运维场景,敬请期待!

完整的示例代码如下

#  coding=utf-8

# if the python sdk is not install using 'sudo pip install aliyun-python-sdk-ecs'
# if the python sdk is install using 'sudo pip install --upgrade aliyun-python-sdk-ecs'
# make sure the sdk version is 4.4.3, you can use command 'pip show aliyun-python-sdk-ecs' to check

import json
import logging
from datetime import datetime
import time

from aliyunsdkcore import client
from aliyunsdkecs.request.v20140526.DescribeInstancesFullStatusRequest import DescribeInstancesFullStatusRequest
from aliyunsdkecs.request.v20140526.RebootInstanceRequest import RebootInstanceRequest

logging.basicConfig(level=logging.INFO,
                    format='%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s',
                    datefmt='%a, %d %b %Y %H:%M:%S')

# your access key Id
ak_id = "YOU_ACCESS_KEY_ID"
# your access key secret
ak_secret = "YOU_ACCESS_SECRET"
region_id = "cn-shanghai"
TIME_OUT = 5 * 60

client = client.AcsClient(ak_id, ak_secret, region_id)


def build_instance_full_status_request():
    request = DescribeInstancesFullStatusRequest()
    request.set_EventType('SystemMaintenance.Reboot')
    return request


# send open api request
def _send_request(request):
    request.set_accept_format('json')
    try:
        response_str = client.do_action_with_exception(request)
        logging.info(response_str)
        response_detail = json.loads(response_str)
        return response_detail
    except Exception as e:
        logging.error(e)


# only_check=True时仅检查是否存在SystemMaintenance.Reboot事件,为False时对SystemMaintenance.Reboot事件进行处理
def check_scheduled_reboot_events(only_check=False, instance_id=None):
    request = build_instance_full_status_request()
    if instance_id:
        request.set_InstanceIds([instance_id])
    response = _send_request(request)
    if response.get('Code') is None:
        instance_full_status_list = response.get('InstanceFullStatusSet').get('InstanceFullStatusType')
        # 因为指定了事件类型查询,无SystemMaintenance.Reboot系统事件的实例不会返回
        exist_reboot_event = len(instance_full_status_list) > 0
        if not exist_reboot_event:
            print "No scheduled SystemMaintenance.Reboot event found"
        if only_check:
            return exist_reboot_event
        for instance_full_status in instance_full_status_list:
            instance_id = instance_full_status.get('InstanceId')
            scheduled_reboot_events = instance_full_status.get('ScheduledSystemEventSet').get(
                'ScheduledSystemEventType')
            for scheduled_reboot_event in scheduled_reboot_events:
                handle_reboot_event(instance_id, scheduled_reboot_event)
    else:
        logging.error(str(response))


def handle_reboot_event(instance_id, reboot_event):
    not_before_str = reboot_event.get('NotBefore')
    not_before = datetime.strptime(not_before_str, '%Y-%m-%dT%H:%M:%SZ')
    print "Instance %s has a SystemMaintenance.Reboot event scheduled to execute at %s" % (instance_id, str(not_before))
    # 根据你的业务特性选择not_before之前的影响最小的时间点
    # 使用定时任务在该时间点进行实例重启

    # 示例中简化为立即重启
    pre_reboot(instance_id)
    reboot_instance(instance_id)
    post_reboot(instance_id)


def reboot_instance(instance_id):
    print "Reboot instance %s now..." % instance_id
    reboot_request = RebootInstanceRequest()
    reboot_request.set_InstanceId(instance_id)
    _send_request(reboot_request)


def pre_reboot(instance_id):
    # 重启前做backup等等准备工作
    print "Do pre-reboot works..."


def post_reboot(instance_id):
    # 重启后做健康检查等等善后工作
    # 检查重启是否成功
    print "Do post-reboot works..."

    # 一般情况下重启成功后几秒后SystemMaintenance.Reboot事件将变为Avoided状态
    # 再次查询DescribeInstancesFullStatus确认SystemMaintenance.Reboot事件无法查询到
    wait_event_disappear(instance_id)


def wait_event_disappear(instance_id):
    wait_sec = 0
    while wait_sec < TIME_OUT:
        exist = check_scheduled_reboot_events(only_check=True, instance_id=instance_id)
        if not exist:
            print "SystemMaintenance.Reboot system event is avoided"
            return
        time.sleep(10)
        wait_sec += 10


if __name__ == '__main__':
    check_scheduled_reboot_events(only_check=False)
AI 代码解读
相关实践学习
快速体验PolarDB开源数据库
本实验环境已内置PostgreSQL数据库以及PolarDB开源数据库:PolarDB PostgreSQL版和PolarDB分布式版,支持一键拉起使用,方便各位开发者学习使用。
7天玩转云服务器
云服务器ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,可降低 IT 成本,提升运维效率。本课程手把手带你了解ECS、掌握基本操作、动手实操快照管理、镜像管理等。了解产品详情:&nbsp;https://www.aliyun.com/product/ecs
betabao
+关注
目录
打赏
0
0
0
0
118
分享
相关文章
精通服务器推送事件(SSE)与 Python 和 Go 实现实时数据流 🚀
服务器推送事件(SSE)是HTML5规范的一部分,允许服务器通过HTTP向客户端实时推送更新。相比WebSocket,SSE更轻量、简单,适合单向通信场景,如实时股票更新或聊天消息。它基于HTTP协议,使用`EventSource` API实现客户端监听,支持自动重连和事件追踪。虽然存在单向通信与连接数限制,但其高效性使其成为许多轻量级实时应用的理想选择。文中提供了Python和Go语言的服务器实现示例,以及HTML/JavaScript的客户端代码,帮助开发者快速集成SSE功能,提升用户体验。
在Ubuntu系统下使用vsftpd配置FTP服务器的步骤
以上就是在Ubuntu系统下使用vsftpd配置FTP服务器的步骤。这些步骤都是基础的,但足够让你建立一个简单的FTP服务器。如果你需要更高级的功能,例如SSL加密、虚拟用户等,你可能需要进一步研究vsftpd的配置选项。
49 13
【阿里云】控制台使用指南:从创建ECS到系统诊断测评
本文介绍了如何通过阿里云获取ECS云服务器并进行操作系统配置与组件安装,以实现高效的资源管理和系统监控。阿里云凭借强大的基础设施和丰富的服务成为用户首选。文中详细描述了获取ECS、RAM授权、开通操作系统控制台及组件安装的步骤,并展示了如何利用控制台实时监控性能指标、诊断系统问题及优化性能。特别针对idle进程进行了深入分析,提出了优化建议。最后,建议定期进行系统健康检查,并希望阿里云能推出更友好的低成本套餐,满足学生等群体的需求。
145 17
【阿里云】控制台使用指南:从创建ECS到系统诊断测评
|
25天前
|
CentOS 7.9系统备份:每日定期发送最新备份文件到另一台服务器。
注意,这个解决方案忽略了很多细节,例如错误处理和通知、备份版本控制、循环处理旧的备份文件等等。此外,你也应该尽量保持源服务器和目标服务器之间快速,稳定且安全的网络连接,并且目标服务器应该有足够的空间用于存放每天的备份文件。如果你需要更高级的备份解决方案,可能需要考虑一下使用专门的备份工具或者服务。
65 18
机器学习+自动化运维:让服务器自己修Bug,运维变轻松!
机器学习+自动化运维:让服务器自己修Bug,运维变轻松!
100 14
深度体验阿里云系统控制台:SysOM 让 Linux 服务器监控变得如此简单
作为一名经历过无数个凌晨三点被服务器报警电话惊醒的运维工程师,我对监控工具有着近乎苛刻的要求。记得去年那次大型活动,我们的主站流量暴增,服务器内存莫名其妙地飙升到90%以上,却找不到原因。如果当时有一款像阿里云 SysOM 这样直观的监控工具,也许我就不用熬通宵排查问题了。今天,我想分享一下我使用 SysOM 的亲身体验,特别是它那令人印象深刻的内存诊断功能。
|
1月前
|
Windows系统云服务器配置多用户登录
本教程介绍了在Windows云服务器上配置远程桌面服务的详细步骤,包括安装桌面会话主机和远程桌面授权、允许多用户远程连接以及配置新用户并加入远程桌面用户组。通过添加角色和功能、设置组策略以及管理用户权限,实现多用户同时登录和远程访问。按照指引操作,可顺利完成服务器的远程访问配置,提升管理和使用效率。
112 0
基于AI的自动化服务器管理:解锁运维的未来
基于AI的自动化服务器管理:解锁运维的未来
180 0
ChatMCP:基于 MCP 协议开发的 AI 聊天客户端,支持多语言和自动化安装 MCP 服务器
ChatMCP 是一款基于模型上下文协议(MCP)的 AI 聊天客户端,支持多语言和自动化安装。它能够与多种大型语言模型(LLM)如 OpenAI、Claude 和 OLLama 等进行交互,具备自动化安装 MCP 服务器、SSE 传输支持、自动选择服务器、聊天记录管理等功能。
1593 16
ChatMCP:基于 MCP 协议开发的 AI 聊天客户端,支持多语言和自动化安装 MCP 服务器
自动化运维之路:使用Ansible进行服务器管理
在现代IT基础设施中,自动化运维已成为提高效率和可靠性的关键。本文将引导您通过使用Ansible这一强大的自动化工具来简化日常的服务器管理任务。我们将一起探索如何配置Ansible、编写Playbook以及执行自动化任务,旨在为读者提供一条清晰的路径,从而步入自动化运维的世界。
104 11

相关产品

  • 云服务器 ECS
  • AI助理

    你好,我是AI助理

    可以解答问题、推荐解决方案等