

La version 4 (V4) du AWS SDK pour .NET est sortie \!

Pour plus d'informations sur l'interruption des modifications et la migration de vos applications, consultez la rubrique [ sur la ](https://docs.aws.amazon.com/sdk-for-net/v4/developer-guide/net-dg-v4.html) migration.

 [![Orange button with text "Click here for details".](https://docs.aws.amazon.com/fr_fr/sdk-for-net/v4/developer-guide/images/BannerButton_less-round.png)](https://docs.aws.amazon.com/sdk-for-net/v4/developer-guide/net-dg-v4.html)

Les traductions sont fournies par des outils de traduction automatique. En cas de conflit entre le contenu d'une traduction et celui de la version originale en anglais, la version anglaise prévaudra.

# Meilleures pratiques en matière de performances pour AWS SDK pour .NET
<a name="net-dg-performance"></a>

La façon dont vous créez des clients, gérez les réponses et configurez votre application a un impact important sur le débit, la latence et l'utilisation de la mémoire. Cette rubrique décrit les modèles d'utilisation et de configuration qui permettent à vos applications de fonctionner de manière efficace et fiable. Ces modèles sont particulièrement importants en cas de charge élevée ou dans des environnements aux ressources limitées, tels que les conteneurs et les fonctions sans serveur. Le respect de ces pratiques peut améliorer les performances et éviter les problèmes courants tels que les réponses lentes, les blocages et l'utilisation excessive de la mémoire.

Les pratiques les plus efficaces sont les suivantes :
+ [Réutilisez un seul client de service à longue durée de vie ](#net-dg-performance-reuse-clients) au lieu d'en créer un par demande.
+ [Supprimez les réponses et les flux ](#net-dg-performance-dispose) afin que les connexions réseau soient rétablies dans le pool de connexions.
+ [Utilisez`async`/`await`correctement ](#net-dg-performance-async) et ne bloquez jamais les appels asynchrones du SDK.
+ [Configurez le ramasse-miettes .NET ](#net-dg-performance-gc) pour les environnements restreints tels qu' AWS Lambda Amazon ECS.
+ [Gérez les connexions HTTP ](#net-dg-performance-connections) et les limites de connexion à haut débit.

Avant de commencer, assurez-vous d'avoir [[ configuré votre environnement ](configuring-the-sdk.md) et votre projet](net-dg-config.md).

## Réutilisez un seul client de service à longue durée de vie
<a name="net-dg-performance-reuse-clients"></a>

Les clients de service tels qu'[AmazonS3Client](https://docs.aws.amazon.com/sdkfornet/v4/apidocs/items/S3/TS3Client.html) [ AmazonDynamoDBClient ](https://docs.aws.amazon.com/sdkfornet/v4/apidocs/items/DynamoDBv2/TDynamoDBClient.html) sont * sûrs pour les threads*, relativement * coûteux * à construire et durables. * * La création d'un client résout les informations de région et de point de terminaison et établit l'infrastructure HTTP sous-jacente. Créez un client par service et réutilisez-le pendant toute la durée de vie de votre application. Si vous appelez plus d'une région, créez un client distinct pour chaque région.

**Avertissement**  
Ne créez pas de nouveau client de service pour chaque demande ou dans une boucle. La création de clients à plusieurs reprises entraîne une désactivation de l'infrastructure HTTP sous-jacente, ce qui ajoute une latence mesurable. Il peut également épuiser les prises ou les poignées et provoquer l'échec des demandes ou leur blocage sous charge.

Dans les applications qui utilisent l'injection de dépendances, enregistrez le client en tant que singleton. La méthode d'`AddAWSService`extension du `AWSSDK.Extensions.NETCore.Setup` NuGet package enregistre le client avec une durée de vie par défaut de`ServiceLifetime.Singleton`. Le client est créé la première fois qu'il est demandé et la même instance est réutilisée pendant toute la durée du processus. Pour plus d'informations sur l'enregistrement de AWS services avec injection de dépendances et les options de lecture depuis la configuration, consultez[AWSSDK.Extensions.NETCore.Setup et iConfiguration](net-dg-config-netcore.md).

Vous pouvez également enregistrer un client en tant que singleton manuellement.

```
builder.Services.AddSingleton<IAmazonS3>(_ => new AmazonS3Client());
```

**Note**  
Étant donné `AddAWSService` que le client est enregistré en tant que singleton par défaut, ne supprimez pas le client qu'il fournit. Si vous avez besoin d'une durée de vie autre que celle par défaut, transmettez une `ServiceLifetime` valeur différente au `lifetime` paramètre facultatif de`AddAWSService`.

La réutilisation du client ne ** signifie ** pas que vous devez arrêter de supprimer les réponses par opération. Réutilisez le client pendant toute la durée de vie de l'application, mais continuez à supprimer les réponses et les flux renvoyés par les différentes opérations, comme décrit dans[Supprimer les réponses et les flux](#net-dg-performance-dispose).

## Éliminez les réponses et les flux pour libérer des connexions
<a name="net-dg-performance-dispose"></a>

Certains objets de réponse du SDK transmettent un flux réseau en direct. L'exemple le plus courant est [ GetObjectResponse ](https://docs.aws.amazon.com/sdkfornet/v4/apidocs/items/S3/TGetObjectResponse.html) celui qui implémente `IDisposable` et expose le contenu de l'objet via sa `ResponseStream` propriété. La réponse maintient une connexion HTTP ouverte jusqu'à ce que le flux soit entièrement lu ou que la réponse soit supprimée. Si vous divulguez ces réponses (par exemple, `GetObject` en appelant en boucle sans supprimer chaque résultat), les connexions ouvertes s'accumulent jusqu'à ce que le pool de connexions soit épuisé et que l'appel suivant soit bloqué. C'est la cause des informations faisant état de téléchargements « suspendus de manière aléatoire » ou bloqués sur le nième objet.

Enveloppez toujours une réponse en streaming dans une `using` déclaration et lisez ou copiez son flux rapidement.

```
using Amazon.S3;
using Amazon.S3.Model;

// s3Client is a reused, long-lived client.
var request = new GetObjectRequest { BucketName = bucketName, Key = key };

using var response = await s3Client.GetObjectAsync(request);
await response.WriteResponseStreamToFileAsync(filePath, append: false, CancellationToken.None);
```

L'élimination de la réponse et l'élimination de la sienne `ResponseStream` sont équivalentes ; l'une ou l'autre ferme le flux réseau sous-jacent et renvoie la connexion au pool.

**Astuce**  
Si vous n'avez besoin que des métadonnées de l'objet, telles que la taille, l'heure de dernière modification, le type de contenu ou l'ETag, appelez `GetObjectMetadata` ou `GetObjectMetadataAsync` à la place de. `GetObject` L'opération de métadonnées émet une `HEAD` requête HTTP et ne transfère aucun corps d'objet. Il n'y a donc aucun flux de contenu à gérer.  

```
var metadata = await s3Client.GetObjectMetadataAsync(bucketName, key);
Console.WriteLine($"Size: {metadata.ContentLength} bytes");
```

**Avertissement**  
Les types de réponse et de flux tels que `GetObjectResponse` n'implémentent pas de finaliseur, vous ne pouvez donc pas compter sur le ramasse-miettes pour libérer leurs connexions à votre place. Vous devez disposer les réponses et les flux de manière déterministe à l'aide `using` d'un appel explicite`Dispose`.

## Utiliser async/await correctement
<a name="net-dg-performance-async"></a>

Sur le .NET moderne, les opérations de service dans le AWS SDK pour .NET sont asynchrones et renvoient un. `Task` Sur .NET Framework, des méthodes synchrones existent également, mais les appels asynchrones sont plus évolutifs et sont recommandés. Effectuez des opérations avec `await` et `async` propagez chaque couche de votre code jusqu'au point d'entrée. Pour plus d'informations sur la programmation asynchrone avec le SDK, consultez. [Programmation asynchrone](sdk-net-async-api.md)

**Avertissement**  
Ne bloquez pas un appel au SDK asynchrone avec`.Result`, `.Wait()` ou. `.GetAwaiter().GetResult()` Ce * modèle de * synchronisation sur asynchrone est une cause fréquente de blocage des applications :  
En cas de charge, le blocage des appels consomme les threads plus rapidement que ne peut augmenter le pool de threads, de sorte que les continuations ne peuvent pas s'exécuter. Ce blocage du * pool de threads * apparaît comme un blocage indéfini et constitue le mode de défaillance dominant sur le .NET moderne (où il n'y en ASP.NET Core a pas par défaut). `SynchronizationContext`
Certains contextes capturent un`SynchronizationContext`, comme les applications classiques ASP.NETWindows Forms,WPF,Blazor WebAssembly, et .NET Framework. Dans ces contextes, le blocage du thread appelant alors qu'une continuation a besoin de ce même thread entraîne un * blocage*. Les opérations du SDK sont utilisées `ConfigureAwait(false)` en interne, elles ne publient donc pas leurs suites dans le contexte capturé. Le blocage provient d'un `async` code situé ailleurs dans votre chaîne d'appels qui le capture. La consommation d'appels SDK avec `await` throughout permet d'éviter complètement le problème.

La méthode suivante bloque l'appel asynchrone et peut bloquer ou priver le pool de threads.

```
// Anti-pattern: do not do this.
public GetObjectResponse Get(GetObjectRequest request)
{
    return s3Client.GetObjectAsync(request).Result;
}
```

Définissez plutôt la méthode `async` et `await` l'appel.

```
public async Task<GetObjectResponse> GetAsync(GetObjectRequest request)
{
    return await s3Client.GetObjectAsync(request);
}
```

Recommandations supplémentaires pour le code asynchrone :
+ Passez un `CancellationToken` à chaque opération afin qu'un appel lent ou bloqué puisse être annulé au lieu d'être suspendu. Pour de plus amples informations, veuillez consulter [Utilisation du `CancellationToken` paramètre pour les délais](retries-timeouts.md#timeouts-async).
+ N'avalez pas les exceptions dans un `catch` bloc vide. Cela masque le véritable échec et rend un blocage impossible à distinguer d'une erreur. Détectez des exceptions spécifiques et enregistrez-les.
+ Lorsque vous renvoyez une exception interceptée, utilisez `throw;` plutôt que `throw ex;` pour que la trace de pile d'origine soit préservée.
+ Si vous devez appeler depuis une frontière synchrone, considérez cela comme un dernier recours et isolez le travail du contexte capturé plutôt que de faire du blocage des appels le modèle par défaut.

## Configurer le ramasse-miettes .NET pour AWS Lambda et Amazon ECS
<a name="net-dg-performance-gc"></a>

Lorsqu'un conteneur semble présenter une « fuite de mémoire », le ramasse-miettes .NET (GC) peut conserver la mémoire récupérée pour la réutiliser. Par conséquent, la mémoire de processus peut sembler élevée et stable même lorsque le tas géré n'augmente pas. De plus, le GC ne détecte pas automatiquement la limite de mémoire d'un conteneur (sa limite de groupe de contrôle). Dans un environnement restreint, le tas peut alors croître vers la mémoire de l'hôte plutôt que vers la limite du conteneur. Cela peut entraîner la `OutOfMemoryException` fermeture du conteneur ou sa fermeture.

Pour aider le GC à bien fonctionner dans des environnements restreints :
+ Définissez une limite de mémoire explicite sur le conteneur afin que le GC respecte la limite du groupe de contrôle, and/or définissez la `DOTNET_GCHeapHardLimit` (une valeur d'octet absolue, en hexadécimal) ou la variable d'`DOTNET_GCHeapHardLimitPercent`environnement pour plafonner le tas géré. Dans plusieurs cas de manque de mémoire signalés sur Amazon ECS, la définition d'une limite de mémoire dure a permis de résoudre les pannes.
+ Sur les hôtes de petite taille AWS Lambda et Amazon ECS, pensez à désactiver la collecte des déchets simultanée (en arrière-plan) afin que le collecteur ne réserve pas de mémoire supplémentaire ; par exemple, définissez la variable d'`DOTNET_gcConcurrent`environnement sur ou définissez-la `<ConcurrentGarbageCollection>false</ConcurrentGarbageCollection>` dans le fichier de projet. `0`
+ Limitez votre concurrence. Le lancement de nombreuses opérations à la fois, comme l'appel d'une grande collection, augmente la mémoire de processus et peut `Task.WhenAll` priver le pool de connexions. Limitez plutôt le degré de parallélisme. Par exemple, évitez ce schéma illimité :

  ```
  // Anti-pattern: starts one task per item with no limit.
  await Task.WhenAll(keys.Select(key => s3Client.GetObjectMetadataAsync(bucket, key)));
  ```

  Au lieu de cela, limitez la simultanéité avec `Parallel.ForEachAsync` :

  ```
  var options = new ParallelOptions { MaxDegreeOfParallelism = 10 };
  await Parallel.ForEachAsync(keys, options, async (key, token) =>
  {
      await s3Client.GetObjectMetadataAsync(bucket, key, token);
  });
  ```

Pour plus d'informations sur ces paramètres, consultez la section Options de configuration [ d'exécution pour la collecte des déchets ](https://learn.microsoft.com/en-us/dotnet/core/runtime-config/garbage-collector) sur learn.microsoft.com. Pour obtenir des conseils spécifiques au AWS calcul, consultez l'article de blog AWS consacré aux outils de développement sur [ la configuration de .NET Garbage Collection pour Amazon ECS et AWS Lambda](https://aws.amazon.com/blogs/developer/configuring-net-garbage-collection-for-amazon-ecs-and-aws-lambda).

## Gérer les connexions HTTP et les limites de connexion
<a name="net-dg-performance-connections"></a>

À haut débit, deux problèmes liés à la connexion sont courants. Le premier est l'ouverture d'un trop grand nombre de connexions éphémères. Cela épuise les ports éphémères, laisse les sockets en `TIME_WAIT` place et augmente la latence de prise de contact TCP et TLS. Le second est le manque de connexions disponibles, ce qui entrave le parallélisme. La réutilisation d'un seul client à longue durée de vie (voir[Réutiliser les clients du service](#net-dg-performance-reuse-clients)) est la base d'un regroupement de connexions sain, car le regroupement dépend de la réutilisation du client.

Pour régler le nombre de connexions simultanées par point de terminaison, définissez la `MaxConnectionsPerServer` propriété dans la configuration du client. Lorsque cette propriété est `null` (valeur par défaut), la valeur `HttpClientHandler` par défaut sous-jacente s'applique, ce qui est effectivement illimité sur le .NET moderne. Ne l'augmentez que lorsque de nombreuses demandes simultanées adressées au même point de terminaison sont bloquées au niveau des connexions. Un bon point de départ est le nombre maximal de demandes simultanées que vous attendez par point de terminaison. Le régler à un niveau bien supérieur à vos besoins en termes de charge de travail gaspille des sockets sans améliorer le débit.

```
using Amazon.S3;

var config = new AmazonS3Config
{
    MaxConnectionsPerServer = 50
};

var s3Client = new AmazonS3Client(config);
```

Si vous utilisez déjà l'injection de dépendances, configurez vos clients via`AWSSDK.Extensions.NETCore.Setup`. Il s'agit de l'approche recommandée lorsque vous utilisez DI ou que vous enregistrez plusieurs clients de service. Il centralise la configuration et facilite l'injection et le test des clients. Vous pouvez définir les valeurs de configuration à partir de la configuration de votre application plutôt que dans le code. Pour de plus amples informations, veuillez consulter [AWSSDK.Extensions.NETCore.Setup et iConfiguration](net-dg-config-netcore.md).

Enfin, limitez votre propre parallélisme afin de ne pas démarrer plus d'opérations simultanées que ne le permet votre limite de connexion. Par exemple, passez des appels dont la `SemaphoreSlim` taille correspond à votre limite de connexion :

```
var throttle = new SemaphoreSlim(50); // match MaxConnectionsPerServer
await throttle.WaitAsync(token);
try
{
    await s3Client.GetObjectAsync(request, token);
}
finally
{
    throttle.Release();
}
```

## Configurer les délais d'attente et les nouvelles tentatives
<a name="net-dg-performance-timeouts"></a>

Les temps morts et les nouvelles tentatives ont un effet direct sur les performances perçues. Une `Timeout` valeur trop élevée entraîne le blocage d'une requête pendant une longue période. Lorsqu'un service renvoie déjà des erreurs de limitation, une politique de nouvelle tentative agressive ajoute d'autres demandes et peut aggraver la situation. Choisissez une politique de nouvelle tentative adaptée à la tolérance de votre application en matière de latence par rapport à l'échec, et laissez les véritables exceptions se propager au lieu de réessayer de manière à masquer un blocage.

**Note**  
La `Timeout` propriété n'affecte pas les appels asynchrones. Si vous utilisez des appels asynchrones, consultez [Utilisation du `CancellationToken` paramètre pour les délais](retries-timeouts.md#timeouts-async) plutôt.

Pour plus d'informations sur les modes de nouvelle tentative et la `Timeout` propriété (`ReadWriteTimeout`s'applique uniquement à .NET Framework), ainsi que des exemples sur la façon de les définir, consultez[Réessais et délais d'attente](retries-timeouts.md). `MaxErrorRetry`

## Optimisez le streaming et les transferts d'objets volumineux (Amazon S3)
<a name="net-dg-performance-streaming"></a>

Pour charger et télécharger des objets volumineux ou de nombreux objets, utilisez la [ TransferUtility ](https://docs.aws.amazon.com/sdkfornet/v4/apidocs/items/S3/TTransferUtility.html) classe de l'`Amazon.S3.Transfer`espace de noms. Il télécharge et télécharge en parallèle à l'aide de transferts partitionnés et gère les flux, les parties et les connexions pour vous. C'est plus rapide qu'un transfert à flux unique et c'est la méthode recommandée pour déplacer des objets volumineux.
+ **Téléchargement en plusieurs parties en parallèle. ** Les versions précédentes du SDK téléchargeaient un objet sous la forme d'un flux unique, au lieu de télécharger des parties en parallèle. À partir de `AWSSDK.S3` la version 4.0.17, `TransferUtility` propose un téléchargement en plusieurs parties (parallèle) via les méthodes `DownloadWithResponseAsync``OpenStreamWithResponseAsync`, et. `DownloadDirectoryWithResponseAsync` Lors de l'utilisation`OpenStreamWithResponseAsync`, les parties de l'objet sont mises en mémoire tampon pendant que vous consommez le flux renvoyé. Contrôlez le nombre de pièces mises en mémoire tampon avec la `MaxInMemoryParts` propriété de [ TransferUtilityOpenStreamRequest](https://docs.aws.amazon.com/sdkfornet/v4/apidocs/items/S3/TTransferUtilityOpenStreamRequest.html). Pour la plupart des transferts, préférez`TransferUtility`. Téléchargez vous-même des plages d'octets avec la `ByteRange` propriété de [ GetObjectRequest ](https://docs.aws.amazon.com/sdkfornet/v4/apidocs/items/S3/TGetObjectRequest.html) uniquement lorsque vous avez besoin d'une plage spécifique ou d'un schéma de parallélisme personnalisé. Pour plus d'informations, consultez la section [ Présentation de la prise en charge du téléchargement en plusieurs parties pour le AWS SDK pour .NET Transfer Manager ](https://aws.amazon.com/blogs/developer/introducing-multipart-download-support-for-aws-sdk-for-net-transfer-manager/) sur le blog AWS Developer Tools.
+ **Longueur du contenu pour les téléchargements. ** Un Amazon S3 `PUT` nécessite une longueur de contenu connue et, par défaut, le SDK calcule une somme de contrôle sur le corps de la requête. Lorsque la longueur est connue et que le flux est consultable, le SDK peut le faire sans mettre l'objet entier en mémoire tampon. Il `TransferUtility` gère pour vous les flux non consultables en les mettant en mémoire tampon si nécessaire. Si vous appelez `PutObjectAsync` directement avec un flux non consultable (tel qu'un corps de requête brutASP.NET Core), la demande peut échouer. Fournissez un flux consultable, définissez explicitement la longueur du contenu ou configurez la façon dont le SDK calcule les sommes de contrôle. Pour plus d'informations, consultez la section Protection de l'intégrité [ des données ](https://docs.aws.amazon.com/sdkref/latest/guide/feature-dataintegrity.html) dans le Guide de référence AWS des kits de développement logiciel et des outils.
+ **Dimensionnement des pièces ** Amazon S3 autorise un maximum de 10 000 parties par téléchargement en plusieurs parties. Lorsque la longueur totale est connue, le SDK calcule automatiquement une taille de pièce qui reste dans cette limite. Vous devez principalement `PartSize` vous fixer pour les streams dont la durée n'est pas connue à l'avance. Dans le cas contraire, les petites parties par défaut peuvent dépasser la limite d'un téléchargement très volumineux. Une taille de pièce plus importante réduit également les frais généraux par pièce, au prix d'une plus grande quantité de mémoire par pièce.

## Diagnostiquer les problèmes de performances
<a name="net-dg-performance-diagnose"></a>

Lorsque vous étudiez un ralentissement, un blocage ou une fuite apparente, les signaux suivants vous aident à en trouver rapidement la cause :
+ Un nombre croissant de sockets à l'`TIME_WAIT`état `CLOSE_WAIT` ou (visible avec`netstat`) est l'empreinte de réponses indisposées ou de clients créés et supprimés par demande. Consultez [Supprimer les réponses et les flux](#net-dg-performance-dispose) et [Réutiliser les clients du service](#net-dg-performance-reuse-clients).
+ Activez les mesures de demande et l'enregistrement des réponses pour confirmer que les demandes sont effectivement envoyées et pour mesurer la latence. Définissez les propriétés de l'[LoggingConfig](https://docs.aws.amazon.com/sdkfornet/v4/apidocs/items/Util/TLoggingConfig.html)objet sur [ AWSConfigs ](https://docs.aws.amazon.com/sdkfornet/v4/apidocs/items/Amazon/TAWSConfigs.html) avant de créer vos clients de service. Un client capture les paramètres, par exemple au `LogMetrics` moment de sa création.

  ```
  using Amazon;
  
  AWSConfigs.LoggingConfig.LogMetrics = true;
  AWSConfigs.LoggingConfig.LogResponses = ResponseLoggingOption.OnError;
  ```
+ Lorsque vous étudiez la mémoire, distinguez la mémoire du processus complet du tas géré. Une mémoire de processus élevée mais stable est souvent le GC contenant la mémoire récupérée plutôt qu'une fuite. Consultez [Configuration de la collecte des déchets](#net-dg-performance-gc).