Ծառայությունների հետագծում, OpenTracing և Jaeger

Ծառայությունների հետագծում, OpenTracing և Jaeger

Մենք օգտագործում ենք միկրոսերվիսային ճարտարապետություն մեր նախագծերում: Երբ կատարողականի խցանումներ են առաջանում, շատ ժամանակ է ծախսվում տեղեկամատյանների մոնիտորինգի և վերլուծության վրա: Առանձին գործառնությունների ժամկետները գրանցամատյանում գրանցելիս սովորաբար դժվար է հասկանալ, թե ինչն է հանգեցրել այդ գործողությունների կանչմանը, հետևել գործողությունների հաջորդականությանը կամ մեկ գործողության ժամանակային հերթափոխին տարբեր ծառայություններում մյուսի նկատմամբ:

Ձեռքի աշխատանքը նվազագույնի հասցնելու համար մենք որոշեցինք օգտագործել հետագծման գործիքներից մեկը: Այն մասին, թե ինչպես և ինչու կարող եք օգտագործել հետագծումը և ինչպես մենք դա արեցինք, և կքննարկվի այս հոդվածում:

Ինչ խնդիրներ կարող են լուծվել հետագծման միջոցով

  1. Գտեք կատարողականի խոչընդոտները և՛ մեկ ծառայության մեջ, և՛ ամբողջ կատարման ծառի մեջ բոլոր մասնակից ծառայությունների միջև: Օրինակ:
    • Շատ կարճ անընդմեջ զանգեր ծառայությունների միջև, օրինակ՝ դեպի գեոկոդավորում կամ տվյալների բազա:
    • Երկար I/O սպասումներ, ինչպիսիք են ցանցային փոխանցումները կամ սկավառակի ընթերցումները:
    • Երկար տվյալների վերլուծություն:
    • Երկար գործողություններ, որոնք պահանջում են պրոցեսոր:
    • Կոդի հատվածներ, որոնք անհրաժեշտ չեն վերջնական արդյունք ստանալու համար և կարող են հեռացվել կամ հետաձգվել:
  2. Հստակ հասկացեք, թե ինչ հաջորդականությամբ ինչ է կոչվում և ինչ է տեղի ունենում, երբ կատարվում է վիրահատությունը:
    Ծառայությունների հետագծում, OpenTracing և Jaeger
    Կարելի է տեսնել, որ, օրինակ, հարցումը եկել է WS ծառայությանը -> WS ծառայությունը լրացրել է տվյալները R ծառայության միջոցով -> այնուհետև հարցում է ուղարկել V ծառայությանը -> V ծառայությունը բեռնել է շատ տվյալներ R ծառայություն -> գնաց P ծառայություն -> P ծառայությունը կրկին գնաց ծառայության R -> ծառայությունը V-ն անտեսեց արդյունքը և անցավ ծառայության J -> և միայն այնուհետև վերադարձրեց պատասխանը ծառայությանը WS, մինչդեռ շարունակում էր այլ բան հաշվարկել: հետին պլան.
    Առանց ամբողջ գործընթացի համար նման հետքի կամ մանրամասն փաստաթղթերի, շատ դժվար է հասկանալ, թե ինչ է տեղի ունենում, երբ առաջին անգամ դիտում ենք կոդը, և ծածկագիրը ցրված է տարբեր ծառայություններում և թաքնված մի փունջ աղբամանների և միջերեսների հետևում:
  3. Կատարման ծառի մասին տեղեկատվության հավաքագրում՝ հետագա հետաձգված վերլուծության համար: Կատարման յուրաքանչյուր փուլում դուք կարող եք տեղեկատվություն ավելացնել հետքին, որը հասանելի է այս փուլում, այնուհետև պարզել, թե ինչ մուտքային տվյալներ են հանգեցրել նմանատիպ սցենարի: Օրինակ:
    • օգտագործողի այ - Դի
    • Իրավունքները
    • Ընտրված մեթոդի տեսակը
    • Մատյան կամ կատարման սխալ
  4. Հետքերը վերածելով չափումների ենթաբազմության և հետագա վերլուծություններ՝ արդեն չափումների տեսքով:

Ինչ հետք կարող է մուտք գործել: Span

Հետագծման մեջ կա span հասկացությունը, սա մեկ գերանի անալոգն է վահանակին: ՍՊԱ-ն ունի.

  • Անունը, սովորաբար այն մեթոդի անվանումը, որը կատարվել է
  • Ծառայության անվանումը, որում ստեղծվել է տիրույթը
  • Սեփական եզակի ID
  • Ինչ-որ մետա տեղեկատվություն՝ դրա մեջ մուտքագրված բանալի/արժեքի տեսքով: Օրինակ, մեթոդի պարամետրերը կամ մեթոդն ավարտվել է սխալով, թե ոչ
  • Այս ժամանակահատվածի մեկնարկի և ավարտի ժամերը
  • Ծնողի միջակայքի ID

Յուրաքանչյուր միջակայք ուղարկվում է span կոլեկտորին, որպեսզի այն պահվի տվյալների բազայում հետագա վերանայման համար, հենց որ այն ավարտի իր կատարումը: Ապագայում դուք կարող եք կառուցել բոլոր բացվածքների ծառ՝ միանալով ծնողի ID-ով: Վերլուծելիս դուք կարող եք գտնել, օրինակ, որոշ ծառայության բոլոր ընդարձակությունները, որոնք ավելի քան որոշ ժամանակ են պահանջում: Այնուհետև, անցնելով որոշակի տարածություն, տեսեք ամբողջ ծառը այս միջակայքի վերևում և ներքևում:

Ծառայությունների հետագծում, OpenTracing և Jaeger

Opentrace-ը, Jagger-ը և ինչպես ենք մենք այն իրականացրել մեր նախագծերի համար

Կա ընդհանուր ստանդարտ բաց հետք, որը նկարագրում է, թե ինչպես և ինչ պետք է հավաքել՝ չկապվելով որևէ լեզվով կոնկրետ իրականացման հետ: Օրինակ, Java-ում հետքերով բոլոր աշխատանքները կատարվում են ընդհանուր Opentrace API-ի միջոցով, և դրա տակ, օրինակ, Jaeger-ը կամ դատարկ լռելյայն իրականացումը, որը ոչինչ չի անում, կարող է թաքնվել:
Մենք օգտագործում ենք Jaeger որպես Opentrace-ի իրականացում: Այն բաղկացած է մի քանի բաղադրիչներից.

Ծառայությունների հետագծում, OpenTracing և Jaeger

  • Jaeger-agent-ը տեղական գործակալ է, որը սովորաբար տեղադրվում է յուրաքանչյուր մեքենայի վրա, և ծառայությունները մուտքագրվում են դրա մեջ տեղական լռելյայն նավահանգստում: Եթե ​​գործակալ չկա, ապա այս մեքենայի բոլոր ծառայությունների հետքերը սովորաբար անջատված են
  • Jaeger-collector - բոլոր գործակալներն ուղարկում են հավաքագրված հետքերը դրան, և այն տեղադրում է ընտրված տվյալների բազայում
  • Տվյալների բազան նրանց նախընտրած cassandra-ն է, բայց մենք օգտագործում ենք elasticsearch, կան իրականացումներ մի քանի այլ տվյալների բազաների համար և հիշողության մեջ ներդրում, որը ոչինչ չի պահում սկավառակի վրա:
  • Jaeger-query-ը ծառայություն է, որը գնում է տվյալների բազա և վերադարձնում արդեն հավաքագրված հետքերը վերլուծության համար
  • Jaeger-ui-ն վեբ ինտերֆեյս է հետքերը որոնելու և դիտելու համար, այն անցնում է jaeger-query-ին

Ծառայությունների հետագծում, OpenTracing և Jaeger

Առանձին բաղադրիչ կարելի է անվանել opentrace jaeger-ի իրականացումը կոնկրետ լեզուների համար, որի միջոցով spans-ները ուղարկվում են jaeger-agent-ին։
Jagger-ի միացում Java-ում հանգում է io.opentracing.Tracer ինտերֆեյսի ներդրմանը, որից հետո դրա միջով բոլոր հետքերը կթռչեն դեպի իրական գործակալ:

Ծառայությունների հետագծում, OpenTracing և Jaeger

Նաև գարնանային բաղադրիչի համար կարող եք միացնել opentracing-spring-cloud- starter և իրականացում Jaeger-ից opentracing-spring-jaeger-cloud- starter որը ավտոմատ կերպով կկազմաձևի հետագծումը այն ամենի համար, ինչ անցնում է այս բաղադրիչներով, օրինակ՝ http հարցումներ կարգավորիչներին, հարցումներ դեպի տվյալների բազա jdbc-ի միջոցով և այլն:

Java-ում գրանցման հետքեր

Ինչ-որ տեղ վերին մակարդակում պետք է ստեղծվի առաջին Span-ը, դա կարող է կատարվել ավտոմատ կերպով, օրինակ՝ զսպանակային կարգավորիչի կողմից, երբ հարցում է ստացվում, կամ ձեռքով, եթե չկա: Այնուհետև այն փոխանցվում է ստորև նշված Շրջանակի միջոցով: Եթե ​​ստորև բերված մեթոդներից որևէ մեկը ցանկանում է ավելացնել Span, այն վերցնում է ընթացիկ activeSpan-ը Scope-ից, ստեղծում է նոր Span և ասում, որ դրա մայրը ստացված activeSpan-ն է և ակտիվացնում է նոր Span-ը: Արտաքին ծառայություններ կանչելիս ընթացիկ ակտիվ տիրույթը փոխանցվում է նրանց, և այդ ծառայությունները ստեղծում են նոր միջակայքեր՝ հղում կատարելով այս տիրույթին:
Ամբողջ աշխատանքն անցնում է Tracer օրինակով, դուք կարող եք այն ստանալ DI մեխանիզմով կամ GlobalTracer.get () որպես գլոբալ փոփոխական, եթե DI մեխանիզմը չի աշխատում: Լռելյայնորեն, եթե հետագծիչը չի սկզբնավորվել, NoopTracer-ը կվերադառնա, որը ոչինչ չի անում:
Այնուհետև, ընթացիկ շրջանակը ստացվում է հետագծողից ScopeManager-ի միջոցով, ներկայիս շրջանակից ստեղծվում է նոր շրջանակ՝ նոր տարածության կապակցմամբ, այնուհետև փակվում է ստեղծված Scope-ը, որը փակում է ստեղծված տիրույթը և վերադարձնում է նախորդ Scope-ը: ակտիվ վիճակը. Շրջանակը կապված է թելի հետ, այնպես որ բազմաթելային ծրագրավորման ժամանակ չպետք է մոռանալ ակտիվ տիրույթը տեղափոխել մեկ այլ թեմա, որպեսզի հետագայում ակտիվացվի մեկ այլ թեմայի շրջանակը` հղում կատարելով այս տարածությանը:

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();

Մեր առջև ծառացած խնդիրներ

  • Beans-ը և DI-ն միշտ չէ, որ աշխատում են, եթե հետագծիչը չի օգտագործվում ծառայության կամ բաղադրիչի մեջ, ապա Ավտոմատ լարով Tracer-ը կարող է չաշխատել, և դուք ստիպված կլինեք օգտագործել GlobalTracer.get():
  • Անոտացիաները չեն աշխատում, եթե այն բաղադրիչ կամ ծառայություն չէ, կամ եթե մեթոդը կանչված է նույն դասի հարևան մեթոդից: Դուք պետք է զգույշ լինեք ստուգելու համար, թե ինչն է աշխատում և օգտագործեք ձեռքով հետքի ստեղծում, եթե @Traced-ը չի աշխատում: Կարող եք նաև կցել լրացուցիչ կոմպիլյատոր java անոտացիաների համար, այնուհետև դրանք պետք է աշխատեն ամենուր:
  • Հին զսպանակային և զսպանակային բեռնախցիկի մեջ բացվող զսպանակային ամպի ավտոմատ կոնֆիգուրացիան չի աշխատում DI-ի սխալների պատճառով, ապա եթե ցանկանում եք, որ գարնանային բաղադրիչների հետքերը ավտոմատ կերպով աշխատեն, կարող եք դա անել անալոգիայի միջոցով: 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
  • Փորձել ռեսուրսներով չի աշխատում groovy, դուք պետք է օգտագործեք փորձեք վերջապես:
  • Յուրաքանչյուր ծառայություն պետք է ունենա իր spring.application.name-ը, որի տակ կգրանցվեն հետքերը: Ինչ է նշանակում առանձին անուն վաճառքի և թեստի համար, որպեսզի չխանգարեն նրանց միասին:
  • Եթե ​​դուք օգտագործում եք GlobalTracer և tomcat, ապա այս tomcat-ում աշխատող բոլոր ծառայություններն ունեն մեկ GlobalTracer, ուստի բոլորը կունենան ծառայության նույն անունը:
  • Մեթոդի վրա հետքեր ավելացնելիս պետք է վստահ լինել, որ այն բազմիցս չի կանչվում օղակում: Բոլոր զանգերի համար անհրաժեշտ է ավելացնել մեկ ընդհանուր հետք, որը երաշխավորում է ընդհանուր աշխատանքային ժամանակը: Հակառակ դեպքում ավելորդ բեռ կստեղծվի։
  • Մի անգամ jaeger-ui-ում չափազանց մեծ խնդրանքներ են արվել մեծ թվով հետքերի համար, և քանի որ նրանք չեն սպասել պատասխանի, նորից են արել: Արդյունքում, jaeger-query-ն սկսեց ուտել շատ հիշողություն և դանդաղեցնել առաձգականությունը: Օգնեց՝ վերագործարկելով jaeger-query-ը

Հետքերի նմուշառում, պահպանում և դիտում

Կան երեք տեսակ նմուշառման հետքեր:

  1. Const, որն ուղարկում և պահպանում է բոլոր հետքերը:
  2. Հավանական, որը զտում է հետքերը որոշակի հավանականությամբ:
  3. Ratelimiting, որը սահմանափակում է հետքերի քանակը վայրկյանում: Դուք կարող եք կարգավորել այս կարգավորումները հաճախորդի վրա՝ կա՛մ jaeger-agent-ի, կա՛մ կոլեկցիոների վրա: Այժմ մենք օգտագործում ենք const 1-ը գնահատողի կույտում, քանի որ հարցումները շատ չեն, բայց դրանք երկար ժամանակ են պահանջում: Ապագայում, եթե դա չափազանց մեծ բեռ կբերի համակարգի վրա, կարող եք սահմանափակել այն:

Եթե ​​դուք օգտագործում եք cassandra, ապա լռելյայն այն պահպանում է հետքերը միայն երկու օր: Մենք օգտագործում ենք առաձգական որոնում և հետքերը պահվում են բոլոր ժամանակներում և չեն ջնջվում: Յուրաքանչյուր օրվա համար ստեղծվում է առանձին ինդեքս, օրինակ՝ jaeger-service-2019-03-04: Ապագայում դուք պետք է կարգավորեք հին հետքերի ավտոմատ մաքրումը:

Հետքերը դիտելու համար ձեզ հարկավոր է.

  • Ընտրեք ծառայությունը, որով ցանկանում եք զտել հետքերը, օրինակ՝ tomcat7-default ծառայության համար, որն աշխատում է tomcat-ում և չի կարող ունենալ իր սեփական անունը:
  • Այնուհետև ընտրեք գործողությունը, ժամանակային միջակայքը և նվազագույն գործառնական ժամանակը, օրինակ՝ 10 վայրկյանից, որպեսզի միայն երկար կատարումներ կատարվեն:
    Ծառայությունների հետագծում, OpenTracing և Jaeger
  • Գնացեք հետքերից մեկի մոտ և տեսեք, թե ինչն է դանդաղում այնտեղ։
    Ծառայությունների հետագծում, OpenTracing և Jaeger

Բացի այդ, եթե որոշ հարցումների id հայտնի է, ապա դուք կարող եք գտնել հետք այս id-ով պիտակների որոնման միջոցով, եթե այս id-ը գրանցված է հետագծման միջակայքում:

Փաստաթղթերով հիմնավորում

Հոդվածներ

Video

  • www.youtube.com/watch?v=qg0ENOdP1Lo Ինչպես մենք օգտագործեցինք Յագերը և Պրոմեթևսը կայծակնային արագ օգտվողների հարցումներ տրամադրելու համար - Բրայան Բորեհեմ
  • www.youtube.com/watch?v=WRntQsUajow Ներածություն՝ Յագեր - Յուրի Շկուրո, Uber & Pavol Loffay, Red Hat
  • www.youtube.com/watch?v=fsHb0qK37bc Սերգեյ Յակովլև, «Մեծ հաղթանակի մի փոքրիկ պատմություն. OpenTracing, AWS և Jaeger»

Source: www.habr.com

Добавить комментарий