阿里雲搶佔例項OpenApi入門實踐
阿里雲競價例項OpenApi入門實踐
目的
本文目標是介紹開發者如何通過阿里雲ECS SDK,合理快速的建立需要的搶佔例項
準備工作:
- 首先要熟悉瞭解阿里雲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>
## 哪些地域與規格可以購買競價例項:
> 典型一個場景,我需要建立一批價格便宜量又足的計算資源,做業務資料處理。
但我不知道去哪個地域去建立需要的計算資源。
我們需要規劃下對計算資源的大致需求:
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
* 介面文件:https://help.aliyun.com/document_detail/25499.html
* 示例程式碼: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種方式來感知
1. vpc 例項可以通過metadata 來獲取
* metadata訪問示例:
curl `http://100.100.100.200/latest/meta-data/instance/spot/termination-time`
返回格式示例:2015-01-05T18:02:00Z,時間為UTC時間,如果返回為空,說明可持續使用
2. 通過查詢 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文件即可。
相關文章
- OpenAPI規範入門API
- 【故障公告】阿里雲搶佔式例項伺服器被釋放引發全站故障阿里伺服器
- TypeScript入門例項TypeScript
- Websocet 入門例項Web
- SoapUI入門例項UI
- Flutter 入門例項Flutter
- Kafka入門例項Kafka
- Struts入門例項
- 阿里雲伺服器ECS購買方式“搶佔式例項”有什麼優缺點?阿里伺服器
- RDS按量付費例項、只讀例項、OPENAPI正式釋出API
- React 入門例項教程React
- ActiveMQ 入門及例項MQ
- 雲伺服器ECS使用OpenAPI管理ECS:使用OpenAPI彈性建立ECS例項伺服器API
- opengl簡單入門例項
- Django+MySQL 例項入門DjangoMySql
- Vue專案入門例項Vue
- React入門學習例項React
- Jquery入門及例項一jQuery
- ECS例項RAM角色實踐
- k8s實踐——HPA實踐例項K8S
- BoltDB 入門實踐
- MQ 入門實踐MQ
- Docker入門實踐Docker
- MyBatis基於Maven入門例項MyBatisMaven
- Web Components 入門例項教程Web
- React 入門-寫個 TodoList 例項React
- React 入門最好的例項-TodoListReact
- 【Oracle】ASM例項安裝入門OracleASM
- Shell程式設計入門例項程式設計
- 阿里雲ros例項阿里ROS
- Python——astroplan庫入門例項(二)PythonAST
- .Net平臺下ActiveMQ入門例項MQ
- 【Akka】Akka入門程式設計例項程式設計
- TypeScript入門與實踐TypeScript
- redux 入門到實踐Redux
- GitHub Actions 入門實踐Github
- locsut 入門與實踐
- Kafka 入門與實踐Kafka