全部产品
Search
文档中心

Elastic Compute Service:O&M Otomatis untuk Event Perubahan Status Host ECS

更新时间:Nov 22, 2025

Topik ini memberikan contoh praktis tentang cara menggunakan Cloud Monitor untuk memproses secara otomatis event perubahan status host Elastic Compute Service (ECS) melalui antrian Simple Message Queue (formerly MNS).

Prasyarat

Informasi latar belakang

Selain event sistem yang sudah ada, Elastic Compute Service (ECS) menerbitkan event perubahan status dan event notifikasi gangguan untuk instans spot melalui Cloud Monitor. Event perubahan status ECS dipicu setiap kali status host ECS berubah—baik oleh tindakan Anda di Konsol, melalui panggilan OpenAPI, maupun SDK, serta secara otomatis oleh layanan seperti Auto Scaling, pembayaran tertunda, atau pengecualian sistem.

Cloud Monitor menyediakan empat metode untuk memproses peringatan yang dipicu oleh event: Simple Message Queue (formerly MNS), Function Compute, callback URL, dan Simple Log Service. Topik ini menggunakan Simple Message Queue (formerly MNS) sebagai contoh untuk menjelaskan tiga praktik terbaik dalam memproses secara otomatis event perubahan status host ECS.

Prosedur

Cloud Monitor mengirimkan semua event perubahan status host ECS ke Simple Message Queue (formerly MNS). Anda kemudian dapat menggunakan Simple Message Queue (formerly MNS) untuk mengambil dan memproses pesan-pesan tersebut.

  • Praktik terbaik 1: Catat event pembuatan dan rilis untuk semua host ECS.

    Anda tidak dapat melakukan kueri terhadap instans yang telah dirilis di Konsol ECS. Untuk memungkinkan kueri terhadap instans yang telah dirilis, gunakan event perubahan status host ECS untuk mencatat siklus hidup semua host ECS di database atau Simple Log Service. Event Created dikirim saat Anda membuat host ECS, sedangkan event Deleted dikirim saat Anda merilis host ECS.

    1. Edit file Conf.

      File Conf harus berisi endpoint untuk Simple Message Queue (formerly MNS), access_key dan access_key_secret untuk Akun Alibaba Cloud Anda, region_id (misalnya `cn-beijing`), serta queue_name.

      Di halaman Queue Details, pada bagian Endpoint, Anda dapat melihat endpoint untuk Internet Access dan Internal Access.
      import os
      
      # Pastikan variabel lingkungan ALIBABA_CLOUD_ACCESS_KEY_ID dan ALIBABA_CLOUD_ACCESS_KEY_SECRET telah disetel.
      # Kebocoran kode Anda dapat mengekspos AccessKey Anda dan membahayakan semua sumber daya dalam akun Anda. Kode berikut menggunakan variabel lingkungan untuk mendapatkan AccessKey. Ini hanya sebagai referensi. Gunakan metode yang lebih aman, seperti Security Token Service (STS).
      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 = 'test'
          vserver_group_id = 'your_vserver_group_id'
                                          
    2. Gunakan MNS SDK untuk menulis klien MNS yang mengambil pesan dari MNS.

      # -*- coding: utf-8 -*-
      import json
      from mns.mns_exception import MNSExceptionBase
      import logging
      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('Antrian %s tidak ada, harap buat antrian sebelum menerima pesan.', self.queue_name)
                      else:
                          logging.error('Tidak ada pesan, lanjutkan menunggu')
      
      
      class BasicListener(object):
          def process(self, event):
              pass
                                      

      Kode di atas memanggil listener untuk mengonsumsi data yang diambil dari Simple Message Queue (formerly MNS), lalu menghapus pesan tersebut.

    3. Daftarkan listener tertentu untuk mengonsumsi event. Listener sederhana ini memeriksa event Created dan Deleted, lalu mencetak entri log saat menerima salah satu event tersebut.

       # -*- 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'Instans {resource_id} berada dalam status {state}')
              elif state == 'Deleted':
                  logging.info(f'Instans {resource_id} berada dalam status {state}')
                                      

      Fungsi main ditulis sebagai berikut:

      mns_client = MNSClient()
      
      mns_client.regist_listener(ListenerLog())
      
      mns_client.run()

      Di lingkungan produksi, Anda mungkin perlu menyimpan event di database atau Simple Log Service (SLS) untuk pencarian dan audit di masa mendatang.

  • Praktik terbaik 2: Secara otomatis mulai ulang host ECS yang berhenti.

    Dalam beberapa skenario, host ECS mungkin berhenti secara tak terduga. Anda dapat mengonfigurasi proses untuk secara otomatis memulai ulang host ECS yang berhenti.

    Untuk secara otomatis memulai ulang host ECS yang berhenti, gunakan kembali klien MNS dari praktik terbaik pertama dan tambahkan listener baru. Saat listener menerima event Stopped, listener tersebut akan mengeksekusi perintah Start pada host ECS tersebut.

    # -*- 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
    
        # Mulai host ECS
        def start_instance(self, instance_id):
            logging.info(f'Memulai instans {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)

    Di lingkungan produksi, setelah menjalankan perintah Start, Anda mungkin perlu memantau event berikutnya, seperti Starting, Running, atau Stopped. Anda kemudian dapat menggunakan pengatur waktu dan penghitung untuk menangani skenario sukses atau gagal.

  • Praktik terbaik 3: Secara otomatis menghapus instans spot dari Instance Server Load Balancer (SLB) sebelum instans spot tersebut dirilis.

    Sekitar lima menit sebelum instans spot dirilis, event peringatan rilis dikirimkan. Anda dapat memanfaatkan jendela waktu singkat ini untuk menjalankan logika kelangsungan bisnis, misalnya dengan secara proaktif menghapus instans tersebut dari server backend Instance Server Load Balancer (SLB) alih-alih menunggu SLB menanganinya secara pasif setelah instans tersebut dirilis.

    Gunakan kembali klien MNS dari praktik terbaik pertama dan tambahkan listener baru. Saat listener menerima peringatan rilis untuk instans spot, listener tersebut akan memanggil SLB SDK.

    # -*- 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 peringatan rilis instans spot berbeda dari yang sebelumnya. Misalnya, panggilan pendaftaran listener adalah mns_client.regist_listener(ListenerSLB(Conf.vserver_group_id), 'Instance:PreemptibleInstanceInterruption').

    Di lingkungan produksi, Anda harus meminta instans spot baru dan menyambungkannya ke instance SLB untuk memastikan ketersediaan layanan.