Pelacakan terdistribusi di aplikasi microservice

Refresh_date: 24-10-2023

Dokumen ini adalah yang keempat dari seri empat bagian tentang mendesain, membangun, dan men-deploy microservice. Seri ini menjelaskan berbagai elemen arsitektur microservice. Seri ini mencakup informasi tentang kelebihan dan kekurangan pola arsitektur microservice, serta cara menerapkannya.

  1. Pengantar microservice
  2. Memfaktorkan ulang monolit menjadi microservice
  3. Komunikasi antarlayanan dalam penyiapan microservice
  4. Pelacakan terdistribusi dalam aplikasi microservice (dokumen ini)

Seri ini ditujukan bagi developer dan arsitek aplikasi yang mendesain dan mengimplementasikan migrasi untuk memfaktorkan ulang aplikasi monolit menjadi aplikasi microservice.

Dalam sistem terdistribusi, penting untuk mengetahui cara permintaan mengalir dari satu layanan ke layanan lainnya, dan berapa lama waktu yang diperlukan untuk melakukan tugas di setiap layanan. Pertimbangkan aplikasi Butik Online berbasis microservice yang Anda deploy di dokumen sebelumnya, Memfaktorkan ulang monolit menjadi microservice. Aplikasi ini terdiri dari beberapa layanan. Contohnya, screenshot berikut menunjukkan halaman detail produk, yang mengambil informasi dari layanan frontend, rekomendasi, dan iklan.

Halaman detail produk.

Untuk merender halaman detail produk, layanan frontend berkomunikasi dengan layanan rekomendasi dan layanan iklan, seperti yang ditunjukkan dalam diagram berikut:

Layanan frontend berkomunikasi dengan layanan rekomendasi, katalog produk, dan layanan iklan.

Gambar 1. Layanan yang ditulis dalam berbagai bahasa.

Pada gambar 1, layanan frontend ditulis dalam Go. Layanan rekomendasi, yang ditulis dalam Python, menggunakan gRPC untuk berkomunikasi dengan layanan frontend. Layanan iklan, yang ditulis dalam Java, juga menggunakan gRPC untuk berkomunikasi dengan layanan frontend. Selain gRPC, metode komunikasi antar-layanan juga dapat berada di REST HTTP.

Saat Anda membangun sistem terdistribusi tersebut, Anda ingin alat kemampuan observasi Anda menyediakan insight berikut:

  • Layanan yang dilalui permintaan.
  • Tempat terjadi penundaan jika permintaan lambat.
  • Tempat terjadinya error jika permintaan gagal.
  • Perbedaan eksekusi permintaan dengan perilaku normal sistem.
  • Apakah perbedaan dalam eksekusi permintaan berkaitan dengan performa (apakah beberapa panggilan layanan memerlukan waktu yang lebih lama atau lebih singkat dari biasanya).

Tujuan

  • Gunakan file manifes kustomisasi untuk menyiapkan infrastruktur.
  • Deploy aplikasi contoh Butik Online ke Google Kubernetes Engine (GKE).
  • Gunakan Cloud Trace untuk meninjau perjalanan pengguna dalam contoh aplikasi.

Biaya

Dalam dokumen ini, Anda menggunakan komponen Google Cloud yang dapat ditagih berikut:

Untuk membuat perkiraan biaya berdasarkan proyeksi penggunaan Anda, gunakan kalkulator harga. Pengguna baru Google Cloud mungkin memenuhi syarat untuk mendapatkan uji coba gratis.

Setelah Anda menyelesaikan dokumen ini, Anda dapat menghindari penagihan berkelanjutan dengan menghapus resource yang Anda buat. Untuk informasi selengkapnya, lihat Pembersihan.

Sebelum memulai

Jika Anda sudah menyiapkan project dengan menyelesaikan dokumen sebelumnya dalam seri ini, Komunikasi antarlayanan dalam penyiapan microservice, Anda dapat menggunakan kembali project tersebut. Selesaikan langkah-langkah berikut untuk mengaktifkan API tambahan dan menetapkan variabel lingkungan.

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

    Buka pemilih project

  2. Pastikan penagihan telah diaktifkan untuk project Google Cloud Anda.

  3. Di konsol Google Cloud, aktifkan Cloud Shell.

    Aktifkan Cloud Shell

  4. Aktifkan API untuk Compute Engine, GKE, Cloud SQL, Artifact Analysis, Trace, dan Container Registry:

     gcloud services enable \
       compute.googleapis.com \
       sql-component.googleapis.com \
       servicenetworking.googleapis.com\
       container.googleapis.com \
       containeranalysis.googleapis.com \
       containerregistry.googleapis.com \
       sqladmin.googleapis.com
    

Pelacakan terdistribusi

Pelacakan terdistribusi melampirkan metadata kontekstual ke setiap permintaan dan memastikan metadata dibagikan di antara permintaan. Anda menggunakan titik trace untuk menginstrumentasikan pelacakan terdistribusi. Contohnya, Anda dapat menginstrumentasikan layanan Anda (frontend, rekomendasi, dan iklan) dengan dua titik trace untuk menangani permintaan klien guna melihat detail produk: satu titik trace untuk mengirim permintaan dan titik trace lainnya untuk menerima respons. Diagram berikut menunjukkan cara kerja instrumentasi titik trace ini:

Instrumentasi titik trace yang memiliki dua titik trace.

Gambar 2. Setiap panggilan antarlayanan memiliki dua titik trace yang terdiri dari pasangan permintaan respons.

Agar titik trace dapat memahami permintaan yang akan dijalankan saat layanan dipanggil, layanan asal akan meneruskan ID trace di sepanjang alur eksekusi. Proses yang meneruskan ID trace disebut penerapan metadata atau penerapan konteks terdistribusi. Penerapan konteks mentransfer metadata melalui panggilan jaringan saat layanan aplikasi terdistribusi saling berkomunikasi selama eksekusi permintaan tertentu. Diagram berikut menunjukkan penerapan metadata:

Penerapan metadata akan meneruskan ID trace.

Gambar 3. Metadata trace diteruskan antarlayanan. Metadata tersebut mencakup informasi seperti layanan mana yang memanggil dan stempel waktunya.

Pada contoh Butik Online, trace dimulai ketika pengguna mengirim permintaan awal untuk mengambil detail produk. ID trace baru akan dibuat, dan setiap permintaan berturut-turut akan diberi header yang berisi metadata kontekstual yang kembali ke permintaan asli.

Setiap operasi yang dipanggil sebagai bagian dari proses untuk memenuhi permintaan pengguna akhir disebut span. Layanan asal memberi tag pada setiap span dengan ID uniknya sendiri dan ID trace span induk. Diagram berikut menunjukkan visualisasi chart Gantt dari trace:

Operasi individual diberi tag sebagai span.

Gambar 4. Span induk mencakup waktu respons span turunan.

Gambar 4 menunjukkan hierarki trace tempat layanan frontend memanggil layanan rekomendasi dan layanan iklan. Layanan frontend adalah span induk, yang menjelaskan waktu respons seperti yang diamati oleh pengguna akhir. Span turunan menjelaskan cara layanan rekomendasi dan layanan iklan dipanggil dan direspons, termasuk informasi waktu respons.

Mesh layanan seperti Istio memungkinkan pelacakan terdistribusi untuk traffic layanan ke layanan tanpa memerlukan instrumentasi khusus apa pun. Namun, mungkin ada situasi saat Anda ingin memiliki kontrol lebih besar atas trace, atau Anda mungkin perlu melacak kode yang tidak berjalan dalam mesh layanan.

Dokumen ini menggunakan OpenTelemetry untuk mengaktifkan instrumentasi aplikasi microservice terdistribusi guna mengumpulkan trace dan metrik. Dengan OpenTelemetry, Anda dapat mengumpulkan metrik dan trace, lalu mengekspornya ke backend, seperti Prometheus, Cloud Monitoring, Datadog, Graphite, Zipkin, dan Jaeger.

Instrumentasi menggunakan OpenTelemetry

Bagian berikut menunjukkan cara menggunakan penerapan konteks untuk memungkinkan span dari beberapa permintaan agar ditambahkan ke satu trace induk.

Contoh ini menggunakan library JavaScript, Python, dan Go OpenTelemetry untuk menginstrumentasikan implementasi rekaman aktivitas untuk layanan pembayaran, rekomendasi, dan frontend. Bergantung pada panjang instrumentasi, pelacakan data dapat memengaruhi biaya project (penagihan Cloud Trace). Untuk mengurangi masalah biaya, sebagian besar sistem pelacakan menggunakan berbagai bentuk pengambilan sampel untuk hanya mengambil persentase tertentu dari trace yang diamati. Di lingkungan produksi, organisasi Anda mungkin memiliki alasan terkait apa yang ingin mereka ambil sampelnya dan juga alasannya. Anda mungkin ingin menyesuaikan strategi pengambilan sampel berdasarkan pengelolaan biaya, dengan berfokus pada pelacakan yang menarik, atau memfilter derau. Untuk mempelajari lebih lanjut pengambilan sampel, lihat Sampling OpenTelemetry.

Dokumen ini menggunakan Trace untuk memvisualisasikan rekaman aktivitas yang terdistribusi. Anda menggunakan pengekspor OpenTelemetry untuk mengirim rekaman aktivitas ke Trace.

Mendaftarkan pengekspor trace

Bagian ini menunjukkan cara mendaftarkan pengekspor trace di setiap layanan dengan menambahkan baris ke kode microservice.

Untuk layanan frontend (yang ditulis di Go), contoh kode berikut akan mendaftarkan pengekspor:

[...]
exporter, err := otlptracegrpc.New(
        ctx,
        otlptracegrpc.WithGRPCConn(svc.collectorConn))
    if err != nil {
        log.Warnf("warn: Failed to create trace exporter: %v", err)
    }
tp := sdktrace.NewTracerProvider(
        sdktrace.WithBatcher(exporter),
        sdktrace.WithSampler(sdktrace.AlwaysSample()))
    otel.SetTracerProvider(tp)

Untuk layanan rekomendasi (yang ditulis di Python), contoh kode berikut akan mendaftarkan pengekspor:

if os.environ["ENABLE_TRACING"] == "1":
    trace.set_tracer_provider(TracerProvider())
    otel_endpoint = os.getenv("COLLECTOR_SERVICE_ADDR", "localhost:4317")
    trace.get_tracer_provider().add_span_processor(
        BatchSpanProcessor(
            OTLPSpanExporter(
            endpoint = otel_endpoint,
            insecure = True
            )
        )
    )

Untuk layanan pembayaran (ditulis dalam JavaScript), contoh kode berikut mendaftarkan eksportir:

provider.addSpanProcessor(new SimpleSpanProcessor(new OTLPTraceExporter({url: collectorUrl})));
provider.register();

Menyiapkan penerapan konteks

Sistem pelacakan harus mengikuti spesifikasi konteks trace yang menentukan format untuk menerapkan konteks pelacakan antarlayanan. Contoh format penerapan mencakup format B3 Zipkin dan X-Google-Cloud-Trace.

OpenTelemetry menyebarkan konteks menggunakan TextMapPropagator global. Contoh ini menggunakan propagator Trace Context, yang menggunakan format traceparent W3C. Library instrumentasi, seperti library HTTP dan gRPC OpenTelemetry, menggunakan propagator global untuk menambahkan konteks rekaman aktivitas sebagai metadata ke permintaan HTTP atau gRPC. Agar penerapan konteks berhasil, klien dan server harus menggunakan format penerapan yang sama.

Penerapan konteks melalui HTTP

Layanan frontend memasukkan konteks rekaman aktivitas ke dalam header permintaan HTTP. Layanan backend mengekstrak konteks rekaman aktivitas. Contoh kode berikut menunjukkan cara layanan frontend diinstrumentasi untuk mengonfigurasi konteks rekaman aktivitas:

otel.SetTextMapPropagator(
    propagation.NewCompositeTextMapPropagator(
        propagation.TraceContext{}, propagation.Baggage{}))

if os.Getenv("ENABLE_TRACING") == "1" {
    log.Info("Tracing enabled.")
    initTracing(log, ctx, svc)
} else {
    log.Info("Tracing disabled.")
}

...

var handler http.Handler = r
handler = &logHandler{log: log, next: handler}     // add logging
handler = ensureSessionID(handler)                 // add session ID
handler = otelhttp.NewHandler(handler, "frontend") // add OpenTelemetry tracing

Penerapan konteks melalui gRPC

Pertimbangkan alur tempat layanan checkout menempatkan pesanan berdasarkan produk yang dipilih pengguna. Layanan ini berkomunikasi melalui gRPC.

Contoh kode berikut menggunakan intersepsi panggilan gRPC yang mencegat panggilan keluar dan memasukkan konteks rekaman aktivitas:

var srv *grpc.Server

// Propagate trace context always
otel.SetTextMapPropagator(
    propagation.NewCompositeTextMapPropagator(
        propagation.TraceContext{}, propagation.Baggage{}))
srv = grpc.NewServer(
    grpc.UnaryInterceptor(otelgrpc.UnaryServerInterceptor()),
    grpc.StreamInterceptor(otelgrpc.StreamServerInterceptor()),
)

Setelah menerima permintaan, layanan pembayaran atau katalog produk (ListProducts) akan mengekstrak konteks dari header permintaan dan menggunakan metadata trace induk untuk menghasilkan span turunan.

Bagian berikut menyediakan detail tentang cara menyiapkan dan meninjau pelacakan terdistribusi untuk contoh aplikasi Butik Online.

Men-deploy aplikasi

Jika Anda sudah memiliki aplikasi yang berjalan setelah menyelesaikan dokumen sebelumnya dalam seri ini, Komunikasi antarlayanan dalam penyiapan microservice, Anda dapat langsung ke bagian berikutnya, Meninjau trace. Jika tidak, selesaikan langkah berikut untuk men-deploy contoh Butik Online:

  1. Untuk menyiapkan infrastruktur, di Cloud Shell, Anda dapat meng-clone repositori GitHub:

    git clone https://github.com/GoogleCloudPlatform/microservices-demo.git
    
  2. Untuk deployment baru, reset variabel lingkungan:

    PROJECT_ID=PROJECT_ID
    REGION=us-central1
    GSA_NAME=microservices-sa
    GSA_EMAIL=$GSA_NAME@$PROJECT_ID.iam.gserviceaccount.com
    

    Ganti kode berikut:

    • PROJECT_ID: ID untuk project ID Anda.
  3. Opsional: Buat cluster baru atau gunakan kembali cluster yang ada jika ada:

    gcloud container clusters create-auto online-boutique --project=${PROJECT_ID}
      --region=${REGION}
    
  4. Buat akun layanan Google:

    gcloud iam service-accounts create $GSA_NAME \
      --project=$PROJECT_ID
    
  5. Aktifkan API:

    gcloud services enable \
    monitoring.googleapis.com \
    cloudtrace.googleapis.com \
    cloudprofiler.googleapis.com \
      --project ${PROJECT_ID}
    
  6. Berikan peran yang diperlukan untuk Cloud Tracing ke GSA:

    gcloud projects add-iam-policy-binding ${PROJECT_ID} \
    --member "serviceAccount:${GSA_NAME}@${PROJECT_ID}.iam.gserviceaccount.com" \
    --role roles/cloudtrace.agent
    
    gcloud projects add-iam-policy-binding ${PROJECT_ID} \
    --member "serviceAccount:${GSA_NAME}@${PROJECT_ID}.iam.gserviceaccount.com" \
    --role roles/monitoring.metricWriter
    
    gcloud projects add-iam-policy-binding ${PROJECT_ID} \
    --member "serviceAccount:${GSA_NAME}@${PROJECT_ID}.iam.gserviceaccount.com" \
    --role roles/cloudprofiler.agent
    
    gcloud iam service-accounts add-iam-policy-binding ${GSA_EMAIL} \
    --role roles/iam.workloadIdentityUser \
    --member "serviceAccount:${PROJECT_ID}.svc.id.goog[default/default]"
    
  7. Anotasikan akun layanan Kubernetes Anda (default/default untuk namespace default) untuk menggunakan akun layanan Google IAM:

    kubectl annotate serviceaccount default \
        iam.gke.io/gcp-service-account=${GSA_EMAIL}
    
  8. Aktifkan konfigurasi Cloud Operations for GKE; yang mengaktifkan pelacakan:

    cd ~/microservices-demo/kustomize && \
    kustomize edit add component components/google-cloud-operations
    
  9. Tindakan ini akan mengupdate file kustomize/kustomization.yaml yang mungkin mirip dengan:

    apiVersion: kustomize.config.k8s.io/v1beta1
    kind: Kustomization
    resources:
    - base
    components:
    - components/google-cloud-operations
    [...]
    
  10. Deploy microservice:

    kubectl apply -k .
    
  11. Periksa status deployment:

    kubectl rollout status deployment/frontend
    kubectl rollout status deployment/paymentservice
    kubectl rollout status deployment/recommendationservice
    kubectl rollout status deployment/adservice
    

    Output untuk setiap perintah terlihat seperti berikut:

    Waiting for deployment "" rollout to finish: 0 of 1 updated replicas are available...
    deployment "" successfully rolled out
    
  12. Dapatkan Alamat IP aplikasi yang di-deploy:

    kubectl get service frontend-external | awk '{print $4}'
    

    Tunggu hingga alamat IP load balancer dipublikasikan. Untuk keluar dari perintah, tekan Ctrl+C. Catat alamat IP load balancer, lalu akses aplikasi di URL http://IP_ADDRESS. Mungkin perlu waktu beberapa saat agar load balancer responsif dan mulai meneruskan traffic.

Meninjau trace menggunakan Cloud Trace

Perjalanan pembelian pengguna di aplikasi Butik Online memiliki alur berikut:

  • Pengguna melihat katalog produk di halaman landing.
  • Untuk melakukan pembelian, pengguna mengklik Beli.
  • Pengguna dialihkan ke halaman detail produk tempat mereka menambahkan item ke keranjang.
  • Pengguna dialihkan ke halaman checkout tempat mereka dapat melakukan pembayaran untuk menyelesaikan pesanan.

Pertimbangkan skenario yang mengharuskan Anda memecahkan masalah waktu respons yang tinggi saat memuat halaman detail produk. Seperti yang dijelaskan sebelumnya, halaman detail produk terdiri dari beberapa microservice. Untuk mengetahui di mana dan mengapa latensi tinggi terjadi, Anda dapat melihat grafik pelacakan terdistribusi untuk meninjau performa seluruh permintaan di berbagai layanan.

Untuk meninjau grafik pelacakan terdistribusi, lakukan tindakan berikut:

  1. Akses aplikasi, lalu klik produk apa pun. Halaman detail produk akan ditampilkan.
  2. Di konsol Google Cloud, buka halaman Trace list dan tinjau linimasa.
  3. Untuk melihat hasil pelacakan terdistribusi, klik Frontend di kolom URI.
  4. Tampilan Trace Waterfall menampilkan span yang terkait dengan URI:

    Tampilan Trace Waterfall menampilkan span.

    Pada screenshot sebelumnya, trace untuk produk berisi span berikut:

    • Rentang Frontend merekam latensi menyeluruh (150,349 md) yang diamati klien dalam memuat halaman detail produk.
    • Rentang Layanan Rekomendasi merekam latensi panggilan backend dalam mengambil rekomendasi (4,246 md) yang terkait dengan produk.
    • Rentang Layanan Iklan merekam latensi panggilan backend dalam pengambilan iklan (4,511 md) yang relevan dengan halaman produk.

Untuk memecahkan masalah waktu respons yang tinggi, Anda dapat meninjau insight yang menyertakan grafik distribusi latensi dari setiap permintaan pencilan saat dependensi layanan tidak memenuhi tujuan tingkat layanan (SLO)-nya. Anda juga dapat menggunakan Cloud Trace untuk mendapatkan insight performa dan membuat laporan analisis dari sampel data.

Pemecahan masalah

Jika rekaman aktivitas di Pengelolaan Performa Aplikasi tidak muncul, periksa Logs Explorer untuk mengetahui error izin ditolak. Izin ditolak terjadi ketika akun layanan tidak memiliki akses untuk mengekspor rekaman aktivitas. Tinjau langkah-langkah untuk memberikan peran yang diperlukan untuk Cloud Trace dan pastikan untuk menganotasi akun layanan dengan namespace yang benar. Setelah itu, mulai ulang opentelemetrycollector:

```
kubectl rollout restart deployment opentelemetrycollector
```

Pembersihan

Agar tidak perlu membayar biaya pada akun Google Cloud Anda untuk resource yang digunakan dalam tutorial ini, hapus project yang berisi resource tersebut, atau simpan project dan hapus setiap resource.

Menghapus project

  1. Di konsol Google Cloud, buka halaman Manage resource.

    Buka Manage resource

  2. Pada daftar project, pilih project yang ingin Anda hapus, lalu klik Delete.
  3. Pada dialog, ketik project ID, lalu klik Shut down untuk menghapus project.

Menghapus resource

Jika Anda ingin menyimpan project Google Cloud yang Anda gunakan dalam dokumen ini, hapus masing-masing resource:

  • Di Cloud Shell, hapus resource:

    gcloud container clusters delete online-boutique --project=${PROJECT_ID} --region=${REGION}
    

Langkah selanjutnya