AutoScaling生命週期掛鉤功能

樸實無華發表於2018-06-24

使用 LifecycleHook 功能,可以更加靈活地管理控制伸縮組內 ECS 例項的生命週期,靈活地控制伸縮組內例項的建立和移出過程。當伸縮組發生伸縮活動,觸發生命週期掛鉤時,伸縮活動將被掛起,結束當前被掛起的伸縮活動有兩種方式:

  1. 等待生命週期活動超時
  2. 呼叫介面 CompleteLifecycleAction 主動結束生命週期活動

本文將系統地介紹生命週期掛鉤功能的使用方式和使用場景,並給出生命週期掛鉤功能的最佳實踐。

LifecycleHook 介紹

LifecycleHook 使用場景

使用 LifecycleHook,可以在伸縮組發生伸縮活動時將正在擴張或即將釋放的 ECS 例項掛起,執行使用者自定義操作,可以更加靈活地管理 ECS 例項在伸縮組內的生命週期。幾個簡單的 LifecycleHook 應用場景:

  • 伸縮組彈出 ECS 例項後需要延遲一段時間(測試服務沒問題以後)掛載到 SLB ,然後對外提供服務
  • 伸縮組釋放 ECS 例項時需要先將例項從 SLB 後端服務移除(防止接收新的請求),待檢測已經接收到的請求處理完成,停止並釋放例項
  • 伸縮組釋放 ECS 例項時執行資料備份操作
  • 伸縮組彈性擴張或者收縮執行一些使用者自定義操作

針對上述第二種場景,如果可以確定每個請求的最長處理時間,可以呼叫 建立生命週期掛鉤 介面建立生命週期掛鉤,設定 LifecycleTransition 引數值為 SCALE_IN,設定 HeartbeatTimeout 為請求最長處理時間,不需要設定通知物件,當發生彈性收縮型別伸縮活動時,ECS 例項從 SLB 移除後會掛起一段時間(HeartbeatTimeout),等待請求處理完成。

LifecycleHook 工作方式

當伸縮組建立了 LifecycleHook,併發生 LifecycleHook 配置的伸縮活動型別(LifecycleTransition)時,那麼伸縮活動唄掛起,使用者可以在伸縮活動掛起這段時間內執行自定義操作,一直到 LifecycleHook 超時(HeartbeatTimeout),或者通過呼叫 CompleteLifecycleAction 介面提前終止伸縮活動掛起。

貼上圖片.png

對於彈性擴張(SCALE_OUT)伸縮活動:

ECS 例項先進入 Pending(加入中)狀態,當例項啟動成功,並新增到 RDS 白名單(如果伸縮組設定了 RDS)以後,觸發 LifecycleHook ,ECS 例項進入 Pending:Wait(加入中掛起)狀態。如果LifecycleHook 配置了通知物件(MNS),則傳送通知內容到 MNS,使用者可通過 MNS控制檯 的方式來消費 MNS 主題或者佇列中的訊息,也可以通過 OpenAPI 的方式消費,具體可參考 ESS 事件通知#訊息接收 章節。當使用者接收到 MNS 訊息後可以執行自定義操作,例如在 ECS 例項上安裝軟體、部署服務等,執行完自定義操作以後,使用者可以通過 CompleteLifecycleAction 介面提前結束掛起的伸縮活動,也可以等待 LifecycleHook 掛起超時。LifecycleHook 掛起結束後有兩個執行方向,CONTINUE or ABANDON,對於彈性擴張伸縮活動,執行方向解釋如下:

  • CONTINUE 繼續,ECS 例項將被投入伸縮組中使用
  • ABANDON 拒絕,伸縮活動回滾,ECS 例項將被釋放
  • 如果伸縮組配置了多個彈性擴張型別的 LifecycleHook,那麼發生彈性擴張伸縮活動時會觸發多個 LifecycleHook,伸縮活動最終的執行方向(CONTINUE or ABANDON)以最後一個結束的 LifecycleHook 執行方向為準。

結束 LifecycleHook 掛起狀態以後,如果伸縮組配置了負載均衡(SLB),那麼將 ECS 例項掛載到 SLB 上以後,例項進入 Inservice(服務中)狀態,此時彈性擴張伸縮活動結束。

對於彈性收縮(SCALE_IN)伸縮活動:

ECS 例項先進入 Terminating(移出中)狀態,,將例項從 SLB 後端伺服器移除以後(如果伸縮組配置了負載均衡(SLB)),觸發 LifecycleHook ,ECS 例項進入 Terminating:Wait(移出中掛起)狀態。如果 LifecycleHook 配置了通知物件(MNS),則傳送通知內容到 MNS,使用者可通過 MNS控制檯 的方式來消費 MNS 主題或者佇列中的訊息,也可以通過 OpenAPI 的方式消費,具體可參考 ESS 事件通知#訊息接收 章節。當使用者接收到 MNS 訊息後可以執行自定義操作,例如檢測 ECS 接收到的請求是否處理完成、停止接收服務等,執行完自定義操作以後,使用者可以通過 CompleteLifecycleAction 介面提前結束掛起的伸縮活動,也可以等待 LifecycleHook 掛起超時。LifecycleHook 掛起結束後有兩個執行方向,CONTINUE or ABANDON,對於彈性收縮伸縮活動,執行方向解釋如下:

  • CONTINUE 繼續,ECS 例項將從伸縮組中移出
  • ABANDON 拒絕,ECS 例項將從伸縮組中移出
  • 如果伸縮組配置了多個彈性收縮型別的 LifecycleHook,那麼發生彈性收縮活動時會觸發多個 LifecycleHook,如果某個 LifecycleHook 掛起結束執行結果為 ABANDON,則其餘掛起的 LifecycleHook 會被提前結束掉,ECS 例項從伸縮組中移出,如果某個 LifecycleHook 掛起結束執行結果為 CONTINUE,則其餘掛起的 LifecycleHook 繼續掛起,直到最後一個 LifecycleHook 掛起結束,伸縮活動恢復執行。

結束 LifecycleHook 掛起狀態以後,彈性伸縮服務會將 ECS 例項先從 RDS 白名單移除(如果伸縮組配置了 RDS),再將 ECS 例項停止(如果 ECS 例項是伸縮組彈出來的不是手動新增的),然後釋放例項(如果 ECS 例項是伸縮組彈出來的不是手動新增的),並將例項從伸縮組中移出。

LifecycleHook 通知方式

如果生命週期掛鉤配置了通知物件,那麼當伸縮組發生伸縮活動觸發 LifecycleHook 時,通知物件將接收到當前的伸縮活動詳細資訊,如果生命週期掛鉤沒有配置通知物件,那麼當伸縮組發生伸縮活動觸發 LifecycleHook 時不會發出任何通知資訊。

生命週期掛鉤目前支援以下兩種通知方式:

  • 訊息服務(MNS)佇列(Queue)
  • 訊息服務(MNS)主題(Topic)

關於 MNS 主題和佇列的介紹,您可以參考 佇列使用幫助主題使用幫助 來了解主題、佇列的建立,訊息的接收方式,以及如何為主題設定訂閱等。
需要注意的是,MNS 訊息服務會收取相應的費用,具體的收費標準可參考 雲產品定價#訊息服務 進行詳細瞭解。

LifecycleHook 通知內容

當伸縮組發生伸縮活動觸發 LifecycleHook 時,如果生命週期掛鉤配置了通知物件(目前只支援通知到 MNS),那麼通知物件將收到關於此次伸縮活動的詳細資訊,通知內容如下:

{
  "content": {
    "defaultResult": "CONTINUE",
    "instanceIds": [
      "i-xxxxxxxxxx1",
      "i-xxxxxxxxxx2",
      "i-xxxxxxxxxx3",
      "i-xxxxxxxxxx4",
      "i-xxxxxxxxxx5"
    ],
    "lifecycleActionToken": "C8BEAE68-CB77-4E60-986D-1E8BBF1A6B99",
    "lifecycleHookId": "ash-wxxxxxxxxxxx",
    "lifecycleHookName": "SCALE_IN_TEST",
    "lifecycleTransition": "SCALE_IN",
    "notificationMetadata": "測試 SCALE_IN HOOK",
    "requestId": "XXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXX",
    "scalingActivityId": "asa-xxxxxxxxxxxxxxxx",
    "scalingGroupId": "asg-xxxxxxxxxxxxxxxxx",
    "scalingGroupName": "test-hook",
    "scalingRuleId": "asr-xxxxxxxxxxxx",
    "scheduledTaskId": "xxxxxxxxxxxxxx"
  },
  "product": "ESS",
  "regionId": "cn-shenzhen",
  "resourceArn": "acs:ess:cn-shenzhen:111111111111111:scalingGroup/asg-xxxxxxxxxxxxx",
  "time": "2018-06-21T03:07:57.641Z",
  "userId": "111111111111111"
}

上述內容中:

  • resourceArn 伸縮組唯一識別符號,包括了伸縮組所在的 Region 資訊,所屬的使用者 ID 資訊,以及伸縮組 ID 資訊。
  • content 生命週期掛鉤觸發的伸縮活動詳細資訊

    • defaultResult 生命週期掛鉤預設執行策略

      • CONTINUE 繼續
      • ABANDON 拒絕
    • instanceIds 生命週期掛鉤掛起的 ECS 例項ID
    • lifecycleActionToken 生命週期掛鉤唯一識別符號,通過獲取該引數與 lifecycleHookId 引數,可通過呼叫 CompleteLifecycleAction 主動結束生命週期活動
    • lifecycleHookId 生命週期掛鉤 ID
    • lifecycleHookName 生命週期掛鉤名稱
    • lifecycleTransition 生命週期掛鉤適用的伸縮活動型別,取值範圍:

      • SCALE_OUT:伸縮組彈性擴張活動
      • SCALE_IN:伸縮組彈性收縮活動
    • notificationMetadata 生命週期掛鉤通知標識
    • scalingActivityId 伸縮活動 ID
    • scalingGroupId 伸縮組ID
    • scalingGroupName 伸縮組名稱
    • scalingRuleId 觸發伸縮活動的伸縮規則名稱(此引數不是必帶)
    • scheduledTaskId 定時任務ID(只有伸縮活動是由定時任務觸發的時候才會有此引數)

MNS 佇列或主題內容的消費方式,推薦參考 MNS 官方給出的 長輪訓最佳實踐 文件,使用長輪詢的方式來消費佇列或主題收到的訊息內容。

最佳實踐

建立 LifecycleHook 通知物件

在建立 LifecycleHook 時,可以配置通知物件,也可以不配置通知物件,如果需要配置通知物件,需要先建立好通知物件,再建立 LifecycleHook。關於通知物件(MNS 主題、佇列)的建立方式,可以參考 ESS 事件通知#建立 MNS 佇列 章節 和 ESS 事件通知#建立 MNS 主題 章節。

建立 LifecycleHook

LifecycleHook 的建立,可以通過 ESS控制檯 完成,也可以通過呼叫 CreateLifecycleHook 介面完成。通過介面建立 LifecycleHook,可基於 CreateLifecycleHook 文件,參考 ESS 事件通知#建立事件通知(OpenAPI) 章節實現。通過 ESS控制檯 建立 LifecycleHook 過程如下:

登入 ESS控制檯,進入生命週期掛鉤列表頁,點選建立生命週期掛鉤按鈕,彈出建立介面如下圖所示:

貼上圖片.png

按提示名稱,通知標識,選擇伸縮活動型別、執行策略和通知方式,點選確定,如下圖所示:

貼上圖片.png

上圖中,建立了兩個 LifecycleHook,一個伸縮活動擴張型別的 LifecycleHook,一個伸縮活動收縮型別的 LifecycleHook。

觸發 LifecycleHook

本章以觸發彈性收縮活動為例,展示 LifecycleHook 工作過程。觸發伸縮活動的方式,可參考 ESS 事件通知#建立事件通知(OpenAPI) 章節完成。

首先觸發減少1臺例項的伸縮活動,如下圖所示:

貼上圖片.png

檢視伸縮組 ECS 例項列表頁,如下圖所示:

貼上圖片1.png

從上圖看出,此時有一臺 ECS 例項處於掛起狀態,由於彈性收縮型別的 LifecycleHook 設定了通知物件,可以登入 MNS控制檯 檢視通知結果,訊息檢視方式可參考 ESS 事件通知#MNS 佇列訊息接收) 章節。

MNS 訊息處理-操作生命週期掛鉤

接收到 LifecycleHook 傳送的通知內容以後,提取 lifecycleActionToken 、lifecycleHookId 引數,然後通過呼叫 CompleteLifecycleAction 介面提前結束 LifecycleHook 掛起狀態,呼叫方式如下:

public class LifecycleHookTest {
    public static final String REGION_ID = "cn-hangzhou";

    public static final String AK        = "xxx";

    public static final String AKS       = "xxx";

    public static void main(String[] args) throws ClientException, Exception {
        IClientProfile clientProfile = DefaultProfile.getProfile(REGION_ID, AK, AKS);
        final IAcsClient client = new DefaultAcsClient(clientProfile);
        completeLifecycleAction(client);
    }

    private static String completeLifecycleAction(IAcsClient client) throws ClientException {
        CompleteLifecycleActionRequest request = new CompleteLifecycleActionRequest();
        request.setLifecycleHookId("ash-xxxxxxxxxxxxx");
        request.setLifecycleActionToken("xxxxxxxxxxxxxxx");
        request.setLifecycleActionResult("CONTINUE");
        CompleteLifecycleActionResponse response = client.getAcsResponse(request);
        return response.getRequestId();
    }
}

使用上述程式碼中,需補充個人 AK 資訊,以及 LifecycleActionToken 和 LifecycleHookId 引數。

LifecycleHook 掛起狀態結束以後,ECS 例項被停止(伸縮組建立的例項),然後釋放(伸縮組建立的例項)並移出伸縮組。

注意事項

如果 LifecycleHook 配置的通知物件被刪除,那麼您將無法收到掛起通知,伸縮活動被掛起。如果伸縮活動觸發 LifecycleHook 被掛起,想要延長伸縮活動被掛起的時間,可以通過呼叫 RecordLifecycleActionHeartbeat 延長掛起時間。

寫在最後

AutoScaling 生命週期掛鉤功能提供了更加靈活地管理伸縮組內 ECS 例項生命週期的能力,通過該功能可以在伸縮組發生彈性擴張和彈性收縮活動時,通過將伸縮活動掛起的方式執行自定義操作。

彈性伸縮服務正在快速地發展,後續會有更多的新功能新特性推出,感謝您的一路陪伴。


相關文章