All Products
Search
Document Center

Cloud Monitor:Otomatisasi O&M berdasarkan event perubahan status instance ECS

Last Updated:Aug 28, 2026

Elastic Compute Service (ECS) menerbitkan event perubahan status melalui Cloud Monitor setiap kali sebuah instans berpindah antar status—baik dipicu oleh tindakan di konsol, panggilan API, operasi SDK, kebijakan Auto Scaling, pembayaran tertunda, maupun pengecualian sistem. Dengan mengarahkan event-event ini ke Simple Message Queue (formerly MNS), Anda dapat membangun respons otomatis seperti mencatat siklus hidup instans, me-restart instans yang berhenti, atau menghapus spot instans dari load balancer sebelum rilis.

Topik ini menunjukkan tiga skenario otomatisasi menggunakan Python dan antrian pesan MNS sebagai mekanisme pengiriman event.

Cara kerja

Cloud Monitor menangkap semua event perubahan status instance ECS dan mengirimkannya ke antrian Simple Message Queue (formerly MNS). Sebuah konsumen Python melakukan polling terhadap antrian tersebut, mengurai setiap event, lalu meneruskannya ke pendengar (listener) yang telah terdaftar berdasarkan nama event (misalnya, Instance:StateChange atau Instance:PreemptibleInstanceInterruption). Setiap pendengar mengimplementasikan aksi otomatisasi tertentu.

Cloud Monitor mendukung empat metode untuk memproses alert yang dipicu oleh event:

Metode

Kasus penggunaan

Simple Message Queue (formerly MNS)

Pemrosesan asinkron dengan logika konsumen kustom (digunakan dalam topik ini)

Function Compute (FC)

Penanganan event tanpa server tanpa perlu mengelola infrastruktur

URL callback

Meneruskan event ke endpoint HTTP eksternal

Simple Log Service (SLS)

Pencatatan dan analisis event terpusat

Prasyarat

Sebelum memulai, pastikan Anda telah:

Untuk detail instalasi SDK, lihat Instal Python SDK. Untuk bahasa pemrograman lainnya, lihat referensi MNS SDK dan ikhtisar ECS SDK.

Langkah 1: Buat file konfigurasi

Definisikan titik akhir MNS, kredensial, wilayah, dan nama antrian dalam file konfigurasi bersama. Ketiga skenario menggunakan konfigurasi ini.

import os

class Conf:
    endpoint = 'http://<id>.mns.<region>.aliyuncs.com/'
    access_key = os.environ['ALIBABA_CLOUD_ACCESS_KEY_ID']
    access_key_secret = os.environ['ALIBABA_CLOUD_ACCESS_KEY_SECRET']
    region_id = 'cn-beijing'
    queue_name = 'ecs-cms-event'
    vserver_group_id = '<your-vserver-group-id>'

Ganti placeholder berikut dengan nilai aktual:

Placeholder

Deskripsi

Contoh

<id>

ID akun Alibaba Cloud Anda

1234567890

<region>

Wilayah antrian MNS Anda

cn-beijing

<your-vserver-group-id>

ID kelompok vServer di Server Load Balancer (SLB), hanya diperlukan untuk Skenario 3

rsp-bp1abc...

Temukan titik akhir MNS di halaman Queue Details pada bagian Endpoint. Titik akhir untuk Internet Access maupun Internal Access tersedia.
Penting

Jangan pernah menyematkan kredensial AccessKey secara langsung di kode sumber. Contoh di atas membaca kredensial dari variabel lingkungan. Untuk beban kerja produksi, gunakan kredensial temporary dari Security Token Service (STS).

Langkah 2: Bangun konsumen MNS

Buat klien MNS yang dapat digunakan ulang untuk melakukan polling terhadap antrian, meneruskan event ke pendengar yang terdaftar, dan menghapus pesan yang telah diproses. Ketiga skenario menggunakan konsumen ini.

# -*- coding: utf-8 -*-
import json
import logging
from mns.mns_exception import MNSExceptionBase
from mns.account import Account
from . import Conf


class MNSClient(object):
    def __init__(self):
        self.account = Account(Conf.endpoint, Conf.access_key, Conf.access_key_secret)
        self.queue_name = Conf.queue_name
        self.listeners = dict()

    def regist_listener(self, listener, eventname='Instance:StateChange'):
        if eventname in self.listeners.keys():
            self.listeners.get(eventname).append(listener)
        else:
            self.listeners[eventname] = [listener]

    def run(self):
        queue = self.account.get_queue(self.queue_name)
        while True:
            try:
                message = queue.receive_message(wait_seconds=5)
                event = json.loads(message.message_body)
                if event['name'] in self.listeners:
                    for listener in self.listeners.get(event['name']):
                        listener.process(event)
                queue.delete_message(receipt_handle=message.receipt_handle)
            except MNSExceptionBase as e:
                if e.type == 'QueueNotExist':
                    logging.error('Queue %s not exist, please create queue before receive message.', self.queue_name)
                else:
                    logging.error('No Message, continue waiting')


class BasicListener(object):
    def process(self, event):
        pass

Konsumen menggunakan long polling (wait_seconds=5) untuk mengambil pesan. Saat pesan tiba, konsumen mengurai isi JSON-nya, mencari pendengar yang terdaftar berdasarkan nama event, lalu memanggil metode process masing-masing pendengar. Setelah diproses, pesan tersebut dihapus dari antrian.

Struktur muatan event

Event perubahan status menggunakan struktur berikut:

Bidang

Deskripsi

Contoh

event['name']

Identifikasi jenis event

Instance:StateChange

event['content']['state']

Status instans saat ini

Created, Starting, Running, Stopped, Deleted

event['content']['resourceId']

ID instance ECS

i-bp1abc...

Skenario 1: Catat event pembuatan dan rilis instans

Lacak seluruh siklus hidup instance ECS dengan mencatat perubahan status Created dan Deleted. Instans yang telah dirilis tidak lagi muncul di konsol ECS—mencatat event ini memberikan jejak audit untuk perencanaan kapasitas dan analisis pasca-insiden.

Buat pendengar

# -*- coding: utf-8 -*-
import logging
from .mns_client import BasicListener


class ListenerLog(BasicListener):
    def process(self, event):
        state = event['content']['state']
        resource_id = event['content']['resourceId']
        if state == 'Created':
            logging.info(f'The instance {resource_id} state is {state}')
        elif state == 'Deleted':
            logging.info(f'The instance {resource_id} state is {state}')

Jalankan konsumen

mns_client = MNSClient()

mns_client.regist_listener(ListenerLog())

mns_client.run()

Verifikasi hasil

  1. Buat atau rilis instance ECS di konsol.

  2. Periksa log konsumen untuk pesan seperti The instance i-bp1abc... state is Created.

Di lingkungan produksi, simpan event di database atau Simple Log Service (SLS) alih-alih mencatat ke stdout. Hal ini memungkinkan pencarian dan audit data historis siklus hidup instans.

Skenario 2: Restart instans yang berhenti secara otomatis

Sebuah instans ECS dapat berhenti secara tak terduga karena pengecualian sistem atau pembayaran tertunda. Pendengar ini memantau event Stopped dan memanggil API ECS StartInstance untuk me-restart instans yang terpengaruh.

Buat pendengar

Gunakan kembali konsumen MNS dari Langkah 2 dan daftarkan pendengar baru:

# -*- coding: utf-8 -*-
import logging

from alibabacloud_ecs20140526.client import Client as Ecs20140526Client
from alibabacloud_ecs20140526.models import StartInstanceRequest
from alibabacloud_tea_openapi.models import Config

from .config import Conf
from .mns_client import BasicListener


class ECSClient(object):
    def __init__(self, client):
        self.client = client

    def start_instance(self, instance_id):
        logging.info(f'Start instance {instance_id} ...')
        request = StartInstanceRequest(
            instance_id=instance_id
        )
        self.client.start_instance(request)


class ListenerStart(BasicListener):
    def __init__(self):
        ecs_config = Config(
            access_key_id=Conf.access_key,
            access_key_secret=Conf.access_key_secret,
            endpoint=f'ecs.{Conf.region_id}.aliyuncs.com'
        )
        client = Ecs20140526Client(ecs_config)
        self.ecs_client = ECSClient(client)

    def process(self, event):
        detail = event['content']
        instance_id = detail['resourceId']
        if detail['state'] == 'Stopped':
            self.ecs_client.start_instance(instance_id)

Jalankan konsumen

mns_client = MNSClient()

mns_client.regist_listener(ListenerStart())

mns_client.run()

Verifikasi hasil

  1. Hentikan instans ECS yang sedang berjalan secara manual.

  2. Periksa log konsumen untuk Start instance i-bp1abc... ....

  3. Konfirmasi bahwa status instans kembali menjadi Running di konsol ECS.

Di lingkungan produksi, pantau transisi status berikutnya (Starting, Running, atau Stopped) setelah mengeluarkan perintah start. Gunakan pengatur waktu dan penghitung percobaan ulang untuk menangani kasus ketika restart gagal.

Skenario 3: Hapus spot instans dari SLB sebelum rilis

Sekitar lima menit sebelum spot instans direklamasi, Cloud Monitor mengirim event Instance:PreemptibleInstanceInterruption. Gunakan jendela waktu ini untuk secara proaktif menghapus instans dari kelompok server backend pada instance Server Load Balancer (SLB), alih-alih menunggu SLB mendeteksi rilis secara pasif.

Buat pendengar

Gunakan kembali konsumen MNS dari Langkah 2 dan daftarkan pendengar untuk event interupsi spot instans:

# -*- coding: utf-8 -*-
from alibabacloud_slb20140515.client import Client as Slb20140515Client
from alibabacloud_slb20140515.models import RemoveVServerGroupBackendServersRequest
from alibabacloud_tea_openapi.models import Config

from .config import Conf
from .mns_client import BasicListener


class SLBClient(object):
    def __init__(self):
        self.client = self.create_client()

    def create_client(self):
        config = Config()
        config.access_key_id = Conf.access_key
        config.access_key_secret = Conf.access_key_secret
        config.endpoint = 'slb.aliyuncs.com'
        return Slb20140515Client(config)

    def remove_vserver_group_backend_servers(self, vserver_group_id, instance_id):
        request = RemoveVServerGroupBackendServersRequest(
            region_id=Conf.region_id,
            vserver_group_id=vserver_group_id,
            backend_servers="[{'ServerId':'" + instance_id + "','Port':'80','Weight':'100'}]"
        )
        response = self.client.remove_vserver_group_backend_servers(request)
        return response


class ListenerSLB(BasicListener):
    def __init__(self, vserver_group_id):
        self.slb_caller = SLBClient()
        self.vserver_group_id = Conf.vserver_group_id

    def process(self, event):
        detail = event['content']
        instance_id = detail['instanceId']
        if detail['action'] == 'delete':
            self.slb_caller.remove_vserver_group_backend_servers(self.vserver_group_id, instance_id)
Penting

Nama event untuk interupsi spot instans berbeda dari event perubahan status. Daftarkan pendengar ini dengan nama event Instance:PreemptibleInstanceInterruption:

mns_client = MNSClient()

mns_client.regist_listener(ListenerSLB(Conf.vserver_group_id), 'Instance:PreemptibleInstanceInterruption')

mns_client.run()

Struktur event interupsi spot instans

Event interupsi spot instans menggunakan nama bidang yang berbeda dibandingkan event perubahan status:

Bidang

Deskripsi

Contoh

event['name']

Identifikasi jenis event

Instance:PreemptibleInstanceInterruption

event['content']['instanceId']

ID instance ECS

i-bp1abc...

event['content']['action']

Aksi interupsi

delete

Verifikasi hasil

  1. Menunggu event interupsi spot instans (atau mensimulasikannya di lingkungan pengujian).

  2. Konfirmasi bahwa instans telah dihapus dari kelompok vServer SLB sebelum rilis.

Di lingkungan produksi, minta instans spot pengganti dan sambungkan segera ke instance SLB untuk menjaga ketersediaan layanan.

Jalankan semua pendengar bersamaan

Daftarkan ketiga pendengar pada satu konsumen MNS untuk menangani beberapa jenis event secara simultan:

mns_client = MNSClient()

# Skenario 1: Catat event siklus hidup
mns_client.regist_listener(ListenerLog())

# Skenario 2: Restart otomatis instans yang berhenti
mns_client.regist_listener(ListenerStart())

# Skenario 3: Hapus spot instans dari SLB sebelum rilis
mns_client.regist_listener(ListenerSLB(Conf.vserver_group_id), 'Instance:PreemptibleInstanceInterruption')

mns_client.run()

Referensi jenis event

Nama Peristiwa

Pemicu

Bidang utama

Instance:StateChange

Transisi status instans (Created, Starting, Running, Stopped, Deleted)

content.state, content.resourceId

Instance:PreemptibleInstanceInterruption

Spot instans dijadwalkan untuk rilis (~5 menit sebelum reklamasi)

content.instanceId, content.action

Referensi