全部產品
Search
文件中心

Compute Nest:PushMeteringData - 推送計量資料

更新時間:May 10, 2025

通過執行個體內部調用PushMeteringData推送計量資料。

介面說明

  • 該命令只支援推送隨用隨付的計算巢服務執行個體的計量資料,推送的計量項目需要定義為服務商上報。

  • 通過計算巢服務建立的ECS或ACK執行個體,可以直接在ECS或ACK內部調用該介面推送計量資料。如需採用OpenAPI的方式進行調用,請參見通過OpenAPI調用PushMeteringData

請求參數

名稱

類型

是否必選

描述

樣本值

Metering

String

樣本中的參數說明如下:

  • StartTime:計量開始時間。單位:秒。

  • EndTime:計量結束時間。單位:秒。

  • Entities:計量實體物件。

    • Key:計量項目屬性名稱。

      • Frequency:使用次數(次)。

      • Period:使用小時時間長度(秒)。

        重要

        請求參數中的時間長度單位為秒,而計費單位為小時,因此計費時會轉換為小時,如推送19:00-20:00的用量1800,計費價格為1 USD/小時,按小時出賬該時段費用為1800/3600×1=0.5 USD,費用如為小數,保留兩位小數,超過兩位捨棄。

      • Storage:使用儲存空間(Byte)。

        重要

        請求參數中的單位為Byte,而計費單位為MB,因此計費時會轉換為MB,如推送19:00-20:00的用量524288,計費價格為1 USD/MB,按小時出賬該時段費用為524288/1024/1024×1=0.5 USD,費用如為小數,保留兩位小數,超過兩位捨棄。

      • NetworkOut:上行使用流量(Bit)。

        重要

        請求參數中的單位為Bit,而計費單位為MB,因此計費時會轉換為MB,如推送 19:00-20:00 的用量 524288,計費價格為 1 USD/MB,按小時出賬該時段費用為 524288/1024/1024×1=0.5 USD,費用如為小數,保留兩位小數,超過兩位捨棄。

      • NetworkIn:下行使用流量(Bit)。

        重要

        請求參數中的單位為Bit,而計費單位為MB,因此計費時會轉換為MB,如推送19:00-20:00的用量 524288,計費價格為1 USD/MB,按小時出賬該時段費用為 524288/1024/1024×1=0.5 USD,費用如為小數,保留兩位小數,超過兩位捨棄。

      • Character:字元數(個)。

      • DailyActiveUser:日活躍使用者數(DAU)。

      • PeriodMin:使用分鐘時間長度(分鐘)。

      • VirtualCpu:虛擬CPU核心數。

        • Unit: Unit(個)

        • Memory: Memory(GB)

    • Value:計量數值(取值>=0),參數類型為Integer。

說明
  • 如果商品設定為即時出賬,StartTime和EndTime為任意時間寬度,但是EndTime一定要大於StartTime。

  • 如果商品設定為非即時出賬(即選擇按小時、按天、按月等),StartTime和EndTime的間隔必須大於5分鐘。

[{"StartTime":"1664451045","EndTime":"1664451198","Entities":[{"Key":"Frequency","Value":"6"}]}]

Token

String

用於計算巢對比,判斷推送方是否是服務商。

使用MD5密碼編譯演算法對Metering&Key加密,加密為32位小寫值。

  • Metering:[{"StartTime":"1664451045","EndTime":"1664451198","Entities":[{"Key":"Frequency","Value":"6"}]}],如何擷取請參見Metering

  • Key:服務Key。樣本e98893f5ecc3ae1ctest,您可在服務詳情頁擷取服務Key。

    說明

    Key全服務唯一,不會隨版本變更而變化。

  • 待加密字串:Metering=[{"StartTime":"1664451045","EndTime":"1664451198","Entities":[{"Key":"Frequency","Value":"6"}]}]&Key=e98893f5ecc3ae1ctest

  • 加密後的Token值:7aa81300b2aea77984b772495c8e4e83

返回參數

名稱

類型

描述

樣本值

RequestId

String

計算巢請求ID。

e6862d3a-9305-4289-8dd3-9c52a680228b

Success

Boolean

成功狀態標識。

true

PushMeteringDataRequestId

String

雲市場請求ID。

7lc658a2-tr41-****-****-c25es45vc248

Token

String

用於服務商對比數位簽章。請參見計算巢校正數位簽章說明

50130a063c6acf833280d23169898bd4

樣本

本樣本是雲市場隨用隨付的計算巢商品建立的ECS中發起調用。

curl樣本

  1. 擷取ECS地區資訊

    在調用PushMeteringData前,您需要擷取應用部署的ECS地區(regionld)資訊。擷取到的地區資訊會在後續步驟中使用,因此需要服務商記錄。

    1. 訪問如下網址,獲得地區資訊。

      curl http://100.100.100.200/latest/meta-data/region-id
    2. 地區返回樣本。

      cn-hangzhou
  2. 準備入參

    "Metering":"[{\"StartTime\":\"1664451045\",\"EndTime\":\"1664451198\",\"Entities\":[{\"Key\":\"Frequency\",\"Value\":\"6\"}]}]","Token":"7aa81300b2aea77984b772495c8e4e83"

    • Metering:[{\"StartTime\":\"1664451045\",\"EndTime\":\"1664451198\",\"Entities\":[{\"Key\":\"Frequency\",\"Value\":\"6\"}]}]

      說明

      由於本樣本通過curl調用PushMeteringData,需要加入轉譯符號\。若使用代碼調用,則不需要轉譯。

    • Token:將字串Metering&服務Key通過MD5加密擷取32位小寫值7aa81300b2aea77984b772495c8e4e83

  3. 請求樣本

    curl -H "Content-Type: application/json" -XPOST https://cn-hangzhou.axt.aliyun.com/computeNest/marketplace/push_metering_data -d '{"Metering":"[{\"StartTime\":\"1664451045\",\"EndTime\":\"1664451198\",\"Entities\":[{\"Key\":\"Frequency\",\"Value\":\"6\"}]}]","Token":"7aa81300b2aea77984b772495c8e4e83"}'
    說明

    https://cn-hangzhou.axt.aliyun.comcn-hangzhou步驟1中擷取的地區,具體調用時請按實際情況更換地區資訊。

  4. 返回樣本

    {
        "RequestId":"4ca591b5-bc30-****-****-c4d0ec5d24ed", 
        "Success":"true",
        "PushMeteringDataRequestId":"7lc658a2-tr41-****-****-c25es45vc248", 
        "Token":"50130a063c6acf833280d23169898bd4"
    }

程式碼範例

Python

import requests
import json
import hashlib
import time
from urllib.request import urlopen

def get_region_id():
    """通過阿里雲中繼資料服務擷取地區 ID(如 cn-hangzhou)"""
    try:
        with urlopen(
            "http://100.100.100.200/latest/meta-data/region-id",
            timeout=2
        ) as response:
            return response.read().decode().strip()
    except Exception as e:
        print(f"Failed to get region ID: {str(e)}", file=sys.stderr)
        sys.exit(1)

def push_metering_data(entities_map, service_key):
    # 動態擷取目前時間(Unix 時間戳記,單位秒)
    current_time = int(time.time())
    start_time = current_time 
    end_time = current_time + 1

    # 構建 Metering 資料
    metering_data = [
        {
            "StartTime": str(start_time),
            "EndTime": str(end_time),
            "Entities": [
                {"Key": key, "Value": str(value)} 
                for key, value in entities_map.items()
            ]
        }
    ]
    metering_str = json.dumps(metering_data)

    # 動態擷取地區 ID 並構建 URL
    region_id = get_region_id()
    url = f"https://{region_id}.axt.aliyun.com/computeNest/marketplace/push_metering_data"

    # 計算 Token
    token_str = metering_str + "&" + service_key
    token = hashlib.md5(token_str.encode()).hexdigest().lower()

    # 發送 POST 請求
    try:
        response = requests.post(
            url,
            json={
                "Metering": metering_str,
                "Token": token
            },
            headers={"Content-Type": "application/json"}
        )
        print(f"Request URL: {url}")
        print(f"Status Code: {response.status_code}")
        print(f"Response: {response.text}")
    except Exception as e:
        print(f"Request Failed: {str(e)}", file=sys.stderr)

if __name__ == "__main__":
    import sys
    # 樣本參數(替換為實際推送資料,key為計量項目,value為數值)
    entities = {
        "Frequency": "6"
    }
    # 服務商Key
    service_key = "your_service_key_here"

    # 調用函數
    push_metering_data(entities, service_key)

運行樣本:

image

Java

import org.json.JSONArray;
import org.json.JSONObject;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.security.MessageDigest;
import java.util.HashMap;
import java.util.Map;     

public class MeteringPusher {
    public static void main(String[] args) {
        try {
            // === 動態擷取地區 ID === #
            String regionId = getRegionId();
            System.out.println("Detected Region ID: " + regionId);

            // === 構造請求體 === #
            Map<String, String> entities = new HashMap<>(); // 構建Entities, 需替換具體推送內容
            entities.put("Frequency", "6");
            String serviceKey = "your_service_key_here"; // 需替換為實際服務商Key
            JSONObject payload = generateDynamicRequest(regionId, entities, serviceKey);
            String paylodString = payload.toString();

            // 若僅測試可注釋上述內容,直接輸入下方內容,其中StartTime、EndTime等參數需替換
            // String paylodString = "{\"Metering\":\"[{\\\"StartTime\\\":\\\"1664451045\\\",\\\"EndTime\\\":\\\"1664451198\\\",\\\"Entities\\\":[{\\\"Key\\\":\\\"Frequency\\\",\\\"Value\\\":\\\"6\\\"}]}]\",\"Token\":\"7aa81300b2aea77984b772495c8e4e83\"}";

            // === 發送 POST 請求 === #
            String urlStr = "https://" + regionId + ".axt.aliyun.com/computeNest/marketplace/push_metering_data";
            URL url = new URL(urlStr);
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            conn.setRequestMethod("POST");
            conn.setRequestProperty("Content-Type", "application/json");
            conn.setDoOutput(true);

            try (OutputStream os = conn.getOutputStream()) {
                byte[] input = paylodString.getBytes("UTF-8");
                os.write(input, 0, input.length);
            }

            // === 讀取響應 === #
            BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()));
            StringBuilder response = new StringBuilder();
            String responseLine;
            while ((responseLine = br.readLine()) != null) {
                response.append(responseLine);
            }
            conn.disconnect();
            System.out.println("Response: " + response.toString());
            System.out.println("Request URL: " + urlStr);

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    // === 動態擷取地區 ID(阿里雲中繼資料服務) === 
    private static String getRegionId() throws Exception {
        String regionIdUrl = "http://100.100.100.200/latest/meta-data/region-id";
        HttpURLConnection conn = (HttpURLConnection) new URL(regionIdUrl).openConnection();
        conn.setRequestMethod("GET");
        conn.setConnectTimeout(2000); // 2秒逾時
        conn.setReadTimeout(2000);

        try (BufferedReader in = new BufferedReader(
            new InputStreamReader(conn.getInputStream()))) {
            return in.readLine().trim();
        }
    }

    //  === 動態產生請求資料  === 
    private static JSONObject generateDynamicRequest(String regionId, Map<String, String> entities, String serviceKey) throws Exception {
        // 擷取目前時間戳
        long currentTime = System.currentTimeMillis() / 1000;
        long startTime = currentTime;
        long endTime = currentTime + 1;

        // 構建Metering資料
        JSONArray meteringArray = new JSONArray();
        JSONObject meteringItem = new JSONObject();
        meteringItem.put("StartTime", String.valueOf(startTime));
        meteringItem.put("EndTime", String.valueOf(endTime));

        JSONArray entitiesArray = new JSONArray();
        for (Map.Entry<String, String> entry : entities.entrySet()) {
            entitiesArray.put(new JSONObject()
                .put("Key", entry.getKey())
                .put("Value", entry.getValue()));
        }
        meteringItem.put("Entities", entitiesArray);
        meteringArray.put(meteringItem);

        // 計算Token
        String meteringStr = meteringArray.toString();
        String tokenStr = meteringStr + "&" + serviceKey;
        String token = md5(tokenStr);

        // 構造完整請求體
        JSONObject payload = new JSONObject();
        payload.put("Metering", meteringStr);
        payload.put("Token", token);
        return payload;
    }

    // === MD5 加密方法 === 
    private static String md5(String input) throws Exception {
        MessageDigest md = MessageDigest.getInstance("MD5");
        byte[] messageDigest = md.digest(input.getBytes());
        StringBuilder hexString = new StringBuilder();
        for (byte b : messageDigest) {
            String hex = Integer.toHexString(0xff & b);
            if (hex.length() == 1) hexString.append('0');
            hexString.append(hex);
        }
        return hexString.toString();
    }
}

運行樣本:

image

說明

確保專案中包含 org.json 庫(如 Maven 依賴):

<dependency>
    <groupId>org.json</groupId>
    <artifactId>json</artifactId>
    <version>20230618</version>
</dependency>

錯誤碼

錯誤碼

錯誤資訊

描述

OperationDenied

The serviceInstance does not supported push metering data.

非隨用隨付服務執行個體不支援推送。

Only metering entities classified as Custom and associated with a service can be pushed. The entity ${EntityId} is invalid.

計量項目****不支援推送,需要設定為服務商上報且完成計量項目綁定。

MissingParameter.${parametersName}

The input parameter "${parametersName}" that is mandatory for processing this request is not supplied.

參數缺失。

InvalidParameter.${parametersName}

The provided parameter "${parametersName}" is invalid.

參數非法。

EntityNotExist.ServiceInstance

The specified service instance cannot be found.

服務執行個體不存在(非計算巢建立的ECS)。