Le traduzioni sono generate tramite traduzione automatica. In caso di conflitto tra il contenuto di una traduzione e la versione originale in Inglese, quest'ultima prevarrà.
Questa guida alla programmazione fornisce un orientamento per i programmatori che desiderano utilizzare Amazon DynamoDB con Java. La guida tratta diversi concetti, tra cui i livelli di astrazione, la gestione della configurazione, la gestione degli errori, il controllo delle politiche di ripetizione dei tentativi e la gestione di keep-alive.
Argomenti
Informazioni su AWS SDK for Java 2.x
È possibile accedere a DynamoDB da Java utilizzando il file ufficiale. AWS SDK for Java La versione SDK per Java è disponibile in due versioni: 1.x e 2.x. La versione end-of-support 1.x è stata annunciata
Per informazioni sulla manutenzione e il supporto per AWS SDKs, consulta la politica di manutenzione di AWS SDK and Tools e la matrice di supporto della versione Tools nella AWS SDKs and Tools Reference AWS SDKsGuide.
AWS SDK for Java 2.x Si tratta di un'importante riscrittura del codice base 1.x. La versione SDK per Java 2.x supporta le moderne funzionalità Java, come l'I/O non bloccante introdotto in Java 8. The SDK for Java 2.x aggiunge anche il supporto per implementazioni HTTP client collegabili per fornire maggiore flessibilità di connessione di rete e opzioni di configurazione.
Un cambiamento evidente tra SDK for Java 1.x e for Java 2.x è l'SDKuso di un nuovo nome di pacchetto. Java 1.x SDK utilizza il nome del com.amazonaws
pacchetto, mentre Java 2.x lo utilizza. SDK software.amazon.awssdk
Allo stesso modo, gli artefatti Maven per Java 1.x SDK utilizzano, mentre gli artefatti Java 2.x utilizzano com.amazonaws
groupId
il. SDK software.amazon.awssdk
groupId
Importante
La versione AWS SDK for Java 1.x ha un pacchetto DynamoDB denominato. com.amazonaws.dynamodbv2
La «v2" nel nome del pacchetto non indica che sia per Java 2 (J2SE). Piuttosto, «v2" indica che il pacchetto supporta la seconda versione di DynamoDB di basso livello API anziché la versione originale di basso livello. API
Support per le versioni Java
AWS SDK for Java 2.x Fornisce il supporto completo per le versioni Java
Nozioni di base su AWS SDK for Java 2.x
Il seguente tutorial mostra come usare Apache Maven
Per completare questo tutorial, procedi come segue:
Fase 1: Configurazione per questo tutorial
Prima di iniziare questo tutorial, è necessario quanto segue:
-
Autorizzazione ad accedere a DynamoDB.
-
Un ambiente di sviluppo Java configurato con accesso Single Sign-On all'utilizzo di. Servizi AWS Portale di accesso AWS
Per configurare questo tutorial, segui le istruzioni riportate nella panoramica sulla configurazione nella Guida per gli AWS SDK for Java 2.x sviluppatori. Dopo aver configurato l'ambiente di sviluppo con l'accesso Single Sign-On per Java SDK e aver avuto una sessione attiva sul portale di AWS accesso, continuate con la Fase 2 di questo tutorial.
Fase 2: Creare il progetto
Per creare il progetto per questo tutorial, esegui un comando Maven che richiede input su come configurare il progetto. Dopo aver inserito e confermato tutti gli input, Maven completa la creazione del progetto creando un pom.xml
file e creando file Java stub.
-
Apri un terminale o una finestra del prompt dei comandi e accedi a una directory a tua scelta, ad esempio la tua cartella o.
Desktop
Home
-
Immettete il seguente comando nel terminale, quindi premete Invio.
mvn archetype:generate \ -DarchetypeGroupId=software.amazon.awssdk \ -DarchetypeArtifactId=archetype-app-quickstart \ -DarchetypeVersion=2.22.0
-
Per ogni prompt, inserisci il valore elencato nella seconda colonna.
Prompt Valore da inserire Define value for property 'service':
dynamodb
Define value for property 'httpClient'
:apache-client
Define value for property 'nativeImage'
:false
Define value for property 'credentialProvider'
identity-center
Define value for property 'groupId':
org.example
Define value for property 'artifactId':
getstarted
Define value for property 'version' 1.0-SNAPSHOT:
<Enter>
Define value for property 'package' org.example:
<Enter>
-
Dopo aver inserito l'ultimo valore, Maven elenca le scelte che hai fatto. Per confermare, inserisci Y. In alternativa, inserisci N, quindi inserisci nuovamente le tue scelte.
Maven crea una cartella di progetto denominata getstarted
in base al artifactId
valore che hai inserito. All'interno della getstarted
cartella, trova un file con un nome README.md
che puoi rivedere, un pom.xml
file e una src
directory.
Maven crea il seguente albero di cartelle.
getstarted ├── README.md ├── pom.xml └── src ├── main │ ├── java │ │ └── org │ │ └── example │ │ ├── App.java │ │ ├── DependencyFactory.java │ │ └── Handler.java │ └── resources │ └── simplelogger.properties └── test └── java └── org └── example └── HandlerTest.java 10 directories, 7 files
Quanto segue mostra il contenuto del file di progetto. pom.xml
La dependencyManagement
sezione contiene una dipendenza da e la AWS SDK for Java 2.xdependencies
sezione ha una dipendenza per DynamoDB. La specificazione di queste dipendenze impone a Maven di includere i file pertinenti nel percorso della classe Java. .jar
Per impostazione predefinita, AWS SDK non include tutte le classi per tutti. Servizi AWS Per DynamoDB, se utilizzi l'interfaccia di basso livello, dovresti avere una dipendenza dall'artefatto. dynamodb
Oppure, se si utilizza l'interfaccia di alto livello, sull'artefatto. dynamodb-enhanced
Se non includi le dipendenze pertinenti, il codice non può essere compilato. Il progetto utilizza Java 1.8 a causa del 1.8
valore delle proprietà maven.compiler.source
andmaven.compiler.target
.
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.example</groupId>
<artifactId>getstarted</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<maven.shade.plugin.version>3.2.1</maven.shade.plugin.version>
<maven.compiler.plugin.version>3.6.1</maven.compiler.plugin.version>
<exec-maven-plugin.version>1.6.0</exec-maven-plugin.version>
<aws.java.sdk.version>2.22.0</aws.java.sdk.version> <-------- SDK version picked up from archetype version
.
<slf4j.version>1.7.28</slf4j.version>
<junit5.version>5.8.1</junit5.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>software.amazon.awssdk</groupId>
<artifactId>bom</artifactId>
<version>${aws.java.sdk.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>software.amazon.awssdk</groupId>
<artifactId>dynamodb</artifactId> <-------- DynamoDB dependency
<exclusions>
<exclusion>
<groupId>software.amazon.awssdk</groupId>
<artifactId>netty-nio-client</artifactId>
</exclusion>
<exclusion>
<groupId>software.amazon.awssdk</groupId>
<artifactId>apache-client</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>software.amazon.awssdk</groupId>
<artifactId>sso</artifactId> <-------- Required for identity center authentication.
</dependency>
<dependency>
<groupId>software.amazon.awssdk</groupId>
<artifactId>ssooidc</artifactId> <-------- Required for identity center authentication.
</dependency>
<dependency>
<groupId>software.amazon.awssdk</groupId>
<artifactId>apache-client</artifactId> <-------- HTTP client specified.
<exclusions>
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${slf4j.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>${slf4j.version}</version>
</dependency>
<!-- Needed to adapt Apache Commons Logging used by Apache HTTP Client to Slf4j to avoid
ClassNotFoundException: org.apache.commons.logging.impl.LogFactoryImpl during runtime -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jcl-over-slf4j</artifactId>
<version>${slf4j.version}</version>
</dependency>
<!-- Test Dependencies -->
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>${junit5.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>${maven.compiler.plugin.version}</version>
</plugin>
</plugins>
</build>
</project>
Passaggio 3: scrivere il codice
Il codice seguente mostra la App
classe creata da Maven. Il main
metodo è il punto di ingresso nell'applicazione, che crea un'istanza della Handler
classe e quindi ne sendRequest
chiama il metodo.
package org.example;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class App {
private static final Logger logger = LoggerFactory.getLogger(App.class);
public static void main(String... args) {
logger.info("Application starts");
Handler handler = new Handler();
handler.sendRequest();
logger.info("Application ends");
}
}
La DependencyFactory
classe creata da Maven contiene il metodo dynamoDbClient
factory che crea e restituisce un'istanza. DynamoDbClient
DynamoDbClient
istanza utilizza un'istanza del client basato su Apache. HTTP Questo perché hai specificato apache-client
quando Maven ti ha chiesto quale client usare. HTTP
Il codice seguente mostra la classe DependencyFactory
.
package org.example;
import software.amazon.awssdk.http.apache.ApacheHttpClient;
import software.amazon.awssdk.services.dynamodb.DynamoDbClient;
/**
* The module containing all dependencies required by the {@link Handler}.
*/
public class DependencyFactory {
private DependencyFactory() {}
/**
* @return an instance of DynamoDbClient
*/
public static DynamoDbClient dynamoDbClient() {
return DynamoDbClient.builder()
.httpClientBuilder(ApacheHttpClient.builder())
.build();
}
}
La Handler
classe contiene la logica principale del programma. Quando Handler
viene creata un'istanza di nella App
classe, DependencyFactory
fornisce il DynamoDbClient
servizio client. Il codice utilizza l'DynamoDbClient
istanza per chiamare DynamoDB.
Maven genera la seguente Handler
classe con un commento. TODO
Il passaggio successivo del tutorial sostituisce il TODO
commento con il codice.
package org.example;
import software.amazon.awssdk.services.dynamodb.DynamoDbClient;
public class Handler {
private final DynamoDbClient dynamoDbClient;
public Handler() {
dynamoDbClient = DependencyFactory.dynamoDbClient();
}
public void sendRequest() {
// TODO: invoking the API calls using dynamoDbClient.
}
}
Per compilare la logica, sostituisci l'intero contenuto della Handler
classe con il codice seguente. Il sendRequest
metodo viene compilato e vengono aggiunte le importazioni necessarie.
Il codice seguente utilizza l'DynamoDbClient
Logger
istanza per registrare i nomi di queste tabelle.
package org.example;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import software.amazon.awssdk.services.dynamodb.DynamoDbClient;
import software.amazon.awssdk.services.dynamodb.model.ListTablesResponse;
public class Handler {
private final DynamoDbClient dynamoDbClient;
public Handler() {
dynamoDbClient = DependencyFactory.dynamoDbClient();
}
public void sendRequest() {
Logger logger = LoggerFactory.getLogger(Handler.class);
logger.info("calling the DynamoDB API to get a list of existing tables");
ListTablesResponse response = dynamoDbClient.listTables();
if (!response.hasTableNames()) {
logger.info("No existing tables found for the configured account & region");
} else {
response.tableNames().forEach(tableName -> logger.info("Table: " + tableName));
}
}
}
Fase 4: Compilare ed eseguire l'applicazione
Dopo aver creato il progetto e aver contenuto la Handler
classe completa, create ed eseguite l'applicazione.
-
Assicurati di avere una AWS IAM Identity Center sessione attiva. Per confermare, esegui il comando AWS Command Line Interface (AWS CLI)
aws sts get-caller-identity
e controlla la risposta. Se non hai una sessione attiva, consulta Accedi utilizzando il AWS CLI per le istruzioni. -
Apri un terminale o una finestra del prompt dei comandi e accedi alla directory
getstarted
del progetto. -
Per creare il tuo progetto, esegui il seguente comando:
mvn clean package
-
Per eseguire l'applicazione, esegui il seguente comando:
mvn exec:java -Dexec.mainClass="org.example.App"
Dopo aver visualizzato il file, eliminate l'oggetto, quindi eliminate il bucket.
Riuscito
Se il tuo progetto Maven è stato creato ed eseguito senza errori, allora congratulazioni! Hai creato con successo la tua prima applicazione Java utilizzando SDK per Java 2.x.
Rimozione
Per ripulire le risorse che hai creato durante questo tutorial, elimina la cartella getstarted
del progetto.
Revisione della AWS SDK for Java 2.x
documentazione
La Guida per gli AWS SDK for Java 2.x sviluppatori copre tutti gli aspetti di SDK Across All Servizi AWS. Ti consigliamo di leggere i seguenti argomenti:
-
Migrazione dalla versione 1.x alla 2.x: include una spiegazione dettagliata delle differenze tra 1.x e 2.x. Questo argomento contiene anche istruzioni su come utilizzare entrambe le versioni principali. side-by-side
-
Guida DynamoDB per Java SDK 2.x: mostra come eseguire le operazioni di base di DynamoDB: creazione di una tabella, manipolazione di elementi e recupero di elementi. Questi esempi utilizzano l'interfaccia di basso livello. Java ha diverse interfacce, come spiegato nella sezione seguente:. Interfacce supportate
Suggerimento
Dopo aver esaminato questi argomenti, aggiungi il riferimento ai segnalibri.AWS SDK for Java 2.x API
Interfacce supportate
AWS SDK for Java 2.x Supporta le seguenti interfacce, a seconda del livello di astrazione desiderato.
Argomenti in questa sezione
Interfaccia di basso livello
L'interfaccia di basso livello fornisce una one-to-one mappatura del servizio sottostante. API Ogni API DynamoDB è disponibile tramite questa interfaccia. Ciò significa che l'interfaccia di basso livello può fornire funzionalità complete, ma è spesso più dettagliata e complessa da usare. Ad esempio, è necessario utilizzare .s()
le funzioni per contenere le stringhe e le .n()
funzioni per contenere i numeri. Il seguente esempio di PutIteminserisce un elemento utilizzando l'interfaccia di basso livello.
import org.slf4j.*;
import software.amazon.awssdk.http.crt.AwsCrtHttpClient;
import software.amazon.awssdk.services.dynamodb.DynamoDbClient;
import software.amazon.awssdk.services.dynamodb.model.*;
import java.util.Map;
public class PutItem {
// Create a DynamoDB client with the default settings connected to the DynamoDB
// endpoint in the default region based on the default credentials provider chain.
private static final DynamoDbClient DYNAMODB_CLIENT = DynamoDbClient.create();
private static final Logger LOGGER = LoggerFactory.getLogger(PutItem.class);
private void putItem() {
PutItemResponse response = DYNAMODB_CLIENT.putItem(PutItemRequest.builder()
.item(Map.of(
"pk", AttributeValue.builder().s("123").build(),
"sk", AttributeValue.builder().s("cart#123").build(),
"item_data", AttributeValue.builder().s("YourItemData").build(),
"inventory", AttributeValue.builder().n("500").build()
// ... more attributes ...
))
.returnConsumedCapacity(ReturnConsumedCapacity.TOTAL)
.tableName("YourTableName")
.build());
LOGGER.info("PutItem call consumed [" + response.consumedCapacity().capacityUnits() + "] Write Capacity Unites (WCU)");
}
}
Interfaccia di alto livello
L'interfaccia di alto livello di AWS SDK for Java 2.x si chiama DynamoDB Enhanced Client. Questa interfaccia offre un'esperienza di creazione del codice più idiomatica.
Il client avanzato offre un modo per mappare tra le classi di dati lato client e le tabelle DynamoDB progettate per archiviare tali dati. È possibile definire le relazioni tra le tabelle e le relative classi di modello corrispondenti nel codice. Quindi, puoi fare affidamento su SDK per gestire la manipolazione dei tipi di dati. Per ulteriori informazioni sul client avanzato, consulta DynamoDB Enhanced API Client nella AWS SDK for Java 2.x Developer Guide.
L'esempio seguente PutItemutilizza l'interfaccia di alto livello. In questo esempio, DynamoDbBean
named YourItem
crea un file TableSchema
che ne consente l'uso diretto come input per la putItem()
chiamata.
import org.slf4j.*;
import software.amazon.awssdk.enhanced.dynamodb.*;
import software.amazon.awssdk.enhanced.dynamodb.mapper.annotations.*;
import software.amazon.awssdk.enhanced.dynamodb.model.*;
import software.amazon.awssdk.services.dynamodb.model.ReturnConsumedCapacity;
public class DynamoDbEnhancedClientPutItem {
private static final DynamoDbEnhancedClient ENHANCED_DYNAMODB_CLIENT = DynamoDbEnhancedClient.builder().build();
private static final DynamoDbTable<YourItem> DYNAMODB_TABLE = ENHANCED_DYNAMODB_CLIENT.table("YourTableName", TableSchema.fromBean(YourItem.class));
private static final Logger LOGGER = LoggerFactory.getLogger(PutItem.class);
private void putItem() {
PutItemEnhancedResponse<YourItem> response = DYNAMODB_TABLE.putItemWithResponse(PutItemEnhancedRequest.builder(YourItem.class)
.item(new YourItem("123", "cart#123", "YourItemData", 500))
.returnConsumedCapacity(ReturnConsumedCapacity.TOTAL)
.build());
LOGGER.info("PutItem call consumed [" + response.consumedCapacity().capacityUnits() + "] Write Capacity Unites (WCU)");
}
@DynamoDbBean
public static class YourItem {
public YourItem() {}
public YourItem(String pk, String sk, String itemData, int inventory) {
this.pk = pk;
this.sk = sk;
this.itemData = itemData;
this.inventory = inventory;
}
private String pk;
private String sk;
private String itemData;
private int inventory;
@DynamoDbPartitionKey
public void setPk(String pk) {
this.pk = pk;
}
public String getPk() {
return pk;
}
@DynamoDbSortKey
public void setSk(String sk) {
this.sk = sk;
}
public String getSk() {
return sk;
}
public void setItemData(String itemData) {
this.itemData = itemData;
}
public String getItemData() {
return itemData;
}
public void setInventory(int inventory) {
this.inventory = inventory;
}
public int getInventory() {
return inventory;
}
}
}
La AWS SDK for Java 1.x ha una propria interfaccia di alto livello, a cui spesso si fa riferimento dalla sua classe principale. DynamoDBMapper
AWS SDK for Java 2.x È pubblicato in un pacchetto separato (e artefatto Maven) denominato. software.amazon.awssdk.enhanced.dynamodb
Java 2.x SDK viene spesso indicato con la sua classe principale. DynamoDbEnhancedClient
Interfaccia di alto livello che utilizza classi di dati immutabili
La funzionalità di mappatura del API client avanzato DynamoDB funziona anche con classi di dati immutabili. Una classe immutabile ha solo getter e richiede una classe builder che viene utilizzata per creare istanze della classe. SDK L'immutabilità in Java è uno stile comunemente usato che gli sviluppatori possono utilizzare per creare classi prive di effetti collaterali. Queste classi hanno un comportamento più prevedibile in applicazioni multithread complesse. Invece di utilizzare l'@DynamoDbBean
annotazione come mostrato inHigh-level interface example, le classi immutabili utilizzano l'@DynamoDbImmutable
annotazione, che accetta la classe builder come input.
L'esempio seguente utilizza la classe builder DynamoDbEnhancedClientImmutablePutItem
come input per creare uno schema di tabella. L'esempio fornisce quindi lo schema come input per la PutItemAPIchiamata.
import org.slf4j.*;
import software.amazon.awssdk.enhanced.dynamodb.*;
import software.amazon.awssdk.enhanced.dynamodb.model.*;
import software.amazon.awssdk.services.dynamodb.model.ReturnConsumedCapacity;
public class DynamoDbEnhancedClientImmutablePutItem {
private static final DynamoDbEnhancedClient ENHANCED_DYNAMODB_CLIENT = DynamoDbEnhancedClient.builder().build();
private static final DynamoDbTable<YourImmutableItem> DYNAMODB_TABLE = ENHANCED_DYNAMODB_CLIENT.table("YourTableName", TableSchema.fromImmutableClass(YourImmutableItem.class));
private static final Logger LOGGER = LoggerFactory.getLogger(DynamoDbEnhancedClientImmutablePutItem.class);
private void putItem() {
PutItemEnhancedResponse<YourImmutableItem> response = DYNAMODB_TABLE.putItemWithResponse(PutItemEnhancedRequest.builder(YourImmutableItem.class)
.item(YourImmutableItem.builder()
.pk("123")
.sk("cart#123")
.itemData("YourItemData")
.inventory(500)
.build())
.returnConsumedCapacity(ReturnConsumedCapacity.TOTAL)
.build());
LOGGER.info("PutItem call consumed [" + response.consumedCapacity().capacityUnits() + "] Write Capacity Unites (WCU)");
}
}
L'esempio seguente mostra la classe di dati immutabile.
@DynamoDbImmutable(builder = YourImmutableItem.YourImmutableItemBuilder.class)
class YourImmutableItem {
private final String pk;
private final String sk;
private final String itemData;
private final int inventory;
public YourImmutableItem(YourImmutableItemBuilder builder) {
this.pk = builder.pk;
this.sk = builder.sk;
this.itemData = builder.itemData;
this.inventory = builder.inventory;
}
public static YourImmutableItemBuilder builder() { return new YourImmutableItemBuilder(); }
@DynamoDbPartitionKey
public String getPk() {
return pk;
}
@DynamoDbSortKey
public String getSk() {
return sk;
}
public String getItemData() {
return itemData;
}
public int getInventory() {
return inventory;
}
static final class YourImmutableItemBuilder {
private String pk;
private String sk;
private String itemData;
private int inventory;
private YourImmutableItemBuilder() {}
public YourImmutableItemBuilder pk(String pk) { this.pk = pk; return this; }
public YourImmutableItemBuilder sk(String sk) { this.sk = sk; return this; }
public YourImmutableItemBuilder itemData(String itemData) { this.itemData = itemData; return this; }
public YourImmutableItemBuilder inventory(int inventory) { this.inventory = inventory; return this; }
public YourImmutableItem build() { return new YourImmutableItem(this); }
}
}
Interfaccia di alto livello che utilizza classi di dati immutabili e librerie di generazione boilerplate di terze parti
Le classi di dati immutabili (mostrate nell'esempio precedente) richiedono del codice standard. Ad esempio, la logica getter e setter sulle classi di dati, oltre alle classi. Builder
Le librerie di terze parti, come Project Lombok
L'esempio seguente dimostra come Project Lombok semplifica il codice necessario per utilizzare il client avanzato DynamoDB. API
import org.slf4j.*;
import software.amazon.awssdk.enhanced.dynamodb.*;
import software.amazon.awssdk.enhanced.dynamodb.model.*;
import software.amazon.awssdk.services.dynamodb.model.ReturnConsumedCapacity;
public class DynamoDbEnhancedClientImmutableLombokPutItem {
private static final DynamoDbEnhancedClient ENHANCED_DYNAMODB_CLIENT = DynamoDbEnhancedClient.builder().build();
private static final DynamoDbTable<YourImmutableLombokItem> DYNAMODB_TABLE = ENHANCED_DYNAMODB_CLIENT.table("YourTableName", TableSchema.fromImmutableClass(YourImmutableLombokItem.class));
private static final Logger LOGGER = LoggerFactory.getLogger(DynamoDbEnhancedClientImmutableLombokPutItem.class);
private void putItem() {
PutItemEnhancedResponse<YourImmutableLombokItem> response = DYNAMODB_TABLE.putItemWithResponse(PutItemEnhancedRequest.builder(YourImmutableLombokItem.class)
.item(YourImmutableLombokItem.builder()
.pk("123")
.sk("cart#123")
.itemData("YourItemData")
.inventory(500)
.build())
.returnConsumedCapacity(ReturnConsumedCapacity.TOTAL)
.build());
LOGGER.info("PutItem call consumed [" + response.consumedCapacity().capacityUnits() + "] Write Capacity Unites (WCU)");
}
}
L'esempio seguente mostra l'oggetto dati immutabile della classe di dati immutabili.
import lombok.*;
import software.amazon.awssdk.enhanced.dynamodb.mapper.annotations.*;
@Builder
@DynamoDbImmutable(builder = YourImmutableLombokItem.YourImmutableLombokItemBuilder.class)
@Value
public class YourImmutableLombokItem {
@Getter(onMethod_=@DynamoDbPartitionKey)
String pk;
@Getter(onMethod_=@DynamoDbSortKey)
String sk;
String itemData;
int inventory;
}
La YourImmutableLombokItem
classe utilizza le seguenti annotazioni fornite da Project Lombok e da: AWS SDK
-
@Builder
— Produce un generatore complesso APIs per le classi di dati fornito da Project Lombok. -
@ DynamoDbImmutable
— Identifica la DynamoDbImmutable
classe come annotazione di entità mappabile DynamoDB che fornisce. AWS SDK -
@Value
— La variante immutabile di. @Data
Per impostazione predefinita, tutti i campi vengono resi privati e definitivi e i setter non vengono generati. Project Lombok fornisce questa annotazione.
Interfaccia del documento
L'interfaccia AWS SDK for Java 2.x Document evita la necessità di specificare i descrittori dei tipi di dati. I tipi di dati sono impliciti nella semantica dei dati stessi. Questa interfaccia Document è simile alla AWS SDK for Java 1.x, interfaccia Document, ma con un'interfaccia riprogettata.
Di seguito Document interface example viene PutItem
illustrata la chiamata espressa utilizzando l'interfaccia Document. L'esempio utilizza anche EnhancedDocument. Per eseguire comandi su una tabella DynamoDB utilizzando il API documento avanzato, è necessario innanzitutto associare la tabella allo schema della tabella dei documenti per creare un DynamoDBTable
oggetto risorsa. Il generatore di schemi per tabelle di documenti richiede i provider principali di convertitori di chiavi di indice e attributi.
È possibile utilizzare AttributeConverterProvider.defaultProvider()
per convertire gli attributi del documento di tipi predefiniti. È possibile modificare il comportamento predefinito generale con un'AttributeConverterProvider
implementazione personalizzata. È inoltre possibile modificare il convertitore per un singolo attributo. La guida di riferimento di AWS SDKs and Tools fornisce maggiori dettagli ed esempi su come utilizzare i convertitori personalizzati. Il loro utilizzo principale è per gli attributi delle classi di dominio che non dispongono di un convertitore predefinito. Utilizzando un convertitore personalizzato, è possibile fornire loro SDK le informazioni necessarie per scrivere o leggere su DynamoDB.
import org.slf4j.*;
import software.amazon.awssdk.enhanced.dynamodb.*;
import software.amazon.awssdk.enhanced.dynamodb.document.EnhancedDocument;
import software.amazon.awssdk.enhanced.dynamodb.model.*;
import software.amazon.awssdk.services.dynamodb.model.ReturnConsumedCapacity;
public class DynamoDbEnhancedDocumentClientPutItem {
private static final DynamoDbEnhancedClient ENHANCED_DYNAMODB_CLIENT = DynamoDbEnhancedClient.builder().build();
private static final DynamoDbTable<EnhancedDocument> DYNAMODB_TABLE =
ENHANCED_DYNAMODB_CLIENT.table("YourTableName", TableSchema.documentSchemaBuilder()
.addIndexPartitionKey(TableMetadata.primaryIndexName(),"pk", AttributeValueType.S)
.addIndexSortKey(TableMetadata.primaryIndexName(), "sk", AttributeValueType.S)
.attributeConverterProviders(AttributeConverterProvider.defaultProvider())
.build());
private static final Logger LOGGER = LoggerFactory.getLogger(DynamoDbEnhancedDocumentClientPutItem.class);
private void putItem() {
PutItemEnhancedResponse<EnhancedDocument> response = DYNAMODB_TABLE.putItemWithResponse(
PutItemEnhancedRequest.builder(EnhancedDocument.class)
.item(
EnhancedDocument.builder()
.attributeConverterProviders(AttributeConverterProvider.defaultProvider())
.putString("pk", "123")
.putString("sk", "cart#123")
.putString("item_data", "YourItemData")
.putNumber("inventory", 500)
.build())
.returnConsumedCapacity(ReturnConsumedCapacity.TOTAL)
.build());
LOGGER.info("PutItem call consumed [" + response.consumedCapacity().capacityUnits() + "] Write Capacity Unites (WCU)");
}
}
Per convertire JSON i documenti da e verso i tipi di dati nativi di Amazon DynamoDB, puoi utilizzare i seguenti metodi di utilità:
-
EnhancedDocument.fromJson(String json)
— Crea una nuova EnhancedDocument istanza da una JSON stringa. -
EnhancedDocument.toJson()
— Crea una rappresentazione in JSON formato stringa del documento che è possibile utilizzare nell'applicazione come qualsiasi altro JSON oggetto.
Confronto delle interfacce con un esempio Query
Questa sezione mostra la stessa Query
chiamata espressa utilizzando le varie interfacce. Per ottimizzare i risultati di queste interrogazioni, tenete presente quanto segue:
-
DynamoDB ha come target un valore specifico della chiave di partizione, quindi è necessario specificare completamente la chiave di partizione.
-
Per fare in modo che la query abbia come target solo gli articoli del carrello, la chiave di ordinamento contiene un'espressione di condizione chiave che utilizza.
begins_with
-
In genere limitiamo
limit()
la richiesta a un massimo di 100 articoli restituiti. -
Abbiamo impostato il valore
scanIndexForward
su false. I risultati vengono restituiti nell'ordine di UTF -8 byte, il che di solito significa che l'articolo del carrello con il numero più basso viene restituito per primo. Impostando il valorescanIndexForward
su false, invertiamo l'ordine e l'articolo del carrello con il numero più alto viene restituito per primo. -
Applichiamo un filtro per rimuovere qualsiasi risultato che non corrisponde ai criteri. I dati filtrati consumano la capacità di lettura indipendentemente dal fatto che l'articolo corrisponda al filtro.
Esempio Query
utilizzando l'interfaccia di basso livello
L'esempio seguente esegue una query su una tabella denominata YourTableName
utilizzando un. keyConditionExpression
Ciò limita la query a un valore di chiave di partizione e a un valore di chiave di ordinamento specifici che iniziano con un valore di prefisso specifico. Queste condizioni chiave limitano la quantità di dati letti da DynamoDB. Infine, la query applica un filtro sui dati recuperati da DynamoDB utilizzando un. filterExpression
import org.slf4j.*;
import software.amazon.awssdk.services.dynamodb.DynamoDbClient;
import software.amazon.awssdk.services.dynamodb.model.*;
import java.util.Map;
public class Query {
// Create a DynamoDB client with the default settings connected to the DynamoDB
// endpoint in the default region based on the default credentials provider chain.
private static final DynamoDbClient DYNAMODB_CLIENT = DynamoDbClient.builder().build();
private static final Logger LOGGER = LoggerFactory.getLogger(Query.class);
private static void query() {
QueryResponse response = DYNAMODB_CLIENT.query(QueryRequest.builder()
.expressionAttributeNames(Map.of("#name", "name"))
.expressionAttributeValues(Map.of(
":pk_val", AttributeValue.fromS("id#1"),
":sk_val", AttributeValue.fromS("cart#"),
":name_val", AttributeValue.fromS("SomeName")))
.filterExpression("#name = :name_val")
.keyConditionExpression("pk = :pk_val AND begins_with(sk, :sk_val)")
.limit(100)
.scanIndexForward(false)
.tableName("YourTableName")
.build());
LOGGER.info("nr of items: " + response.count());
LOGGER.info("First item pk: " + response.items().get(0).get("pk"));
LOGGER.info("First item sk: " + response.items().get(0).get("sk"));
}
}
Esempio Query
utilizzando l'interfaccia Document
L'esempio seguente esegue una query su una tabella denominata YourTableName
utilizzando l'interfaccia Document.
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import software.amazon.awssdk.enhanced.dynamodb.*;
import software.amazon.awssdk.enhanced.dynamodb.document.EnhancedDocument;
import software.amazon.awssdk.enhanced.dynamodb.model.*;
import java.util.Map;
public class DynamoDbEnhancedDocumentClientQuery {
// Create a DynamoDB client with the default settings connected to the DynamoDB
// endpoint in the default region based on the default credentials provider chain.
private static final DynamoDbEnhancedClient ENHANCED_DYNAMODB_CLIENT = DynamoDbEnhancedClient.builder().build();
private static final DynamoDbTable<EnhancedDocument> DYNAMODB_TABLE =
ENHANCED_DYNAMODB_CLIENT.table("YourTableName", TableSchema.documentSchemaBuilder()
.addIndexPartitionKey(TableMetadata.primaryIndexName(),"pk", AttributeValueType.S)
.addIndexSortKey(TableMetadata.primaryIndexName(), "sk", AttributeValueType.S)
.attributeConverterProviders(AttributeConverterProvider.defaultProvider())
.build());
private static final Logger LOGGER = LoggerFactory.getLogger(DynamoDbEnhancedDocumentClientQuery.class);
private void query() {
PageIterable<EnhancedDocument> response = DYNAMODB_TABLE.query(QueryEnhancedRequest.builder()
.filterExpression(Expression.builder()
.expression("#name = :name_val")
.expressionNames(Map.of("#name", "name"))
.expressionValues(Map.of(":name_val", AttributeValue.fromS("SomeName")))
.build())
.limit(100)
.queryConditional(QueryConditional.sortBeginsWith(Key.builder()
.partitionValue("id#1")
.sortValue("cart#")
.build()))
.scanIndexForward(false)
.build());
LOGGER.info("nr of items: " + response.items().stream().count());
LOGGER.info("First item pk: " + response.items().iterator().next().getString("pk"));
LOGGER.info("First item sk: " + response.items().iterator().next().getString("sk"));
}
}
Esempio Query
utilizzando l'interfaccia di alto livello
L'esempio seguente esegue una query su una tabella denominata YourTableName
utilizzando il client avanzato DynamoDB. API
import org.slf4j.*;
import software.amazon.awssdk.enhanced.dynamodb.*;
import software.amazon.awssdk.enhanced.dynamodb.mapper.annotations.*;
import software.amazon.awssdk.enhanced.dynamodb.model.*;
import software.amazon.awssdk.services.dynamodb.model.AttributeValue;
import java.util.Map;
public class DynamoDbEnhancedClientQuery {
private static final DynamoDbEnhancedClient ENHANCED_DYNAMODB_CLIENT = DynamoDbEnhancedClient.builder().build();
private static final DynamoDbTable<YourItem> DYNAMODB_TABLE = ENHANCED_DYNAMODB_CLIENT.table("YourTableName", TableSchema.fromBean(DynamoDbEnhancedClientQuery.YourItem.class));
private static final Logger LOGGER = LoggerFactory.getLogger(DynamoDbEnhancedClientQuery.class);
private void query() {
PageIterable<YourItem> response = DYNAMODB_TABLE.query(QueryEnhancedRequest.builder()
.filterExpression(Expression.builder()
.expression("#name = :name_val")
.expressionNames(Map.of("#name", "name"))
.expressionValues(Map.of(":name_val", AttributeValue.fromS("SomeName")))
.build())
.limit(100)
.queryConditional(QueryConditional.sortBeginsWith(Key.builder()
.partitionValue("id#1")
.sortValue("cart#")
.build()))
.scanIndexForward(false)
.build());
LOGGER.info("nr of items: " + response.items().stream().count());
LOGGER.info("First item pk: " + response.items().iterator().next().getPk());
LOGGER.info("First item sk: " + response.items().iterator().next().getSk());
}
@DynamoDbBean
public static class YourItem {
public YourItem() {}
public YourItem(String pk, String sk, String name) {
this.pk = pk;
this.sk = sk;
this.name = name;
}
private String pk;
private String sk;
private String name;
@DynamoDbPartitionKey
public void setPk(String pk) {
this.pk = pk;
}
public String getPk() {
return pk;
}
@DynamoDbSortKey
public void setSk(String sk) {
this.sk = sk;
}
public String getSk() {
return sk;
}
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
}
Interfaccia di alto livello che utilizza classi di dati immutabili
Quando si esegue un'operazione Query
con le classi di dati immutabili di alto livello, il codice è lo stesso dell'esempio di interfaccia di alto livello, ad eccezione della costruzione della classe di entità o. YourItem
YourImmutableItem
Per ulteriori informazioni, consulta l'esempio. PutItem
Interfaccia di alto livello che utilizza classi di dati immutabili e librerie di generazione boilerplate di terze parti
Quando si esegue un'operazione Query
con le classi di dati immutabili di alto livello, il codice è lo stesso dell'esempio di interfaccia di alto livello, ad eccezione della costruzione della classe di entità o. YourItem
YourImmutableLombokItem
Per ulteriori informazioni, consulta l'esempio. PutItem
Esempi di codice aggiuntivi
Per ulteriori esempi di utilizzo di DynamoDB con SDK for Java 2.x, fate riferimento ai seguenti repository di esempi di codice:
Programmazione sincrona e asincrona
AWS SDK for Java 2.x Fornisce client sincroni e asincroni per, Servizi AWS come DynamoDB.
DynamoDbEnhancedClient
Le classi DynamoDbClient
and forniscono metodi sincroni che bloccano l'esecuzione del thread finché il client non riceve una risposta dal servizio. Questo client è il modo più semplice per interagire con DynamoDB se non sono necessarie operazioni asincrone.
DynamoDbEnhancedAsyncClient
Le classi DynamoDbAsyncClient
and forniscono metodi asincroni che ritornano immediatamente e restituiscono il controllo al thread chiamante senza attendere una risposta. Il client non bloccante presenta un vantaggio che sfrutta per un'elevata concorrenza su pochi thread, il che consente una gestione efficiente delle richieste di I/O con risorse di elaborazione minime. Ciò migliora il throughput e la reattività.
AWS SDK for Java 2.x Utilizza il supporto nativo per I/O non bloccanti. La versione AWS SDK for Java 1.x doveva simulare I/O non bloccanti.
I metodi sincroni ritornano prima che sia disponibile una risposta, quindi è necessario un modo per ottenere la risposta quando è pronta. I metodi asincroni in AWS SDK for Java restituiscono un CompletableFuture
get()
o join()
su questi CompletableFuture
oggetti, il codice si blocca finché il risultato non è disponibile. Se li chiami contemporaneamente alla richiesta, il comportamento è simile a una semplice chiamata sincrona.
Per ulteriori informazioni sulla programmazione asincrona, consulta Use asynchronous programming nella Developer Guide.AWS SDK for Java 2.x
HTTPclienti
Per supportare ogni cliente, esiste un HTTP client che gestisce la comunicazione con Servizi AWS. Puoi collegare HTTP client alternativi, scegliendone uno che abbia le caratteristiche più adatte alla tua applicazione. Alcuni sono più leggeri, altri hanno più opzioni di configurazione.
Alcuni HTTP client supportano solo l'uso sincrono, mentre altri supportano solo l'uso asincrono. Per un diagramma di flusso che può aiutarti a selezionare il HTTP client ottimale per il tuo carico di lavoro, consulta i consigli per i HTTPclienti nella Guida per gli sviluppatori.AWS SDK for Java 2.x
L'elenco seguente presenta alcuni dei possibili HTTP client:
Argomenti
Client basato su HTTP Apache
La ApacheHttpClient
ApacheHttpClient
classe, consulta Configurare il HTTP client basato su Apache nella Guida per gli sviluppatori.AWS SDK for Java 2.x
URLConnection
client basato HTTP
La UrlConnectionHttpClient
UrlConnectionHttpClient
classe, consulta Configure the URLConnection based HTTP client nella Developer Guide.AWS SDK for Java 2.x
Client basato su Netty HTTP
La NettyNioAsyncHttpClient
classe supporta client asincroni. È la scelta predefinita per l'uso asincrono. Per informazioni sulla configurazione della NettyNioAsyncHttpClient
classe, consulta Configurare il HTTP client basato su Netty nella Guida per gli sviluppatori.AWS SDK for Java 2.x
AWS CRTclient basato HTTP
Le nuove AwsCrtHttpClient
e AwsCrtAsyncHttpClient
le classi delle librerie AWS Common Runtime (CRT) sono altre opzioni che supportano client sincroni e asincroni. Rispetto ad altri clienti, offre: HTTP AWS CRT
-
Tempo di SDK avvio più rapido
-
Minore ingombro di memoria
-
Tempo di latenza ridotto
-
Gestione dello stato della connessione
-
DNSbilanciamento del carico
Per informazioni sulla configurazione delle AwsCrtAsyncHttpClient
classi AwsCrtHttpClient
and, consulta Configure the AWS CRT based HTTP client nella AWS SDK for Java 2.x Developer Guide.
Il HTTP client AWS CRT basato non è l'impostazione predefinita perché ciò comprometterebbe la compatibilità con le versioni precedenti delle applicazioni esistenti. Tuttavia, per DynamoDB consigliamo di utilizzare AWS CRT il client HTTP basato sia per usi sincronizzati che asincroni.
Per un'introduzione al HTTP client AWS CRT basato, vedi Annuncio della disponibilità del AWS CRT HTTP client nel blog AWS SDK for Java 2.x sugli strumenti per sviluppatori
Configurazione di un client HTTP
Durante la configurazione di un client, puoi fornire varie opzioni di configurazione, tra cui:
-
Impostazione dei timeout per diversi aspetti delle chiamate. API
-
Attivazione di TCP Keep-Alive.
-
Controllo della politica dei tentativi in caso di errori.
-
Specificare gli attributi di esecuzione che le istanze di Execution Interceptor possono modificare. Gli intercettori di esecuzione possono scrivere codice che intercetta l'esecuzione delle richieste e delle risposte. API Ciò consente di eseguire attività come la pubblicazione di metriche e la modifica delle richieste in corso.
-
Aggiungere o manipolare le intestazioni. HTTP
-
Abilitazione del monitoraggio delle metriche delle prestazioni lato client. L'utilizzo di questa funzionalità ti aiuta a raccogliere metriche sui client di servizio nella tua applicazione e ad analizzare l'output in Amazon CloudWatch.
-
Specificare un servizio esecutore alternativo da utilizzare per la pianificazione di attività, come tentativi di riprova asincroni e attività di timeout.
È possibile controllare la configurazione fornendo un oggetto alla classe client del servizio. ClientOverrideConfiguration
Builder
Lo vedrai in alcuni esempi di codice nelle sezioni seguenti.
ClientOverrideConfiguration
Fornisce scelte di configurazione standard. I diversi HTTP client collegabili hanno anche possibilità di configurazione specifiche per l'implementazione.
Argomenti in questa sezione
Configurazione del timeout
È possibile regolare la configurazione del client per controllare vari timeout relativi alle chiamate di servizio. DynamoDB offre latenze inferiori rispetto ad altri. Servizi AWS Pertanto, potresti voler modificare queste proprietà per ridurre i valori di timeout in modo da poter fallire rapidamente in caso di problemi di rete.
È possibile personalizzare il comportamento relativo alla latenza utilizzando ClientOverrideConfiguration
il client DynamoDB o modificando le opzioni di configurazione dettagliate sull'implementazione client sottostante. HTTP
È possibile configurare le seguenti proprietà di impatto utilizzando: ClientOverrideConfiguration
-
apiCallAttemptTimeout
— Il tempo di attesa necessario per il completamento di un singolo tentativo di HTTP richiesta prima di rinunciare e scadere. -
apiCallTimeout
— La quantità di tempo a disposizione del client per eseguire completamente una API chiamata. Ciò include l'esecuzione del gestore delle richieste che consiste in tutte le HTTP richieste, compresi i nuovi tentativi.
AWS SDK for Java 2.x Fornisce valori predefinitiClientOverrideConfiguration
, SDK utilizza invece il valore di timeout del socket per il timeout complessivo della chiamata. API Il timeout del socket ha un valore predefinito di 30 secondi.
RetryMode
Un'altra configurazione relativa alla configurazione del timeout da prendere in considerazione è l'oggetto di RetryMode
configurazione. Questo oggetto di configurazione contiene una raccolta di comportamenti relativi ai tentativi.
Il SDK for Java 2.x supporta le seguenti modalità di riprova:
-
legacy
— La modalità di riprova predefinita se non la si modifica esplicitamente. Questa modalità di riprova è specifica di Java. SDK È caratterizzato da un massimo di tre tentativi, o più per servizi come DynamoDB, che dispone di un massimo di otto tentativi. -
standard
— Denominato «standard» perché è più coerente con gli altri. AWS SDKs Questa modalità attende un periodo di tempo casuale compreso tra 0 ms e 1.000 ms per il primo tentativo. Se è necessario un altro tentativo, questa modalità seleziona un altro tempo casuale da 0 ms a 1.000 ms e lo moltiplica per due. Se è necessario un altro tentativo, esegue la stessa scelta casuale moltiplicata per quattro e così via. Ogni attesa è limitata a 20 secondi. Questa modalità esegue nuovi tentativi su un numero maggiore di condizioni di errore rilevate rispetto allalegacy
modalità. Per DynamoDB, esegue fino a un massimo di tre tentativi, a meno che non si esegua l'override con. numRetries -
adaptive
— Si basa sullastandard
modalità e limita dinamicamente la frequenza delle AWS richieste per massimizzare la percentuale di successo. Ciò può avvenire a scapito della latenza delle richieste. Non consigliamo la modalità di riprova adattiva quando la latenza prevedibile è importante.
È possibile trovare una definizione estesa di queste modalità di ripetizione nell'argomento sul comportamento Riprova nella Guida di riferimento agli strumenti e agli strumenti.AWS SDKs
Criteri relativi ai nuovi tentativi
Tutte le RetryMode
configurazioni hanno un RetryPolicy
RetryCondition
TokenBucketRetryCondition
TokenBucket
Quando un client rileva un errore riutilizzabile, ad esempio un'eccezione di limitazione o un errore temporaneo del server, riprova automaticamente la richiesta. SDK È possibile controllare quante volte e con quale rapidità si verificano questi nuovi tentativi.
Quando si configura un client, è possibile fornire un client RetryPolicy
che supporti i seguenti parametri:
-
numRetries
— Il numero massimo di tentativi da applicare prima che una richiesta venga considerata fallita. Il valore predefinito è 8 indipendentemente dalla modalità di ripetizione utilizzata.avvertimento
Assicuratevi di modificare questo valore predefinito dopo la dovuta considerazione.
-
backoffStrategy
—BackoffStrategy
Da applicare ai nuovi tentativi, FullJitterBackoffStrategy
essendo la strategia predefinita. Questa strategia esegue un ritardo esponenziale tra tentativi aggiuntivi in base al numero o ai tentativi correnti, un ritardo di base e un tempo massimo di backoff. Quindi aggiunge il jitter per fornire un po' di casualità. Il ritardo di base utilizzato nel ritardo esponenziale è di 25 ms indipendentemente dalla modalità di ripetizione. -
retryCondition
—RetryCondition
Determina se riprovare o meno una richiesta. Per impostazione predefinita, riprova un set specifico di codici di HTTP stato ed eccezioni che ritiene riutilizzabili. Per la maggior parte delle situazioni, la configurazione predefinita dovrebbe essere sufficiente.
Il codice seguente fornisce una politica di riprova alternativa. Specifica un totale di cinque tentativi (sei richieste totali). Il primo tentativo deve avvenire dopo un ritardo di circa 100 ms, con ogni tentativo aggiuntivo che raddoppia tale tempo in modo esponenziale, fino a un ritardo massimo di un secondo.
DynamoDbClient client = DynamoDbClient.builder()
.overrideConfiguration(ClientOverrideConfiguration.builder()
.retryPolicy(RetryPolicy.builder()
.backoffStrategy(FullJitterBackoffStrategy.builder()
.baseDelay(Duration.ofMillis(100))
.maxBackoffTime(Duration.ofSeconds(1))
.build())
.numRetries(5)
.build())
.build())
.build();
DefaultsMode
Le proprietà di timeout che ClientOverrideConfiguration
e RetryMode
non gestiscono sono in genere configurate implicitamente specificando a. DefaultsMode
La AWS SDK for Java 2.x (versione 2.17.102 o successiva) ha introdotto il supporto per. DefaultsMode
Questa funzionalità fornisce un set di valori predefiniti per le impostazioni configurabili più comuni, come le impostazioni di HTTP comunicazione, il comportamento dei tentativi, le impostazioni regionali degli endpoint del servizio e, potenzialmente, qualsiasi configurazione correlata. SDK Quando si utilizza questa funzionalità, è possibile ottenere nuove impostazioni di configurazione predefinite personalizzate per scenari di utilizzo comuni.
Le modalità predefinite sono standardizzate in tutti i. AWS SDKs Il SDK for Java 2.x supporta le seguenti modalità predefinite:
-
legacy
— Fornisce impostazioni predefinite che variano di base AWS SDK e che esistevano prima cheDefaultsMode
venissero stabilite. -
standard
— Fornisce impostazioni predefinite non ottimizzate per la maggior parte degli scenari. -
in-region
— Si basa sulla modalità standard e include impostazioni personalizzate per le applicazioni che effettuano chiamate Servizi AWS dall'interno della stessa. Regione AWS -
cross-region
— Si basa sulla modalità standard e include impostazioni con timeout elevati per le applicazioni che effettuano chiamate Servizi AWS in una regione diversa. -
mobile
— Si basa sulla modalità standard e include impostazioni con timeout elevati personalizzate per applicazioni mobili con latenze più elevate. -
auto
— Si basa sulla modalità standard e include funzionalità sperimentali. I SDK tentativi di scoprire l'ambiente di runtime per determinare automaticamente le impostazioni appropriate. Il rilevamento automatico è basato sull'euristica e non fornisce una precisione del 100%. Se non è possibile determinare l'ambiente di esecuzione, viene utilizzata la modalità standard. Il rilevamento automatico potrebbe interrogare i metadati dell'istanza e i dati utente, il che potrebbe introdurre latenza. Se la latenza di avvio è fondamentale per la tua applicazione, ti consigliamo invece di sceglierne una esplicita.DefaultsMode
È possibile configurare la modalità predefinita nei seguenti modi:
-
Direttamente su un client, tramite.
AwsClientBuilder.Builder#defaultsMode(DefaultsMode)
-
Su un profilo di configurazione, tramite la proprietà del file di
defaults_mode
profilo. -
A livello globale, tramite la proprietà
aws.defaultsMode
di sistema. -
A livello globale, tramite la variabile di
AWS_DEFAULTS_MODE
ambiente.
Nota
Per qualsiasi modalità diversalegacy
, i valori predefiniti forniti potrebbero cambiare man mano che le migliori pratiche si evolvono. Pertanto, se utilizzi una modalità diversa dalegacy
, ti consigliamo di eseguire dei test durante l'aggiornamento di. SDK
Le impostazioni predefinite di Smart nella AWS SDKsand Tools Reference Guide fornisce un elenco delle proprietà di configurazione e dei relativi valori predefiniti nelle diverse modalità predefinite.
Scegliete il valore della modalità predefinita in base alle caratteristiche dell'applicazione e al tipo con Servizio AWS cui l'applicazione interagisce.
Questi valori sono configurati tenendo conto di un'ampia gamma di Servizi AWS opzioni. Per una distribuzione tipica di DynamoDB in cui sia le tabelle che l'applicazione DynamoDB sono distribuite in un'unica regione, la modalità defaults è la più rilevante tra in-region
le modalità predefinite. standard
Esempio Configurazione del client SDK DynamoDB ottimizzata per chiamate a bassa latenza
L'esempio seguente regola i timeout su valori inferiori per una chiamata DynamoDB a bassa latenza prevista.
DynamoDbAsyncClient asyncClient = DynamoDbAsyncClient.builder()
.defaultsMode(DefaultsMode.IN_REGION)
.httpClientBuilder(AwsCrtAsyncHttpClient.builder())
.overrideConfiguration(ClientOverrideConfiguration.builder()
.apiCallTimeout(Duration.ofSeconds(3))
.apiCallAttemptTimeout(Duration.ofMillis(500))
.build())
.build();
L'implementazione individuale del HTTP client può fornirti un controllo ancora più granulare sul timeout e sul comportamento di utilizzo della connessione. Ad esempio, per il client AWS CRT basato, è possibile abilitareConnectionHealthConfiguration
, che consente al client di monitorare attivamente lo stato delle connessioni utilizzate. Per ulteriori informazioni, consulta Configurazione avanzata dei HTTP client AWS CRT basati nella Guida per gli AWS SDK for Java 2.x sviluppatori.
Configurazione Keep-Alive
L'abilitazione di keep-alive può ridurre le latenze riutilizzando le connessioni. Esistono due diversi tipi di keep-alive: Keep-Alive e Keep-Alive. HTTP TCP
-
HTTPKeep-Alive tenta di mantenere la HTTPS connessione tra il client e il server in modo che le richieste successive possano riutilizzare tale connessione. In questo modo si evita la pesante autenticazione sulle richieste successiveHTTPS. HTTP Keep-Alive è abilitato per impostazione predefinita su tutti i client.
-
TCPKeep-Alive richiede che il sistema operativo sottostante invii piccoli pacchetti tramite la connessione socket per garantire ulteriormente che il socket sia mantenuto attivo e per rilevare immediatamente eventuali cadute. Ciò garantisce che una richiesta successiva non perda tempo a cercare di utilizzare un socket caduto. Per impostazione predefinita, TCP Keep-Alive è disabilitato su tutti i client. I seguenti esempi di codice mostrano come abilitarlo su ogni HTTP client. Se abilitato per tutti i HTTP client non CRT basati, l'effettivo meccanismo Keep-Alive dipende dal sistema operativo. Pertanto, è necessario configurare valori TCP Keep-Alive aggiuntivi, come il timeout e il numero di pacchetti, tramite il sistema operativo. Puoi farlo usando
sysctl
Linux o macOS o usando i valori di registro su Windows.
Esempio per abilitare TCP Keep-Alive su un client basato su Apache HTTP
DynamoDbClient client = DynamoDbClient.builder()
.httpClientBuilder(ApacheHttpClient.builder().tcpKeepAlive(true))
.build();
URLConnection
HTTPclient basato
Qualsiasi client sincrono che utilizza il HTTP client URLConnection
basato HttpURLConnection
Esempio per abilitare TCP Keep-Alive su un client basato su Netty HTTP
DynamoDbAsyncClient client = DynamoDbAsyncClient.builder()
.httpClientBuilder(NettyNioAsyncHttpClient.builder().tcpKeepAlive(true))
.build();
Esempio per abilitare TCP Keep-Alive su un client basato AWS CRT HTTP
Con il HTTP client AWS CRT basato, puoi abilitare TCP keep-alive e controllarne la durata.
DynamoDbClient client = DynamoDbClient.builder()
.httpClientBuilder(AwsCrtHttpClient.builder()
.tcpKeepAliveConfiguration(TcpKeepAliveConfiguration.builder()
.keepAliveInterval(Duration.ofSeconds(50))
.keepAliveTimeout(Duration.ofSeconds(5))
.build()))
.build();
Quando si utilizza il client DynamoDB asincrono, è possibile TCP abilitare Keep-Alive come mostrato nel codice seguente.
DynamoDbAsyncClient client = DynamoDbAsyncClient.builder()
.httpClientBuilder(AwsCrtAsyncHttpClient.builder()
.tcpKeepAliveConfiguration(TcpKeepAliveConfiguration.builder()
.keepAliveInterval(Duration.ofSeconds(50))
.keepAliveTimeout(Duration.ofSeconds(5))
.build()))
.build();
Gestione degli errori
Per quanto riguarda la gestione delle eccezioni, utilizza eccezioni di runtime (non selezionate). AWS SDK for Java 2.x
L'eccezione di base, che copre tutte le SDK eccezioni, è SdkServiceException
RuntimeException
Se lo catturi, catturerai tutte le eccezioni che SDK genera.
SdkServiceException
ha una sottoclasse chiamata. AwsServiceException
DynamoDbException
Sono disponibili tipi di eccezioni più specifici in.DynamoDbException
Alcuni di questi tipi di eccezioni si applicano a operazioni sul piano di controllo come. TableAlreadyExistsException
-
ConditionalCheckFailedException
— Hai specificato una condizione nella richiesta che è risultata falsa. Ad esempio, è possibile che abbia provato un aggiornamento condizionale su un item, ma il valore effettivo dell'attributo non corrispondeva al valore previsto nella condizione. Una richiesta che fallisce in questo modo non viene ritentata.
In altre situazioni non è definita un'eccezione specifica. Ad esempio, quando le richieste vengono limitate, ProvisionedThroughputExceededException
potrebbero essere generate quelle specifiche, mentre in altri casi viene generata una richiesta più genericaDynamoDbException
. In entrambi i casi, puoi determinare se la limitazione ha causato l'eccezione controllando se restituisce. isThrottlingException()
true
A seconda delle esigenze dell'applicazione, è possibile catturare tutte le AwsServiceException
DynamoDbException
istanze. Tuttavia, spesso è necessario un comportamento diverso in situazioni diverse. La logica utilizzata per gestire un errore nel controllo delle condizioni è diversa da quella per gestire il throttling. Definisci quali percorsi eccezionali vuoi affrontare e assicurati di testare i percorsi alternativi. Questo ti aiuta ad assicurarti di poter affrontare tutti gli scenari pertinenti.
Per un elenco degli errori più comuni che potresti riscontrare, consultaGestione degli errori con DynamoDB. Vedi anche Errori comuni in Amazon DynamoDB Reference API. Il API riferimento fornisce anche gli errori esatti possibili per ogni API operazione, ad esempio per l'Query
operazione. Per informazioni sulla gestione delle eccezioni, consulta la sezione Gestione delle eccezioni AWS SDK for Java 2.x nella Guida per gli AWS SDK for Java 2.x sviluppatori.
AWS ID della richiesta
Ogni richiesta include un ID della richiesta, che può essere utile da recuperare se stai lavorando Supporto AWS per diagnosticare un problema. Ogni eccezione derivata da SdkServiceException
ha un requestId()
Registrazione
L'utilizzo della registrazione SDK fornita può essere utile sia per catturare messaggi importanti dalle librerie client sia per scopi di debug più approfonditi. I logger sono gerarchici e vengono utilizzati come logger root. SDK software.amazon.awssdk
È possibile configurare il livello con uno dei seguentiTRACE
,,,DEBUG
, INFO
WARN
, ERROR
o. ALL
OFF
Il livello configurato si applica a quel logger e scende nella gerarchia dei logger.
Per la sua registrazione, AWS SDK for Java 2.x utilizza Simple Logging Façade for Java (). SLF4J Questo funge da livello di astrazione rispetto agli altri logger e puoi usarlo per collegare il logger che preferisci. Per istruzioni su come collegare i logger, consultate il manuale utente. SLF4J
Ogni logger ha un comportamento particolare. Per impostazione predefinita, il logger Log4j 2.x crea unConsoleAppender
, che aggiunge gli eventi di registro System.out
e i valori predefiniti al livello di registro. ERROR
Il SimpleLogger logger incluso negli SLF4J output per impostazione predefinita è e il valore predefinito è il livello di registro. System.err
INFO
Ti consigliamo di impostare il livello in modo che qualsiasi implementazione WARN
di software.amazon.awssdk
produzione catturi eventuali messaggi importanti dalle librerie client SDK della piattaforma, limitando al contempo la quantità di output.
Se non SLF4J riesci a trovare un logger supportato nel percorso della classe (nessun SLF4J binding), l'impostazione predefinita è un'implementazione senza operazioni.System.err
spiegano che non è stato SLF4J possibile trovare un'implementazione del logger nel classpath. Per evitare questa situazione, è necessario aggiungere un'implementazione del logger. Per fare ciò, puoi aggiungere una dipendenza in Apache Maven pom.xml
da artefatti, come o. org.slf4j.slf4j-simple
org.apache.logging.log4j.log4j-slf4j2-imp
Per informazioni su come configurare la registrazione inSDK, inclusa l'aggiunta di dipendenze di registrazione alla configurazione dell'applicazione, consulta Logging with the for Java 2.x nella Developer Guide. SDK AWS SDK for Java
La seguente configurazione nel Log4j2.xml
file mostra come regolare il comportamento di registrazione se si utilizza il logger Apache Log4j 2. Questa configurazione imposta il livello del logger root su. WARN
Tutti i logger della gerarchia ereditano questo livello di registro, incluso il logger. software.amazon.awssdk
Per impostazione predefinita, l'output va a. System.out
Nell'esempio seguente, sovrascriviamo ancora l'appender Log4j di output predefinito per applicare un Log4j personalizzato. PatternLayout
Log4j2.xml
Esempio di file di configurazione
La seguente configurazione registra i messaggi sulla console ai WARN
livelli ERROR
e per tutte le gerarchie di logger.
<Configuration status="WARN">
<Appenders>
<Console name="ConsoleAppender" target="SYSTEM_OUT">
<PatternLayout pattern="%d{YYYY-MM-dd HH:mm:ss} [%t] %-5p %c:%L - %m%n" />
</Console>
</Appenders>
<Loggers>
<Root level="WARN">
<AppenderRef ref="ConsoleAppender"/>
</Root>
</Loggers>
</Configuration>
AWS richiedere la registrazione degli ID
Quando qualcosa va storto, puoi trovare la richiesta IDs tra le eccezioni. Tuttavia, se desideri la richiesta IDs per le richieste che non generano eccezioni, puoi utilizzare la registrazione.
Il software.amazon.awssdk.request
logger emette la richiesta IDs a livello. DEBUG
L'esempio seguente estende il precedente configuration example per mantenere il livello del logger root al livelloERROR
, al livello software.amazon.awssdk
WARN
at e al software.amazon.awssdk.request
livello. DEBUG
L'impostazione di questi livelli aiuta a catturare la richiesta IDs e altri dettagli relativi alla richiesta, come l'endpoint e il codice di stato.
<Configuration status="WARN">
<Appenders>
<Console name="ConsoleAppender" target="SYSTEM_OUT">
<PatternLayout pattern="%d{YYYY-MM-dd HH:mm:ss} [%t] %-5p %c:%L - %m%n" />
</Console>
</Appenders>
<Loggers>
<Root level="ERROR">
<AppenderRef ref="ConsoleAppender"/>
</Root>
<Logger name="software.amazon.awssdk" level="WARN" />
<Logger name="software.amazon.awssdk.request" level="DEBUG" />
</Loggers>
</Configuration>
Di seguito è riportato un esempio di output del log:
2022-09-23 16:02:08 [main] DEBUG software.amazon.awssdk.request:85 - Sending Request: DefaultSdkHttpFullRequest(httpMethod=POST, protocol=https, host=dynamodb.us-east-1.amazonaws.com, encodedPath=/, headers=[amz-sdk-invocation-id, Content-Length, Content-Type, User-Agent, X-Amz-Target], queryParameters=[]) 2022-09-23 16:02:08 [main] DEBUG software.amazon.awssdk.request:85 - Received successful response: 200, Request ID: QS9DUMME2NHEDH8TGT9N5V53OJVV4KQNSO5AEMVJF66Q9ASUAAJG, Extended Request ID: not available
Paginazione
Alcune richieste, come Query
and Scan
, limitano la dimensione dei dati restituiti su una singola richiesta e richiedono l'esecuzione di richieste ripetute per richiamare le pagine successive.
È possibile controllare il numero massimo di elementi da leggere per ogni pagina con il Limit
parametro. Ad esempio, è possibile utilizzare il Limit
parametro per recuperare solo gli ultimi 10 elementi. Questo limite specifica il numero di elementi da leggere dalla tabella prima di applicare qualsiasi filtro. Se desideri esattamente 10 elementi dopo il filtraggio, non c'è modo di specificarlo. Puoi controllare solo il conteggio prefiltrato e controllare lato client quando hai effettivamente recuperato 10 articoli. Indipendentemente dal limite, le risposte hanno sempre una dimensione massima di 1 MB.
Un LastEvaluatedKey
potrebbe essere incluso nella API risposta. Ciò indica che la risposta è terminata perché ha raggiunto un limite di conteggio o di dimensione. Questa chiave è l'ultima chiave valutata per quella risposta. Interagendo direttamente conAPI, è possibile recuperarla LastEvaluatedKey
e passarla a una chiamata successiva per leggere il blocco successivo ExclusiveStartKey
da quel punto di partenza. Se LastEvaluatedKey
viene restituito no, significa che non ci sono più elementi che corrispondono alla chiamata or. Query
Scan
API
L'esempio seguente utilizza l'interfaccia di basso livello per limitare gli elementi a 100 in base al keyConditionExpression
parametro.
QueryRequest.Builder queryRequestBuilder = QueryRequest.builder()
.expressionAttributeValues(Map.of(
":pk_val", AttributeValue.fromS("123"),
":sk_val", AttributeValue.fromN("1000")))
.keyConditionExpression("pk = :pk_val AND sk > :sk_val")
.limit(100)
.tableName(TABLE_NAME);
while (true) {
QueryResponse queryResponse = DYNAMODB_CLIENT.query(queryRequestBuilder.build());
queryResponse.items().forEach(item -> {
LOGGER.info("item PK: [" + item.get("pk") + "] and SK: [" + item.get("sk") + "]");
});
if (!queryResponse.hasLastEvaluatedKey()) {
break;
}
queryRequestBuilder.exclusiveStartKey(queryResponse.lastEvaluatedKey());
}
AWS SDK for Java 2.x Possono semplificare questa interazione con DynamoDB fornendo metodi di impaginazione automatica che effettuano più chiamate di servizio per ottenere automaticamente le pagine successive di risultati. Questo semplifica il codice, ma toglie un certo controllo sull'utilizzo delle risorse che avresti con la lettura manuale delle pagine.
Utilizzando i Iterable
metodi disponibili nel client DynamoDB, QueryPaginator
ScanPaginator
QueryPaginator
come illustrato nell'esempio seguente.
QueryPublisher queryPublisher =
DYNAMODB_CLIENT.queryPaginator(QueryRequest.builder()
.expressionAttributeValues(Map.of(
":pk_val", AttributeValue.fromS("123"),
":sk_val", AttributeValue.fromN("1000")))
.keyConditionExpression("pk = :pk_val AND sk > :sk_val")
.limit(100)
.tableName("YourTableName")
.build());
queryPublisher.items().subscribe(item ->
System.out.println(item.get("itemData"))).join();
Annotazioni delle classi di dati
Java SDK fornisce diverse annotazioni che puoi inserire negli attributi della tua classe di dati. Queste annotazioni influenzano il modo in cui SDK interagisce con gli attributi. Aggiungendo un'annotazione, puoi fare in modo che un attributo si comporti come un contatore atomico implicito, mantenga un valore di timestamp generato automaticamente o tenga traccia del numero di versione di un elemento. Per ulteriori informazioni, consulta Annotazioni della classe Data.