Panduan untuk pengujian beban layanan backend dengan Load Balancer Aplikasi

Saat mengintegrasikan layanan backend dengan Application Load Balancer, penting untuk mengukur performa layanan backend itu sendiri, tanpa load balancer. Pengujian beban dalam kondisi terkontrol membantu Anda menilai kompromi perencanaan kapasitas antara berbagai dimensi performa, seperti throughput dan latensi. Karena perencanaan kapasitas yang cermat masih dapat underestimate permintaan sebenarnya, sebaiknya gunakan pengujian beban untuk secara proaktif menentukan pengaruh ketersediaan layanan saat sistem kelebihan beban.

Sasaran pengujian beban

Pengujian beban standar mengukur perilaku layanan backend yang terlihat secara eksternal dalam berbagai dimensi beban. Beberapa dimensi pengujian ini yang paling relevan adalah sebagai berikut:

  • Throughput permintaan: Jumlah permintaan yang ditayangkan per detik.
  • Konkurensi permintaan: Jumlah permintaan yang diproses secara serentak.
  • Throughput koneksi: Jumlah koneksi yang dimulai oleh klien per detik. Sebagian besar layanan yang menggunakan Transport Layer Security (TLS) memiliki beberapa overhead negosiasi TLS dan transpor jaringan yang terkait dengan setiap koneksi yang tidak bergantung pada pemrosesan permintaan.
  • Konkurensi koneksi: Jumlah koneksi klien yang diproses secara serentak.

  • Latensi permintaan: Total waktu yang berlalu antara awal permintaan dan akhir respons.

  • Rasio error: Seberapa sering permintaan menyebabkan error, seperti error HTTP 5xx dan koneksi yang ditutup sebelum waktunya.

Untuk menilai kondisi server saat beban, prosedur pengujian beban juga dapat mengumpulkan metrik layanan internal berikut:

  • Penggunaan resource sistem: Resource sistem, seperti CPU, RAM, dan handle file (soket), biasanya dinyatakan dalam persentase.

    Pentingnya metrik ini berbeda-beda berdasarkan cara layanan diimplementasikan. Aplikasi mengalami penurunan performa, beban yang berkurang, atau error saat kehabisan resource. Oleh karena itu, penting untuk menentukan ketersediaan resource saat host mengalami beban berat.

  • Penggunaan resource terbatas lainnya: Resource non-sistem yang dapat habis saat beban tinggi, seperti di lapisan aplikasi.

    Beberapa contoh resource tersebut mencakup:

    • Kumpulan thread atau proses pekerja yang dibatasi.
    • Untuk server aplikasi yang menggunakan thread, biasanya jumlah thread pekerja yang beroperasi secara serentak dibatasi. Batas ukuran kumpulan thread berguna untuk mencegah kehabisan memori dan CPU, tetapi setelan default sering kali sangat konservatif. Batas yang terlalu rendah dapat mencegah penggunaan resource sistem secara memadai.
    • Beberapa server menggunakan kumpulan proses, bukan kumpulan thread. Misalnya, server Apache saat disiapkan dengan Model Multi-Pemrosesan Prefork, menetapkan satu proses ke setiap koneksi klien. Jadi, batas ukuran kumpulan menentukan batas atas konkurensi koneksi.
    • Layanan yang di-deploy sebagai frontend ke layanan lain yang memiliki kumpulan koneksi backend dengan ukuran terbatas.

Perencanaan kapasitas versus pengujian overload

Alat pengujian beban membantu Anda mengukur berbagai dimensi penskalaan satu per satu. Untuk perencanaan kapasitas, tentukan nilai minimum beban untuk performa yang dapat diterima dalam beberapa dimensi. Misalnya, alih-alih mengukur batas absolut permintaan layanan secara keseluruhan, pertimbangkan untuk mengukur hal berikut:

  • Rasio permintaan saat layanan dapat ditayangkan dengan latensi persentil ke-99 yang kurang dari jumlah milidetik yang ditentukan. Jumlah ini ditentukan oleh SLO layanan.
  • Rasio permintaan maksimum yang tidak menyebabkan pemanfaatan resource sistem melebihi tingkat optimal. Perhatikan bahwa penggunaan optimal bervariasi menurut aplikasi dan dapat jauh lebih rendah dari 100%. Misalnya, pada penggunaan memori puncak 80%, aplikasi mungkin dapat menangani lonjakan beban kecil lebih baik daripada jika penggunaan puncaknya mencapai 99%.

Meskipun penting untuk menggunakan hasil uji beban guna membentuk keputusan perencanaan kapasitas, penting juga untuk memahami perilaku layanan saat beban melebihi kapasitas. Beberapa perilaku server yang sering dievaluasi menggunakan pengujian overload adalah sebagai berikut:

  • Pengurangan beban: Saat menerima permintaan atau koneksi masuk yang berlebihan, layanan dapat merespons dengan memperlambat semua permintaan, atau dengan menolak beberapa permintaan untuk mempertahankan performa yang dapat diterima untuk permintaan yang tersisa. Sebaiknya gunakan pendekatan kedua untuk mencegah waktu tunggu klien habis sebelum menerima respons dan mengurangi risiko kehabisan memori dengan menurunkan permintaan serentak di server.

  • Ketahanan terhadap kehabisan resource: Layanan umumnya menghindari error akibat kehabisan resource karena permintaan yang tertunda sulit untuk melakukan progres lebih lanjut jika layanan mengalami error. Jika layanan backend memiliki banyak instance, keandalan setiap instance sangat penting untuk ketersediaan layanan secara keseluruhan. Saat instance dimulai ulang dari error, instance lain mungkin mengalami lebih banyak beban, yang berpotensi menyebabkan kegagalan beruntun.

Pedoman pengujian umum

Saat menentukan kasus pengujian, pertimbangkan panduan berikut.

Membuat pengujian berskala kecil

Buat pengujian skala kecil untuk mengukur batas performa server. Dengan kapasitas server yang berlebihan, ada risiko bahwa pengujian tidak akan mengungkapkan batas performa layanan itu sendiri, tetapi mungkin menemukan bottleneck di sistem lain, seperti host klien atau lapisan jaringan.

Untuk hasil terbaik, pertimbangkan kasus pengujian yang menggunakan satu instance virtual machine (VM) atau Pod Google Kubernetes Engine (GKE) untuk menguji layanan secara independen. Untuk mencapai beban penuh di server, jika perlu, Anda dapat menggunakan beberapa VM, tetapi ingat bahwa VM dapat mempersulit pengumpulan data performa.

Memilih pola pemuatan loop terbuka

Sebagian besar generator beban menggunakan pola loop tertutup untuk membatasi jumlah permintaan serentak dan menunda permintaan baru hingga permintaan sebelumnya selesai. Sebaiknya jangan gunakan pendekatan ini karena klien produksi layanan mungkin tidak menunjukkan perilaku throttling tersebut.

Sebaliknya, pola loop terbuka memungkinkan generator beban menyimulasikan beban produksi dengan mengirim permintaan pada kecepatan yang stabil, terlepas dari kecepatan respons server yang diterima.

Sebaiknya gunakan generator beban berikut untuk pengujian beban layanan backend:

Nighthawk

Nighthawk adalah alat open source yang dikembangkan dengan koordinasi project Envoy. Anda dapat menggunakannya untuk menghasilkan beban klien, memvisualisasikan benchmark, dan mengukur performa server untuk sebagian besar skenario pengujian beban layanan HTTPS.

Menguji HTTP/1

Untuk menguji HTTP/1, gunakan perintah berikut:

nighthawk_client URI \
    --duration DURATION \
    --open-loop \
    --no-default-failure-predicates \
    --protocol http1 \
    --request-body-size REQ_BODY_SIZE \
    --concurrency CONCURRENCY \
    --rps RPS \
    --connections CONNECTIONS

Ganti kode berikut:

  • URI: URI untuk benchmark
  • DURATION: total waktu pengujian dalam detik
  • REQ_BODY_SIZE: ukuran payload POST dalam setiap permintaan
  • CONCURRENCY: jumlah total loop peristiwa serentak

    Jumlah ini harus cocok dengan jumlah core VM klien

  • RPS: target kecepatan permintaan per detik, per loop peristiwa

  • CONNECTIONS: jumlah koneksi serentak, per loop peristiwa

Lihat contoh berikut:

nighthawk_client http://10.20.30.40:80 \
    --duration 600 --open-loop --no-default-failure-predicates \
    --protocol http1 --request-body-size 5000 \
    --concurrency 16 --rps 500 --connections 200

Output dari setiap pengujian yang dijalankan memberikan histogram latensi respons. Dalam contoh dari dokumentasi Nighthawk, perhatikan bahwa latensi persentil ke-99 adalah sekitar 135 mikrodetik.

Initiation to completion
    samples: 9992
    mean:    0s 000ms 113us
    pstdev:  0s 000ms 061us

    Percentile  Count       Latency
    0           1           0s 000ms 077us
    0.5         4996        0s 000ms 115us
    0.75        7495        0s 000ms 118us
    0.8         7998        0s 000ms 118us
    0.9         8993        0s 000ms 121us
    0.95        9493        0s 000ms 124us
    0.990625    9899        0s 000ms 135us
    0.999023    9983        0s 000ms 588us
    1           9992        0s 004ms 090us

Menguji HTTP/2

Untuk menguji HTTP/2, gunakan perintah berikut:

nighthawk_client URI \
    --duration DURATION \
    --open-loop \
    --no-default-failure-predicates \
    --protocol http2 \
    --request-body-size REQ_BODY_SIZE \
    --concurrency CONCURRENCY \
    --rps RPS \
    --max-active-requests MAX_ACTIVE_REQUESTS \
    --max-concurrent-streams MAX_CONCURRENT_STREAMS

Ganti kode berikut:

  • URI: URI untuk benchmark
  • DURATION: total waktu pengujian dalam detik
  • REQ_BODY_SIZE: ukuran payload POST dalam setiap permintaan
  • CONCURRENCY: jumlah total loop peristiwa serentak

    Jumlah ini harus cocok dengan jumlah core VM klien

  • RPS: target kecepatan permintaan per detik untuk setiap loop peristiwa

  • MAX_ACTIVE_REQUESTS: jumlah maksimum permintaan aktif serentak untuk setiap loop peristiwa

  • MAX_CONCURRENT_STREAMS: jumlah maksimum streaming serentak yang diizinkan di setiap koneksi HTTP/2

Lihat contoh berikut:

nighthawk_client http://10.20.30.40:80 \
    --duration 600 --open-loop --no-default-failure-predicates \
    --protocol http2 --request-body-size 5000 \
    --concurrency 16 --rps 500 \
    --max-active-requests 200 --max-concurrent-streams 1

ab (Alat benchmark Apache)

ab adalah alternatif yang kurang fleksibel dibandingkan Nighthawk, tetapi tersedia sebagai paket di hampir setiap distribusi Linux. ab hanya direkomendasikan untuk pengujian yang cepat dan sederhana.

Untuk menginstal ab, gunakan perintah berikut:

  • Di Debian dan Ubuntu, jalankan sudo apt-get install apache2-utils.
  • Pada distribusi berbasis RedHat, jalankan sudo yum install httpd-utils.

Setelah menginstal ab, gunakan perintah berikut untuk menjalankannya:

ab -c CONCURRENCY \
    -n NUM_REQUESTS \
    -t TIMELIMIT \
    -p POST_FILE URI

Ganti kode berikut:

  • CONCURRENCY: jumlah permintaan serentak yang akan dilakukan
  • NUM_REQUESTS: jumlah permintaan yang akan dilakukan
  • TIMELIMIT: jumlah maksimum detik yang akan dihabiskan untuk permintaan
  • POST_FILE: file lokal yang berisi payload HTTP POST
  • URI: URI untuk benchmark

Lihat contoh berikut:

ab -c 200 -n 1000000 -t 600 -P body http://10.20.30.40:80

Perintah dalam contoh sebelumnya mengirimkan permintaan dengan konkurensi 200 (pola loop tertutup), dan berhenti setelah 1.000.000 (satu juta) permintaan atau 600 detik waktu berlalu. Perintah ini juga menyertakan konten file body sebagai payload POST HTTP.

Perintah ab menghasilkan histogram latensi respons yang mirip dengan Nighthawk, tetapi resolusinya dibatasi hingga milidetik, bukan mikrodetik:

Percentage of the requests served within a certain time (ms)
    50%     7
    66%     7
    75%     7
    80%     7
    90%    92
    95%   121
    98%   123
    99%   127
    100%  156 (longest request)

Langkah selanjutnya