Seorang pengguna membuka tiket: aplikasi mudah alih lembap. Anda menyemak papan pemuka anda. Penggunaan CPU mendatar. Kadar ralat adalah sifar. Lampu APM anda berwarna hijau yang menenangkan. Backend, mengikut setiap ukuran yang kelihatan, adalah sihat. Tetapi pengguna itu tidak salah. Kelambatan itu benar, dan ia berlaku di suatu tempat dalam koridor panjang yang gelap antara peranti Android dan pelayan anda.

Masalahnya ialah kebanyakan alat observability berhenti pada sempadan aplikasi. Ia mengukur apa yang berlaku selepas rangka kerja anda menghuraikan permintaan. Ia menjejaki pertanyaan pangkalan data, padanan cache, dan panggilan perkhidmatan hiliran. Apa yang mereka terlepas ialah mekanik permintaan itu sendiri: masa yang dihabiskan oleh panggilan OkHttp di dalam timbunan HTTP Android, transit merentasi rangkaian mudah alih yang tidak stabil, rundingan jabat tangan TLS, dan penantian senyap yang berlaku di dalam giliran kernel sebelum kod anda sempat berjalan. Jurang ini menelan milisaat—atau saat yang lengkap—sementara APM anda kekal senyap.

Penyulitan melengkapkan lagi kebutaan ini. Aplikasi Android moden menghalakan segala-galanya melalui BoringSSL. Menjelang masa paket sampai ke timbunan rangkaian kernel, pengepala HTTP telah disulitkan. tcpdump standard atau cangkuk rangkaian hanya melihat rekod TLS yang legap. Anda boleh memerhatikan bahawa trafik sedang mengalir, tetapi anda tidak boleh membacanya. Anda pastinya tidak boleh mengaitkan segmen TCP pada tahap kernel tertentu kembali kepada panggilan API pengguna tertentu. Konteks jejak yang anda perlukan terperangkap di dalam teks sifer.

eBPF mengubah keadaan kerana ia membolehkan anda melakukan instrumentasi pada sistem dari dalam ke luar tanpa mengubah kod aplikasi anda. Daripada meminta aplikasi anda melaporkan kependaman (latency) sendiri, anda melampirkan program kecil terus ke kernel dan ke perpustakaan ruang pengguna yang kritikal. Program-program ini memerhatikan peristiwa semasa ia berlaku, mengekstrak apa yang anda perlukan, dan menghantarnya ke ring buffer. Tiada bloat SDK di dalam APK Android anda selain daripada pengepala ringan, dan tiada ejen instrumentasi yang menulis semula kelas backend anda.

Persediaan Empat Bahagian

Membina saluran paip ini melibatkan empat lapisan pemerhatian yang berbeza.

1. Sauh traceparent. Pada peranti Android, anda menambah perencat (interceptor) OkHttp yang menyuntik pengepala traceparent W3C ke dalam setiap permintaan keluar. Ini adalah satu-satunya perubahan yang diperlukan pada bahagian mudah alih, dan ia adalah minimal. Pengepala tersebut bergerak di dalam muatan tersulit sehingga ke backend anda. Oleh kerana ia berada di dalam lapisan HTTP, ia terselamat di dalam teks biasa (plaintext) yang akhirnya didedahkan oleh enjin TLS.

2. Pemasaan ketibaan TCP. Pada hos backend, anda menggunakan cangkuk (hooks) Kawalan Trafik eBPF yang dilampirkan pada antara muka rangkaian. Program-program ini dicetuskan apabila segmen TCP individu tiba. Ia menangkap nombor urutan dan cap masa di pinggir rangkaian. Anda kini tahu dengan tepat bila bit meninggalkan kabel dan memasuki mesin anda, lama sebelum aplikasi anda membaca satu bait pun.

3. Prob penyulitan. Backend anda menamatkan TLS menggunakan OpenSSL atau BoringSSL. Di sinilah seni bina ini menjadi menarik. Menggunakan uprobes—prob ruang pengguna dinamik—anda melampirkan pada SSL_write dan SSL_read di dalam perpustakaan TLS. Fungsi-fungsi ini dicetuskan sebaik sahaja data teks biasa melalui enjin penyulitan. Program eBPF anda membaca penimbal (buffer) yang telah dinyahsulit itu, mengimbas pengepala traceparent, dan mengekstraknya. Kernel kini memiliki pemetaan langsung antara aliran TCP mentah dan permintaan mudah alih tertentu, tanpa anda perlu mengendalikan sijil atau kunci dalam alat tersuai.

4. Penggiliran kernel. Walaupun selepas data dinyahsulit dan sedia, aplikasi anda mungkin tidak menggunakannya dengan segera. Anda melampirkan kprobes pada fungsi kernel yang berkaitan yang mengendalikan penimbal soket dan peristiwa penjadualan. Ini mengukur kependaman penggiliran (queueing latency): masa yang dihabiskan oleh permintaan semasa menunggu di dalam kawasan kernel kerana proses anda bersaing untuk CPU atau sekadar belum memanggil read() lagi.

Keempat-empat sumber isyarat menulis peristiwa ke dalam ring buffer eBPF. Satu proses sidecar yang berjalan di ruang pengguna mengalirkan penimbal ini, mengaitkan peristiwa mengikut ID traceparent, dan membina semula satu garis masa tunggal yang koheren untuk setiap permintaan. Apa yang sebelum ini merupakan serakan hingar kernel yang tidak bersambung kini menjadi jejak (trace) yang berstruktur.

Membaca Laluan Penuh

Output yang digabungkan biasanya dipaparkan sebagai graf nyala (flame graph) atau pokok span berstruktur yang membahagikan kependaman kepada empat bahagian konkrit:

  • Masa transit rangkaian: Tempoh dari radio Android menghantar bait terakhir permintaan sehingga NIC backend menerimanya. Di sinilah ketidaktentuan selular berlaku.
  • Tempoh jabat tangan TLS: Masa yang dihabiskan untuk merundingkan terowong tersulit. Pada rangkaian yang tidak stabil, ini boleh jauh mengatasi pemindahan data sebenar.
  • Latensi giliran kernel: Masa yang dihabiskan dalam penimbal kernel dan giliran penjadual selepas segmen tiba tetapi sebelum ruang pengguna (userspace) menggunakannya.
  • Masa pemprosesan aplikasi: Bahagian yang sebenarnya digunakan oleh rangka kerja backend dan logik perniagaan anda.

Anda mungkin mendapati bahawa permintaan