阿裏雲競價實例OpenApi入門實踐
阿裏雲競價實例OpenApi入門實踐
目的
本文目標是介紹開發者如何通過阿裏雲ECS SDK,合理快速的創建需要的SPOT競價實例
準備工作:
- 首先要熟悉了解阿裏雲SDK的基礎知識和調用方法,可以參考SDK 使用說明
- Spot競價實例代碼需要依賴的ECS SDK版本4.2.0 以上,
- 以JAVA POM依賴舉例,修改引入pom依賴:
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>aliyun-java-sdk-core</artifactId>
<version>3.2.8</version>
</dependency>
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>aliyun-java-sdk-ecs</artifactId>
<version>4.2.0</version>
</dependency>
- 目前競價實例灰度開放部分用戶白名單開放,您可以用您的賬號登陸購買頁麵,確認你的賬號是否具備spot購買權限
- 建議您提前通過自定義鏡像來保證SOPT實例可以快速開始自己的業務功能。
哪些地域與規格可以購買競價實例:
典型一個場景,我需要創建一批價格便宜量又足的計算資源,做業務數據處理。
但我不知道去哪個地域去創建需要的計算資源。
我們需要規劃下對計算資源的大致需求:
1. 地域,創建的競價實例哪個地域創建。
2. 規格 根據你的業務需求確定什麼樣規格實例但是由於目前aliyun 每個地域因為售賣比率不同,每個地域可用對外開放售賣的規格存在很大差異。
所以建議通過DesribeZones接口來獲取您的賬戶可創建的地域與規格信息,幫助您選擇地域和規格。
- API名稱: DesribeZones
- API說明:https://help.aliyun.com/document_detail/25610.html
代碼示例:
OpenApiCaller.java
public class OpenApiCaller {
IClientProfile profile;
IAcsClient client;
public OpenApiCaller() {
profile = DefaultProfile.getProfile("cn-hangzhou", AKSUtil.accessKeyId, AKSUtil.accessKeySecret);
client = new DefaultAcsClient(profile);
}
public <T extends AcsResponse> T doAction(AcsRequest<T> var1) {
try {
return client.getAcsResponse(var1);
} catch (Throwable e) {
e.printStackTrace();
return null;
}
}
}
DescribeZonesSample.java
public class DescribeZonesSample {
public static void main(String[] args) {
OpenApiCaller caller = new OpenApiCaller();
DescribeZonesRequest request = new DescribeZonesRequest();
request.setRegionId("cn-zhangjiakou");//可以通過DescribeRegionsRequest獲取每個地域的regionId
request.setSpotStrategy("SpotWithPriceLimit");//對於查詢是否可購買競價實例此項必填
request.setInstanceChargeType("PostPaid");//後付費模式,競價實例必須是後付費模式
DescribeZonesResponse response = caller.doAction(request);
System.out.println(JSON.toJSONString(response));
}
}
輸出結果:
{
"requestId": "388D6321-E587-470C-8CFA-8985E2963DAE",
"zones": [
{
"localName": "華北 3 可用區 A",
"zoneId": "cn-zhangjiakou-a",
"availableDiskCategories": [
"cloud_ssd",
"cloud_efficiency"
],
"availableInstanceTypes": [
"ecs.e4.large",
"ecs.n4.4xlarge",
"ecs.sn2.medium",
"ecs.i1.2xlarge",
"ecs.se1.2xlarge",
"ecs.n4.xlarge",
"ecs.se1ne.2xlarge",
"ecs.se1.large",
"ecs.sn2.xlarge",
"ecs.se1ne.xlarge",
"ecs.xn4.small",
"ecs.sn2ne.4xlarge",
"ecs.se1ne.4xlarge",
"ecs.sn1.medium",
"ecs.n4.8xlarge",
"ecs.mn4.large",
"ecs.e4.2xlarge",
"ecs.mn4.2xlarge",
"ecs.mn4.8xlarge",
"ecs.n4.2xlarge",
"ecs.e4.xlarge",
"ecs.sn2ne.large",
"ecs.sn2ne.xlarge",
"ecs.sn1ne.large",
"ecs.n4.large",
"ecs.sn1.3xlarge",
"ecs.e4.4xlarge",
"ecs.sn1ne.2xlarge",
"ecs.e4.small",
"ecs.i1.4xlarge",
"ecs.se1.4xlarge",
"ecs.sn2ne.2xlarge",
"ecs.sn2.3xlarge",
"ecs.i1.xlarge",
"ecs.n4.small",
"ecs.sn1ne.4xlarge",
"ecs.mn4.4xlarge",
"ecs.sn1ne.xlarge",
"ecs.se1ne.large",
"ecs.sn2.large",
"ecs.i1-c5d1.4xlarge",
"ecs.sn1.xlarge",
"ecs.sn1.large",
"ecs.mn4.small",
"ecs.mn4.xlarge",
"ecs.se1.xlarge"
],
"availableResourceCreation": [
"VSwitch",
"IoOptimized",
"Instance",
"Disk"
],
"availableResources": [
{
"dataDiskCategories": [
"cloud_ssd",
"cloud_efficiency"
],
"instanceGenerations": [
"ecs-3",
"ecs-2"
],
"instanceTypeFamilies": [
"ecs.mn4",
"ecs.sn1",
"ecs.sn2",
"ecs.sn1ne",
"ecs.xn4",
"ecs.i1",
"ecs.se1",
"ecs.e4",
"ecs.n4",
"ecs.se1ne",
"ecs.sn2ne"
],
"instanceTypes": [
"ecs.n4.4xlarge",
"ecs.sn2.medium",
"ecs.i1.2xlarge",
"ecs.se1.2xlarge",
"ecs.n4.xlarge",
"ecs.se1ne.2xlarge",
"ecs.se1.large",
"ecs.sn2.xlarge",
"ecs.se1ne.xlarge",
"ecs.xn4.small",
"ecs.sn2ne.4xlarge",
"ecs.se1ne.4xlarge",
"ecs.sn1.medium",
"ecs.n4.8xlarge",
"ecs.mn4.large",
"ecs.mn4.2xlarge",
"ecs.mn4.8xlarge",
"ecs.n4.2xlarge",
"ecs.sn2ne.large",
"ecs.sn2ne.xlarge",
"ecs.sn1ne.large",
"ecs.n4.large",
"ecs.sn1.3xlarge",
"ecs.sn1ne.2xlarge",
"ecs.e4.small",
"ecs.i1.4xlarge",
"ecs.se1.4xlarge",
"ecs.sn2ne.2xlarge",
"ecs.sn2.3xlarge",
"ecs.i1.xlarge",
"ecs.n4.small",
"ecs.sn1ne.4xlarge",
"ecs.mn4.4xlarge",
"ecs.sn1ne.xlarge",
"ecs.se1ne.large",
"ecs.sn2.large",
"ecs.i1-c5d1.4xlarge",
"ecs.sn1.xlarge",
"ecs.sn1.large",
"ecs.mn4.small",
"ecs.mn4.xlarge",
"ecs.se1.xlarge"
],
"ioOptimized": true,
"networkTypes": [
"vpc"
],
"systemDiskCategories": [
"cloud_ssd",
"cloud_efficiency"
]
}
],
"availableVolumeCategories": [
"san_ssd",
"san_efficiency"
]
}
]
}
通過查詢spot曆史價格接口來獲得最佳性價比的地域,規格信息
通過上一步我們可以基本確定哪個可用區可以生產的哪些具體規格,有了這些信息就可以通過
DescribeSpotPriceHistory接口查詢獲取價格曆史變化,最多允許獲取30天內的價格變化數據。
- API名稱:DescribeSpotPriceHistory
- API文檔:https://help.aliyun.com/document_detail/60400.html
- 代碼實例:DescribeSpotPriceHistorySample.java
public class DescribeSpotPriceHistorySample {
public static void main(String[] args) {
OpenApiCaller caller = new OpenApiCaller();
List<DescribeSpotPriceHistoryResponse.SpotPriceType> result = new ArrayList<DescribeSpotPriceHistoryResponse.SpotPriceType>();
int offset = 0;
while (true) {
DescribeSpotPriceHistoryRequest request = new DescribeSpotPriceHistoryRequest();
request.setRegionId("cn-hangzhou");//可以通過DescribeRegionsRequest獲取可購買的每個地域的regionId
request.setZoneId("cn-hangzhou-b");//可用區必填
request.setInstanceType("ecs.sn2.medium");//參考DescribeZones 返回的實例類型,必填
request.setNetworkType("vpc");//參考DescribeZones 返回的網絡類型,必填
// request.setIoOptimized("optimized");//是否Io優化類型,DescribeZones 返回的IoOptimized,選填
// request.setStartTime("2017-09-20T08:45:08Z");//價格開始時間,選填,默認3天內數據
// request.setEndTime("2017-09-28T08:45:08Z");//價格結束時間,選填
request.setOffset(offset);
DescribeSpotPriceHistoryResponse response = caller.doAction(request);
if (response != null && response.getSpotPrices() != null) {
result.addAll(response.getSpotPrices());
}
if (response.getNextOffset() == null || response.getNextOffset() == 0) {
break;
} else {
offset = response.getNextOffset();
}
}
if (!result.isEmpty()) {
for (DescribeSpotPriceHistoryResponse.SpotPriceType spotPriceType : result) {
System.out.println(spotPriceType.getTimestamp() + "--->spotPrice:" + spotPriceType.getSpotPrice() + "---->originPrice:" + spotPriceType.getOriginPrice());
}
System.out.println(result.size());
} else {
}
}
}
- 返回結果
2017-09-26T06:28:55Z--->spotPrice:0.24---->originPrice:1.2
2017-09-26T14:00:00Z--->spotPrice:0.36---->originPrice:1.2
2017-09-26T15:00:00Z--->spotPrice:0.24---->originPrice:1.2
2017-09-27T14:00:00Z--->spotPrice:0.36---->originPrice:1.2
2017-09-27T15:00:00Z--->spotPrice:0.24---->originPrice:1.2
2017-09-28T14:00:00Z--->spotPrice:0.36---->originPrice:1.2
2017-09-28T15:00:00Z--->spotPrice:0.24---->originPrice:1.2
2017-09-29T06:28:55Z--->spotPrice:0.24---->originPrice:1.2
- 重複以上步驟,您可以判斷出該規格資源在可用區的價格變化趨勢和最近價格。
- 簡單的策略通過平均價格和最高價格來決定是否可以接受購買該spot實例。
- 當然從最小成本出發,可以通過更加合理的數據模型來分析價曆史價格數據,隨時調整創建資源的規格和可用區,到達最佳性價比。
創建Spot實例
通過以上過程,我們最終得到可以創建的資源的地域信息,規格屬性,磁盤,網絡等信息。
現在就可以開始真正創建競價實例了。
- API名稱:CreateInstance
- 建議您提前在控製台或者openapi方式 在需要創建vm資源的地區創建好vpc專有網絡,獲取創建參數vswitchId
建議您提前在控製台或者openapi方式 在需要創建vm資源的地區創建安全組,獲取創建參數:SecurityGroupId
示例代碼:CreateInstaneSample.java
public class CreateInstaneSample {
public static void main(String[] args) {
OpenApiCaller caller = new OpenApiCaller();
CreateInstanceRequest request = new CreateInstanceRequest();
request.setRegionId("cn-hangzhou");//地域Id
request.setZoneId("cn-hangzhou-b"); //可用區Id
request.setSecurityGroupId("sg-bp11nhf94ivkdxwb2gd4");//提前創建的安全組Id
request.setImageId("centos_7_03_64_20G_alibase_20170818.vhd");//建議選擇您自己在該地域準備的自定義鏡像
request.setVSwitchId("vsw-bp164cyonthfudn9kj5br");//vpc 類型需要虛擬路由Id
request.setInstanceType("ecs.sn2.medium"); //填入您詢價後需要購買的規格
request.setIoOptimized("optimized");//參考 DescirbeZones返回參數
request.setSystemDiskCategory("cloud_ssd");//參考 DescirbeZones返回參數,多選一 cloud_ssd,cloud_efficiency,cloud
request.setSystemDiskSize(40);
request.setInstanceChargeType("PostPaid");//競價實例必須後付費
request.setSpotStrategy("SpotWithPriceLimit");//SpotWithPriceLimit出價模式,SpotAsPriceGo不用出價,最高按量付費價格
request.setSpotPriceLimit(0.25F);//SpotWithPriceLimit出價模式生效,用戶您能接受的最高價格,單元元每小時,必須高於當前的公共價格才能成功
CreateInstanceResponse response = caller.doAction(request);
System.out.println(response.getInstanceId());
}
}
spot實例中斷
- 競價實例可能會因為價格因素或者其他ecs內部庫存因素會強製回收競價資源,此時會觸發spot的中斷
- 在真正開始釋放vm前 vm 會進入鎖定狀態, 提示vm 將會被自動回收,您可以針對vm 回收狀態來自動化處理實例的退出邏輯
- 目前spot的中斷鎖定狀態可以通過2種方式來感知
vpc 實例可以通過metadata 來獲取
metadata訪問示例:
curl 'https://100.100.100.200/latest/meta-data/instance/spot/termination-time'
返回格式示例:2015-01-05T18:02:00Z,時間為UTC時間,如果返回為空,說明可持續使用
- 通過查詢 describeInstances 返回的OperationLocks 感知是否vm進入準備回收狀態
- openapi獲取鎖定狀態代碼示例:DescribeInstancesSample.java
public class DescribeInstancesSample {
public static void main(String[] args) throws InterruptedException {
OpenApiCaller caller = new OpenApiCaller();
JSONArray allInstances = new JSONArray();
allInstances.addAll(Arrays.asList("i-bp18hgfai8ekoqwo0y2n", "i-bp1ecbyds24ij63w146c"));
while (!allInstances.isEmpty()) {
DescribeInstancesRequest request = new DescribeInstancesRequest();
request.setRegionId("cn-hangzhou");
request.setInstanceIds(allInstances.toJSONString());//指定實例Id,效率最高
DescribeInstancesResponse response = caller.doAction(request);
List<DescribeInstancesResponse.Instance> instanceList = response.getInstances();
if (instanceList != null && !instanceList.isEmpty()) {
for (DescribeInstancesResponse.Instance instance : instanceList) {
System.out.println("result:instance:" + instance.getInstanceId() + ",az:" + instance.getZoneId());
if (instance.getOperationLocks() != null) {
for (DescribeInstancesResponse.Instance.LockReason lockReason : instance.getOperationLocks()) {
System.out.println("instance:" + instance.getInstanceId() + "-->lockReason:" + lockReason.getLockReason() + ",vmStatus:" + instance.getStatus());
if ("Recycling".equals(lockReason.getLockReason())) {
//do your action
System.out.println("spot instance will be recycled immediately, instance id:" + instance.getInstanceId());
allInstances.remove(instance.getInstanceId());
}
}
}
}
System.out.print("try describeInstances again later ...");
Thread.sleep(2 * 60 * 1000);
} else {
break;
}
}
}
}
觸發回收時輸出結果:
instance:i-bp1ecbyds24ij63w146c-->lockReason:Recycling,vmStatus:Stopped
spot instance will be recycled immediately, instance id:i-bp1ecbyds24ij63w146c
啟動,關機,釋放 SPOT競價實例
啟動,停止,釋放實例Spot 實例和其他實例沒有任何區別,本文不再介紹,請參看相關api文檔即可。
最後更新:2017-10-19 15:33:23
上一篇:
Nature重磅:人工智能從0到1, 無師自通完爆阿法狗100-0 | 深度解析
下一篇:
【沉澱】實例遷移、Insert和寫入性能——數倍,甚至數十倍提升,HybridDB for MySQL負責人王騫談自己經曆和收獲
PostgreSQL數據保留窗口功能的使用
撿到iPhone7怎麼解鎖?iPhone 鎖屏密碼忘記手機被鎖怎麼辦?
為什麼Firefox OS對於Mozilla很重要?
從架構到監控報警,支付係統的設計如何步步為營
C++對象模型(一):The Semantics of Constructors The Default Constructor (默認構造函數什麼時候會被創建出來)
你知道眾創空間辦公無線網絡到底有多重要嗎?
人臉識別技術國內機場發展簡史
九度題目1364:v字仇殺隊
利用js生成文本框的setfocus的問題
Yet another nio framework for java