共用方式為


Azure 中繼資料服務:Linux VM 的已排定事件

適用於:✔️ Linux VM ✔️ 彈性擴展集 ✔️ 統一擴展集

已排定的事件是一項「Azure 中繼資料服務」,可讓您的應用程式有時間準備虛擬機器維護。 它提供即將進行維護事件 (例如重新啟動) 的相關資訊,讓您的應用程式可進行準備以及限制中斷。 它適用於所有 Azure 虛擬機器類型 (包括 Windows 和 Linux 上的 PaaS 和 IaaS)。

如需 Linux 上已排定事件的資訊,請參閱 Linux VM 的已排定事件

排程事件提供即將發生的事件的主動式通知,如需過去發生的事件回應資訊,請參閱 Azure Resource Graph 中的 VM 可用性資訊 ,以及 建立 Azure 虛擬機的可用性警示規則

注意

已排定事件已在所有 Azure 區域中正式推出。 請參閱版本和區域可用性以取得最新的版本資訊。

為什麼要使用已排定事件?

許多應用程式可受益於 VM 維護的準備時間。 這些時間可用來執行應用程式特定的工作,能改善可用性、可靠性與服務性,包括:

  • 檢查點和還原。
  • 清空連線。
  • 主要複本容錯移轉。
  • 從負載平衡器移除集區。
  • 事件記錄。
  • 順利關機。

使用已排定事件,應用程式就可以探索維護所發生的時間,以及限制其影響的觸發工作。

排程的事件會提供下列使用案例中的事件:

  • 平台起始的維護 (例如,主機的 VM 重新啟動、即時移轉或記憶體保留更新)。
  • 虛擬機器正於預期即將失敗的降級主機硬體 (英文) 上執行。
  • 虛擬機器在發生硬體失敗的主機上執行。
  • 使用者起始的維護 (例如,使用者重新啟動或重新部署 VM)。
  • 現成 VM現成擴展集執行個體收回。

基本概念

如果您是使用可由 VM 內存取的 REST 端點來執行 VM,中繼資料服務會公開這類相關資訊。 這項資訊是透過無法路由傳送的 IP 所取得,且不會在 VM 之外公開。

範圍

已排定事件會傳送到下列目標,並由其進行認可:

  • 獨立虛擬機器。
  • Azure 雲端服務 (傳統) 中的所有 VM。
  • 可用性設定組中的所有 VM。
  • 擴展集放置群組中的所有 VM。

在整個可用性設定組,或虛擬機器擴展集的放置群組中,不論可用性區域的使用方式,所有虛擬機器 (VM) 的已排定事件都會傳送至相同群組或集合中的所有其他 VM。

因此,請檢查事件中的 Resources 欄位以找出哪些 VM 受到影響。

注意

規模設定中的 GPU 加速虛擬機在使用一個容錯網域(FD = 1)時,僅接收與受影響資源相關的排程事件。 事件不會廣播到相同配置組中的所有 VM。

端點探索

針對已啟用 VNET 的 VM,可以從靜態非可路由 IP 169.254.169.254 取得「中繼資料服務」。 最新版已排定事件的完整端點為:

http://169.254.169.254/metadata/scheduledevents?api-version=2020-07-01

如果未在虛擬網路內建立 VM,雲端服務和傳統 VM 的預設案例,則需要其他邏輯來探索要使用的 IP 位址。 請參閱此範例以了解如何探索主機端點 \(英文\)。

版本和區域可用性

已排定事件服務已進行版本設定。 版本是必要項目;目前版本為 2020-07-01

版本 版本類型 地區 版本資訊
2020-07-01 正式發行 全部
  • 事件持續時間的新增支援
  • 2019-08-01 正式發行 全部
  • 事件來源的新增支援
  • 2019-04-01 正式發行 全部
  • 事件描述的新增支援
  • 2019-01-01 正式發行 全部
  • 已新增支援虛擬機器擴展集 EventType 'Terminate'
  • 2017-11-01 正式發行 全部
  • 已新增支援現成 VM 收回 EventType 'Preempt'
  • 2017 年 8 月 1 日 正式發行 全部
  • 已從 IaaS VM 的資源名稱中移除預留底線
  • 強制所有要求的中繼資料標頭需求
  • 2017-03-01 預覽​​ 全部
  • 初始版本
  • 注意

    先前排定事件的預覽版支援作為 API 版本的 {latest}。 此格式將不再受到支援且之後會遭到取代。

    啟用和停用已排定事件

    系統會在您第一次提出事件要求時,為您的服務啟用「已排定事件」。 您應該會在第一次呼叫多達兩分鐘時遇到延遲的回應,而您會在 5 分鐘內開始接收事件。 如果長達 24 小時未向端點提出要求,服務就會停用已排定事件。

    使用者起始的維護

    使用者透過 Azure 入口網站、API、CLI 或 PowerShell 起始的 VM 維護,將會產生「已排定事件」。 這可讓您測試應用程式中的維護準備邏輯,讓應用程式可以為使用者起始的維護預作準備。

    如果您重新啟動 VM,則會排定類型為 Reboot 的事件。 如果您重新部署 VM,則會排定類型為 Redeploy 的事件。 一般而言,可以立即核准具有使用者事件來源的事件,以避免延遲使用者起始的動作。 建議以主要與次要 VM 進行通訊,並核准使用者產生的已排定事件,避免主要 VM 沒有回應。 藉由立即核准事件,可防止在應用程式復原過程中出現延遲。

    只有適用於支援記憶體保留更新的一般用途 VM 大小,才支援 虛擬機器擴展集客體 OS 升級或重新安裝映像的已排定事件。 但不適用於 G、M、N 和 H 系列。 根據預設,虛擬機器擴展集客體 OS 升級或重新安裝映像的已排定事件會處於停用狀態。 若要在支援的 VM 大小上為這些作業啟用已排定事件,請先使用 OSImageNotificationProfile 加以啟用。

    使用 API

    高階概述

    處理已排定事件時,可使用準備與復原兩個主要元件。 所有影響 VM 的目前已排定事件,都能透過 IMDS 已排定事件端點進行讀取。 當事件達到終端機狀態時,就會從事件清單中移除。 下圖說明了單一已排定事件可能經歷的各種狀態轉換:

    此狀態圖表顯示已排定事件可採用的各種轉換。

    針對 EventStatus:“Scheduled” 狀態中的事件,您必須採取步驟來準備工作負載。 準備完成後,應使用已排定事件 API 來核准事件。 否則,一旦到達 NotBefore 時間,即會自動核准事件。 如果 VM 位於共用基礎結構上,系統則會等待相同硬體上的所有其他租用戶也核准作業或逾時。 完成所有受影響 VM 或 NotBefore 時間的核准程序之後,Azure 就會使用 EventStatus: "Started" 產生新的排程事件負載,並觸發維護事件開始。 當事件達到終端機狀態時,就會從事件清單中移除。 這可做為客戶復原其 VM 的訊號。

    pseudo 程式代碼示範如何在您的應用程式中讀取和管理安排的事件:

    current_list_of_scheduled_events = get_latest_from_se_endpoint()
    #prepare for new events
    for each event in current_list_of_scheduled_events:
      if event not in previous_list_of_scheduled_events:
        prepare_for_event(event)
    #recover from completed events
    for each event in previous_list_of_scheduled_events:
      if event not in current_list_of_scheduled_events:
        receover_from_event(event)
    #prepare for future jobs
    previous_list_of_scheduled_events = current_list_of_scheduled_events
    

    由於已排定事件通常用於具有高可用性需求的應用程式,因此應考慮一些例外狀況:

    1. 已排定事件完成並從陣列中移除後,如果沒有新的事件 (包括另一個 EventStatus 為「已啟動」狀態的事件),便不會再產生影響
    2. Azure 會監視整個機群的維護作業,並在極少數情況下,因認為維護作業的風險太高而判斷無法套用。 在此情況下,排程的事件會直接從「Scheduled」變為從事件陣列中被移除。
    3. 如果發生硬體故障,Azure 會略過「已排程」狀態,並立即移至 EventStatus:“Started” 狀態。
    4. 雖然事件仍處於 EventStatus 為「已啟動」的狀態,也可能會因持續時間比已排定事件中公告的還短,而產生其他影響。

    不同容錯網域的 VM 不會同時受到例行維護作業的影響,以保障 Azure 的可用性。 然而,作業可一個接一個連續執行。 一個容錯網域中的 VM 可以在另一個容錯網域維護完成後,立即接收 EventStatus 為「已排程」的已排定事件。 無論選擇何種結構,請始終檢查 VM 是否有待處理的新事件。

    雖然事件發生的具體時間各不相同,但可根據下圖提供的粗略指導方針,了解典型維護作業如何是如何進行:

    • 從 EventStatus「已排程」到「核准逾時」:15 分鐘
    • 影響持續時間:7 秒
    • 從 EventStatus「已啟動」到「已完成」(事件從事件陣列中移除):10 分鐘

    顯示已排定事件流程的時間軸圖表。

    影響 VM 可用性的所有作業都會建立排程的事件,但並非所有排程的事件都會出現在其他 Azure 介面中,例如 Azure 活動記錄或資源健康狀態。 定期檢查已排程的事件,可確保您擁有最 up-to最新的 VM 影響相關信息。

    標頭

    查詢中繼資料服務時,您必須提供 Metadata:true 標頭以免不小心重新導向要求。 所有排程的事件都需要 Metadata:true 標頭。 要求中未包含標頭會導致中繼資料服務「不正確的要求」回應。

    查詢事件

    您只要進行下列呼叫,即可查詢已排定事件:

    Bash 範例

    curl -H Metadata:true http://169.254.169.254/metadata/scheduledevents?api-version=2020-07-01
    

    PowerShell 範例

    Invoke-RestMethod -Headers @{"Metadata"="true"} -Method GET -Uri "http://169.254.169.254/metadata/scheduledevents?api-version=2020-07-01" | ConvertTo-Json -Depth 64
    

    Python 範例

    import json
    import requests
    
    metadata_url ="http://169.254.169.254/metadata/scheduledevents"
    header = {'Metadata' : 'true'}
    query_params = {'api-version':'2020-07-01'}
    
    def get_scheduled_events():           
        resp = requests.get(metadata_url, headers = header, params = query_params)
        data = resp.json()
        return data
    
    

    回應包含排定的事件陣列。 空白陣列表示目前沒有任何排定的事件。 在有排定事件的情況下,回應會包含事件陣列。

    {
        "DocumentIncarnation": {IncarnationID},
        "Events": [
            {
                "EventId": {eventID},
                "EventType": "Reboot" | "Redeploy" | "Freeze" | "Preempt" | "Terminate",
                "ResourceType": "VirtualMachine",
                "Resources": [{resourceName}],
                "EventStatus": "Scheduled" | "Started",
                "NotBefore": {timeInUTC},       
                "Description": {eventDescription},
                "EventSource" : "Platform" | "User",
                "DurationInSeconds" : {timeInSeconds},
            }
        ]
    }
    

    事件屬性

    屬性 說明
    文件內建 當事件陣列變更時增加的整數。 具有相同化身的檔包含相同的事件資訊,而當事件變更時,化身就會遞增。
    EventId 此事件的全域唯一識別碼。

    範例:
    • 602d9444-d2cd-49c7-8624-8643e7171297
    事件類型 此事件可能造成的預期影響。

    值:
    • Freeze:虛擬機器已排定暫停幾秒鐘。 CPU 和網路連線可能會暫止,但不會影響記憶體或已開啟的檔案。
    • Reboot:虛擬機器已排定要重新開機 (非持續性記憶體都會遺失)。 在極少數情況下,排程 EventType 為「重新啟動」的 VM 可能不會重新啟動,而是遭遇凍結事件。 請遵循上述指示,檢查事件是否已完成,又能否安全地還原工作負載。
    • Redeploy︰虛擬機器已排定要移至另一個節點 (暫時磁碟都會遺失)。
    • Preempt︰正在刪除現成虛擬機器 (暫時磁碟都會遺失)。 此事件會盡最大努力提供
    • Terminate︰虛擬機器已排定要刪除。
    資源類型 受此事件影響的資源類型。

    值:
    • VirtualMachine
    資源 受此事件影響的資源清單。

    範例:
    • [“FrontEnd_IN_0”、“BackEnd_IN_0”]
    事件狀態 此事件的狀態。

    值:
    • Scheduled︰此事件已排定在 NotBefore 屬性所指定的時間之後啟動。
    • Started︰已啟動事件。
    未曾提供 Completed 或類似的狀態。 當事件完成時,不會再傳回事件。
    不早於 自此之後可啟動此事件的時間。 事件保證不會在此時間之前啟動。 當事件啟動後,它將會是空白的。

    範例:
    • Mon, 19 Sep 2016 18:29:47 GMT
    說明 此事件的描述。

    範例:
    • 正在維修主機伺服器。
    • 主機伺服器基礎結構正在進行維護。
    • 虛擬機正在暫停,因為正在進行記憶體保留的即時移轉操作。
    • 虛擬機將會依照授權使用者的要求重新啟動。
    • 主機伺服器正在進行緊急修復。
    事件來源 事件啟動器。

    範例:
    • Platform:平臺發起了這個事件。
    • User:使用者起始此事件。
    時間長度(秒) 事件所造成的中斷預期持續時間。 在影響期間,可能有較短持續時間的次要影響。

    範例:
    • 9:事件所造成的中斷持續 9 秒。
    • 0:事件不會中斷 VM 或影響其可用性(例如,更新至網路)
    • -1:如果影響持續時間未知或不適用,則使用預設值。

    事件排定

    系統會根據事件類型,為每個事件在未來安排最少的時間量。 事件的 NotBefore 屬性會反映這個時間。

    事件類型 最短時間通知
    凍結 15 分鐘
    重新啟動 15 分鐘
    重新部署 10 分鐘
    搶佔 30 秒
    終止 使用者可設定:5 至 15 分鐘

    這表示在事件發生前的最短通知時間內,您能夠偵測到事件的未來排程。 事件已排定後,會在通過核准或 Started 時間後進入 NotBefore 狀態。 不過,在極少數情況下,Azure 會在作業啟動之前取消作業。 在此情況下,事件會從 Events 陣列中移除,而且不會如先前排程而發生影響。

    注意

    在某些情況下,Azure 能夠因硬體性能下降而預測主機故障,並嘗試藉由排程遷移來減少對您的服務的中斷。 受影響的虛擬機器會收到含有 NotBefore (通常是未來幾天) 的已排定事件。 實際時間依預測的失敗風險評量而有所不同。 Azure 會儘可能嘗試提供 7 天的提前通知。 實際通知時間會有所不同,如果硬體即將故障的可能性很高,可能會較短。 若要將您服務的風險降至最低,以防萬一硬體在系統起始移轉之前失敗,我們建議您盡快重新部署虛擬機器。

    注意

    如果主機節點發生硬體故障,Azure 會略過最低通知期間,並立即開始受影響虛擬機的復原程式。 這可減少受影響 VM 無法回應時的復原時間。 在復原過程中,會針對具有 EventType = RebootEventStatus = Started的所有受影響 VM 建立事件。

    輪詢頻率

    您可以自行決定輪詢端點更新的頻率。 然而,要求間隔時間越久,您可能會花更多時間回應即將發生的事件。 大部分事件都有 5 到 15 分鐘的事先通知,但在某些情況下,預先通知可能不到 30 秒。 為確保盡可能有較多時間採取緩和動作,建議您每秒輪詢一次服務。

    啟動事件

    在您得知即將發生的事件,並完成正常關機邏輯之後,即可使用 POST 向中繼資料服務進行 EventId 呼叫,以核准未處理的事件。 對 Azure 來說,此呼叫可以將通知時間縮到最短 (可能的話)。 事件可能不會在核准時立即啟動。 在某些情況下,Azure 需要核准節點上裝載的所有 VM,然後再繼續進行事件。

    以下是 POST 要求本文中必須要有的 JSON 範例。 要求需包含 StartRequests 清單。 每個 StartRequest 都包含您需要加速之事件的 EventId

    {
    	"StartRequests" : [
    		{
    			"EventId": {EventId}
    		}
    	]
    }
    

    如果服務傳遞了有效的事件識別碼,則即使另一個 VM 已核准事件,也一律會傳回 200 成功碼。 400 錯誤碼表示要求標頭或酬載的格式錯誤。

    注意

    事件除非已透過 POST 訊息核准或 NotBefore 時間已過,否則不會繼續。 這包括使用者觸發的事件,例如從 Azure 入口網站重新啟動 VM。

    Bash 範例

    curl -H Metadata:true -X POST -d '{"StartRequests": [{"EventId": "f020ba2e-3bc0-4c40-a10b-86575a9eabd5"}]}' http://169.254.169.254/metadata/scheduledevents?api-version=2020-07-01
    

    PowerShell 範例

    Invoke-RestMethod -Headers @{"Metadata" = "true"} -Method POST -body '{"StartRequests": [{"EventId": "5DD55B64-45AD-49D3-BBC9-F57D4EA97BD7"}]}' -Uri http://169.254.169.254/metadata/scheduledevents?api-version=2020-07-01 | ConvertTo-Json -Depth 64
    

    Python 範例

    import json
    import requests
    
    def confirm_scheduled_event(event_id):  
       # This payload confirms a single event with id event_id
       payload = json.dumps({"StartRequests": [{"EventId": event_id }]})
       response = requests.post("http://169.254.169.254/metadata/scheduledevents", 
                                headers =  {'Metadata' : 'true'}, 
                                params = {'api-version':'2020-07-01'}, 
                                data = payload)    
       return response.status_code
    

    注意

    認可事件時,即會允許事件中所有 Resources 的事件繼續進行,而不僅是認可此事件 VM。 因此,您可以挑選一位領導者來協調確認,這可能和Resources欄位中的第一部機器一樣簡單。

    範例回應

    下列事件是從兩個已即時移轉至另一個節點的 VM 中得出的範例。

    每當 DocumentIncarnation 中有新的資訊時,Events 就會變動。 事件的核准可讓 WestNO_0 和 WestNO_1 的凍結繼續。

    {
        "DocumentIncarnation":  1,
        "Events":  [
                   ]
    }
    
    {
        "DocumentIncarnation":  2,
        "Events":  [
                       {
                           "EventId":  "C7061BAC-AFDC-4513-B24B-AA5F13A16123",
                           "EventStatus":  "Scheduled",
                           "EventType":  "Freeze",
                           "ResourceType":  "VirtualMachine",
                           "Resources":  [
                                             "WestNO_0",
                                             "WestNO_1"
                                         ],
                           "NotBefore":  "Mon, 11 Apr 2022 22:26:58 GMT",
                           "Description":  "Virtual machine is being paused because of a memory-preserving Live Migration operation.",
                           "EventSource":  "Platform",
                           "DurationInSeconds":  5
                       }
                   ]
    }
    
    {
        "DocumentIncarnation":  3,
        "Events":  [
                       {
                           "EventId":  "C7061BAC-AFDC-4513-B24B-AA5F13A16123",
                           "EventStatus":  "Started",
                           "EventType":  "Freeze",
                           "ResourceType":  "VirtualMachine",
                           "Resources":  [
                                             "WestNO_0",
                                             "WestNO_1"
                                         ],
                           "NotBefore":  "",
                           "Description":  "Virtual machine is being paused because of a memory-preserving Live Migration operation.",
                           "EventSource":  "Platform",
                           "DurationInSeconds":  5
                       }
                   ]
    }
    
    {
        "DocumentIncarnation":  4,
        "Events":  [
                   ]
    }
    
    

    Python 範例

    此範例會查詢元數據服務是否有預定事件,並核准每個待處理的事件。 您可以在 Listener.py 檔案的 vm-scheduled-events-mock-server 存放庫中找到程序代碼。

    #!/usr/bin/python
    import json
    import requests
    from time import sleep
    
    # The URL to access the metadata service
    metadata_url ="http://169.254.169.254/metadata/scheduledevents"
    # This must be sent otherwise the request will be ignored
    header = {'Metadata' : 'true'}
    # Current version of the API
    query_params = {'api-version':'2020-07-01'}
    
    def get_scheduled_events():           
        resp = requests.get(metadata_url, headers = header, params = query_params)
        data = resp.json()
        return data
    
    def confirm_scheduled_event(event_id):  
        # This payload confirms a single event with id event_id
        # You can confirm multiple events in a single request if needed      
        payload = json.dumps({"StartRequests": [{"EventId": event_id }]})
        response = requests.post(metadata_url, 
                                headers= header,
                                params = query_params, 
                                data = payload)    
        return response.status_code
    
    def log(event): 
        # This is an optional placeholder for logging events to your system 
        print(event["Description"])
        return
    
    def advanced_sample(last_document_incarnation): 
        # Poll every second to see if there are new scheduled events to process
        # Since some events may have necessarily short warning periods, it is 
        # recommended to poll frequently
        found_document_incarnation = last_document_incarnation
        while (last_document_incarnation == found_document_incarnation):
            sleep(1)
            payload = get_scheduled_events()    
            found_document_incarnation = payload["DocumentIncarnation"]        
            
        # We recommend processing all events in a document together, 
        # even if you won't be actioning on them right away
        for event in payload["Events"]:
    
            # Events that already started, logged for tracking
            if (event["EventStatus"] == "Started"):
                log(event)
                
            # Approve all user initiated events. These are typically created by an 
            # administrator and approving them immediately can help to avoid delays 
            # in admin actions
            elif (event["EventSource"] == "User"):
                confirm_scheduled_event(event["EventId"])            
                
            # For this application, freeze events less that 9 seconds are considered
            # no impact. This will immediately approve them
            elif (event["EventType"] == "Freeze" and 
                int(event["DurationInSeconds"]) >= 0  and 
                int(event["DurationInSeconds"]) < 9):
                confirm_scheduled_event(event["EventId"])
                
            # Events that may be impactful (for example reboot or redeploy) may need custom 
            # handling for your application
            else: 
                #TODO Custom handling for impactful events
                log(event)
        print("Processed events from document: " + str(found_document_incarnation))
        return found_document_incarnation
    
    def main():
        # This will track the last set of events seen 
        last_document_incarnation = "-1"
    
        input_text = "\
            Press 1 to poll for new events \n\
            Press 2 to exit \n "
        program_exit = False 
    
        while program_exit == False:
            user_input = input(input_text)    
            if (user_input == "1"):                        
                last_document_incarnation = advanced_sample(last_document_incarnation)
            elif (user_input == "2"):
                program_exit = True       
    
    if __name__ == '__main__':
        main()
    

    預定事件測試

    測試應用程式回應排程事件的兩個常見方式,是手動觸發用戶模擬事件或使用模擬伺服器。

    您可以從 [VM] 刀鋒視窗選取 [重新啟動] 或 [重新部署] VM 選項,透過 Azure 入口網站或 Azure CLI 手動觸發重新部署和重新啟動事件。 這會建立事件,並將它傳送至您的作業流程。

    影響多個 VM 的作業,例如主機更新,無法視需要觸發,因此您可以改用模擬伺服器。 vm-scheduled-events-mock-server 提供一個架構,能透過重放實際事件流程來測試應用程式對不同情境的回應,以進行開發和測試。 根據預設,伺服器支援 9 個不同的案例,全都從在 Azure 中執行的 VM 擷取,並代表最常見的案例。 視您的應用程式特定特性而定,這些案例可以擴充為包含更多選項。

    下一步