使用EAS提供的官方SDK進行服務調用,可以有效減少編寫調用邏輯的時間並提高調用穩定性。本文介紹官方Java SDK介面詳情。同時,以字串輸入輸出、TensorFlow輸入輸出、QueueService用戶端和請求資料壓縮為例,提供了使用Java SDK進行服務調用的完整程式樣本。
添加依賴項
使用Java編寫用戶端代碼時,在Maven工程中使用EAS Java SDK,必須在pom.xml檔案<dependencies>中添加eas-sdk的依賴,樣本如下,最新版本以Maven倉庫中顯示的為準。
<dependency>
<groupId>com.aliyun.openservices.eas</groupId>
<artifactId>eas-sdk</artifactId>
<version>2.0.20</version>
</dependency>
EAS2.0.5及以上版本增加了QueueService用戶端功能,支援多優先順序非同步佇列服務。如果需要使用該功能,為避免依賴版本衝突,您還需自行添加如下兩個依賴,並修改這兩個依賴至合適版本:
<dependency>
<groupId>org.java-websocket</groupId>
<artifactId>Java-WebSocket</artifactId>
<version>1.5.1</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.1</version>
</dependency>
介面列表
類 | 介面 | 描述 |
PredictClient |
|
|
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
| 功能:自訂請求 URL。 | |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
HttpConfig |
|
|
|
| |
|
| |
|
| |
|
| |
|
| |
| 返回最近一次調用的狀態代碼。 | |
| 返回最近一次調用的狀態資訊。 | |
TFRequest |
|
|
|
| |
|
| |
TFResponse |
|
|
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
QueueClient |
|
|
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
| 功能:關閉佇列服務。 | |
DataFrame |
|
|
|
| |
|
|
程式樣本
字串輸入輸出樣本
對於使用自訂Processor部署服務的使用者而言,通常採用字串進行服務調用(例如,PMML模型服務的調用),具體的Demo程式如下。
import com.aliyun.openservices.eas.predict.http.PredictClient;
import com.aliyun.openservices.eas.predict.http.HttpConfig;
public class TestString {
public static void main(String[] args) throws Exception {
// 啟動並初始化用戶端, client對象需要共用,千萬不可每個請求都建立一個client對象。
PredictClient client = new PredictClient(new HttpConfig());
client.setToken("YWFlMDYyZDNmNTc3M2I3MzMwYmY0MmYwM2Y2MTYxMTY4NzBkNzdj****");
// 如果要使用網路直連功能,需使用setDirectEndpoint方法
// 如 client.setDirectEndpoint("pai-eas-vpc.cn-shanghai.aliyuncs.com");
// 網路直連需打通在EAS控制台開通,提供用於訪問EAS服務的源vswitch,打通後可繞過網關以軟負載的方式直接存取服務的執行個體,以實現更好的穩定性和效能。
// 註:普通網關訪問時請使用以使用者uid為開頭的endpoint,在eas控制台服務的調用資訊中可查到。直連訪問時請使用如上的pai-eas-vpc.{region_id}.aliyuncs.com的網域名稱進行訪問。
client.setEndpoint("182848887922****.vpc.cn-shanghai.pai-eas.aliyuncs.com");
client.setModelName("scorecard_pmml_example");
// 輸入字串定義
String request = "[{\"money_credit\": 3000000}, {\"money_credit\": 10000}]";
System.out.println(request);
// 通過eas返回字串
try {
String response = client.predict(request);
System.out.println(response);
} catch (Exception e) {
e.printStackTrace();
}
// 關閉用戶端
client.shutdown();
return;
}
}
如上述程式所示,使用Java SDK調用服務的流程如下:
通過
PredictClient
介面建立用戶端服務物件。如果在程式中需要使用多個服務,則建立多個Client對象。為PredictClient對象配置Token、Endpoint及ModelName。
構造STRING類型的request作為輸入,通過
client.predict
發送HTTP請求,系統返回response。
TensorFlow輸入輸出樣本
使用TensorFlow的使用者,需要將TFRequest和TFResponse分別作為輸入和輸出資料格式,具體Demo樣本如下。
import java.util.List;
import com.aliyun.openservices.eas.predict.http.PredictClient;
import com.aliyun.openservices.eas.predict.http.HttpConfig;
import com.aliyun.openservices.eas.predict.request.TFDataType;
import com.aliyun.openservices.eas.predict.request.TFRequest;
import com.aliyun.openservices.eas.predict.response.TFResponse;
public class TestTF {
public static TFRequest buildPredictRequest() {
TFRequest request = new TFRequest();
request.setSignatureName("predict_images");
float[] content = new float[784];
for (int i = 0; i < content.length; i++) {
content[i] = (float) 0.0;
}
request.addFeed("images", TFDataType.DT_FLOAT, new long[]{1, 784}, content);
request.addFetch("scores");
return request;
}
public static void main(String[] args) throws Exception {
PredictClient client = new PredictClient(new HttpConfig());
// 如果要使用網路直連功能,需使用setDirectEndpoint方法。
// 如 client.setDirectEndpoint("pai-eas-vpc.cn-shanghai.aliyuncs.com");
// 網路直連需打通在EAS控制台開通,提供用於訪問EAS服務的源vswitch,打通後可繞過網關以軟負載的方式直接存取服務的執行個體,以實現更好的穩定性和效能。
// 註:普通網關訪問時請使用以使用者uid為開頭的endpoint,在eas控制台服務的調用資訊中可查到。直連訪問時請使用如上的pai-eas-vpc.{region_id}.aliyuncs.com的網域名稱進行訪問。
client.setEndpoint("182848887922****.vpc.cn-shanghai.pai-eas.aliyuncs.com");
client.setModelName("mnist_saved_model_example");
client.setToken("YTg2ZjE0ZjM4ZmE3OTc0NzYxZDMyNmYzMTJjZTQ1YmU0N2FjMTAy****");
long startTime = System.currentTimeMillis();
int count = 1000;
for (int i = 0; i < count; i++) {
try {
TFResponse response = client.predict(buildPredictRequest());
List<Float> result = response.getFloatVals("scores");
System.out.print("Predict Result: [");
for (int j = 0; j < result.size(); j++) {
System.out.print(result.get(j).floatValue());
if (j != result.size() - 1) {
System.out.print(", ");
}
}
System.out.print("]\n");
} catch (Exception e) {
e.printStackTrace();
}
}
long endTime = System.currentTimeMillis();
System.out.println("Spend Time: " + (endTime - startTime) + "ms");
client.shutdown();
}
}
如上述程式所示,使用Java SDK調用TensorFlow服務的流程如下:
通過
PredictClient
介面建立用戶端服務物件。如果在程式中需要使用多個服務,則建立多個Client對象。為PredictClient對象配置Token、Endpoint及ModelName。
使用TFRequest類封裝輸入資料,使用TFResponse類封裝輸出資料。
QueueService用戶端樣本
支援通過QueueClient介面使用佇列服務功能,具體demo樣本如下:
import com.alibaba.fastjson.JSONObject;
import com.aliyun.openservices.eas.predict.http.HttpConfig;
import com.aliyun.openservices.eas.predict.http.QueueClient;
import com.aliyun.openservices.eas.predict.queue_client.QueueUser;
import com.aliyun.openservices.eas.predict.queue_client.WebSocketWatcher;
public class DemoWatch {
public static void main(String[] args) throws Exception {
/** 建立佇列服務用戶端 */
String queueEndpoint = "18*******.cn-hangzhou.pai-eas.aliyuncs.com";
String inputQueueName = "test_queue_service";
String sinkQueueName = "test_queue_service/sink";
String queueToken = "test-token";
/** 輸入隊列,往輸入隊列添加資料,推理服務會自動從輸入隊列中讀取請求資料 */
QueueClient inputQueue =
new QueueClient(queueEndpoint, inputQueueName, queueToken, new HttpConfig(), new QueueUser());
/** 輸出隊列,推理服務處理輸入資料後會將結果寫入輸出隊列 */
QueueClient sinkQueue =
new QueueClient(queueEndpoint, sinkQueueName, queueToken, new HttpConfig(), new QueueUser());
/** 清除隊列資料!!!請謹慎使用 */
inputQueue.clear();
sinkQueue.clear();
/** 往輸入隊列添加資料 */
int count = 10;
for (int i = 0; i < count; ++i) {
String data = Integer.toString(i);
inputQueue.put(data.getBytes(), null);
/** 佇列服務支援多優先順序隊列,可通過put函數設定資料優先順序,預設優先順序為0 */
// inputQueue.put(data.getBytes(), 0L, null);
}
/** 通過watch函數訂閱輸出隊列的資料,視窗大小為5 */
WebSocketWatcher watcher = sinkQueue.watch(0L, 5L, false, true, null);
/** WatchConfig參數可自訂重試次數、稍候再試(單位為秒)、是否無限重試;未配置WatchConfig則預設重試次數:3,稍候再試:5 */
// WebSocketWatcher watcher = sink_queue.watch(0L, 5L, false, true, null, new WatchConfig(3, 1));
// WebSocketWatcher watcher = sink_queue.watch(0L, 5L, false, true, null, new WatchConfig(true, 10));
/** 擷取輸出資料 */
for (int i = 0; i < count; ++i) {
try {
/** getDataFrame 函數用於擷取DataFrame資料類,沒有資料時會被阻塞 */
byte[] data = watcher.getDataFrame().getData();
System.out.println("[watch] data = " + new String(data));
} catch (RuntimeException ex) {
System.out.println("[watch] error = " + ex.getMessage());
break;
}
}
/** 關閉已經開啟的watcher對象,每個用戶端執行個體只允許存在一個watcher對象,若watcher對象不關閉,再運行時會報錯 */
watcher.close();
Thread.sleep(2000);
JSONObject attrs = sinkQueue.attributes();
System.out.println(attrs.toString());
/** 關閉用戶端 */
inputQueue.shutdown();
sinkQueue.shutdown();
}
}
如上述程式所示,使用Java SDK調用服務的流程如下:
通過
QueueClient
介面建立佇列服務用戶端對象。如果建立了推理服務,需同時建立輸入隊列和輸出隊列對象。使用
put()
函數向輸入隊列中發送資料;使用watch()
函數從輸出隊列中訂閱資料。說明現實情境中,發送資料和訂閱資料可以由不同的線程處理,本樣本中為了示範方便,在同一線程中完成,先Put資料,後Watch結果。
請求資料壓縮樣本
對於請求資料量較大的情況,EAS支援將資料壓縮之後再發送至服務端,目前支援Zlib和Gzip兩種壓縮格式。該功能需要在服務配置中指定相應的rpc.decompressor
才會生效。
服務配置如下所示:
"metadata": {
"rpc": {
"decompressor": "zlib"
}
}
SDK代碼調用樣本如下:
package com.aliyun.openservices.eas.predict;
import com.aliyun.openservices.eas.predict.http.Compressor;
import com.aliyun.openservices.eas.predict.http.PredictClient;
import com.aliyun.openservices.eas.predict.http.HttpConfig;
public class TestString {
public static void main(String[] args) throws Exception{
// 啟動並初始化用戶端。
PredictClient client = new PredictClient(new HttpConfig());
client.setEndpoint("18*******.cn-hangzhou.pai-eas.aliyuncs.com");
client.setModelName("echo_compress");
client.setToken("YzZjZjQwN2E4NGRkMDMxNDk5NzhhZDcwZDBjOTZjOGYwZDYxZGM2****");
// 或者使用Compressor.Gzip。
client.setCompressor(Compressor.Zlib);
// 輸入字串定義。
String request = "[{\"money_credit\": 3000000}, {\"money_credit\": 10000}]";
System.out.println(request);
// 通過eas返回字串。
String response = client.predict(request);
System.out.println(response);
// 關閉用戶端。
client.shutdown();
return;
}
}
相關文檔
在服務調用時,您可以通過查看訪問服務返回的狀態代碼來確定請求執行結果,具體的狀態代碼請參見附錄:服務狀態代碼說明。
更多調用方式,請參見服務調用方式。