Mengoptimalkan aplikasi Go

Dalam tutorial ini, Anda akan men-deploy aplikasi Go yang sengaja dibuat tidak efisien dan 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 Activate Cloud Shell:

    Mengaktifkan Cloud Shell.

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

    Sesi Cloud Shell.

  6. Contoh aplikasi

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

    Server, menggunakan framework gRPC, menerima kata atau frasa, lalu menampilkan jumlah kemunculan kata atau frasa tersebut 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 diinstruksikan 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 akan terlihat mirip dengan contoh berikut:

      Grafik flame 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 flame.

      Contoh output yang dicetak di Cloud Shell ditampilkan di bawah:

      $ 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 "Simulated 20 requests in 17.3s, rate of 1.156069 reqs / sec" menunjukkan bahwa server menjalankan sekitar 1 permintaan per detik. Pada putaran terakhir, entri "Simulated 20 requests in 1m48.03s, rate of 0.185134 reqs / sec" menunjukkan bahwa server menjalankan 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 yang intensif CPU dan mengoptimalkan implementasinya. Di bagian ini, Anda akan menggunakan profil waktu CPU untuk mengidentifikasi metode yang 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 yang diperluas dari frame root grafik flame.

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

    Mengubah aplikasi

    Mengevaluasi perubahan

    Untuk mengevaluasi perubahan, 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 mengeksekusi 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 aplikasi versi ini:

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

    Sebagai contoh, grafik nyala api ditampilkan seperti berikut:

    Grafik flame yang menunjukkan penggunaan waktu CPU versi 2.

    Dalam gambar ini, frame root menampilkan nilai 7.8 s. Sebagai akibat dari mengubah 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% inti CPU menjadi menggunakan 78% inti 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 flame graph asli, frame yang sama ini 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 pemakaian 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 menggambarkan cara Anda dapat menggunakan profil heap dan heap yang dialokasikan untuk mengidentifikasi metode yang intensif alokasinya dalam 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, 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 profil heap dan heap yang dialokasikan.

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

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

      Sebagai contoh, grafik nyala api ditampilkan seperti berikut:

      Grafik flame profil heap yang dialokasikan untuk versi 3.

    Mengidentifikasi kecepatan alokasi heap

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

    Mengubah aplikasi

    Mengevaluasi perubahan

    Untuk mengevaluasi perubahan, 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 aplikasi versi ini:

      • Klik SEKARANG untuk memuat data profil terbaru.
      • Di menu Version, pilih 4.
      • Di menu Profiler type, pilih Allocated heap.
    3. Untuk mengukur efek perubahan readFiles pada tingkat 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 berkurang sebesar 1,301 GiB, jika dibandingkan dengan versi 3. Tooltip untuk readFiles.func1 menunjukkan penurunan sebesar 1,045 GiB:

      Perbandingan tooltip file siap untuk jenis profil heap yang dialokasikan.

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

      Perbandingan penggunaan waktu CPU proses pengumpulan sampah latar belakang v4 dengan 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 pada 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 memahami efek modifikasi pada readFiles secara lebih lengkap dengan melihat profil heap. Perbandingan profil heap untuk versi 4 dengan versi 3 menunjukkan bahwa penggunaan heap menurun dari 70,95 MiB menjadi 18,47 MiB:

      Perbandingan penggunaan heap untuk versi 4 dengan versi 3.

    Ringkasan

    Dalam panduan memulai ini, profil waktu CPU dan heap yang dialokasikan digunakan untuk mengidentifikasi potensi pengoptimalan pada 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, 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, kecepatan permintaan server meningkat menjadi 15 permintaan per detik dan jumlah memori rata-rata yang dialokasikan selama pengumpulan profil 10 detik berkurang sebesar 1.301 GiB.

    Langkah berikutnya

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