Penjejakan Perkhidmatan, OpenTracing dan Jaeger

Penjejakan Perkhidmatan, OpenTracing dan Jaeger

Kami menggunakan seni bina perkhidmatan mikro dalam projek kami. Apabila kesesakan prestasi berlaku, banyak masa dihabiskan untuk memantau dan menghuraikan log. Apabila mengelog pemasaan operasi individu ke fail log, biasanya sukar untuk memahami perkara yang membawa kepada pemanggilan operasi ini, untuk menjejaki urutan tindakan atau peralihan masa satu operasi berbanding dengan yang lain dalam perkhidmatan yang berbeza.

Untuk meminimumkan kerja manual, kami memutuskan untuk menggunakan salah satu alat pengesanan. Mengenai bagaimana dan mengapa anda boleh menggunakan pengesanan dan bagaimana kami melakukannya, dan akan dibincangkan dalam artikel ini.

Apakah masalah yang boleh diselesaikan dengan mengesan

  1. Cari kesesakan prestasi dalam satu perkhidmatan dan dalam keseluruhan pokok pelaksanaan antara semua perkhidmatan yang mengambil bahagian. Sebagai contoh:
    • Banyak panggilan pendek berturut-turut antara perkhidmatan, contohnya, ke geocoding atau ke pangkalan data.
    • I/O menunggu lama, seperti pemindahan rangkaian atau pembacaan cakera.
    • Penghuraian data yang panjang.
    • Operasi lama yang memerlukan cpu.
    • Bahagian kod yang tidak diperlukan untuk mendapatkan hasil akhir dan boleh dialih keluar atau ditangguhkan.
  2. Memahami dengan jelas dalam urutan apa yang dipanggil dan apa yang berlaku apabila operasi dilakukan.
    Penjejakan Perkhidmatan, OpenTracing dan Jaeger
    Ia boleh dilihat bahawa, sebagai contoh, Permintaan datang ke perkhidmatan WS -> perkhidmatan WS menambah data melalui perkhidmatan R -> kemudian menghantar permintaan ke perkhidmatan V -> perkhidmatan V memuatkan banyak data daripada R perkhidmatan -> pergi ke perkhidmatan P -> perkhidmatan P pergi lagi ke perkhidmatan R -> perkhidmatan V mengabaikan hasilnya dan pergi ke perkhidmatan J -> dan hanya kemudian mengembalikan respons kepada perkhidmatan WS, sambil terus mengira sesuatu yang lain dalam latar belakang.
    Tanpa jejak atau dokumentasi terperinci untuk keseluruhan proses, adalah sangat sukar untuk memahami apa yang berlaku apabila anda melihat kod buat kali pertama, dan kod itu tersebar di seluruh perkhidmatan yang berbeza dan tersembunyi di sebalik sekumpulan tong dan antara muka.
  3. Pengumpulan maklumat tentang pokok pelaksanaan untuk analisis tertunda berikutnya. Pada setiap peringkat pelaksanaan, anda boleh menambah maklumat pada surih yang tersedia pada peringkat ini dan kemudian memikirkan data input yang membawa kepada senario yang serupa. Sebagai contoh:
    • ID Pengguna
    • Hak
    • Jenis kaedah yang dipilih
    • Log atau ralat pelaksanaan
  4. Mengubah jejak menjadi subset metrik dan analisis lanjut sudah dalam bentuk metrik.

Apa jejak boleh log. Span

Dalam mengesan terdapat konsep span, ini adalah analog satu log, kepada konsol. Spa mempunyai:

  • Nama, biasanya nama kaedah yang telah dilaksanakan
  • Nama perkhidmatan di mana rentang dijana
  • ID unik sendiri
  • Beberapa jenis maklumat meta dalam bentuk kunci/nilai yang telah dilog masuk ke dalamnya. Sebagai contoh, parameter kaedah atau kaedah berakhir dengan ralat atau tidak
  • Masa mula dan tamat untuk rentang ini
  • ID rentang ibu bapa

Setiap span dihantar kepada pengumpul span untuk disimpan dalam pangkalan data untuk semakan kemudian sebaik sahaja ia selesai melaksanakannya. Pada masa hadapan, anda boleh membina pepohon semua rentang dengan menyambung menggunakan id induk. Semasa menganalisis, anda boleh menemui, sebagai contoh, semua rentang dalam sesetengah perkhidmatan yang mengambil masa lebih daripada beberapa waktu. Selanjutnya, dengan pergi ke rentang tertentu, lihat keseluruhan pokok di atas dan di bawah rentang ini.

Penjejakan Perkhidmatan, OpenTracing dan Jaeger

Opentrace, Jagger dan cara kami melaksanakannya untuk projek kami

Terdapat standard biasa jejak terbuka, yang menerangkan cara dan perkara yang perlu dikumpulkan, tanpa terikat dengan menjejak kepada pelaksanaan tertentu dalam mana-mana bahasa. Sebagai contoh, di Java, semua kerja dengan jejak dijalankan melalui Opentrace API biasa, dan di bawahnya, sebagai contoh, Jaeger atau pelaksanaan lalai kosong yang tidak melakukan apa-apa boleh disembunyikan.
Kami sedang menggunakan Jaeger sebagai pelaksanaan Opentrace. Ia terdiri daripada beberapa komponen:

Penjejakan Perkhidmatan, OpenTracing dan Jaeger

  • Jaeger-agent ialah ejen tempatan yang biasanya dipasang pada setiap mesin dan perkhidmatan dilog masuk ke dalamnya pada port lalai tempatan. Jika tiada ejen, maka kesan semua perkhidmatan pada mesin ini biasanya dilumpuhkan
  • Jaeger-collector - semua ejen menghantar jejak terkumpul kepadanya, dan ia meletakkannya dalam pangkalan data yang dipilih
  • Pangkalan data adalah cassandra pilihan mereka, tetapi kami menggunakan elasticsearch, terdapat pelaksanaan untuk beberapa pangkalan data lain dan pelaksanaan dalam memori yang tidak menyimpan apa-apa ke cakera
  • Jaeger-query ialah perkhidmatan yang pergi ke pangkalan data dan mengembalikan jejak yang telah dikumpulkan untuk analisis
  • Jaeger-ui ialah antara muka web untuk mencari dan melihat jejak, ia pergi ke jaeger-query

Penjejakan Perkhidmatan, OpenTracing dan Jaeger

Komponen berasingan boleh dipanggil pelaksanaan opentrace jaeger untuk bahasa tertentu, yang melaluinya span dihantar ke jaeger-agent.
Menghubungkan Jagger di Jawa turun untuk melaksanakan antara muka io.opentracing.Tracer, selepas itu semua jejak melaluinya akan terbang ke ejen sebenar.

Penjejakan Perkhidmatan, OpenTracing dan Jaeger

Juga untuk komponen spring, anda boleh menyambung opentracing-spring-cloud-starter dan pelaksanaan daripada Jaeger opentracing-spring-jaeger-cloud-starter yang akan mengkonfigurasi pengesanan secara automatik untuk semua yang melalui komponen ini, contohnya permintaan http kepada pengawal, permintaan kepada pangkalan data melalui jdbc, dsb.

Jejak pembalakan di Jawa

Di suatu tempat di peringkat atas, Span pertama mesti dibuat, ini boleh dilakukan secara automatik, contohnya, oleh pengawal spring apabila permintaan diterima, atau secara manual jika tiada. Ia kemudiannya dihantar melalui Skop di bawah. Jika mana-mana kaedah di bawah ingin menambah Span, ia mengambil activeSpan semasa daripada Skop, mencipta Span baharu dan mengatakan induknya ialah activeSpan yang terhasil dan menjadikan Span baharu aktif. Apabila memanggil perkhidmatan luaran, rentang aktif semasa dihantar kepada mereka dan perkhidmatan tersebut mencipta rentang baharu dengan merujuk kepada rentang ini.
Semua kerja melalui contoh Tracer, anda boleh mendapatkannya melalui mekanisme DI, atau GlobalTracer.get () sebagai pembolehubah global jika mekanisme DI tidak berfungsi. Secara lalai, jika pengesan belum dimulakan, NoopTracer akan kembali yang tidak melakukan apa-apa.
Selanjutnya, skop semasa diperolehi daripada pengesan melalui ScopeManager, skop baharu dicipta daripada skop semasa dengan pengikatan rentang baharu, dan kemudian Skop yang dibuat ditutup, yang menutup rentang yang dibuat dan mengembalikan Skop sebelumnya kepada keadaan aktif. Skop terikat pada benang, jadi apabila pengaturcaraan berbilang benang, anda tidak boleh lupa untuk memindahkan rentang aktif ke benang lain, untuk pengaktifan lanjut Skop benang lain dengan merujuk kepada rentang ini.

io.opentracing.Tracer tracer = ...; // GlobalTracer.get()

void DoSmth () {
   try (Scope scope = tracer.buildSpan("DoSmth").startActive(true)) {
      ...
   }
}
void DoOther () {
    Span span = tracer.buildSpan("someWork").start();
    try (Scope scope = tracer.scopeManager().activate(span, false)) {
        // Do things.
    } catch(Exception ex) {
        Tags.ERROR.set(span, true);
        span.log(Map.of(Fields.EVENT, "error", Fields.ERROR_OBJECT, ex, Fields.MESSAGE, ex.getMessage()));
    } finally {
        span.finish();
    }
}

void DoAsync () {
    try (Scope scope = tracer.buildSpan("ServiceHandlerSpan").startActive(false)) {
        ...
        final Span span = scope.span();
        doAsyncWork(() -> {
            // STEP 2 ABOVE: reactivate the Span in the callback, passing true to
            // startActive() if/when the Span must be finished.
            try (Scope scope = tracer.scopeManager().activate(span, false)) {
                ...
            }
        });
    }
}

Untuk pengaturcaraan berbilang benang, terdapat juga TracedExecutorService dan pembalut serupa yang secara automatik memajukan rentang semasa ke utas apabila tugas tak segerak dilancarkan:

private ExecutorService executor = new TracedExecutorService(
    Executors.newFixedThreadPool(10), GlobalTracer.get()
);

Untuk permintaan http luaran ada TracingHttpClient

HttpClient httpClient = new TracingHttpClientBuilder().build();

Masalah yang kami hadapi

  • Beans dan DI tidak selalu berfungsi jika pengesan tidak digunakan dalam perkhidmatan atau komponen, maka Autowayed Tracer mungkin tidak berfungsi dan anda perlu menggunakan GlobalTracer.get().
  • Anotasi tidak berfungsi jika ia bukan komponen atau perkhidmatan, atau jika kaedah dipanggil daripada kaedah jiran kelas yang sama. Anda perlu berhati-hati untuk menyemak perkara yang berfungsi dan menggunakan penciptaan jejak manual jika @Traced tidak berfungsi. Anda juga boleh melampirkan pengkompil tambahan untuk anotasi java, maka ia harus berfungsi di mana-mana.
  • Dalam but musim bunga dan musim bunga lama, konfigurasi awan musim bunga opentraing tidak berfungsi kerana pepijat dalam DI, maka jika anda mahu jejak dalam komponen musim bunga berfungsi secara automatik, anda boleh melakukannya dengan analogi dengan github.com/opentracing-contrib/java-spring-jaeger/blob/master/opentracing-spring-jaeger-starter/src/main/java/io/opentracing/contrib/java/spring/jaeger/starter/JaegerAutoConfiguration.java
  • Cuba dengan sumber tidak berfungsi dalam groovy, anda mesti menggunakan cuba akhirnya.
  • Setiap perkhidmatan mesti mempunyai spring.application.name sendiri yang mana jejak akan direkodkan. Apakah nama yang berasingan untuk jualan dan ujian, supaya tidak mengganggu mereka bersama-sama.
  • Jika anda menggunakan GlobalTracer dan tomcat, maka semua perkhidmatan yang berjalan dalam tomcat ini mempunyai satu GlobalTracer, jadi mereka semua akan mempunyai nama perkhidmatan yang sama.
  • Apabila menambah kesan pada kaedah, anda perlu memastikan bahawa ia tidak dipanggil berkali-kali dalam gelung. Ia adalah perlu untuk menambah satu jejak biasa untuk semua panggilan, yang menjamin jumlah masa kerja. Jika tidak, lebihan beban akan dibuat.
  • Sekali di jaeger-ui, permintaan yang terlalu besar dibuat untuk sejumlah besar jejak, dan kerana mereka tidak menunggu jawapan, mereka melakukannya sekali lagi. Akibatnya, jaeger-query mula memakan banyak memori dan memperlahankan elastik. Dibantu dengan memulakan semula jaeger-query

Persampelan, menyimpan dan melihat kesan

Terdapat tiga jenis jejak persampelan:

  1. Const yang menghantar dan menyimpan semua jejak.
  2. Probabilistik yang menapis jejak dengan beberapa kebarangkalian tertentu.
  3. Ratelimting yang mengehadkan bilangan jejak sesaat. Anda boleh mengkonfigurasi tetapan ini pada klien, sama ada pada jaeger-agent atau pada collector. Sekarang kita menggunakan const 1 dalam timbunan valuator, kerana permintaan tidak begitu banyak, tetapi ia mengambil masa yang lama. Pada masa hadapan, jika ini akan memberikan beban yang berlebihan pada sistem, anda boleh mengehadkannya.

Jika anda menggunakan cassandra, maka secara lalai ia hanya menyimpan jejak selama dua hari. Kami sedang menggunakan elasticsearch dan jejak disimpan untuk sepanjang masa dan tidak dipadamkan. Indeks berasingan dibuat untuk setiap hari, contohnya jaeger-service-2019-03-04. Pada masa hadapan, anda perlu mengkonfigurasi pembersihan automatik jejak lama.

Untuk melihat jejak yang anda perlukan:

  • Pilih perkhidmatan yang anda ingin menapis jejak, contohnya, tomcat7-default untuk perkhidmatan yang berjalan dalam tomcat dan tidak boleh mempunyai namanya sendiri.
  • Kemudian pilih operasi, selang masa dan masa operasi minimum, contohnya dari 10 saat, untuk mengambil hanya pelaksanaan yang lama.
    Penjejakan Perkhidmatan, OpenTracing dan Jaeger
  • Pergi ke salah satu jejak dan lihat apa yang perlahan di sana.
    Penjejakan Perkhidmatan, OpenTracing dan Jaeger

Selain itu, jika beberapa id permintaan diketahui, maka anda boleh mencari jejak mengikut id ini melalui carian teg, jika id ini dilog dalam rentang jejak.

Dokumentasi

artikel

Video

Sumber: www.habr.com

Tambah komen