使用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.14</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;
}
}
相關文檔
在服務調用時,您可以通過查看訪問服務返回的狀態碼來確定請求執行結果,具體的狀態碼請參見附錄:服務狀態碼說明。
更多調用方式,請參見調用方式概覽。