Mengoptimalkan aplikasi Go

Dalam tutorial ini, Anda akan men-deploy aplikasi Go yang sengaja tidak efisien yang dikonfigurasi untuk mengumpulkan data profil. Anda menggunakan antarmuka Profiler untuk melihat data profil dan mengidentifikasi potensi pengoptimalan. Kemudian, Anda mengubah aplikasi, men-deploy-nya, dan mengevaluasi efek perubahan.

Sebelum memulai

  1. Sign in to your Google Cloud account. If you're new to Google Cloud, create an account to evaluate how our products perform in real-world scenarios. New customers also get $300 in free credits to run, test, and deploy workloads.
  2. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Go to project selector

  3. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Go to project selector

  4. Enable the required API.

    Enable the API

  5. Untuk membuka Cloud Shell, di toolbar konsol Google Cloud, klik Aktifkan Cloud Shell:

    Mengaktifkan Cloud Shell.

    Setelah beberapa saat, sesi Cloud Shell akan terbuka di dalam konsol Google Cloud:

    Sesi Cloud Shell.

Contoh aplikasi

Tujuan utamanya adalah memaksimalkan jumlah kueri per detik yang dapat diproses server. Tujuan sekundernya adalah mengurangi penggunaan memori dengan menghilangkan alokasi memori yang tidak perlu.

Server, menggunakan framework gRPC, menerima kata atau frasa, lalu menampilkan frekuensi kemunculan kata atau frasa dalam karya Shakespeare.

Jumlah rata-rata kueri per detik yang dapat ditangani server ditentukan oleh pengujian beban server. Untuk setiap putaran pengujian, simulator klien dipanggil dan diperintahkan untuk mengeluarkan 20 kueri berurutan. Setelah putaran selesai, jumlah kueri yang dikirim oleh simulator klien, waktu yang berlalu, dan jumlah rata-rata kueri per detik akan ditampilkan.

Kode server sengaja dibuat tidak efisien.

Menjalankan aplikasi contoh

Download dan jalankan aplikasi contoh:

  1. Di Cloud Shell, jalankan perintah berikut:

    git clone https://github.com/GoogleCloudPlatform/golang-samples.git
    cd golang-samples/profiler/shakesapp
    
  2. Jalankan aplikasi dengan versi yang ditetapkan ke 1 dan jumlah putaran yang ditetapkan ke 15:

    go run . -version 1 -num_rounds 15
    

    Setelah satu atau dua menit, data profil akan ditampilkan. Data profil terlihat seperti contoh berikut:

    Flame chart awal untuk penggunaan waktu CPU.

    Pada screenshot, perhatikan bahwa Jenis profil ditetapkan ke CPU time. Hal ini menunjukkan bahwa data penggunaan CPU ditampilkan dalam grafik api.

    Contoh output yang dicetak di Cloud Shell ditampilkan di bawah ini:

    $ go run . -version 1 -num_rounds 15
    2020/08/27 17:27:34 Simulating client requests, round 1
    2020/08/27 17:27:34 Stackdriver Profiler Go Agent version: 20200618
    2020/08/27 17:27:34 profiler has started
    2020/08/27 17:27:34 creating a new profile via profiler service
    2020/08/27 17:27:51 Simulated 20 requests in 17.3s, rate of 1.156069 reqs / sec
    2020/08/27 17:27:51 Simulating client requests, round 2
    2020/08/27 17:28:10 Simulated 20 requests in 19.02s, rate of 1.051525 reqs / sec
    2020/08/27 17:28:10 Simulating client requests, round 3
    2020/08/27 17:28:29 Simulated 20 requests in 18.71s, rate of 1.068947 reqs / sec
    ...
    2020/08/27 17:44:32 Simulating client requests, round 14
    2020/08/27 17:46:04 Simulated 20 requests in 1m32.23s, rate of 0.216849 reqs / sec
    2020/08/27 17:46:04 Simulating client requests, round 15
    2020/08/27 17:47:52 Simulated 20 requests in 1m48.03s, rate of 0.185134 reqs / sec
    

    Output Cloud Shell menampilkan waktu yang berlalu untuk setiap iterasi dan tingkat permintaan rata-rata. Saat aplikasi dimulai, entri "Simulasi 20 permintaan dalam 17,3 detik, kecepatan 1,156069 permintaan / detik" menunjukkan bahwa server menjalankan sekitar 1 permintaan per detik. Pada putaran terakhir, entri "Simulasi 20 permintaan dalam 1m48,03s, rasio 0,185134 reqs / dtk" menunjukkan bahwa server mengeksekusi sekitar 1 permintaan setiap 5 detik.

Menggunakan profil waktu CPU untuk memaksimalkan kueri per detik

Salah satu pendekatan untuk memaksimalkan jumlah kueri per detik adalah dengan mengidentifikasi metode intens CPU dan mengoptimalkan penerapannya. Di bagian ini, Anda akan menggunakan profil waktu CPU untuk mengidentifikasi metode yang membebani CPU di server.

Mengidentifikasi penggunaan waktu CPU

Frame root grafik api mencantumkan total waktu CPU yang digunakan oleh aplikasi selama interval pengumpulan 10 detik:

Tampilan yang diperluas dari frame root diagram lingkaran api.

Dalam contoh ini, layanan menggunakan 2.37 s. Saat sistem berjalan di satu core, penggunaan waktu CPU 2,37 detik sesuai dengan penggunaan 23,7% dari core tersebut. Untuk informasi selengkapnya, lihat Jenis pembuatan profil yang tersedia.

Mengubah aplikasi

Mengevaluasi perubahan

Untuk mengevaluasi perubahan tersebut, lakukan hal berikut:

  1. Jalankan aplikasi dengan versi aplikasi yang ditetapkan ke 2:

    go run . -version 2 -num_rounds 40
    

    Bagian selanjutnya menunjukkan bahwa dengan pengoptimalan, waktu yang diperlukan untuk menjalankan satu putaran jauh lebih sedikit daripada aplikasi yang tidak dimodifikasi. Untuk memastikan aplikasi berjalan cukup lama untuk mengumpulkan dan mengupload profil, jumlah putaran akan ditingkatkan.

  2. Tunggu hingga aplikasi selesai, lalu lihat data profil untuk versi aplikasi ini:

    • Klik NOW untuk memuat data profil terbaru. Untuk informasi selengkapnya, lihat Rentang waktu.
    • Di menu Version, pilih 2.

Misalnya, grafik api seperti yang ditunjukkan:

Grafik flame yang menunjukkan penggunaan waktu CPU versi 2.

Dalam gambar ini, frame root menampilkan nilai 7.8 s. Sebagai akibat dari perubahan fungsi pencocokan string, waktu CPU yang digunakan oleh aplikasi meningkat dari 2,37 detik menjadi 7,8 detik, atau aplikasi beralih dari menggunakan 23,7% core CPU menjadi menggunakan 78% core CPU.

Lebar frame adalah ukuran proporsional dari penggunaan waktu CPU. Dalam contoh ini, lebar frame untuk GetMatchCount menunjukkan bahwa fungsi menggunakan sekitar 49% dari semua waktu CPU yang digunakan oleh aplikasi. Dalam grafik api asli, bingkai yang sama ini adalah sekitar 72% dari lebar grafik. Untuk melihat penggunaan waktu CPU yang tepat, Anda dapat menggunakan tooltip frame atau menggunakan Daftar fungsi fokus:

Daftar fungsi fokus yang menampilkan penggunaan waktu CPU versi 2.

Output di Cloud Shell menunjukkan bahwa versi yang diubah menyelesaikan sekitar 5,8 permintaan per detik:

$ go run . -version 2 -num_rounds 40
2020/08/27 18:21:40 Simulating client requests, round 1
2020/08/27 18:21:40 Stackdriver Profiler Go Agent version: 20200618
2020/08/27 18:21:40 profiler has started
2020/08/27 18:21:40 creating a new profile via profiler service
2020/08/27 18:21:44 Simulated 20 requests in 3.67s, rate of 5.449591 reqs / sec
2020/08/27 18:21:44 Simulating client requests, round 2
2020/08/27 18:21:47 Simulated 20 requests in 3.72s, rate of 5.376344 reqs / sec
2020/08/27 18:21:47 Simulating client requests, round 3
2020/08/27 18:21:51 Simulated 20 requests in 3.58s, rate of 5.586592 reqs / sec
...
2020/08/27 18:23:51 Simulating client requests, round 39
2020/08/27 18:23:54 Simulated 20 requests in 3.46s, rate of 5.780347 reqs / sec
2020/08/27 18:23:54 Simulating client requests, round 40
2020/08/27 18:23:58 Simulated 20 requests in 3.4s, rate of 5.882353 reqs / sec

Perubahan kecil pada aplikasi memiliki dua efek yang berbeda:

  • Jumlah permintaan per detik meningkat dari kurang dari 1 per detik menjadi 5,8 per detik.

  • Waktu CPU per permintaan, yang dihitung dengan membagi penggunaan CPU dengan jumlah permintaan per detik, menurun menjadi 13,4% dari 23,7%.

    Perhatikan bahwa waktu CPU per permintaan menurun meskipun penggunaan waktu CPU meningkat dari 2,37 detik, yang sesuai dengan penggunaan 23,7% dari satu core CPU, menjadi 7,8 detik, atau 78% dari core CPU.

Menggunakan profil heap yang dialokasikan untuk meningkatkan penggunaan resource

Bagian ini mengilustrasikan cara menggunakan heap dan profil heap yang dialokasikan untuk mengidentifikasi metode yang intensif alokasi di aplikasi:

  • Profil heap menunjukkan jumlah memori yang dialokasikan di heap program pada saat profil dikumpulkan.

  • Profil heap yang dialokasikan menunjukkan jumlah total memori yang dialokasikan di heap program selama interval saat profil dikumpulkan. Dengan membagi nilai ini dengan 10 detik, yaitu interval pengumpulan profil, Anda dapat menafsirkannya sebagai rasio alokasi.

Mengaktifkan pengumpulan profil heap

  1. Jalankan aplikasi dengan versi aplikasi yang ditetapkan ke 3 dan aktifkan pengumpulan heap dan profil heap yang dialokasikan.

    go run . -version 3 -num_rounds 40 -heap -heap_alloc
    
  2. Tunggu hingga aplikasi selesai, lalu lihat data profil untuk versi aplikasi ini:

    • Klik NOW untuk memuat data profil terbaru.
    • Di menu Version, pilih 3.
    • Di menu Profiler type, pilih Allocated heap.

    Misalnya, grafik api seperti yang ditunjukkan:

    Grafik flame dari profil heap yang dialokasikan untuk versi 3.

Mengidentifikasi tingkat alokasi heap

Frame root menampilkan jumlah total heap yang dialokasikan selama 10 detik saat profil dikumpulkan, yang dirata-ratakan di semua profil. Dalam contoh ini, frame root menunjukkan bahwa, rata-rata, memori 1,535 GiB dialokasikan.

Mengubah aplikasi

Mengevaluasi perubahan

Untuk mengevaluasi perubahan tersebut, lakukan hal berikut:

  1. Jalankan aplikasi dengan versi aplikasi yang ditetapkan ke 4:

    go run . -version 4 -num_rounds 60 -heap -heap_alloc
    
  2. Tunggu hingga aplikasi selesai, lalu lihat data profil untuk versi aplikasi ini:

    • Klik NOW untuk memuat data profil terbaru.
    • Di menu Version, pilih 4.
    • Di menu Profiler type, pilih Allocated heap.
  3. Untuk mengukur efek perubahan readFiles pada rasio alokasi heap, bandingkan profil heap yang dialokasikan untuk versi 4 dengan yang dikumpulkan untuk 3:

    Perbandingan profil heap yang dialokasikan antara versi 4 dan 3.

    Tooltip frame root menunjukkan bahwa dengan versi 4, jumlah rata-rata memori yang dialokasikan selama pengumpulan profil menurun sebesar 1,301 GiB, dibandingkan dengan versi 3. Tooltip untuk readFiles.func1 menunjukkan penurunan 1,045 GiB:

    Perbandingan tooltip file siap untuk jenis profil heap yang dialokasikan.

  4. Untuk mengukur efek pada pembersihan sampah memori, konfigurasikan perbandingan profil waktu CPU. Pada screenshot berikut, filter diterapkan untuk menampilkan stack untuk pengumpulan sampah Go runtime.gcBgMarkWorker.*. Screenshot menunjukkan bahwa penggunaan CPU untuk pembersihan sampah dikurangi menjadi 4,97% dari 16,8%.

    Perbandingan penggunaan waktu CPU dari proses pengumpulan sampah latar belakang v4 ke v3.

  5. Untuk menentukan apakah ada dampak perubahan pada jumlah permintaan per detik yang ditangani oleh aplikasi, lihat output di Cloud Shell. Dalam contoh ini, versi 4 menyelesaikan hingga 15 permintaan per detik, yang jauh lebih tinggi daripada 5,8 permintaan per detik versi 3:

    $ go run . -version 4 -num_rounds 60 -heap -heap_alloc
    2020/08/27 21:51:42 Simulating client requests, round 1
    2020/08/27 21:51:42 Stackdriver Profiler Go Agent version: 20200618
    2020/08/27 21:51:42 profiler has started
    2020/08/27 21:51:42 creating a new profile via profiler service
    2020/08/27 21:51:44 Simulated 20 requests in 1.47s, rate of 13.605442 reqs / sec
    2020/08/27 21:51:44 Simulating client requests, round 2
    2020/08/27 21:51:45 Simulated 20 requests in 1.3s, rate of 15.384615 reqs / sec
    2020/08/27 21:51:45 Simulating client requests, round 3
    2020/08/27 21:51:46 Simulated 20 requests in 1.31s, rate of 15.267176 reqs / sec
    ...
    

    Peningkatan kueri per detik yang ditayangkan oleh aplikasi mungkin disebabkan oleh sedikitnya waktu yang dihabiskan untuk pembersihan sampah memori.

  • Anda bisa mendapatkan pemahaman yang lebih lengkap tentang efek perubahan pada readFiles dengan melihat profil heap. Perbandingan profil heap untuk versi 4 dengan versi 3 menunjukkan bahwa penggunaan heap menurun menjadi 18,47 MiB dari 70,95 MiB:

    Perbandingan penggunaan heap untuk versi 4 hingga versi 3.

Ringkasan

Dalam panduan memulai ini, waktu CPU dan profil heap yang dialokasikan digunakan untuk mengidentifikasi potensi pengoptimalan pada aplikasi. Sasarannya adalah untuk memaksimalkan jumlah permintaan per detik dan menghilangkan alokasi yang tidak perlu.

  • Dengan menggunakan profil waktu CPU, fungsi yang menggunakan CPU secara intensif telah diidentifikasi. Setelah menerapkan perubahan sederhana, rasio permintaan server meningkat menjadi 5,8 per detik, naik dari sekitar 1 per detik.

  • Dengan menggunakan profil heap yang dialokasikan, fungsi shakesapp/server.go readFiles diidentifikasi memiliki tingkat alokasi yang tinggi. Setelah mengoptimalkan readFiles, kapasitas permintaan server meningkat menjadi 15 permintaan per detik dan jumlah rata-rata memori yang dialokasikan selama pengumpulan profil 10 detik turun sebesar 1,301 GiB.

Langkah selanjutnya

Untuk informasi tentang cara menjalankan agen Cloud Profiler, lihat: