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:
Membuat antrian (misalnya,
ecs-cms-event) di konsol Simple Message Queue (formerly MNS)Mengonfigurasi aturan alert yang dipicu oleh event sistem di konsol Cloud Monitor (versi lama)
Menginstal Python 3.7 atau versi yang lebih baru
Menginstal MNS SDK untuk Python dan ECS SDK untuk Python
Menyetel variabel lingkungan
ALIBABA_CLOUD_ACCESS_KEY_IDdanALIBABA_CLOUD_ACCESS_KEY_SECRET
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 akun Alibaba Cloud Anda |
|
| Wilayah antrian MNS Anda |
|
| ID kelompok vServer di Server Load Balancer (SLB), hanya diperlukan untuk Skenario 3 |
|
Temukan titik akhir MNS di halaman Queue Details pada bagian Endpoint. Titik akhir untuk Internet Access maupun Internal Access tersedia.
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):
passKonsumen 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 |
| Identifikasi jenis event |
|
| Status instans saat ini |
|
| ID instance ECS |
|
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
Buat atau rilis instance ECS di konsol.
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
Hentikan instans ECS yang sedang berjalan secara manual.
Periksa log konsumen untuk
Start instance i-bp1abc... ....Konfirmasi bahwa status instans kembali menjadi
Runningdi konsol ECS.
Di lingkungan produksi, pantau transisi status berikutnya (Starting,Running, atauStopped) 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)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 |
| Identifikasi jenis event |
|
| ID instance ECS |
|
| Aksi interupsi |
|
Verifikasi hasil
Menunggu event interupsi spot instans (atau mensimulasikannya di lingkungan pengujian).
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 |
| Transisi status instans (Created, Starting, Running, Stopped, Deleted) |
|
| Spot instans dijadwalkan untuk rilis (~5 menit sebelum reklamasi) |
|