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 akan memodifikasi aplikasi, men-deploy-nya, dan mengevaluasi efek modifikasi tersebut.

Sebelum memulai

  1. Login ke akun Google Cloud Anda. Jika Anda baru menggunakan Google Cloud, buat akun untuk mengevaluasi performa produk kami dalam skenario dunia nyata. Pelanggan baru juga mendapatkan kredit gratis senilai $300 untuk menjalankan, menguji, dan men-deploy workload.
  2. Di konsol Google Cloud, pada halaman pemilih project, pilih atau buat project Google Cloud.

    Buka pemilih project

  3. Di konsol Google Cloud, pada halaman pemilih project, pilih atau buat project Google Cloud.

    Buka pemilih project

  4. Pada panel navigasi Google Cloud Console, pilih APIs & Services, klik Enable APIs and Services, lalu aktifkan Cloud Profiler API:

    Buka setelan Profiler API

  5. Jika API diaktifkan ditampilkan, berarti API sudah diaktifkan. Jika belum, klik tombol Enable.

  6. Untuk membuka Cloud Shell, di toolbar Konsol Google Cloud, klik Activate 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 oleh server. Tujuan sekundernya adalah mengurangi penggunaan memori dengan menghilangkan alokasi memori yang tidak perlu.

Server, yang menggunakan framework gRPC, menerima kata atau frasa, lalu menampilkan berapa kali kata atau frasa tersebut muncul dalam karya Shakespeare.

Jumlah rata-rata kueri per detik yang dapat ditangani server ditentukan dengan melakukan pengujian beban pada server. Untuk setiap putaran pengujian, simulator klien dipanggil dan diminta untuk mengeluarkan 20 kueri berurutan. Pada akhir satu putaran, jumlah kueri yang dikirim oleh simulator klien, waktu yang berlalu, dan jumlah rata-rata kueri per detik akan ditampilkan.

Kode server sengaja tidak efisien.

Menjalankan aplikasi contoh

Download dan jalankan aplikasi contoh:

  1. Jalankan perintah berikut di Cloud Shell:

    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 ditetapkan ke 15:

    go run . -version 1 -num_rounds 15
    

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

    Grafik flame awal untuk penggunaan waktu CPU.

    Di screenshot, perhatikan bahwa Profile type disetel ke CPU time. Ini menunjukkan bahwa data penggunaan CPU ditampilkan dalam grafik flame.

    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 telah 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 mengeksekusi sekitar 1 permintaan per detik. Di babak terakhir, entri "Simulasi 20 permintaan dalam 1m48.03 detik, kecepatan 0,185134 permintaan / detik" 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 CPU intensif dan mengoptimalkan implementasinya. Di bagian ini, Anda akan menggunakan profil waktu CPU untuk mengidentifikasi metode intensif CPU di server.

Mengidentifikasi penggunaan waktu CPU

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

Tampilan frame root grafik Flame diperluas.

Dalam contoh ini, layanan menggunakan 2.37 s. Jika sistem berjalan pada satu core, penggunaan waktu CPU selama 2,37 detik setara dengan 23,7% penggunaan dari inti tersebut. Untuk mengetahui informasi selengkapnya, lihat Jenis pembuatan profil yang tersedia.

Memodifikasi aplikasi

Mengevaluasi perubahan

Untuk mengevaluasi perubahan, lakukan hal berikut:

  1. Jalankan aplikasi dengan versi aplikasi yang disetel 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 dieksekusi 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 SEKARANG untuk memuat data profil terbaru. Untuk informasi selengkapnya, lihat Rentang waktu.
    • Di menu Version, pilih 2.

Sebagai satu contoh, grafik flame adalah seperti yang ditunjukkan berikut ini:

Grafik Flame yang menampilkan penggunaan waktu CPU versi 2.

Dalam gambar ini, frame root menunjukkan nilai 7.8 s. Akibat adanya 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 78% dari 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 flame asli, frame yang sama ini berukuran 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 menampilkan penggunaan waktu CPU versi 2.

Output di Cloud Shell menunjukkan bahwa versi yang dimodifikasi 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 ini 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 pemakaian CPU dengan jumlah permintaan per detik, turun menjadi 13,4% dari 23,7%.

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

Menggunakan profil heap yang dialokasikan untuk meningkatkan penggunaan resource

Bagian ini mengilustrasikan cara menggunakan profil heap dan alokasikan heap untuk mengidentifikasi metode yang membutuhkan banyak alokasi dalam aplikasi:

  • Profil heap menampilkan jumlah memori yang dialokasikan dalam heap program tepat pada saat profil dikumpulkan.

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

Mengaktifkan pengumpulan profil heap

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

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

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

    Sebagai satu contoh, grafik flame adalah seperti yang ditunjukkan berikut ini:

    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 dari semua profil. Dalam contoh ini, frame root menunjukkan bahwa, rata-rata, memori telah dialokasikan sebesar 1,535 GiB.

Memodifikasi aplikasi

Mengevaluasi perubahan

Untuk mengevaluasi perubahan, lakukan hal berikut:

  1. Jalankan aplikasi dengan versi aplikasi yang disetel 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 SEKARANG untuk memuat data profil terbaru.
    • Di menu Version, pilih 4.
    • Di menu Profiler type, pilih Alalokasi heap.
  3. Untuk mengukur efek perubahan readFiles pada rasio alokasi heap, bandingkan profil heap yang dialokasikan untuk versi 4 dengan profil yang dikumpulkan untuk versi 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, konfigurasi perbandingan profil waktu CPU. Dalam screenshot berikut, filter diterapkan untuk menampilkan tumpukan untuk runtime.gcBgMarkWorker.* pembersih sampah memori Go. Screenshot menunjukkan bahwa penggunaan CPU untuk pembersihan sampah memori dikurangi menjadi 4,97% dari 16,8%.

    Perbandingan penggunaan waktu CPU dari proses pembersihan sampah memori 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 lebih sedikit waktu yang dihabiskan untuk pembersihan sampah memori.

  • Anda dapat lebih memahami efek modifikasi pada readFiles dengan melihat profil heap. Perbandingan profil heap untuk versi 4 dan versi 3 menunjukkan bahwa penggunaan heap turun menjadi 18,47 MiB dari 70.95 MiB:

    Perbandingan penggunaan heap untuk versi 4 dengan versi 3.

Ringkasan

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

  • Dengan menggunakan profil waktu CPU, fungsi intensif CPU 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 rasio alokasi yang tinggi. Setelah mengoptimalkan readFiles, rasio permintaan server meningkat menjadi 15 permintaan per detik dan jumlah rata-rata memori yang dialokasikan selama pengumpulan profil 10 detik berkurang sebesar 1,301 GiB.

Langkah selanjutnya

Untuk mengetahui informasi tentang cara menjalankan agen Cloud Profiler, lihat: