Ce guide explique comment utiliser le SDK Java pour appeler les services de modèle Elastic Algorithm Service (EAS). Il fournit des exemples d'entrées et de sorties ainsi qu'un exemple de programme.
Pour en savoir plus sur les cas d'utilisation et les principes du SDK, reportez-vous à la rubrique SDK d'appel de service.
Prérequis
Pour utiliser le SDK Java EAS dans votre projet Maven, ajoutez la dépendance eas-sdk à la section <dependencies> de votre fichier pom.xml. Pour obtenir la dernière version, consultez le référentiel Maven.
<dependency>
<groupId>com.aliyun.openservices.eas</groupId>
<artifactId>eas-sdk</artifactId>
<version>2.0.20</version>
</dependency>
Le SDK EAS 2.0.5 et versions ultérieures inclut la fonctionnalité de client QueueService pour le service de file d'attente asynchrone à priorités multiples. Pour utiliser cette fonctionnalité et éviter les conflits de dépendances, ajoutez les deux dépendances suivantes et ajustez leurs versions si nécessaire :
<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>
Démarrage rapide
Pour effectuer un appel de service avec le SDK Java, suivez ces trois étapes :
Obtenir les informations d'appel : Sur la page des détails du service dans la console EAS, accédez à l'onglet Call Information pour récupérer le endpoint, le nom du service et le token.
-
Choisir le type de requête et écrire le code : Sélectionnez la classe Request/Response appropriée en fonction du format des données d'entrée de votre modèle, puis rédigez votre code en vous basant sur l'exemple minimal ci-dessous.
RemarqueSi vous avez déployé votre service avec un built-in Processor, le SDK fournit les classes d'entrée et de sortie correspondantes. Par exemple, le TensorFlow Processor intégré correspond à
TFRequest. Pour plus d'informations, consultez la documentation de chaque processeur dans la section Built-in Processors. Exécuter et vérifier : Exécutez le programme client et vérifiez la réponse. En cas d'erreur, reportez-vous au guide Dépannage.
Le code suivant constitue un exemple minimal de bout en bout pour une requête de type chaîne. Pour plus d'exemples, consultez la section Exemples de programmes :
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());
// To use a VPC direct connection, call the setDirectEndpoint method. The format is typically {uid}.vpc.{region-id}.pai-eas.aliyuncs.com.
client.setDirectEndpoint("182848887922****.vpc.cn-shanghai.aliyuncs.com");
// The public endpoint for the EAS service. The format is typically {uid}.{region-id}.pai-eas.aliyuncs.com.
// client.setEndpoint("182848887922****.cn-shanghai.pai-eas.aliyuncs.com");
// The name of the EAS service.
client.setModelName("your_service_name");
client.setToken("YOUR_SERVICE_TOKEN");
// The request path. The complete request URL is http://<endpoint>/api/direct/<modelName>/<requestPath>.
client.setRequestPath("your_custom_path");
// Construct the request body. The supported input classes depend on the SDK. This example uses a String.
String request = "[{}]";
String response = client.predict(request);
System.out.println(response);
client.shutdown();
}
}
Référence de l'API
Le SDK Java met à disposition les classes suivantes :
Groupe | Description de la classe |
Classe cliente principale |
|
Configuration de la connexion |
|
Entrées/sorties |
|
Service de file d'attente |
|
Classe PredictClient
Il s'agit de la classe cliente principale. Elle permet de configurer les informations du service, d'envoyer des requêtes et de recevoir les résultats de prédiction.
API | Description |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| Définit une URL de requête personnalisée. |
|
|
|
|
|
|
|
|
|
|
|
|
Classe HttpConfig
Cette classe configure les paramètres sous-jacents de la connexion HTTP, tels que les délais d'attente, le nombre de threads et le pool de connexions.
API | Description |
|
|
|
Important Ce délai s'applique uniquement après l'établissement de la connexion. Il diffère du délai d'expiration de la requête défini par la méthode |
|
Important Ce délai couvre l'intégralité du cycle de vie de la requête, y compris l'établissement de la connexion, le transfert des données et le traitement côté serveur. Il diffère du délai de lecture défini par la méthode |
|
|
|
|
|
|
|
|
| Renvoie le code d'état du dernier appel d'API. |
| Renvoie le message d'état du dernier appel d'API. |
Classe TFRequest
Construit les données d'entrée pour un modèle TensorFlow.
API | Description |
|
|
|
|
|
|
Classe TFResponse
Analyse et accède aux données de sortie issues d'une prédiction de modèle TensorFlow.
API | Description |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Classe QueueClient
Cette classe interagit avec le service de file d'attente EAS pour produire, consommer et gérer les données.
API | Description |
|
|
|
|
|
|
|
|
|
|
|
|
|
Important Lorsque vous appelez
|
|
|
|
|
| Ferme la connexion au service de file d'attente. |
Classe DataFrame
Wrapper pour un élément de données issu du service de file d'attente.
API | Description |
|
|
|
|
|
|
Exemples de code
Exemples d'inférence synchrone
Choisissez l'exemple qui correspond au format d'entrée et de sortie de votre service.
String
Si vous avez déployé un service avec un processeur personnalisé, vous utilisez généralement des chaînes de caractères pour l'appeler. Cette pratique est courante pour les services de modèles PMML, comme le montre l'exemple suivant.
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 {
// Initialize the client. The client object should be shared. Do not create a new client object for each request.
PredictClient client = new PredictClient(new HttpConfig());
client.setToken("YWFlMDYyZDNmNTc3M2I3MzMwYmY0MmYwM2Y2MTYxMTY4NzBkNzdj****");
// To use a direct network connection, call the setDirectEndpoint method.
// Example: client.setDirectEndpoint("182848887922****.vpc.cn-shanghai.aliyuncs.com");
// To enable a direct network connection, you must enable it in the EAS console and provide the source vSwitch used to access the EAS service. This bypasses the gateway, allowing you to directly access service instances via software load balancing for improved stability and performance.
// Note: For standard gateway access, use the endpoint that starts with your user ID. You can find this endpoint in the "Call Information" of the service in the EAS console. For direct network connections, use a domain name in the format 182848887922****.vpc.{region_id}.aliyuncs.com.
client.setEndpoint("182848887922****.vpc.cn-shanghai.pai-eas.aliyuncs.com");
client.setModelName("scorecard_pmml_example");
// Define the input string.
String request = "[{\"money_credit\": 3000000}, {\"money_credit\": 10000}]";
System.out.println(request);
// Get the response string from EAS.
try {
String response = client.predict(request);
System.out.println(response);
} catch (Exception e) {
e.printStackTrace();
}
// Shut down the client.
client.shutdown();
return;
}
}
TensorFlow
Si vous utilisez un modèle TensorFlow, servez-vous des classes TFRequest et TFResponse pour les entrées et les sorties, comme l'illustre l'exemple ci-dessous.
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());
// To use a direct network connection, call the setDirectEndpoint method. The endpoint format is {uid}.vpc.{region_id}.aliyuncs.com.
// client.setDirectEndpoint("182848887922****.vpc.cn-shanghai.aliyuncs.com");
// For standard gateway access, use the endpoint that starts with your user ID. You can find this endpoint in the "Call Information" of the service in the EAS console.
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();
}
}
Exemple de service de file d'attente
Pour accéder au service de file d'attente, utilisez l'interface QueueClient. L'exemple suivant indique la marche à suivre.
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 {
/** Create a queue service client. */
String queueEndpoint = "18*******.cn-hangzhou.pai-eas.aliyuncs.com";
String inputQueueName = "test_queue_service";
String sinkQueueName = "test_queue_service/sink";
String queueToken = "test-token";
/** The input queue. The inference service automatically reads request data from this queue. */
QueueClient inputQueue =
new QueueClient(queueEndpoint, inputQueueName, queueToken, new HttpConfig(), new QueueUser());
/** The output queue. After the inference service processes the input data, it writes the results to this queue. */
QueueClient sinkQueue =
new QueueClient(queueEndpoint, sinkQueueName, queueToken, new HttpConfig(), new QueueUser());
/** Clear queue data. Use with caution. */
inputQueue.clear();
sinkQueue.clear();
/** Add data to the input queue. */
int count = 10;
for (int i = 0; i < count; ++i) {
String data = Integer.toString(i);
inputQueue.put(data.getBytes(), null);
/** The queue service supports multiple priorities. You can use the put method to set the data priority. The default priority is 0. */
// inputQueue.put(data.getBytes(), 0L, null);
}
/** Use the watch method to subscribe to data from the output queue. The window size is 5. */
WebSocketWatcher watcher = sinkQueue.watch(0L, 5L, false, true, null);
/** Use the WatchConfig parameter to customize the number of retries, retry interval (in seconds), and whether to retry indefinitely. If you do not configure WatchConfig, the system defaults to 3 retries with a 5-second interval. */
// 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));
/** Get the output data. */
for (int i = 0; i < count; ++i) {
try {
/** The getDataFrame() method retrieves DataFrame data. This call blocks until data is available. */
byte[] data = watcher.getDataFrame().getData();
System.out.println("[watch] data = " + new String(data));
} catch (RuntimeException ex) {
System.out.println("[watch] error = " + ex.getMessage());
break;
}
}
/** Close the watcher object. Each client instance supports only one watcher object. If you do not close the watcher, an error occurs on the next run. */
watcher.close();
Thread.sleep(2000);
JSONObject attrs = sinkQueue.attributes();
System.out.println(attrs.toString());
/** Shut down the clients. */
inputQueue.shutdown();
sinkQueue.shutdown();
}
}
L'appel d'un service avec le SDK Java implique les étapes suivantes :
Utilisez l'interface
QueueClientpour créer un objet client de service de file d'attente. Si vous créez un service d'inférence, vous devez également créer des objets de file d'attente d'entrée et de sortie.-
Servez-vous de la fonction
put()pour envoyer des données à la file d'attente d'entrée, et de la fonctionwatch()pour vous abonner aux données de la file d'attente de sortie.RemarqueDans un environnement de production, vous devriez utiliser des threads distincts pour l'envoi des données et l'abonnement aux données. À des fins de démonstration, cet exemple effectue ces opérations dans le même thread.
Compression des données de requête
Pour les requêtes contenant un grand volume de données, EAS prend en charge la compression des données au format Zlib ou Gzip avant leur envoi au serveur. Pour activer cette fonctionnalité, vous devez spécifier rpc.decompressor dans la configuration du service.
La configuration du service est la suivante :
"metadata": {
"rpc": {
"decompressor": "zlib"
}
}
Voici un exemple de code :
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{
// Initialize the client.
PredictClient client = new PredictClient(new HttpConfig());
client.setEndpoint("18*******.cn-hangzhou.pai-eas.aliyuncs.com");
client.setModelName("echo_compress");
client.setToken("YzZjZjQwN2E4NGRkMDMxNDk5NzhhZDcwZDBjOTZjOGYwZDYxZGM2****");
// You can also use Compressor.Gzip.
client.setCompressor(Compressor.Zlib);
// Define the input string.
String request = "[{\"money_credit\": 3000000}, {\"money_credit\": 10000}]";
System.out.println(request);
// Get the response string from EAS.
String response = client.predict(request);
System.out.println(response);
// Shut down the client.
client.shutdown();
return;
}
}
Dépannage
Pour résoudre les problèmes liés aux exceptions d'appel du Java SDK, y compris les problèmes courants d'authentification, de routage, de connexion et les erreurs côté serveur, consultez la section « Dépannage des exceptions d'appel » dans la rubrique SDK d'appel de service.
Pour obtenir la liste complète des codes d'état de service, la signification des messages d'erreur et les actions recommandées, consultez la rubrique Annexe : Codes d'état de service et erreurs courantes.