Մենք օգտագործում ենք միկրոսերվիսային ճարտարապետություն մեր նախագծերում: Երբ կատարողականի խցանումներ են առաջանում, շատ ժամանակ է ծախսվում տեղեկամատյանների մոնիտորինգի և վերլուծության վրա: Առանձին գործառնությունների ժամկետները գրանցամատյանում գրանցելիս սովորաբար դժվար է հասկանալ, թե ինչն է հանգեցրել այդ գործողությունների կանչմանը, հետևել գործողությունների հաջորդականությանը կամ մեկ գործողության ժամանակային հերթափոխին տարբեր ծառայություններում մյուսի նկատմամբ:
Ձեռքի աշխատանքը նվազագույնի հասցնելու համար մենք որոշեցինք օգտագործել հետագծման գործիքներից մեկը: Այն մասին, թե ինչպես և ինչու կարող եք օգտագործել հետագծումը և ինչպես մենք դա արեցինք, և կքննարկվի այս հոդվածում:
Ինչ խնդիրներ կարող են լուծվել հետագծման միջոցով
Գտեք կատարողականի խոչընդոտները և՛ մեկ ծառայության մեջ, և՛ ամբողջ կատարման ծառի մեջ բոլոր մասնակից ծառայությունների միջև: Օրինակ:
Շատ կարճ անընդմեջ զանգեր ծառայությունների միջև, օրինակ՝ դեպի գեոկոդավորում կամ տվյալների բազա:
Երկար I/O սպասումներ, ինչպիսիք են ցանցային փոխանցումները կամ սկավառակի ընթերցումները:
Երկար տվյալների վերլուծություն:
Երկար գործողություններ, որոնք պահանջում են պրոցեսոր:
Կոդի հատվածներ, որոնք անհրաժեշտ չեն վերջնական արդյունք ստանալու համար և կարող են հեռացվել կամ հետաձգվել:
Հստակ հասկացեք, թե ինչ հաջորդականությամբ ինչ է կոչվում և ինչ է տեղի ունենում, երբ կատարվում է վիրահատությունը:
Կարելի է տեսնել, որ, օրինակ, հարցումը եկել է WS ծառայությանը -> WS ծառայությունը լրացրել է տվյալները R ծառայության միջոցով -> այնուհետև հարցում է ուղարկել V ծառայությանը -> V ծառայությունը բեռնել է շատ տվյալներ R ծառայություն -> գնաց P ծառայություն -> P ծառայությունը կրկին գնաց ծառայության R -> ծառայությունը V-ն անտեսեց արդյունքը և անցավ ծառայության J -> և միայն այնուհետև վերադարձրեց պատասխանը ծառայությանը WS, մինչդեռ շարունակում էր այլ բան հաշվարկել: հետին պլան.
Առանց ամբողջ գործընթացի համար նման հետքի կամ մանրամասն փաստաթղթերի, շատ դժվար է հասկանալ, թե ինչ է տեղի ունենում, երբ առաջին անգամ դիտում ենք կոդը, և ծածկագիրը ցրված է տարբեր ծառայություններում և թաքնված մի փունջ աղբամանների և միջերեսների հետևում:
Կատարման ծառի մասին տեղեկատվության հավաքագրում՝ հետագա հետաձգված վերլուծության համար: Կատարման յուրաքանչյուր փուլում դուք կարող եք տեղեկատվություն ավելացնել հետքին, որը հասանելի է այս փուլում, այնուհետև պարզել, թե ինչ մուտքային տվյալներ են հանգեցրել նմանատիպ սցենարի: Օրինակ:
օգտագործողի այ - Դի
Իրավունքները
Ընտրված մեթոդի տեսակը
Մատյան կամ կատարման սխալ
Հետքերը վերածելով չափումների ենթաբազմության և հետագա վերլուծություններ՝ արդեն չափումների տեսքով:
Ինչ հետք կարող է մուտք գործել: Span
Հետագծման մեջ կա span հասկացությունը, սա մեկ գերանի անալոգն է վահանակին: ՍՊԱ-ն ունի.
Անունը, սովորաբար այն մեթոդի անվանումը, որը կատարվել է
Ծառայության անվանումը, որում ստեղծվել է տիրույթը
Սեփական եզակի ID
Ինչ-որ մետա տեղեկատվություն՝ դրա մեջ մուտքագրված բանալի/արժեքի տեսքով: Օրինակ, մեթոդի պարամետրերը կամ մեթոդն ավարտվել է սխալով, թե ոչ
Այս ժամանակահատվածի մեկնարկի և ավարտի ժամերը
Ծնողի միջակայքի ID
Յուրաքանչյուր միջակայք ուղարկվում է span կոլեկտորին, որպեսզի այն պահվի տվյալների բազայում հետագա վերանայման համար, հենց որ այն ավարտի իր կատարումը: Ապագայում դուք կարող եք կառուցել բոլոր բացվածքների ծառ՝ միանալով ծնողի ID-ով: Վերլուծելիս դուք կարող եք գտնել, օրինակ, որոշ ծառայության բոլոր ընդարձակությունները, որոնք ավելի քան որոշ ժամանակ են պահանջում: Այնուհետև, անցնելով որոշակի տարածություն, տեսեք ամբողջ ծառը այս միջակայքի վերևում և ներքևում:
Opentrace-ը, Jagger-ը և ինչպես ենք մենք այն իրականացրել մեր նախագծերի համար
Կա ընդհանուր ստանդարտ բաց հետք, որը նկարագրում է, թե ինչպես և ինչ պետք է հավաքել՝ չկապվելով որևէ լեզվով կոնկրետ իրականացման հետ: Օրինակ, Java-ում հետքերով բոլոր աշխատանքները կատարվում են ընդհանուր Opentrace API-ի միջոցով, և դրա տակ, օրինակ, Jaeger-ը կամ դատարկ լռելյայն իրականացումը, որը ոչինչ չի անում, կարող է թաքնվել:
Մենք օգտագործում ենք Jaeger որպես Opentrace-ի իրականացում: Այն բաղկացած է մի քանի բաղադրիչներից.
Jaeger-agent-ը տեղական գործակալ է, որը սովորաբար տեղադրվում է յուրաքանչյուր մեքենայի վրա, և ծառայությունները մուտքագրվում են դրա մեջ տեղական լռելյայն նավահանգստում: Եթե գործակալ չկա, ապա այս մեքենայի բոլոր ծառայությունների հետքերը սովորաբար անջատված են
Jaeger-collector - բոլոր գործակալներն ուղարկում են հավաքագրված հետքերը դրան, և այն տեղադրում է ընտրված տվյալների բազայում
Տվյալների բազան նրանց նախընտրած cassandra-ն է, բայց մենք օգտագործում ենք elasticsearch, կան իրականացումներ մի քանի այլ տվյալների բազաների համար և հիշողության մեջ ներդրում, որը ոչինչ չի պահում սկավառակի վրա:
Jaeger-query-ը ծառայություն է, որը գնում է տվյալների բազա և վերադարձնում արդեն հավաքագրված հետքերը վերլուծության համար
Jaeger-ui-ն վեբ ինտերֆեյս է հետքերը որոնելու և դիտելու համար, այն անցնում է jaeger-query-ին
Առանձին բաղադրիչ կարելի է անվանել opentrace jaeger-ի իրականացումը կոնկրետ լեզուների համար, որի միջոցով spans-ները ուղարկվում են jaeger-agent-ին։ Jagger-ի միացում Java-ում հանգում է io.opentracing.Tracer ինտերֆեյսի ներդրմանը, որից հետո դրա միջով բոլոր հետքերը կթռչեն դեպի իրական գործակալ:
Նաև գարնանային բաղադրիչի համար կարող եք միացնել 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-ը: ակտիվ վիճակը. Շրջանակը կապված է թելի հետ, այնպես որ բազմաթելային ծրագրավորման ժամանակ չպետք է մոռանալ ակտիվ տիրույթը տեղափոխել մեկ այլ թեմա, որպեսզի հետագայում ակտիվացվի մեկ այլ թեմայի շրջանակը` հղում կատարելով այս տարածությանը:
Բազմաթելային ծրագրավորման համար կա նաև TracedExecutorService և նմանատիպ փաթաթիչներ, որոնք ավտոմատ կերպով փոխանցում են ընթացիկ տարածությունը դեպի շարանը, երբ գործարկվում են ասինխրոն առաջադրանքներ.
private ExecutorService executor = new TracedExecutorService(
Executors.newFixedThreadPool(10), GlobalTracer.get()
);
HttpClient httpClient = new TracingHttpClientBuilder().build();
Մեր առջև ծառացած խնդիրներ
Beans-ը և DI-ն միշտ չէ, որ աշխատում են, եթե հետագծիչը չի օգտագործվում ծառայության կամ բաղադրիչի մեջ, ապա Ավտոմատ լարով Tracer-ը կարող է չաշխատել, և դուք ստիպված կլինեք օգտագործել GlobalTracer.get():
Անոտացիաները չեն աշխատում, եթե այն բաղադրիչ կամ ծառայություն չէ, կամ եթե մեթոդը կանչված է նույն դասի հարևան մեթոդից: Դուք պետք է զգույշ լինեք ստուգելու համար, թե ինչն է աշխատում և օգտագործեք ձեռքով հետքի ստեղծում, եթե @Traced-ը չի աշխատում: Կարող եք նաև կցել լրացուցիչ կոմպիլյատոր java անոտացիաների համար, այնուհետև դրանք պետք է աշխատեն ամենուր:
Փորձել ռեսուրսներով չի աշխատում groovy, դուք պետք է օգտագործեք փորձեք վերջապես:
Յուրաքանչյուր ծառայություն պետք է ունենա իր spring.application.name-ը, որի տակ կգրանցվեն հետքերը: Ինչ է նշանակում առանձին անուն վաճառքի և թեստի համար, որպեսզի չխանգարեն նրանց միասին:
Եթե դուք օգտագործում եք GlobalTracer և tomcat, ապա այս tomcat-ում աշխատող բոլոր ծառայություններն ունեն մեկ GlobalTracer, ուստի բոլորը կունենան ծառայության նույն անունը:
Մեթոդի վրա հետքեր ավելացնելիս պետք է վստահ լինել, որ այն բազմիցս չի կանչվում օղակում: Բոլոր զանգերի համար անհրաժեշտ է ավելացնել մեկ ընդհանուր հետք, որը երաշխավորում է ընդհանուր աշխատանքային ժամանակը: Հակառակ դեպքում ավելորդ բեռ կստեղծվի։
Մի անգամ jaeger-ui-ում չափազանց մեծ խնդրանքներ են արվել մեծ թվով հետքերի համար, և քանի որ նրանք չեն սպասել պատասխանի, նորից են արել: Արդյունքում, jaeger-query-ն սկսեց ուտել շատ հիշողություն և դանդաղեցնել առաձգականությունը: Օգնեց՝ վերագործարկելով jaeger-query-ը
Հավանական, որը զտում է հետքերը որոշակի հավանականությամբ:
Ratelimiting, որը սահմանափակում է հետքերի քանակը վայրկյանում: Դուք կարող եք կարգավորել այս կարգավորումները հաճախորդի վրա՝ կա՛մ jaeger-agent-ի, կա՛մ կոլեկցիոների վրա: Այժմ մենք օգտագործում ենք const 1-ը գնահատողի կույտում, քանի որ հարցումները շատ չեն, բայց դրանք երկար ժամանակ են պահանջում: Ապագայում, եթե դա չափազանց մեծ բեռ կբերի համակարգի վրա, կարող եք սահմանափակել այն:
Եթե դուք օգտագործում եք cassandra, ապա լռելյայն այն պահպանում է հետքերը միայն երկու օր: Մենք օգտագործում ենք առաձգական որոնում և հետքերը պահվում են բոլոր ժամանակներում և չեն ջնջվում: Յուրաքանչյուր օրվա համար ստեղծվում է առանձին ինդեքս, օրինակ՝ jaeger-service-2019-03-04: Ապագայում դուք պետք է կարգավորեք հին հետքերի ավտոմատ մաքրումը:
Հետքերը դիտելու համար ձեզ հարկավոր է.
Ընտրեք ծառայությունը, որով ցանկանում եք զտել հետքերը, օրինակ՝ tomcat7-default ծառայության համար, որն աշխատում է tomcat-ում և չի կարող ունենալ իր սեփական անունը:
Այնուհետև ընտրեք գործողությունը, ժամանակային միջակայքը և նվազագույն գործառնական ժամանակը, օրինակ՝ 10 վայրկյանից, որպեսզի միայն երկար կատարումներ կատարվեն:
Գնացեք հետքերից մեկի մոտ և տեսեք, թե ինչն է դանդաղում այնտեղ։
Բացի այդ, եթե որոշ հարցումների id հայտնի է, ապա դուք կարող եք գտնել հետք այս id-ով պիտակների որոնման միջոցով, եթե այս id-ը գրանցված է հետագծման միջակայքում:
www.youtube.com/watch?v=qg0ENOdP1Lo Ինչպես մենք օգտագործեցինք Յագերը և Պրոմեթևսը կայծակնային արագ օգտվողների հարցումներ տրամադրելու համար - Բրայան Բորեհեմ