Este guia explica como usar o Java SDK para chamar services de modelo do Elastic Algorithm Service (EAS) e fornece exemplos de entrada/saída e um programa de amostra.
Para casos de uso e princípios do SDK, consulte SDK de invocação de service.
Pré-requisitos
Para usar o EAS Java SDK em seu projeto Maven, adicione a dependência eas-sdk à seção <dependencies> do seu arquivo pom.xml. Para obter a versão mais recente, verifique o repositório Maven.
<dependency>
<groupId>com.aliyun.openservices.eas</groupId>
<artifactId>eas-sdk</artifactId>
<version>2.0.20</version>
</dependency>
EAS SDK 2.0.5 e versões posteriores incluem a funcionalidade de cliente QueueService para o service de fila assíncrona com múltiplas prioridades. Para utilizar esse recurso e evitar conflitos de dependência, adicione as duas dependências a seguir e ajuste suas versões conforme necessário:
<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>
Início rápido
Para realizar uma chamada de service com o Java SDK, siga estas três etapas:
Obtenha as informações de chamada: Na página de detalhes do service no console EAS, acesse a aba Call Information para obter o endpoint, o nome do service e o token.
-
Escolha um tipo de solicitação e escreva o código: Selecione a classe Request/Response apropriada com base no formato dos dados de entrada do seu modelo e, em seguida, escreva seu código usando o exemplo mínimo abaixo.
NotaSe você implantou seu service com um Processor integrado, o SDK fornece classes de entrada e saída correspondentes. Por exemplo, o TensorFlow Processor integrado corresponde a
TFRequest. Para mais informações, consulte a documentação de cada processor em Processors Integrados. Execute e verifique: Execute o programa cliente e verifique a resposta. Se ocorrer um erro, consulte o guia Solução de problemas.
O código a seguir é um exemplo mínimo de ponta a ponta de uma solicitação de string. Para mais exemplos, consulte Exemplos de Programa:
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();
}
}
Referência da API
O Java SDK fornece as seguintes classes:
|
Grupo |
Descrição da classe |
|
Classe principal do cliente |
|
|
Configuração de conexão |
|
|
Entrada/saída |
|
|
Queue service |
|
Classe PredictClient
Classe principal do cliente. Ela configura as informações do service, envia solicitações e recebe resultados de previsão.
|
API |
Descrição |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Define uma URL de solicitação personalizada. |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Classe HttpConfig
Configura parâmetros subjacentes de conexão HTTP, como timeouts, contagem de threads e pool de conexões.
|
API |
Descrição |
|
|
|
|
|
Importante
Este timeout se aplica somente após o estabelecimento da conexão. Ele difere do timeout de solicitação definido pelo método |
|
|
Importante
Este timeout abrange todo o ciclo de vida da solicitação, incluindo estabelecimento de conexão, transferência de dados e processamento pelo servidor. Ele difere do timeout de leitura definido pelo método |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Retorna o código de status da última chamada de API. |
|
|
Retorna a mensagem de status da última chamada de API. |
Classe TFRequest
Constrói os dados de entrada para um modelo TensorFlow.
|
API |
Descrição |
|
|
|
|
|
|
|
|
|
Classe TFResponse
Analisa e acessa os dados de saída de uma previsão de modelo TensorFlow.
|
API |
Descrição |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Classe QueueClient
Interage com o queue service do EAS para produzir, consumir e gerenciar dados.
|
API |
Descrição |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Importante
Ao chamar
|
|
|
|
|
|
|
|
|
Fecha a conexão com o queue service. |
Classe DataFrame
Um wrapper para um item de dados do queue service.
|
API |
Descrição |
|
|
|
|
|
|
|
|
|
Exemplos de código
Exemplos de inferência síncrona
Escolha o exemplo que corresponde ao formato de entrada e saída do seu service.
String
Se você implantou um service com um processor personalizado, normalmente usa strings para chamá-lo. Essa prática é comum para services de modelo PMML, conforme mostra o exemplo a seguir.
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
Se você usar um modelo TensorFlow, utilize as classes TFRequest e TFResponse para entrada e saída, conforme demonstra o exemplo a seguir.
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();
}
}
Exemplo de queue service
Para acessar o queue service, use a interface QueueClient. O exemplo a seguir mostra como fazer isso.
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();
}
}
Chamar um service com o Java SDK envolve as seguintes etapas:
Use a interface
QueueClientpara criar um objeto cliente do queue service. Se você criar um service de inferência, também deverá criar objetos de fila de entrada e fila de saída.-
Use a função
put()para enviar dados para a fila de entrada e a funçãowatch()para assinar dados da fila de saída.NotaEm um ambiente de produção, use threads separadas para enviar dados e assinar dados. Para fins de demonstração, este exemplo executa essas operações na mesma thread.
Compactação de dados de solicitação
Para solicitações que contêm uma grande quantidade de dados, o EAS suporta a compactação dos dados usando o formato Zlib ou Gzip antes de enviá-los ao lado do servidor. Para ativar esse recurso, especifique rpc.decompressor na configuração do service.
A configuração do service é a seguinte:
"metadata": {
"rpc": {
"decompressor": "zlib"
}
}
Segue um exemplo de código:
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;
}
}
Solução de problemas
Para solucionar problemas de Java SDK exceções de invocação, incluindo problemas comuns com autenticação, roteamento, conexão e erros do lado do servidor, consulte a seção "Solução de problemas de exceções de invocação" em SDK de Invocação de Service.
Para obter uma lista completa de códigos de status do service, significados de mensagens de erro e ações recomendadas, consulte Apêndice: Códigos de Status do Service e Erros Comuns.