Pengujian Kinerja Akurat dengan `wrk`
API7.ai
November 25, 2022
Dalam artikel ini, kita akan membahas tentang pengujian kinerja. Bagian ini tidak unik untuk OpenResty tetapi berlaku untuk layanan backend lainnya.
Pengujian kinerja sangat umum, dan ketika kita mengirimkan produk, semuanya dilengkapi dengan metrik kinerja, seperti QPS, TPS, latensi, jumlah pengguna yang didukung secara bersamaan, dan sebagainya. Untuk proyek open-source, kami juga melakukan pengujian kinerja sebelum merilis versi untuk membandingkannya dengan versi sebelumnya untuk melihat apakah ada penurunan yang signifikan. Ada juga situs netral yang mempublikasikan data kinerja komparatif dari produk sejenis. Harus saya akui bahwa pengujian kinerja sangat dekat dengan kita.
Jadi, bagaimana cara melakukan pengujian kinerja yang ilmiah dan ketat?
Alat Pengujian Kinerja
Untuk melakukan pekerjaan dengan baik, Anda harus menggunakan alat yang baik. Memilih alat pengujian kinerja yang baik adalah setengah dari kesuksesan.
Alat Apache Benchmark, juga dikenal sebagai ab, yang seharusnya Anda kenal, bisa dibilang adalah alat pengujian kinerja yang paling mudah, tetapi sayangnya, tidak terlalu berguna. Ini karena server saat ini dikembangkan berdasarkan I/O konkuren dan asinkron, yang kinerjanya tidak buruk. ab tidak memanfaatkan multi-core mesin dan permintaan yang dihasilkan tidak memberikan tekanan yang cukup. Dalam hal ini, hasil yang diperoleh dari pengujian ab tidak nyata.
Oleh karena itu, kita dapat memilih kriteria untuk alat pengujian tekanan: alat itu sendiri memiliki kinerja yang solid dan dapat menghasilkan tekanan yang cukup signifikan untuk menekan program server.
Tentu saja, Anda juga bisa menghabiskan lebih banyak uang untuk memulai banyak klien pengujian tekanan dan mengubahnya menjadi sistem pengujian tekanan terdistribusi. Namun, jangan lupa bahwa kompleksitasnya juga meningkat.
Kembali ke praktik OpenResty, alat pengujian kinerja yang kami rekomendasikan adalah wrk. Pertama, mengapa kami memilihnya?
Pertama, wrk memenuhi kriteria pemilihan alat. Tekanan yang dihasilkan oleh wrk pada satu mesin dapat dengan mudah membuat NGINX mencapai 100% penggunaan CPU, apalagi aplikasi server lainnya.
Kedua, wrk memiliki banyak kesamaan dengan OpenResty. wrk bukan proyek open-source yang ditulis dari awal; ia berdiri di atas bahu LuaJIT dan Redis dan memanfaatkan sumber daya multi-core sistem untuk menghasilkan permintaan. Selain itu, wrk mengekspos API Lua yang memungkinkan Anda menyematkan skrip Lua Anda sendiri untuk menyesuaikan header dan konten permintaan, membuatnya sangat fleksibel.
Jadi, bagaimana kita harus menggunakan wrk? Ini semudah melihat cuplikan kode berikut.
wrk -t12 -c400 -d30s http://127.0.0.1:8080/index.html
Ini berarti wrk akan menggunakan 12 thread, memegang 400 koneksi panjang selama 30 detik, untuk mengirim permintaan HTTP ke antarmuka API yang ditentukan. Tentu saja, jika Anda tidak menentukan parameter, wrk akan memulai dua thread dan sepuluh koneksi panjang secara default.
Lingkungan Pengujian
Setelah menemukan alat pengujian, kita tidak bisa langsung memulai pengujian tekanan. Kita perlu memeriksa lingkungan pengujian sekali lagi. Ada empat item utama yang perlu diperiksa dalam lingkungan pengujian, dan saya akan membahasnya secara detail.
1. Matikan SELinux
Jika Anda memiliki sistem operasi CentOS/RedHat, disarankan untuk mematikan SELinux. Jika tidak, Anda mungkin akan menghadapi banyak masalah izin yang aneh.
Mari kita periksa apakah SELinux diaktifkan dengan perintah berikut.
$ sestatus SELinux status: disabled
Jika dikatakan aktif (enforcing), Anda dapat mematikannya sementara dengan $ setenforce 0; juga, modifikasi file /etc/selinux/config untuk mematikannya secara permanen dengan mengubah SELINUX=enforcing menjadi SELINUX=disabled.
2. Jumlah maksimum file terbuka
Kemudian, Anda perlu memeriksa jumlah maksimum file terbuka sistem saat ini dengan perintah berikut.
$ cat /proc/sys/fs/file-nr 3984 0 3255296
Angka terakhir 3255296 di sini adalah jumlah maksimum file terbuka. Jika angka ini kecil di mesin Anda, Anda perlu memodifikasi file /etc/sysctl.conf untuk meningkatkannya.
fs.file-max = 1020000 net.ipv4.ip_conntrack_max = 1020000 net.ipv4.netfilter.ip_conntrack_max = 1020000
Setelah modifikasi, Anda harus memulai ulang layanan sistem untuk membuatnya berlaku.
sudo sysctl -p /etc/sysctl.conf
3. Batasan Proses
Selain jumlah maksimum file terbuka pada sistem secara keseluruhan, ada juga batasan jumlah file yang dapat dibuka oleh suatu proses, yang dapat Anda periksa dengan perintah ulimit.
$ ulimit -n 1024
Anda akan melihat bahwa nilai ini defaultnya adalah 1024, nilai yang kecil. Karena setiap permintaan pengguna sesuai dengan satu handle file, dan pengujian tekanan menghasilkan banyak permintaan, kita perlu meningkatkan nilai ini dan mengubahnya menjadi jutaan, yang dapat Anda ubah sementara dengan perintah berikut.
ulimit -n 1024000
Anda juga dapat memodifikasi file konfigurasi /etc/security/limits.conf untuk membuatnya permanen.
* hard nofile 1024000 * soft nofile 1024000
4. Konfigurasi NGINX
Terakhir, Anda perlu melakukan sedikit perubahan pada konfigurasi NGINX, yaitu tiga baris kode berikut.
events { worker_connections 10240; }
Ini memungkinkan kita untuk meningkatkan jumlah koneksi per Worker. Karena nilai defaultnya hanya 512, ini tidak cukup untuk pengujian tekanan tinggi.
Pemeriksaan Sebelum Pengujian Tekanan
Pada titik ini, lingkungan pengujian sudah siap. Anda pasti ingin segera memulai dan mengujinya, bukan? Mari kita periksa sekali lagi sebelum meluncurkan pengujian dengan wrk. Bagaimanapun, manusia bisa melakukan kesalahan, sehingga penting untuk melakukan pengujian silang.
Pengujian terakhir ini dapat dibagi menjadi dua langkah.
1. Gunakan alat otomatis c1000k
c1000k berasal dari penulis SSDB. Seperti yang bisa Anda lihat dari namanya, tujuan alat ini adalah untuk memeriksa apakah lingkungan Anda dapat memenuhi persyaratan 10^6 koneksi bersamaan.
Penggunaan alat ini juga sangat mudah. Kita memulai server dan client, yang sesuai dengan program server yang mendengarkan pada port 7000 dan program klien yang meluncurkan pengujian tekanan untuk mensimulasikan pengujian tekanan dalam lingkungan nyata:
. /server 7000 . /client 127.0.0.1 7000
Segera setelah itu, client mengirimkan permintaan ke server untuk memeriksa apakah lingkungan sistem saat ini dapat mendukung satu juta koneksi bersamaan. Anda dapat menjalankannya sendiri dan melihat hasilnya.
2. Periksa apakah program server berjalan normal
Jika program server tidak berfungsi dengan benar, pengujian tekanan bisa menjadi pengujian pembaruan log kesalahan atau pengujian respons 404.
Jadi, langkah terakhir dan paling penting dari pengujian lingkungan pengujian adalah menjalankan set pengujian unit server atau memanggil beberapa antarmuka utama secara manual untuk memastikan bahwa semua antarmuka, respons, dan kode respons HTTP dari pengujian wrk normal dan tidak ada pesan tingkat kesalahan di logs/error.log.
Mengirim Permintaan
Oke, sekarang semuanya siap. Mari kita mulai pengujian tekanan dengan wrk!
$ wrk -d 30 http://127.0.0.2:9080/hello Running 30s test @ http://127.0.0.2:9080/hello 2 threads and 10 connections Thread Stats Avg Stdev Max +/- Stdev Latency 595.39us 178.51us 22.24ms 90.63% Req/Sec 8.33k 642.91 9.46k 59.80% 499149 requests in 30.10s, 124.22MB read Requests/sec: 16582.76 Transfer/sec: 4.13MB
Saya tidak menentukan parameter di sini sehingga wrk akan memulai 2 thread dan 10 koneksi panjang secara default. Anda tidak perlu menyesuaikan jumlah thread dan koneksi di wrk menjadi sangat besar; selama Anda bisa membuat program target mencapai 100% penggunaan CPU, itu sudah cukup.
Tetapi waktu pengujian tekanan tidak boleh terlalu singkat karena beberapa detik pengujian tekanan tidak berarti. Jika tidak, pengujian tekanan kemungkinan besar akan selesai sebelum program server menyelesaikan hot reloading. Pada saat yang sama, Anda perlu menggunakan alat pemantauan seperti top atau htop untuk memeriksa apakah program target di server berjalan pada 100% penggunaan CPU selama pengujian tekanan.
Secara fenomenal, jika CPU sepenuhnya dimuat dan penggunaan CPU dan memori menurun dengan cepat setelah pengujian dihentikan, maka selamat, pengujian berhasil diselesaikan. Namun, jika ada pengecualian seperti berikut, sebagai pengembang server, Anda harus memperhatikannya.
- CPU tidak dapat sepenuhnya dimuat. Ini bukan masalah
wrk; bisa jadi batasan jaringan atau operasi blocking dalam kode Anda. Anda dapat menentukan ini dengan meninjau kode Anda atau menggunakan flame graphoff CPU. - CPU selalu sepenuhnya dimuat, bahkan ketika tekanan berhenti. Ini menunjukkan adanya loop tak terbatas dalam kode yang disebabkan oleh ekspresi reguler atau bug LuaJIT, yang pernah saya temui di lingkungan nyata. Pada titik ini, Anda perlu menggunakan flame graph CPU untuk menentukannya.
Akhirnya, mari kita lihat statistik wrk. Mengenai hasil ini, kami umumnya fokus pada dua nilai.
Pertama adalah QPS, atau Requests/sec: 16582.76, yang merupakan angka pasti yang menunjukkan berapa banyak permintaan yang diproses per detik di sisi server.
Kedua adalah Latency: Latency 595.39us 178.51us 22.24ms 90.63%, sama pentingnya dengan QPS, yang mencerminkan kecepatan respons sistem. Misalnya, untuk aplikasi gateway, kami ingin menjaga latensi dalam 1 ms.
Selain itu, wrk juga menyediakan parameter latency yang mencetak distribusi persentase latensi secara detail, misalnya.
Latency Distribution 50% 134.00us 75% 180.00us 90% 247.00us 99% 552.00us
Namun, data distribusi latensi wrk tidak akurat karena secara artifisial menambahkan gangguan jaringan dan alat yang memperbesar latensi, yang memerlukan perhatian khusus Anda.
Ringkasan
Pengujian kinerja adalah pekerjaan teknis; tidak banyak orang yang bisa melakukannya dengan benar dan baik. Saya harap artikel ini akan memberi Anda pemahaman yang lebih komprehensif tentang pengujian kinerja.
Terakhir, saya akan meninggalkan Anda dengan pertanyaan: wrk mendukung skrip Lua kustom untuk melakukan pengujian tekanan, jadi bisakah Anda menulis skrip Lua sederhana berdasarkan dokumentasinya? Mungkin sedikit sulit, tetapi Anda akan memahami maksud antarmuka yang diekspos wrk ketika Anda menyelesaikannya.
Anda dipersilakan untuk membagikan artikel ini dengan lebih banyak orang, dan kita akan membuat kemajuan bersama.