通过实例内部调用PushMeteringData推送计量数据。
接口说明
该命令只支持推送按量付费的计算巢服务实例的计量数据,推送的计量项需要定义为服务商上报。
通过计算巢服务创建的ECS或ACK实例,可以直接在ECS或ACK内部调用该接口推送计量数据。如需采用OpenAPI的方式进行调用,请参见通过OpenAPI调用PushMeteringData。
请求参数
名称 | 类型 | 是否必选 | 描述 | 示例值 |
Metering | String | 是 | 示例中的参数说明如下:
说明
|
|
Token | String | 是 | 用于计算巢对比,判断推送方是否是服务商。 使用MD5加密算法对
|
|
返回参数
名称 | 类型 | 描述 | 示例值 | ||
RequestId | String | 计算巢请求ID。 | e6862d3a-9305-4289-8dd3-9c52a680228b | ||
Success | Boolean | 成功状态标识。 | true | ||
PushMeteringDataRequestId | String | 云市场请求ID。 | 7lc658a2-tr41-****-****-c25es45vc248 | ||
Token | String | 用于服务商对比数字签名。请参见计算巢校验数字签名说明。 | 50130a063c6acf833280d23169898bd4 |
示例
本示例是云市场按量付费的计算巢商品创建的ECS中发起调用。
curl示例
获取ECS地域信息
在调用PushMeteringData前,您需要获取应用部署的ECS地域(regionld)信息。获取到的地域信息会在后续步骤中使用,因此需要服务商记录。
访问如下网址,获得地域信息。
curl http://100.100.100.200/latest/meta-data/region-id
地域返回示例。
cn-hangzhou
准备入参
"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
。
请求示例
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.com
中cn-hangzhou
为步骤1中获取的地域,具体调用时请按实际情况更换地域信息。返回示例
{ "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)
运行示例:
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();
}
}
运行示例:
确保项目中包含 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)。 |