Հարմարավետ ճարտարապետական ​​նախշեր

Հե՜յ Հաբր։

Կորոնավիրուսի հետևանքով պայմանավորված ընթացիկ իրադարձությունների լույսի ներքո մի շարք ինտերնետային ծառայություններ սկսել են ավելի մեծ բեռ ստանալ։ Օրինակ, Մեծ Բրիտանիայի մանրածախ առևտրի ցանցերից մեկը պարզապես դադարեցրեց իր առցանց պատվերների կայքը:, քանի որ բավարար հզորություն չի եղել։ Եվ միշտ չէ, որ հնարավոր է արագացնել սերվերը՝ պարզապես ավելի հզոր սարքավորումներ ավելացնելով, բայց հաճախորդի հարցումները պետք է մշակվեն (կամ նրանք կգնան մրցակիցներին):

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

Հորիզոնական մասշտաբավորում

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

Օրինակ, ես կվերցնեմ վերացական ամպային ֆայլերի պահեստավորում, այսինքն՝ OwnCloud-ի, OneDrive-ի և այլնի որոշ անալոգներ:

Նման շղթայի ստանդարտ պատկերը ներկայացված է ստորև, բայց դա միայն ցույց է տալիս համակարգի բարդությունը: Ի վերջո, մենք պետք է ինչ-որ կերպ համաժամացնենք ծառայությունները: Ի՞նչ կլինի, եթե օգտատերը պահի ֆայլը պլանշետից և այնուհետև ցանկանա դիտել այն հեռախոսից:

Հարմարավետ ճարտարապետական ​​նախշեր
Մոտեցումների տարբերությունը. ուղղահայաց մասշտաբով մենք պատրաստ ենք ավելացնել հանգույցների հզորությունը, իսկ հորիզոնական մասշտաբով մենք պատրաստ ենք ավելացնել նոր հանգույցներ՝ բեռը բաշխելու համար։

CQRS

Հրամանի հարցումների պատասխանատվության տարանջատում Բավական կարևոր օրինաչափություն, քանի որ այն թույլ է տալիս տարբեր հաճախորդների ոչ միայն միանալ տարբեր ծառայություններին, այլև ստանալ նույն իրադարձությունների հոսքերը: Դրա առավելություններն այնքան էլ ակնհայտ չեն պարզ հավելվածի համար, սակայն այն չափազանց կարևոր է (և պարզ) զբաղված ծառայության համար: Դրա էությունը. մուտքային և ելքային տվյալների հոսքերը չպետք է հատվեն: Այսինքն, դուք չեք կարող հարցում ուղարկել և ակնկալել պատասխան, փոխարենը հարցում եք ուղարկում A ծառայությանը, բայց պատասխան եք ստանում B ծառայությունից:

Այս մոտեցման առաջին բոնուսը երկար խնդրանքը կատարելիս կապը խզելու ունակությունն է (բառի լայն իմաստով): Օրինակ, եկեք վերցնենք քիչ թե շատ ստանդարտ հաջորդականություն.

  1. Հաճախորդը հարցում է ուղարկել սերվերին:
  2. Սերվերը սկսել է երկար մշակման ժամանակ:
  3. Սերվերը պատասխանում է հաճախորդին արդյունքով:

Պատկերացնենք, որ 2-րդ կետում կապը խզվել է (կամ ցանցը նորից միացել է, կամ օգտատերը գնացել է այլ էջ՝ խզելով կապը)։ Այս դեպքում սերվերի համար դժվար կլինի օգտատիրոջը պատասխան ուղարկել այն մասին, թե կոնկրետ ինչ է մշակվել: Օգտագործելով CQRS, հաջորդականությունը մի փոքր տարբեր կլինի.

  1. Հաճախորդը բաժանորդագրվել է թարմացումներին:
  2. Հաճախորդը հարցում է ուղարկել սերվերին:
  3. Սերվերը պատասխանել է «խնդրանքն ընդունված է»:
  4. Սերվերը արձագանքեց արդյունքին «1» կետից ալիքի միջոցով:

Հարմարավետ ճարտարապետական ​​նախշեր

Ինչպես տեսնում եք, սխեման մի փոքր ավելի բարդ է: Ավելին, այստեղ բացակայում է ինտուիտիվ հարցում-պատասխան մոտեցումը։ Այնուամենայնիվ, ինչպես տեսնում եք, հարցումը մշակելիս կապի ընդհատումը սխալի չի հանգեցնի: Ավելին, եթե իրականում օգտատերը ծառայությանը միացված է մի քանի սարքերից (օրինակ՝ բջջային հեռախոսից և պլանշետից), կարող եք համոզվել, որ պատասխանը գալիս է երկու սարքերին էլ։

Հետաքրքիր է, որ մուտքային հաղորդագրությունների մշակման կոդը դառնում է նույնը (ոչ 100%) ինչպես հաճախորդի կողմից ազդված իրադարձությունների, այնպես էլ այլ իրադարձությունների համար, ներառյալ այլ հաճախորդների:

Այնուամենայնիվ, իրականում մենք ստանում ենք հավելյալ բոնուս՝ պայմանավորված այն հանգամանքով, որ միակողմանի հոսքը կարող է կառավարվել ֆունկցիոնալ ոճով (օգտագործելով RX և այլն): Եվ սա արդեն լուրջ պլյուս է, քանի որ, ըստ էության, հավելվածը կարելի է ամբողջությամբ ռեակտիվ դարձնել, ինչպես նաև օգտագործել ֆունկցիոնալ մոտեցում։ Ճարպային ծրագրերի համար դա կարող է զգալիորեն խնայել զարգացման և աջակցության ռեսուրսները:

Եթե ​​մենք համատեղում ենք այս մոտեցումը հորիզոնական մասշտաբի հետ, ապա որպես բոնուս մենք ստանում ենք հարցումներ մի սերվեր ուղարկելու և մյուսից պատասխաններ ստանալու հնարավորություն։ Այսպիսով, հաճախորդը կարող է ընտրել իրեն հարմար ծառայությունը, իսկ ներսում գտնվող համակարգը դեռ կկարողանա ճիշտ մշակել իրադարձությունները։

Իրադարձությունների աղբյուր

Ինչպես գիտեք, բաշխված համակարգի հիմնական հատկանիշներից մեկը ընդհանուր ժամանակի, ընդհանուր կրիտիկական հատվածի բացակայությունն է։ Մեկ գործընթացի համար դուք կարող եք կատարել համաժամացում (նույն մուտեքսների վրա), որի շրջանակներում վստահ եք, որ ոչ ոք չի կատարում այս կոդը: Այնուամենայնիվ, սա վտանգավոր է բաշխված համակարգի համար, քանի որ այն կպահանջի ծախսեր, ինչպես նաև կսպանի մասշտաբի ողջ գեղեցկությունը. բոլոր բաղադրիչները դեռ կսպասեն մեկին:

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

Կարևոր է հասկանալ, որ դասական տվյալների բազաների համար այն բավականին հաճախ է օգտագործվում ուժեղ հետևողականություն, որտեղ յուրաքանչյուր հանգույց ունի նույն տեղեկությունը (սա հաճախ ձեռք է բերվում այն ​​դեպքում, երբ գործարքը համարվում է կայացած միայն երկրորդ սերվերի պատասխանից հետո)։ Այստեղ որոշակի հանգստություններ կան՝ պայմանավորված մեկուսացման մակարդակով, բայց ընդհանուր գաղափարը մնում է նույնը՝ դուք կարող եք ապրել լիովին ներդաշնակ աշխարհում:

Այնուամենայնիվ, վերադառնանք բուն առաջադրանքին։ Եթե ​​համակարգի մի մասը կարելի է կառուցել վերջնական հետևողականություն, ապա մենք կարող ենք կառուցել հետևյալ դիագրամը.

Հարմարավետ ճարտարապետական ​​նախշեր

Այս մոտեցման կարևոր առանձնահատկությունները.

  • Յուրաքանչյուր մուտքային հարցում տեղադրվում է մեկ հերթում:
  • Հարցումը մշակելիս ծառայությունը կարող է առաջադրանքներ տեղադրել նաև այլ հերթերում:
  • Յուրաքանչյուր մուտքային իրադարձություն ունի նույնացուցիչ (որն անհրաժեշտ է կրկնօրինակման համար):
  • Հերթը գաղափարապես գործում է «միայն հավելված» սխեմայով։ Դուք չեք կարող հեռացնել տարրերը կամ վերադասավորել դրանք:
  • Հերթը աշխատում է FIFO սխեմայով (ներողություն տավտոլոգիայի համար): Եթե ​​Ձեզ անհրաժեշտ է կատարել զուգահեռ կատարում, ապա մի փուլում դուք պետք է օբյեկտները տեղափոխեք տարբեր հերթեր:

Հիշեցնեմ, որ մենք դիտարկում ենք առցանց ֆայլերի պահպանման դեպքը։ Այս դեպքում համակարգը կունենա հետևյալ տեսքը.

Հարմարավետ ճարտարապետական ​​նախշեր

Կարևոր է, որ դիագրամի ծառայությունները պարտադիր կերպով չեն նշանակում առանձին սերվեր: Նույնիսկ գործընթացը կարող է նույնը լինել: Կարևոր է մեկ այլ բան. գաղափարապես այս բաներն այնպես են տարանջատված, որ հորիզոնական մասշտաբները հեշտությամբ կիրառվեն։

Իսկ երկու օգտատերերի համար դիագրամը կունենա այսպիսի տեսք (տարբեր օգտատերերի համար նախատեսված ծառայությունները նշված են տարբեր գույներով).

Հարմարավետ ճարտարապետական ​​նախշեր

Նման համակցությունից բոնուսներ.

  • Տեղեկատվության մշակման ծառայություններն առանձնացված են: Հերթերը նույնպես առանձնացված են. Եթե ​​մենք պետք է մեծացնենք համակարգի թողունակությունը, ապա մենք պարզապես պետք է գործարկենք ավելի շատ ծառայություններ ավելի շատ սերվերների վրա:
  • Երբ մենք տեղեկատվություն ենք ստանում օգտվողից, մենք ստիպված չենք լինի սպասել, մինչև տվյալները ամբողջությամբ պահպանվեն: Ընդհակառակը, մենք պարզապես պետք է պատասխանենք «ok» և հետո աստիճանաբար սկսենք աշխատել: Միևնույն ժամանակ, հերթը հարթեցնում է գագաթնակետերը, քանի որ նոր օբյեկտի ավելացումը տեղի է ունենում արագ, և օգտագործողը ստիպված չէ սպասել ամբողջական անցման ամբողջ ցիկլով:
  • Որպես օրինակ, ես ավելացրեցի deduplication ծառայություն, որը փորձում է միաձուլել նույնական ֆայլերը: Եթե ​​1% դեպքերում այն ​​երկար աշխատի, հաճախորդը դժվար թե դա նկատի (տես վերևում), ինչը մեծ պլյուս է, քանի որ մեզնից այլևս չի պահանջվում լինել XNUMX% արագություն և հուսալի:

Այնուամենայնիվ, թերությունները անմիջապես տեսանելի են.

  • Մեր համակարգը կորցրել է իր խիստ հետևողականությունը։ Սա նշանակում է, որ եթե, օրինակ, բաժանորդագրվեք տարբեր ծառայությունների, ապա տեսականորեն կարող եք այլ վիճակ ստանալ (քանի որ ծառայություններից մեկը կարող է ժամանակ չունենալ ներքին հերթից ծանուցում ստանալու համար): Որպես ևս մեկ հետևանք՝ համակարգն այժմ չունի ընդհանուր ժամանակ։ Այսինքն, անհնար է, օրինակ, բոլոր իրադարձությունները դասավորել պարզապես ժամանման ժամանակով, քանի որ սերվերների միջև ժամացույցները կարող են համաժամանակ չլինել (ավելին, երկու սերվերների վրա նույն ժամանակը ուտոպիա է):
  • Այժմ ոչ մի իրադարձություն չի կարող պարզապես հետաձգվել (ինչպես կարելի է անել տվյալների բազայի դեպքում): Փոխարենը, դուք պետք է ավելացնեք նոր իրադարձություն − փոխհատուցման միջոցառում, որը կփոխի վերջին վիճակը անհրաժեշտին: Որպես օրինակ նմանատիպ տարածքից. առանց պատմությունը վերաշարադրելու (ինչը որոշ դեպքերում վատ է), դուք չեք կարող հետ գցել commit-ը git-ում, բայց կարող եք կատարել հատուկ հետադարձ պարտավորություն, որն ըստ էության պարզապես վերադարձնում է հին վիճակը։ Այնուամենայնիվ, և՛ սխալ կատարումը, և՛ հետադարձ կապը կմնան պատմության մեջ:
  • Տվյալների սխեման կարող է փոխվել թողարկումից մինչև թողարկում, սակայն հին իրադարձություններն այլևս չեն կարողանա թարմացվել նոր ստանդարտով (քանի որ իրադարձությունները սկզբունքորեն չեն կարող փոխվել):

Ինչպես տեսնում եք, Event Sourcing-ը լավ է աշխատում CQRS-ի հետ: Ավելին, արդյունավետ և հարմար հերթերով, բայց առանց տվյալների հոսքերի տարանջատման համակարգի ներդրումն ինքնին արդեն իսկ դժվար է, քանի որ ստիպված կլինեք ավելացնել համաժամացման կետեր, որոնք կչեզոքացնեն հերթերի ողջ դրական ազդեցությունը։ Միանգամից կիրառելով երկու մոտեցումները՝ անհրաժեշտ է մի փոքր կարգավորել ծրագրի կոդը։ Մեր դեպքում, ֆայլը սերվեր ուղարկելիս պատասխանը գալիս է միայն «ok», ինչը նշանակում է միայն, որ «ֆայլի ավելացման գործողությունը պահպանվել է»: Ֆորմալ կերպով դա չի նշանակում, որ տվյալներն արդեն հասանելի են այլ սարքերում (օրինակ, կրկնօրինակման ծառայությունը կարող է վերակառուցել ինդեքսը): Այնուամենայնիվ, որոշ ժամանակ անց հաճախորդը կստանա ծանուցում «X ֆայլը պահպանվել է» ոճով:

Որպես արդյունք:

  • Ֆայլերի ուղարկման կարգավիճակների թիվն ավելանում է. դասական «ֆայլ ուղարկված»-ի փոխարեն մենք ստանում ենք երկու՝ «ֆայլն ավելացվել է սերվերի հերթում» և «ֆայլը պահվել է պահեստում»: Վերջինս նշանակում է, որ այլ սարքեր արդեն կարող են սկսել ստանալ ֆայլը (ճշգրտված այն բանի համար, որ հերթերն աշխատում են տարբեր արագությամբ):
  • Հաշվի առնելով այն հանգամանքը, որ ներկայացման տեղեկատվությունը այժմ գալիս է տարբեր ուղիներով, մենք պետք է լուծումներ գտնենք ֆայլի մշակման կարգավիճակը ստանալու համար: Սրա հետևանքով. ի տարբերություն դասական հարցում-պատասխանի, հաճախորդը կարող է վերագործարկվել ֆայլը մշակելիս, բայց ինքնին այս մշակման կարգավիճակը ճիշտ կլինի։ Ավելին, այս տարրը, ըստ էության, աշխատում է տուփից դուրս: Արդյունքում՝ մենք հիմա ավելի հանդուրժող ենք ձախողումների նկատմամբ։

Shading

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

  • Առանձնացրեք ֆայլերը ըստ տեսակի: Օրինակ՝ նկարները/տեսանյութերը կարող են վերծանվել և ավելի արդյունավետ ձևաչափ ընտրել:
  • Առանձին հաշիվներ ըստ երկրների: Շատ օրենքների պատճառով դա կարող է պահանջվել, բայց այս ճարտարապետական ​​սխեման ավտոմատ կերպով նման հնարավորություն է տալիս

Հարմարավետ ճարտարապետական ​​նախշեր

Եթե ​​ցանկանում եք տվյալներ փոխանցել մեկ պահեստից մյուսը, ապա ստանդարտ միջոցներն այլևս բավարար չեն: Ցավոք, այս դեպքում դուք պետք է դադարեցնեք հերթը, կատարեք միգրացիան, ապա սկսեք այն: Ընդհանուր դեպքում, տվյալները չեն կարող փոխանցվել «թռիչքի վրա», սակայն, եթե իրադարձությունների հերթն ամբողջությամբ պահվում է, և դուք ունեք նախկին պահեստավորման վիճակների լուսանկար, ապա մենք կարող ենք վերարտադրել իրադարձությունները հետևյալ կերպ.

  • Իրադարձությունների աղբյուրում յուրաքանչյուր իրադարձություն ունի իր նույնացուցիչը (իդեալական՝ չնվազող): Սա նշանակում է, որ մենք կարող ենք դաշտ ավելացնել պահեստում՝ վերջին մշակված տարրի id-ը:
  • Մենք կրկնօրինակում ենք հերթը, որպեսզի բոլոր իրադարձությունները կարողանան մշակվել մի քանի անկախ պահեստների համար (առաջինը այն է, որում տվյալները արդեն պահված են, իսկ երկրորդը նոր է, բայց դեռ դատարկ): Երկրորդ հերթին, իհարկե, դեռ ընթացք չի տրվում։
  • Մենք գործարկում ենք երկրորդ հերթը (այսինքն, մենք սկսում ենք վերարտադրել իրադարձությունները):
  • Երբ նոր հերթը համեմատաբար դատարկ է (այսինքն՝ տարր ավելացնելու և այն առբերելու միջև միջին ժամանակային տարբերությունն ընդունելի է), կարող եք սկսել ընթերցողներին փոխել նոր պահեստ:

Ինչպես տեսնում եք, մենք մեր համակարգում չենք ունեցել և դեռևս չունենք։ Կա միայն վերջնական հետևողականություն, այսինքն՝ երաշխիք, որ իրադարձությունները մշակվում են նույն հերթականությամբ (բայց հնարավոր է տարբեր ուշացումներով): Եվ սա օգտագործելով՝ մենք կարող ենք համեմատաբար հեշտությամբ տվյալներ փոխանցել՝ առանց համակարգը կանգնեցնելու երկրագնդի մյուս կողմ:

Այսպիսով, շարունակելով մեր օրինակը ֆայլերի առցանց պահպանման մասին, նման ճարտարապետությունը մեզ արդեն տալիս է մի շարք բոնուսներ.

  • Մենք կարող ենք օբյեկտները դինամիկ կերպով մոտեցնել օգտվողներին: Այս կերպ Դուք կարող եք բարելավել սպասարկման որակը:
  • Մենք կարող ենք որոշ տվյալներ պահել ընկերությունների ներսում: Օրինակ, Enterprise-ի օգտատերերը հաճախ պահանջում են, որ իրենց տվյալները պահվեն վերահսկվող տվյալների կենտրոններում (տվյալների արտահոսքից խուսափելու համար): Շարդինգի միջոցով մենք կարող ենք հեշտությամբ աջակցել դրան: Եվ խնդիրը նույնիսկ ավելի հեշտ է, եթե հաճախորդն ունի համատեղելի ամպ (օրինակ. Azure ինքնակառավարման հյուրընկալվել).
  • Եվ ամենակարևորն այն է, որ մենք ստիպված չենք դա անել: Ի վերջո, սկզբից մենք շատ գոհ կլինենք բոլոր հաշիվների համար մեկ պահեստով (արագ աշխատելու համար): Եվ այս համակարգի հիմնական առանձնահատկությունն այն է, որ թեև այն ընդարձակելի է, սակայն սկզբնական փուլում այն ​​բավականին պարզ է։ Պարզապես պետք չէ անմիջապես գրել կոդ, որն աշխատում է միլիոն առանձին անկախ հերթերով և այլն: Անհրաժեշտության դեպքում դա կարելի է անել ապագայում:

Ստատիկ բովանդակության հոստինգ

Այս կետը կարող է բավականին ակնհայտ թվալ, բայց այն դեռևս անհրաժեշտ է քիչ թե շատ ստանդարտ բեռնված հավելվածի համար: Դրա էությունը պարզ է. ամբողջ ստատիկ բովանդակությունը բաշխվում է ոչ թե նույն սերվերից, որտեղ գտնվում է հավելվածը, այլ հատուկներից, որոնք հատուկ են այս առաջադրանքին: Արդյունքում, այս գործողությունները կատարվում են ավելի արագ (պայմանական nginx-ը ֆայլերը սպասարկում է ավելի արագ և էժան, քան Java սերվերը): Plus CDN ճարտարապետություն (Բովանդակության մատակարարման ցանց) թույլ է տալիս մեզ ավելի մոտ տեղորոշել մեր ֆայլերը վերջնական օգտագործողներին, ինչը դրականորեն է ազդում ծառայության հետ աշխատելու հարմարության վրա:

Ստատիկ բովանդակության ամենապարզ և ստանդարտ օրինակը վեբկայքի համար նախատեսված սցենարների և պատկերների հավաքածուն է: Նրանց մոտ ամեն ինչ պարզ է՝ նախապես հայտնի են, այնուհետև արխիվը վերբեռնվում է CDN սերվերներ, որտեղից դրանք բաժանվում են վերջնական օգտագործողներին։

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

  • Սերվերը տրամադրում է ներբեռնման URL: Այն կարող է լինել file_id + բանալի ձևի, որտեղ բանալին մինի թվային ստորագրություն է, որն իրավունք է տալիս մուտք գործել ռեսուրս հաջորդ XNUMX ժամվա ընթացքում:
  • Ֆայլը տարածվում է պարզ nginx-ի միջոցով՝ հետևյալ ընտրանքներով.
    • Բովանդակության քեշավորում: Քանի որ այս ծառայությունը կարող է տեղակայվել առանձին սերվերի վրա, մենք մեզ պահուստ ենք թողել ապագայի համար՝ բոլոր վերջին ներբեռնված ֆայլերը սկավառակի վրա պահելու ունակությամբ:
    • Բանալին ստուգում կապի ստեղծման պահին
  • Լրացուցիչ՝ հոսքային բովանդակության մշակում: Օրինակ, եթե մենք սեղմում ենք ծառայության բոլոր ֆայլերը, ապա մենք կարող ենք ուղղակիորեն այս մոդուլում unzipping անել: Արդյունքում. IO գործողությունները կատարվում են այնտեղ, որտեղ նրանք պատկանում են: Java-ում արխիվատորը հեշտությամբ կհատկացնի շատ լրացուցիչ հիշողություն, բայց բիզնես տրամաբանությամբ ծառայությունը Rust/C++ պայմանականների մեջ վերագրանցելը նույնպես կարող է անարդյունավետ լինել: Մեր դեպքում օգտագործվում են տարբեր գործընթացներ (կամ նույնիսկ ծառայություններ), և, հետևաբար, մենք կարող ենք բավականին արդյունավետ կերպով առանձնացնել բիզնես տրամաբանությունը և IO գործողությունները:

Հարմարավետ ճարտարապետական ​​նախշեր

Այս սխեման այնքան էլ նման չէ ստատիկ բովանդակության բաշխմանը (քանի որ մենք ինչ-որ տեղ չենք վերբեռնում ամբողջ ստատիկ փաթեթը), բայց իրականում այս մոտեցումը վերաբերում է անփոփոխ տվյալների բաշխմանը: Ավելին, այս սխեման կարող է ընդհանրացվել այլ դեպքերի վրա, երբ բովանդակությունը պարզապես ստատիկ չէ, այլ կարող է ներկայացվել որպես անփոփոխ և չջնջվող բլոկների մի շարք (չնայած դրանք կարող են ավելացվել):

Որպես մեկ այլ օրինակ (ուժեղացման համար). եթե դուք աշխատել եք Jenkins/TeamCity-ի հետ, ապա գիտեք, որ երկու լուծումներն էլ գրված են Java-ով: Նրանք երկուսն էլ Java գործընթաց են, որը կարգավորում է ինչպես կառուցապատման նվագախումբը, այնպես էլ բովանդակության կառավարումը: Մասնավորապես, նրանք երկուսն էլ ունեն առաջադրանքներ, ինչպիսիք են «ֆայլը/թղթապանակը սերվերից փոխանցել»: Որպես օրինակ՝ արտեֆակտների թողարկում, սկզբնական կոդի փոխանցում (երբ գործակալը չի ​​ներբեռնում կոդը անմիջապես պահոցից, բայց սերվերը դա անում է նրա փոխարեն), մուտք դեպի տեղեկամատյաններ։ Այս բոլոր առաջադրանքները տարբերվում են իրենց IO բեռից: Այսինքն՝ պարզվում է, որ բարդ բիզնես տրամաբանության համար պատասխանատու սերվերը պետք է միաժամանակ կարողանա արդյունավետորեն իր միջոցով մղել տվյալների մեծ հոսքեր։ Եվ ամենահետաքրքիրն այն է, որ նման գործողությունը կարող է պատվիրակվել նույն nginx-ին՝ ճիշտ նույն սխեմայի համաձայն (բացառությամբ, որ տվյալների բանալին պետք է ավելացվի հարցումին):

Այնուամենայնիվ, եթե վերադառնանք մեր համակարգին, մենք կստանանք նմանատիպ դիագրամ.

Հարմարավետ ճարտարապետական ​​նախշեր

Ինչպես տեսնում եք, համակարգը արմատապես բարդացել է։ Այժմ դա պարզապես մինի-գործընթաց չէ, որը պահում է ֆայլերը տեղում: Այժմ պահանջվողը ամենապարզ աջակցությունը չէ, API-ի տարբերակի վերահսկումը և այլն: Հետևաբար, բոլոր գծապատկերները գծելուց հետո ավելի լավ է մանրամասնորեն գնահատել, թե արդյոք ընդարձակելիությունը արժե ծախսել: Այնուամենայնիվ, եթե ցանկանում եք ընդլայնել համակարգը (ներառյալ ավելի մեծ թվով օգտվողների հետ աշխատելը), ապա ստիպված կլինեք գնալ նմանատիպ լուծումների: Բայց արդյունքում համակարգը ճարտարապետական ​​առումով պատրաստ է ավելացած բեռի համար (գրեթե յուրաքանչյուր բաղադրիչ կարող է կլոնավորվել հորիզոնական մասշտաբի համար): Համակարգը կարող է թարմացվել առանց այն դադարեցնելու (ուղղակի որոշ գործողություններ մի փոքր կդանդաղեցվեն):

Ինչպես հենց սկզբում ասացի, այժմ մի շարք ինտերնետային ծառայություններ սկսել են ավելացված բեռ ստանալ։ Եվ նրանցից ոմանք պարզապես սկսեցին դադարել ճիշտ աշխատել։ Փաստորեն, համակարգերը խափանվեցին հենց այն պահին, երբ բիզնեսը պետք է փող աշխատեր։ Այսինքն՝ հետաձգված առաքման փոխարեն, փոխանակ առաջարկելու հաճախորդներին «պլանավորել ձեր առաքումը առաջիկա ամիսների համար», համակարգը պարզապես ասել է «գնացեք ձեր մրցակիցներին»: Իրականում սա ցածր արտադրողականության գինն է. կորուստները տեղի կունենան հենց այն ժամանակ, երբ շահույթը կլինի ամենաբարձրը:

Ամփոփում

Այս բոլոր մոտեցումները հայտնի էին նախկինում։ Նույն VK-ն վաղուց օգտագործում է Static Content Hosting-ի գաղափարը՝ պատկերներ ցուցադրելու համար: Շատ առցանց խաղեր օգտագործում են Sharding սխեման՝ խաղացողներին բաժանելու տարածաշրջանների կամ առանձնացնելու խաղերի վայրերը (եթե աշխարհն ինքնին այդպիսին է): Իրադարձությունների աղբյուրների մոտեցումը ակտիվորեն օգտագործվում է էլ. Առևտրային հավելվածների մեծ մասը, որտեղ տվյալները մշտապես ստացվում են, իրականում կառուցված են CQRS մոտեցման վրա, որպեսզի կարողանան զտել ստացված տվյալները: Դե, հորիզոնական մասշտաբը բավականին երկար ժամանակ օգտագործվում է բազմաթիվ ծառայություններում:

Այնուամենայնիվ, ամենակարևորը, այս բոլոր օրինաչափությունները դարձել են շատ հեշտ կիրառելի ժամանակակից կիրառություններում (եթե դրանք, իհարկե, տեղին են): Ամպերն առաջարկում են Sharding և հորիզոնական մասշտաբավորում անմիջապես, ինչը շատ ավելի հեշտ է, քան ինքներդ պատվիրել տարբեր հատուկ սերվերներ տարբեր տվյալների կենտրոններում: CQRS-ը դարձել է շատ ավելի հեշտ, եթե միայն RX-ի նման գրադարանների զարգացման շնորհիվ: Մոտ 10 տարի առաջ հազվագյուտ կայք կարող էր աջակցել դրան: Event Sourcing-ը նույնպես աներևակայելի հեշտ է կարգավորվում՝ շնորհիվ Apache Kafka-ի հետ պատրաստի տարաների: 10 տարի առաջ սա նորամուծություն կլիներ, հիմա սովորական բան է։ Դա նույնն է Static Content Hosting-ի դեպքում. ավելի հարմար տեխնոլոգիաների շնորհիվ (ներառյալ այն փաստը, որ կա մանրամասն փաստաթղթեր և պատասխանների մեծ բազա), այս մոտեցումն էլ ավելի պարզ է դարձել:

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

Եվ ամենակարևորը. խնդրում ենք մի օգտագործեք այս մոտեցումները, եթե ունեք պարզ հավելված: Այո, դրանք գեղեցիկ են և հետաքրքիր, բայց 100 հոգանոց գագաթնակետ ունեցող կայքի համար հաճախ կարելի է դասական մոնոլիտով յոլա գնալ (գոնե արտաքինից, ներսում ամեն ինչ կարելի է բաժանել մոդուլների և այլն):

Source: www.habr.com

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