Service Tracing, OpenTracing болон Jaeger

Service Tracing, OpenTracing болон Jaeger

Бид төсөлдөө микро үйлчилгээний архитектурыг ашигладаг. Гүйцэтгэлийн саатал гарсан тохиолдолд бүртгэлийг хянах, задлан шинжлэхэд маш их цаг зарцуулдаг. Бүртгэлийн файлд бие даасан үйлдлүүдийн цагийг бүртгэхдээ дүрмээр бол эдгээр үйлдлүүдийг дуудахад юу хүргэсэнийг ойлгох, өөр өөр үйлчилгээн дэх үйлдлийн дараалал эсвэл нэг үйлдлийн нөгөөтэй харьцуулахад цагийн шилжилтийг хянах нь хэцүү байдаг.

Гарын хөдөлмөрийг багасгахын тулд бид мөрдөх хэрэгслийн аль нэгийг ашиглахаар шийдсэн. Та мөшгих аргыг хэрхэн, яагаад ашиглаж болох, бид үүнийг хэрхэн хийсэн талаар энэ нийтлэлд авч үзэх болно.

Мөшгих замаар ямар асуудлыг шийдэж болох вэ

  1. Нэг үйлчилгээ болон бүх оролцогч үйлчилгээний хоорондох гүйцэтгэлийн модонд гүйцэтгэлийн саад бэрхшээлийг олоорой. Жишээлбэл:
    • Үйлчилгээний хооронд дараалсан олон богино дуудлага, жишээлбэл, геокод эсвэл мэдээллийн сан руу.
    • Сүлжээний шилжүүлэг эсвэл диск унших гэх мэт удаан оролт/гаралтын хүлээлт.
    • Урт өгөгдөл задлан шинжлэх.
    • Процессор шаарддаг урт ажиллагаа.
    • Эцсийн үр дүнд хүрэхэд шаардлагагүй кодын хэсгүүдийг арилгах эсвэл хойшлуулах боломжтой.
  2. Ямар дарааллаар дуудаж, үйл ажиллагаа явуулахад юу болохыг тодорхой ойлгоорой.
    Service Tracing, OpenTracing болон Jaeger
    Жишээлбэл, WS үйлчилгээнд Хүсэлт ирсэн болохыг харж болно -> WS үйлчилгээ нь R үйлчилгээгээр дамжуулан өгөгдлийг нэмсэн -> дараа нь V үйлчилгээ рүү хүсэлт илгээсэн -> V үйлчилгээ нь олон тооны өгөгдлийг ачаалсан. R үйлчилгээ -> P үйлчилгээ рүү очсон -> P үйлчилгээ R үйлчилгээ рүү дахин очсон -> V үр дүнг үл тоомсорлон J -> үйлчилгээ рүү очсон бөгөөд зөвхөн дараа нь WS үйлчилгээнд хариуг нь буцаасан бөгөөд энэ дотор өөр ямар нэг зүйлийг үргэлжлүүлэн тооцоолж байв. дэвсгэр.
    Ийм ул мөр, бүх үйл явцын нарийвчилсан баримт бичиггүйгээр кодыг анх удаа харахад юу болж байгааг ойлгоход маш хэцүү бөгөөд код нь янз бүрийн үйлчилгээнүүдэд тархаж, олон тооны хогийн сав, интерфейсийн ард нуугддаг.
  3. Цаашид хойшлуулсан шинжилгээнд зориулж гүйцэтгэх модны талаархи мэдээллийг цуглуулах. Гүйцэтгэлийн үе шат бүрт та энэ үе шатанд байгаа ул мөрийг нэмж, дараа нь ямар оролтын өгөгдөл ижил төстэй хувилбарт хүргэсэн болохыг олж мэдэх боломжтой. Жишээлбэл:
    • Хэрэглэгчийн ID
    • Эрх
    • Сонгосон аргын төрөл
    • Бүртгэл эсвэл гүйцэтгэлийн алдаа
  4. Мөрүүдийг хэмжүүрийн дэд хэсэг болгон хувиргаж, цаашдын шинжилгээг хэмжүүр хэлбэрээр хийнэ.

Ямар ул мөр бүртгэх боломжтой. Хүрээ

Мөшгих ажилд span гэсэн ойлголт байдаг бөгөөд энэ нь консолын нэг гуалингийн аналог юм. Рашаан нь:

  • Нэр, ихэвчлэн гүйцэтгэсэн аргын нэр
  • Хэмжээ үүсгэсэн үйлчилгээний нэр
  • Өөрийн өвөрмөц ID
  • Түүнд нэвтэрсэн түлхүүр/утга хэлбэрээр зарим мета мэдээлэл. Жишээлбэл, аргын параметрүүд эсвэл арга нь алдаатай төгссөн эсвэл үгүй
  • Энэ хугацааны эхлэх ба дуусах цаг
  • Эцэг эхийн хүрээний ID

Спан бүрийг гүйцэтгэлээ дуусгасны дараа өгөгдлийн санд хадгалахаар span коллектор руу илгээдэг. Ирээдүйд та эцэг эхийн дугаараар холбогдож бүх хүрээний модыг барьж болно. Шинжилгээ хийхдээ, жишээлбэл, зарим үйлчилгээнд хэсэг хугацаа зарцуулсан бүх хүрээг олж болно. Цаашилбал, тодорхой зайд орсноор энэ зайн дээрх болон доор байгаа модыг бүхэлд нь харна уу.

Service Tracing, OpenTracing болон Jaeger

Opentrace, Jagger болон бид үүнийг төслүүддээ хэрхэн хэрэгжүүлсэн

Нийтлэг стандарт байдаг нээлттэй мөр, ямар ч хэл дээрх тодорхой хэрэгжилтийг мөрдөж уяагүйгээр, хэрхэн, юу цуглуулах ёстойг тодорхойлсон. Жишээлбэл, Java-д ул мөр бүхий бүх ажлыг нийтлэг Opentrace API-ээр гүйцэтгэдэг бөгөөд үүний доор жишээ нь Jaeger эсвэл юу ч хийдэггүй хоосон анхдагч хэрэгжүүлэлтийг нууж болно.
Бид ашиглаж байна Jeger Opentrace-ийн хэрэгжилт. Энэ нь хэд хэдэн бүрэлдэхүүн хэсгээс бүрдэнэ:

Service Tracing, OpenTracing болон Jaeger

  • Jaeger-агент нь ихэвчлэн машин бүр дээр суурилагдсан локал агент бөгөөд үйлчилгээнүүд нь дотоод өгөгдмөл порт дээр нэвтэрдэг. Хэрэв агент байхгүй бол энэ машин дээрх бүх үйлчилгээний ул мөрийг ихэвчлэн идэвхгүй болгодог
  • Jaeger-цуглуулагч - бүх агентууд цуглуулсан ул мөрийг түүн рүү илгээж, сонгосон мэдээллийн санд оруулдаг.
  • Мэдээллийн сан нь тэдний илүүд үздэг кассандра, гэхдээ бид elasticsearch ашигладаг, өөр хэд хэдэн мэдээллийн санд зориулсан хэрэгжүүлэлтүүд байдаг бөгөөд дискэнд юу ч хадгалдаггүй санах ойн хэрэгжилт байдаг.
  • Jaeger-query нь мэдээллийн сан руу орж, аль хэдийн цуглуулсан ул мөрийг дүн шинжилгээнд буцаадаг үйлчилгээ юм
  • Jaeger-ui нь ул мөр хайх, үзэх вэб интерфэйс бөгөөд jaeger-query руу очдог.

Service Tracing, OpenTracing болон Jaeger

Тусдаа бүрэлдэхүүн хэсэг нь тодорхой хэлүүдэд зориулсан opentrace jaeger-ийн хэрэгжилт гэж нэрлэгдэх боломжтой бөгөөд үүгээр дамжуулан jaeger-агент руу дамжуулдаг.
Жаггерыг Java дээр холбож байна io.opentracing.Tracer интерфэйсийг хэрэгжүүлэхээр ирдэг бөгөөд үүний дараагаар дамжин өнгөрөх бүх ул мөр нь жинхэнэ агент руу нисэх болно.

Service Tracing, OpenTracing болон Jaeger

Мөн хаврын бүрэлдэхүүн хэсгийн хувьд та холбож болно opentracing-spring-cloud-starter болон Jaeger-ийн хэрэгжилт opentracing-spring-jaeger-cloud-starter Энэ нь эдгээр бүрэлдэхүүн хэсгүүдээр дамждаг бүх зүйлийн ул мөрийг автоматаар тохируулах болно, тухайлбал хянагчдад зориулсан http хүсэлт, jdbc-ээр дамжуулан мэдээллийн сан руу илгээх хүсэлт гэх мэт.

Java-д нэвтэрч буй ул мөр

Дээд түвшний хаа нэгтээ эхний Span-ийг үүсгэх ёстой бөгөөд үүнийг автоматаар, жишээлбэл, хүсэлтийг хүлээн авах үед пүрш хянагчаар эсвэл байхгүй бол гараар хийж болно. Дараа нь доорх хамрах хүрээгээр дамжуулагдана. Хэрэв доорх аль нэг арга нь Span нэмэхийг хүсвэл Scope-ээс одоогийн activeSpan-г авч, шинэ Span үүсгэж, түүний эцэг эх нь үр дүнд нь activeSpan гэж хэлж, шинэ Span-ийг идэвхтэй болгоно. Гадны үйлчилгээнүүдийг дуудах үед тэдгээрт одоогийн идэвхтэй спам дамжих ба тэдгээр үйлчилгээнүүд нь энэ хүрээн дээр тулгуурлан шинэ хүрээ үүсгэдэг.
Бүх ажил Tracer жишээгээр дамждаг, та үүнийг DI механизмаар дамжуулан авах боломжтой, эсвэл DI механизм ажиллахгүй бол GlobalTracer.get () глобал хувьсагчаар авч болно. Анхдагч байдлаар, хэрэв мөрийг эхлүүлээгүй бол NoopTracer буцаж ирэх бөгөөд юу ч хийхгүй.
Цаашилбал, одоогийн хамрах хүрээг ScopeManager-ээр дамжуулан мөрдөгчөөс авч, шинэ хүрээг холбосноор одоогийнхоос шинэ хамрах хүрээг үүсгэж, дараа нь үүсгэсэн хамрах хүрээг хааж, үүсгэсэн хүрээг хааж, өмнөх хамрах хүрээг буцаана. идэвхтэй төлөв. Хамрах хүрээ нь утастай холбоотой тул олон урсгалтай програмчлалын үед та өөр хэлхээний хамрах хүрээг идэвхжүүлэхийн тулд идэвхтэй хүрээг өөр урсгал руу шилжүүлэхээ санах хэрэгтэй.

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)) {
                ...
            }
        });
    }
}

Олон урсгалтай програмчлалын хувьд асинхрон даалгавруудыг эхлүүлэх үед урсгал руу автоматаар дамжуулдаг TracedExecutorService болон ижил төстэй боодолууд байдаг:

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

Гадаад http хүсэлтийн хувьд байдаг TracingHttpClient

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

Бидэнд тулгарсан асуудлууд

  • Хэрэв тракер нь үйлчилгээ эсвэл бүрэлдэхүүн хэсэгт ашиглагдаагүй бол шош болон DI үргэлж ажилладаггүй Автоматаар холбогдсон Tracer ажиллахгүй байж магадгүй бөгөөд та GlobalTracer.get()-г ашиглах хэрэгтэй болно.
  • Хэрэв энэ нь бүрэлдэхүүн хэсэг эсвэл үйлчилгээ биш юмуу эсвэл ижил ангийн хөрш зэргэлдээ аргаас дуудагдсан бол тайлбарууд ажиллахгүй. Та юу болж байгааг шалгахдаа болгоомжтой байх хэрэгтэй бөгөөд хэрэв @Traced ажиллахгүй бол гараар ул мөр үүсгэхийг ашиглах хэрэгтэй. Та мөн java тайлбарт зориулсан нэмэлт хөрвүүлэгчийг хавсаргаж болно, тэгвэл тэд хаа сайгүй ажиллах ёстой.
  • Хуучин хавар, хаврын гутал дээр DI дахь алдааны улмаас opentraing пүршний үүлэн автомат тохиргоо ажиллахгүй байгаа тул хаврын бүрэлдэхүүн хэсгүүдийн ул мөр автоматаар ажиллахыг хүсвэл та үүнийг аналоги байдлаар хийж болно. 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
  • Нөөцөөр оролдох нь тийм ч хэцүү биш, та try finally ашиглах ёстой.
  • Үйлчилгээ бүр өөрийн гэсэн spring.application.name-тэй байх ёстой бөгөөд үүний дагуу ул мөрийг бүртгэх болно. Борлуулалт, туршилтыг тусад нь юу гэж нэрлэдэг вэ, ингэснээр тэднийг хамтдаа саад болохгүй.
  • Хэрэв та GlobalTracer болон tomcat ашигладаг бол энэ tomcat-д ажиллаж байгаа бүх үйлчилгээнүүд нэг GlobalTracer-тэй байх тул бүгд ижил үйлчилгээний нэртэй байх болно.
  • Арга руу ул мөр нэмэхдээ үүнийг давталтаар олон удаа дууддаггүй гэдэгт итгэлтэй байх хэрэгтэй. Бүх дуудлагад нэг нийтлэг мөрийг нэмэх шаардлагатай бөгөөд энэ нь нийт ажлын цагийг баталгаажуулдаг. Үгүй бол илүүдэл ачаалал үүснэ.
  • Нэгэн удаа jaeger-ui-д олон тооны ул мөрийг авахын тулд хэтэрхий том хүсэлт тавьсан бөгөөд тэд хариу хүлээгээгүй тул дахин хийсэн. Үүний үр дүнд jaeger-query маш их санах ой идэж, уян хатан чанарыг удаашруулж эхлэв. jaeger-query-г дахин эхлүүлснээр тусалсан

Дээж авах, хадгалах, ул мөр үзэх

Гурван төрөл байдаг дээж авах ул мөр:

  1. Const нь бүх ул мөрийг илгээж, хадгалдаг.
  2. Өгөгдсөн магадлалаар ул мөрийг шүүдэг магадлал.
  3. Хэмжээ хязгаарлах нь секундэд мөрийн тоог хязгаарладаг. Та jaeger-агент эсвэл коллектор дээр эдгээр тохиргоог клиент дээр тохируулах боломжтой. Одоо бид үнэлэгчийн стек дээр const 1-г ашиглаж байна, учир нь тийм ч олон хүсэлт байдаггүй, гэхдээ тэд удаан хугацаа шаарддаг. Ирээдүйд, хэрэв энэ нь системд хэт их ачаалал өгөх юм бол та үүнийг хязгаарлаж болно.

Хэрэв та кассандра ашигладаг бол анхдагч байдлаар энэ нь зөвхөн хоёр өдрийн турш ул мөрийг хадгалдаг. Бид ашиглаж байна эластик хайлт мөн ул мөр нь бүх цаг хугацаанд хадгалагдах ба устгагдахгүй. Өдөр бүр тусдаа индекс үүсгэнэ, жишээ нь jaeger-service-2019-03-04. Ирээдүйд та хуучин ул мөрийг автоматаар цэвэрлэх тохиргоог хийх хэрэгтэй.

Ул мөрийг харахын тулд танд хэрэгтэй:

  • Та ул мөрийг шүүхийг хүсч буй үйлчилгээгээ сонгоно уу, жишээлбэл, tomcat-д ажиллаж байгаа, өөрийн нэргүй үйлчилгээний tomcat7-default.
  • Дараа нь зөвхөн урт гүйцэтгэлийг авахын тулд үйл ажиллагаа, хугацааны интервал, хамгийн бага ажиллах хугацааг, жишээлбэл 10 секундээс сонго.
    Service Tracing, OpenTracing болон Jaeger
  • Нэг ул мөр рүү очоод тэнд юу удааширч байгааг хараарай.
    Service Tracing, OpenTracing болон Jaeger

Мөн хэрэв зарим хүсэлтийн ID нь мэдэгдэж байгаа бол, хэрэв энэ id нь trace span-д нэвтэрсэн бол шошгоны хайлтаар дамжуулан энэ id-р мөрийг олох боломжтой.

Баримт бичиг

Зүйл

Видео

Эх сурвалж: www.habr.com

сэтгэгдэл нэмэх