

Versi 4 (V4) AWS SDK untuk .NET telah dirilis\!

Untuk informasi tentang mengubah perubahan dan memigrasikan aplikasi Anda, lihat topik [https://docs.aws.amazon.com/sdk-for-net/v4/developer-guide/net-dg-v4.html](https://docs.aws.amazon.com/sdk-for-net/v4/developer-guide/net-dg-v4.html) migrasi.

 [![Orange button with text "Click here for details".](https://docs.aws.amazon.com/id_id/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)

Terjemahan disediakan oleh mesin penerjemah. Jika konten terjemahan yang diberikan bertentangan dengan versi bahasa Inggris aslinya, utamakan versi bahasa Inggris.

# Praktik terbaik kinerja untuk AWS SDK untuk .NET
<a name="net-dg-performance"></a>

Cara Anda membuat klien, menangani respons, dan mengonfigurasi aplikasi Anda memiliki efek besar pada throughput, latensi, dan penggunaan memori. Topik ini menjelaskan pola penggunaan dan konfigurasi yang membantu aplikasi Anda berjalan secara efisien dan andal. Pola-pola ini paling penting di bawah beban tinggi atau di lingkungan yang terbatas sumber daya seperti wadah dan fungsi tanpa server. Mengikuti praktik ini dapat meningkatkan kinerja dan mencegah masalah umum seperti respons lambat, hang, dan penggunaan memori yang tinggi.

Praktik yang paling berdampak adalah sebagai berikut:
+ [Gunakan kembali satu klien layanan berumur panjang al ](#net-dg-performance-reuse-clients) ih-alih membuat satu per permintaan.
+ [Buang respons dan aliran ](#net-dg-performance-dispose) sehingga koneksi jaringan dilepaskan kembali ke kumpulan koneksi.
+ [Gunakan`async`/`await`dengan benar ](#net-dg-performance-async) dan jangan pernah memblokir panggilan SDK asinkron.
+ [Konfigurasikan pengumpulan sampah .NET ](#net-dg-performance-gc) untuk lingkungan terbatas seperti AWS Lambda dan Amazon ECS.
+ [Kelola koneksi HTTP ](#net-dg-performance-connections) dan batas koneksi di bawah throughput tinggi.

Sebelum Anda mulai, pastikan Anda telah [ mengatur lingkungan Anda ](net-dg-config.md) dan meng [ konfigurasi proyek Anda](configuring-the-sdk.md).

## Gunakan kembali satu klien layanan yang berumur panjang
<a name="net-dg-performance-reuse-clients"></a>

Layanan klien seperti [ Amazons3Client ](https://docs.aws.amazon.com/sdkfornet/v4/apidocs/items/S3/TS3Client.html) dan * aman untuk ut [ AmazonDynamoDBClient ](https://docs.aws.amazon.com/sdkfornet/v4/apidocs/items/DynamoDBv2/TDynamoDBClient.html) as*, relatif * mahal * untuk dibangun, dan berumur panjang. * * Membangun klien menyelesaikan informasi Wilayah dan titik akhir dan menetapkan infrastruktur HTTP yang mendasarinya. Buat satu klien per layanan dan gunakan kembali selama masa pakai aplikasi Anda. Jika Anda memanggil lebih dari satu Wilayah, buat klien terpisah untuk setiap Wilayah.

**Awas**  
Jangan membuat klien layanan baru untuk setiap permintaan atau di dalam loop. Membuat klien berulang kali mengubah infrastruktur HTTP yang mendasarinya, yang menambahkan latensi terukur. Ini juga dapat mengeluarkan soket atau pegangan dan menyebabkan permintaan gagal atau menggantung di bawah beban.

Dalam aplikasi yang menggunakan injeksi ketergantungan, daftarkan klien sebagai singleton. Metode `AddAWSService` ekstensi dari `AWSSDK.Extensions.NETCore.Setup` NuGet paket mendaftarkan klien dengan masa pakai default`ServiceLifetime.Singleton`. Klien dibuat saat pertama kali diminta, dan instance yang sama digunakan kembali selama masa proses. Untuk informasi selengkapnya tentang mendaftar AWS kan layanan dengan injeksi ketergantungan dan opsi membaca dari konfigurasi, lihat[AWSSDK.Extensions.NETCore.Setup dan IConfiguration](net-dg-config-netcore.md).

Anda juga dapat mendaftarkan klien sebagai singleton secara manual.

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

**catatan**  
Karena `AddAWSService` mendaftarkan klien sebagai singleton secara default, jangan buang klien yang disediakannya. Jika Anda memerlukan masa pakai non-default, berikan `ServiceLifetime` nilai yang berbeda ke `lifetime` parameter opsional. `AddAWSService`

Menggunakan kembali klien ** tidak ** berarti Anda harus berhenti membuang respons per operasi. Gunakan kembali klien selama masa pakai aplikasi, tetapi terus buang respons dan aliran yang dikembalikan oleh operasi individual, seperti yang dijelaskan dalam[Buang tanggapan dan aliran](#net-dg-performance-dispose).

## Buang respons dan aliran untuk melepaskan koneksi
<a name="net-dg-performance-dispose"></a>

Beberapa objek respons SDK membawa aliran jaringan langsung. Contoh yang paling umum adalah [ GetObjectResponse](https://docs.aws.amazon.com/sdkfornet/v4/apidocs/items/S3/TGetObjectResponse.html), yang mengimplementasikan `IDisposable` dan mengekspos konten objek melalui `ResponseStream` propertinya. Respons menahan koneksi HTTP terbuka sampai aliran dibaca sepenuhnya atau respons dibuang. Jika Anda membocorkan respons ini (misalnya, dengan memanggil `GetObject` dalam satu loop tanpa membuang setiap hasil), koneksi terbuka terakumulasi hingga kumpulan koneksi habis, dan panggilan berikutnya diblokir. Ini adalah penyebab di balik laporan unduhan yang “hang secara acak” atau terhenti pada objek ke-N.

Selalu bungkus respons streaming dalam `using` pernyataan dan baca atau salin streamingnya segera.

```
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);
```

Membuang respons dan membuangnya `ResponseStream` setara; salah satu menutup aliran jaringan yang mendasarinya dan mengembalikan koneksi ke pool.

**Tip**  
Jika Anda hanya memerlukan metadata objek, seperti ukuran, waktu modifikasi terakhir, jenis konten, atau ETag, panggil atau alih-alih`GetObjectMetadata`. `GetObjectMetadataAsync` `GetObject` Operasi metadata mengeluarkan `HEAD` permintaan HTTP dan tidak mentransfer badan objek, jadi tidak ada aliran konten untuk dikelola.  

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

**Awas**  
Jenis respons dan aliran seperti `GetObjectResponse` tidak menerapkan finalizer, jadi Anda tidak dapat mengandalkan pengumpulan sampah untuk melepaskan koneksi mereka untuk Anda. Anda harus membuang respons dan aliran secara deterministik dengan `using` atau panggilan eksplisit`Dispose`.

## Gunakan async/await dengan benar
<a name="net-dg-performance-async"></a>

Pada .NET modern, operasi layanan di dalamnya asinkron dan mengembalikan a. AWS SDK untuk .NET `Task` Pada .NET Framework, metode sinkron juga ada, tetapi panggilan asinkron berskala lebih baik dan direkomendasikan. Gunakan operasi dengan`await`, dan `async` sebarkan melalui setiap lapisan kode Anda hingga titik masuk. Untuk informasi selengkapnya tentang pemrograman asinkron dengan SDK, lihat. [Pemrograman asinkron](sdk-net-async-api.md)

**Awas**  
Jangan memblokir panggilan SDK asinkron dengan`.Result`,`.Wait()`, atau. `.GetAwaiter().GetResult()` Pola * sinkronisasi over-async * ini adalah penyebab umum aplikasi yang hang:  
Di bawah beban, pemblokiran panggilan menghabiskan utas lebih cepat daripada yang dapat tumbuh kumpulan utas, sehingga kelanjutan tidak dapat berjalan. Kelap * aran kumpulan utas ini * muncul sebagai hang yang tidak terbatas dan merupakan mode kegagalan dominan di .NET modern (di mana tidak ASP.NET Core memiliki default). `SynchronizationContext`
Beberapa konteks menangkap`SynchronizationContext`, seperti aplikasi klasikASP.NET,,Windows Forms,WPF,Blazor WebAssembly, dan .NET Framework. Dalam konteks ini, memblokir utas panggilan sementara kelanjutan membutuhkan utas yang sama menghasilkan kebun * tuan*. Operasi di SDK digunakan `ConfigureAwait(false)` secara internal, sehingga mereka tidak memposting kelanjutannya kembali ke konteks yang diambil. Kebuntuan muncul dari `async` kode di tempat lain dalam rantai panggilan Anda yang menangkapnya. Mengkonsumsi panggilan SDK dengan `await` seluruhnya menghindari masalah sepenuhnya.

Metode berikut memblokir panggilan asinkron dan dapat menemui jalan buntu atau membuat kumpulan thread kelaparan.

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

Sebaliknya, buat metode `async` dan `await` panggilan.

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

Rekomendasi tambahan untuk kode asinkron:
+ Berikan a `CancellationToken` ke setiap operasi sehingga panggilan yang lambat atau terhenti dapat dibatalkan alih-alih digantung. Untuk informasi selengkapnya, lihat [Menggunakan `CancellationToken` parameter untuk batas waktu](retries-timeouts.md#timeouts-async).
+ Jangan menelan pengecualian di `catch` blok kosong. Melakukannya menyembunyikan kegagalan yang sebenarnya dan membuat hang tidak dapat dibedakan dari kesalahan. Tangkap pengecualian tertentu dan catat.
+ Saat mengembalikan pengecualian yang tertangkap, gunakan alih- `throw;` `throw ex;` alih agar jejak tumpukan asli dipertahankan.
+ Jika Anda harus memanggil dari batas sinkron, perlakukan itu sebagai upaya terakhir dan isolasi pekerjaan dari konteks yang ditangkap daripada menjadikan panggilan pemblokiran sebagai pola default.

## Konfigurasikan pengumpulan sampah .NET untuk AWS Lambda dan Amazon ECS
<a name="net-dg-performance-gc"></a>

Ketika sebuah wadah tampaknya memiliki “kebocoran memori,” .NET sampah kolektor (GC) mungkin mempertahankan memori yang direklamasi untuk digunakan kembali. Akibatnya, memori proses dapat tampak tinggi dan stabil bahkan ketika heap yang dikelola tidak tumbuh. Selain itu, GC tidak secara otomatis mendeteksi batas memori wadah (batas cgroup-nya). Dalam lingkungan yang terbatas, tumpukan kemudian dapat tumbuh ke arah memori host daripada batas wadah. Hal ini dapat menyebabkan `OutOfMemoryException` atau wadah dihentikan.

Untuk membantu GC bekerja dengan baik di lingkungan terbatas:
+ Tetapkan batas memori eksplisit pada wadah sehingga GC menghormati batas cgroup, and/or atur `DOTNET_GCHeapHardLimit` (nilai byte absolut, dalam heksadesimal) atau variabel `DOTNET_GCHeapHardLimitPercent` lingkungan untuk menutup heap yang dikelola. Dalam beberapa kasus kehabisan memori Amazon ECS yang dilaporkan, pengaturan batas memori keras menyelesaikan crash.
+ Pada host ECS kecil AWS Lambda dan Amazon, pertimbangkan untuk menonaktifkan pengumpulan sampah (latar belakang) bersamaan sehingga kolektor tidak mencadangkan memori tambahan; misalnya, atur variabel `DOTNET_gcConcurrent` lingkungan ke`0`, atau disetel `<ConcurrentGarbageCollection>false</ConcurrentGarbageCollection>` dalam file proyek.
+ Ikat konkurensi Anda. Meluncurkan banyak operasi sekaligus, seperti memanggil `Task.WhenAll` koleksi besar, meningkatkan memori proses dan dapat membuat kumpulan koneksi kelaparan. Tutup tingkat paralelisme sebagai gantinya. Misalnya, hindari pola tak terbatas ini:

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

  Sebagai gantinya, batasi konkurensi dengan: `Parallel.ForEachAsync`

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

Untuk informasi selengkapnya tentang pengaturan ini, lihat Opsi konfigurasi [ Runtime untuk pengumpulan sampah ](https://learn.microsoft.com/en-us/dotnet/core/runtime-config/garbage-collector) di learn.microsoft.com. Untuk panduan khusus untuk AWS komputasi, lihat posting Blog Alat Peng AWS embang Meng [ konfigurasi Pengumpulan Sampah.NET untuk Amazon ECS dan. AWS Lambda](https://aws.amazon.com/blogs/developer/configuring-net-garbage-collection-for-amazon-ecs-and-aws-lambda)

## Kelola koneksi HTTP dan batas koneksi
<a name="net-dg-performance-connections"></a>

Di bawah throughput tinggi, dua masalah terkait koneksi umum terjadi. Yang pertama adalah membuka terlalu banyak koneksi berumur pendek. Ini menghabiskan port sementara, meninggalkan soket, dan menambahkan latensi jabat tangan `TIME_WAIT` TCP dan TLS. Yang kedua adalah memiliki terlalu sedikit koneksi yang tersedia, yang menghambat paralelisme. Menggunakan kembali satu klien berumur panjang (lihat[Gunakan kembali klien layanan](#net-dg-performance-reuse-clients)) adalah dasar untuk pengumpulan koneksi yang sehat, karena pengumpulan tergantung pada klien yang digunakan kembali.

Untuk menyetel jumlah koneksi bersamaan per titik akhir, atur `MaxConnectionsPerServer` properti pada konfigurasi klien. Ketika properti ini adalah `null` (default), default yang mendasarinya `HttpClientHandler` berlaku, yang secara efektif tidak terbatas di.NET modern. Naikkan hanya ketika banyak permintaan bersamaan ke titik akhir yang sama mengalami hambatan pada koneksi. Titik awal yang baik adalah jumlah puncak permintaan bersamaan yang Anda harapkan per titik akhir. Mengaturnya jauh lebih tinggi dari kebutuhan beban kerja Anda membuang soket tanpa meningkatkan throughput.

```
using Amazon.S3;

var config = new AmazonS3Config
{
    MaxConnectionsPerServer = 50
};

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

Jika Anda sudah menggunakan injeksi ketergantungan, konfigurasikan klien Anda melalui`AWSSDK.Extensions.NETCore.Setup`. Ini adalah pendekatan yang disarankan ketika Anda menggunakan DI atau mendaftarkan beberapa klien layanan. Ini memusatkan konfigurasi dan membuat klien mudah disuntikkan dan diuji. Anda dapat mengatur nilai konfigurasi dari konfigurasi aplikasi Anda, bukan dalam kode. Untuk informasi selengkapnya, lihat [AWSSDK.Extensions.NETCore.Setup dan IConfiguration](net-dg-config-netcore.md).

Terakhir, ikat paralelisme Anda sendiri sehingga Anda tidak memulai lebih banyak operasi bersamaan daripada yang diizinkan batas koneksi Anda. Misalnya, panggilan gerbang dengan `SemaphoreSlim` ukuran batas koneksi Anda:

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

## Konfigurasikan batas waktu dan percobaan ulang
<a name="net-dg-performance-timeouts"></a>

Batas waktu dan percobaan ulang memiliki efek langsung pada kinerja yang dirasakan. `Timeout`Nilai yang terlalu tinggi memungkinkan permintaan yang terhenti memblokir untuk waktu yang lama. Ketika layanan sudah mengembalikan kesalahan pelambatan, kebijakan coba ulang yang agresif menambahkan lebih banyak permintaan dan dapat memperburuk pelambatan. Pilih kebijakan coba ulang yang sesuai dengan toleransi aplikasi Anda untuk latensi versus kegagalan, dan biarkan pengecualian asli menyebar daripada mencoba lagi dengan cara yang menutupi hang.

**catatan**  
Pro `Timeout` perti tidak mempengaruhi panggilan asinkron. Jika Anda menggunakan panggilan asinkron, lihat [Menggunakan `CancellationToken` parameter untuk batas waktu](retries-timeouts.md#timeouts-async) sebagai gantinya.

Untuk informasi selengkapnya tentang mode coba lagi`MaxErrorRetry`,, dan `Timeout` properti (hanya `ReadWriteTimeout` berlaku untuk.NET Framework), bersama dengan contoh cara mengaturnya, lihat[Percobaan ulang dan batas waktu](retries-timeouts.md).

## Mengoptimalkan streaming dan transfer objek besar (Amazon S3)
<a name="net-dg-performance-streaming"></a>

Untuk mengunggah dan mengunduh objek besar, atau banyak objek, gunakan [ TransferUtility ](https://docs.aws.amazon.com/sdkfornet/v4/apidocs/items/S3/TTransferUtility.html) kelas di `Amazon.S3.Transfer` namespace. Ini mengunggah dan mengunduh secara paralel menggunakan transfer multipart, dan mengelola aliran, bagian, dan koneksi untuk Anda. Ini lebih cepat daripada transfer aliran tunggal dan merupakan cara yang disarankan untuk memindahkan objek besar.
+ **Unduhan multibagian paralel. ** Versi SDK sebelumnya mengunduh objek sebagai aliran tunggal, daripada mengunduh bagian secara paralel. Dimulai dengan `AWSSDK.S3` versi 4.0.17, `TransferUtility` menyediakan unduhan multibagian (paralel) melalui metode`DownloadWithResponseAsync`,`OpenStreamWithResponseAsync`, dan. `DownloadDirectoryWithResponseAsync` Saat Anda menggunakan`OpenStreamWithResponseAsync`, bagian-bagian objek akan di-buffer dalam memori saat Anda menggunakan aliran yang dikembalikan. Kontrol berapa banyak bagian yang disangga dengan `MaxInMemoryParts` properti dari [ TransferUtilityOpenStreamRequest](https://docs.aws.amazon.com/sdkfornet/v4/apidocs/items/S3/TTransferUtilityOpenStreamRequest.html). Untuk sebagian besar transfer, lebih suka`TransferUtility`. Unduh rentang byte sendiri dengan `ByteRange` properti [ GetObjectRequest ](https://docs.aws.amazon.com/sdkfornet/v4/apidocs/items/S3/TGetObjectRequest.html) hanya ketika Anda memerlukan rentang tertentu atau skema paralelisme khusus. Untuk informasi selengkapnya, lihat [ Memperkenalkan dukungan unduhan multibagian untuk AWS SDK untuk .NET Transfer Manager ](https://aws.amazon.com/blogs/developer/introducing-multipart-download-support-for-aws-sdk-for-net-transfer-manager/) di Blog AWS Alat Pengembang.
+ **Panjang konten untuk unggahan. ** Amazon S3 `PUT` memerlukan panjang konten yang diketahui, dan secara default SDK menghitung checksum atas isi permintaan. Ketika panjangnya diketahui dan aliran dapat dicari, SDK dapat melakukan ini tanpa menyangga seluruh objek dalam memori. Menangani `TransferUtility` aliran yang tidak dapat dicari untuk Anda dengan melakukan buffering sesuai kebutuhan. Jika Anda menelep `PutObjectAsync` on langsung dengan aliran yang tidak dapat dicari (seperti isi permintaan mentahASP.NET Core), permintaan dapat gagal. Menyediakan aliran yang dapat dicari, atur panjang konten secara eksplisit, atau konfigurasikan cara SDK menghitung checksum. Untuk informasi selengkapnya, lihat [ Perlindungan integritas data ](https://docs.aws.amazon.com/sdkref/latest/guide/feature-dataintegrity.html) di Panduan Refer AWS ensi SDK dan Alat.
+ **Ukuran bagian. ** Amazon S3 memungkinkan maksimum 10.000 bagian per unggahan multipart. Ketika panjang total diketahui, SDK menghitung ukuran bagian yang tetap dalam batas ini secara otomatis. Anda terutama perlu mengatur `PartSize` sendiri untuk streaming yang panjangnya tidak diketahui sebelumnya. Jika tidak, bagian default kecil dapat melebihi batas pada unggahan yang sangat besar. Ukuran bagian yang lebih besar juga mengurangi overhead per bagian, dengan mengorbankan lebih banyak memori per bagian.

## Mendiagnosis masalah kinerja
<a name="net-dg-performance-diagnose"></a>

Saat Anda menyelidiki perlambatan, hang, atau kebocoran yang tampak jelas, sinyal berikut membantu Anda menemukan penyebabnya dengan cepat:
+ Semakin banyak soket di `TIME_WAIT` status `CLOSE_WAIT` atau (terlihat dengan`netstat`) adalah sidik jari tanggapan yang tidak diinginkan atau klien yang dibuat dan dibuang per permintaan. Lihat [Buang tanggapan dan aliran](#net-dg-performance-dispose) dan [Gunakan kembali klien layanan](#net-dg-performance-reuse-clients).
+ Aktifkan metrik permintaan dan pencatatan respons untuk mengonfirmasi bahwa permintaan benar-benar dikirim dan untuk mengukur latensi. Tetapkan properti [ LoggingConfig ](https://docs.aws.amazon.com/sdkfornet/v4/apidocs/items/Util/TLoggingConfig.html) objek pada [ AWSConfig ](https://docs.aws.amazon.com/sdkfornet/v4/apidocs/items/Amazon/TAWSConfigs.html) sebelum Anda membuat klien layanan Anda. Klien menangkap pengaturan seperti `LogMetrics` saat dibangun.

  ```
  using Amazon;
  
  AWSConfigs.LoggingConfig.LogMetrics = true;
  AWSConfigs.LoggingConfig.LogResponses = ResponseLoggingOption.OnError;
  ```
+ Saat menyelidiki memori, bedakan memori seluruh proses dari tumpukan terkelola. Memori proses yang tinggi namun stabil seringkali merupakan GC yang menyimpan memori reklamasi daripada kebocoran. Lihat [Konfigurasikan pengumpulan sampah](#net-dg-performance-gc).