Цулаас микро үйлчилгээ рүү шилжих шилжилт: түүх ба практик

Энэ нийтлэлд миний ажиллаж байгаа төсөл хэрхэн том цул байснаас микро үйлчилгээний багц болон хувирсан тухай ярих болно.

Төсөл түүхээ нэлээд эрт буюу 2000 оны эхээр эхлүүлсэн. Эхний хувилбарууд нь Visual Basic 6 дээр бичигдсэн. Цаг хугацаа өнгөрөхөд IDE-ээс хойш энэ хэлийг хөгжүүлэх нь ирээдүйд дэмжлэг үзүүлэхэд хэцүү байх нь тодорхой болсон. мөн хэл нь өөрөө муу хөгжсөн. 2000-аад оны сүүлээр илүү ирээдүйтэй C# руу шилжихээр шийдсэн. Шинэ хувилбар нь хуучин хувилбарын засвартай зэрэгцэн бичигдсэн бөгөөд аажмаар илүү олон кодыг .NET дээр бичсэн. C# хэл дээрх backend нь анх үйлчилгээний архитектурт төвлөрч байсан боловч хөгжүүлэлтийн явцад логик бүхий нийтлэг номын сангуудыг ашиглаж, үйлчилгээг нэг процессоор эхлүүлсэн. Үүний үр дүнд бидний "үйлчилгээний цул" гэж нэрлэдэг програм гарч ирэв.

Энэхүү хослолын цөөн хэдэн давуу талуудын нэг нь гадаад API-ээр дамжуулан үйлчилгээнүүд бие биенээ дуудах чадвар байв. Илүү зөв үйлчилгээ, ирээдүйд микро үйлчилгээний архитектурт шилжих тодорхой урьдчилсан нөхцөлүүд байсан.

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

Цулаас микро үйлчилгээ рүү шилжих шилжилт: түүх ба практик

Агуулга

Архитектур ба одоо байгаа шийдлийн асуудлууд


Эхэндээ архитектур нь иймэрхүү харагдаж байсан: UI нь тусдаа програм, цул хэсэг нь Visual Basic 6 дээр бичигдсэн, .NET програм нь нэлээд том мэдээллийн сантай ажилладаг холбогдох үйлчилгээний багц юм.

Өмнөх шийдлийн сул талууд

Нэг бүтэлгүйтлийн цэг
Бидэнд нэг л бүтэлгүйтэл байсан: .NET програм нь нэг процессоор ажилладаг. Хэрэв аль нэг модуль бүтэлгүйтсэн бол бүх програм амжилтгүй болсон тул дахин эхлүүлэх шаардлагатай болно. Бид янз бүрийн хэрэглэгчдэд зориулсан олон тооны процессуудыг автоматжуулдаг тул тэдгээрийн аль нэг нь бүтэлгүйтсэний улмаас хүн бүр хэсэг хугацаанд ажиллах боломжгүй болсон. Програм хангамжийн алдаа гарсан тохиолдолд нөөцлөлт хүртэл тусалсангүй.

Сайжруулалтын дараалал
Энэ сул тал нь зохион байгуулалттай холбоотой юм. Манай аппликейшн олон хэрэглэгчтэй бөгөөд тэд бүгд үүнийг аль болох хурдан сайжруулахыг хүсдэг. Өмнө нь үүнийг зэрэгцээ хийх боломжгүй байсан тул бүх үйлчлүүлэгчид дараалалд зогсдог байв. Энэ үйл явц нь бизнес эрхлэгчдэд сөрөг үр дагавартай байсан, учир нь тэд ажил нь үнэ цэнэтэй гэдгийг батлах ёстой байв. Мөн хөгжүүлэлтийн баг энэ дарааллыг зохион байгуулахад цаг хугацаа зарцуулсан. Энэ нь маш их цаг хугацаа, хүчин чармайлт шаардсан бөгөөд эцсийн эцэст бүтээгдэхүүн нь тэдний хүссэнээр хурдан өөрчлөгдөж чадахгүй байв.

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

Орчин үеийн технологийг нэвтрүүлэхэд хэцүү
Бүх хөгжүүлэгчдэд танил болсон асуудал: орчин үеийн технологиудыг төсөлд нэвтрүүлэх хүсэл байгаа ч боломж байхгүй. Том хэмжээний цул шийдлийн тусламжтайгаар одоогийн номын сангийн аливаа шинэчлэлт, тэр дундаа шинэ номын сан руу шилжих нь тийм ч чухал биш ажил болж хувирдаг. Энэ нь дэмий үрсэн мэдрэлээс илүү урамшуулал авчирна гэдгийг багийн ахлагчдаа нотлоход их хугацаа шаардагдана.

Өөрчлөлтийг гаргахад бэрхшээлтэй
Энэ бол хамгийн ноцтой асуудал байсан - бид хоёр сар тутамд хувилбаруудыг гаргадаг байсан.
Хөгжүүлэгчдийн туршилт, хүчин чармайлтыг үл харгалзан хувилбар бүр нь банкны хувьд жинхэнэ сүйрэл болж хувирав. Долоо хоногийн эхээр түүний зарим функц ажиллахгүй гэдгийг бизнес ойлгосон. Хөгжүүлэгчид тэднийг долоо хоног ноцтой хэрэг явдал хүлээж байгааг ойлгосон.
Хүн бүр нөхцөл байдлыг өөрчлөх хүсэл эрмэлзэлтэй байсан.

Микро үйлчилгээний хүлээлт


Бэлэн болсон үед бүрэлдэхүүн хэсгүүдийн асуудал. Уусмалыг задлах, өөр өөр процессуудыг салгах замаар бэлэн болсон бүрэлдэхүүн хэсгүүдийг хүргэх.

Жижиг бүтээгдэхүүний баг. Хуучин цул дээр ажиллаж байсан том багийг удирдахад хэцүү байсан тул энэ нь чухал юм. Ийм баг хатуу журмын дагуу ажиллахаас өөр аргагүй байсан ч тэд илүү бүтээлч байдал, бие даасан байдлыг хүсч байв. Зөвхөн жижиг багууд үүнийг төлж чадна.

Тусдаа үйл явц дахь үйлчилгээг тусгаарлах. Хамгийн тохиромжтой нь би үүнийг контейнерт тусгаарлахыг хүссэн боловч .NET Framework дээр бичигдсэн олон тооны үйлчилгээ зөвхөн Windows дээр ажилладаг. .NET Core дээр суурилсан үйлчилгээнүүд одоо гарч байгаа боловч цөөхөн нь байна.

Байршуулах уян хатан байдал. Бид үйлчилгээнүүдийг кодоор албадсан байдлаар биш харин өөрт хэрэгтэй байдлаар нь хослуулахыг хүсч байна.

Шинэ технологи ашиглах. Энэ нь ямар ч програмистад сонирхолтой байдаг.

Шилжилтийн асуудлууд


Мэдээжийн хэрэг, монолитийг бичил үйлчилгээ болгон задлахад хялбар байсан бол энэ талаар бага хурал дээр ярих, нийтлэл бичих шаардлагагүй болно. Энэ үйл явцад олон бэрхшээл тулгардаг бөгөөд би бидэнд саад болсон гол зүйлсийг тайлбарлах болно.

Эхний асуудал Ихэнх цулуудын хувьд ердийн зүйл: бизнесийн логикийн уялдаа холбоо. Бид монолит бичихдээ шаардлагагүй код бичихгүйн тулд ангиудаа дахин ашиглахыг хүсдэг. Микро үйлчилгээ рүү шилжих үед энэ нь асуудал болж хувирдаг: бүх код нь хоорондоо нягт уялдаатай байдаг тул үйлчилгээг салгахад хэцүү байдаг.

Ажил эхлэх үед тус сан нь 500 гаруй төсөл, 700 гаруй мянган мөр кодтой байжээ. Энэ бол нэлээд том шийдвэр бөгөөд хоёр дахь асуудал. Үүнийг зүгээр л аваад микро үйлчилгээнд хуваах боломжгүй байсан.

Гурав дахь асуудал - шаардлагатай дэд бүтэц дутмаг. Үнэндээ бид эх кодыг серверүүд рүү гараар хуулж байсан.

Цулаас микро үйлчилгээ рүү хэрхэн шилжих вэ


Бичил үйлчилгээ үзүүлэх

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

Микро үйлчилгээг тусгаарлахын тулд бид ямар аргыг ашигладаг вэ?

Эхний арга - одоо байгаа модулиудыг үйлчилгээ болгон шилжүүлэх. Үүнтэй холбогдуулан бид азтай байсан: WCF протоколыг ашиглан ажиллаж байсан бүртгэлтэй үйлчилгээнүүд аль хэдийн байсан. Тэд тусдаа чуулганд хуваагдсан. Бид тэдгээрийг тусад нь зөөвөрлөж, угсралт бүрт жижиг эхлүүлэгч нэмсэн. Энэ нь гайхалтай Topshelf номын санг ашиглан бичигдсэн бөгөөд энэ нь програмыг үйлчилгээ болон консол болгон ажиллуулах боломжийг олгодог. Шийдвэрт нэмэлт төсөл шаардлагагүй тул энэ нь дибаг хийхэд тохиромжтой.

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

Хосттой угсрах нь Програмын ангид зөвхөн нэг мөр код юм. Бид туслах ангид Topshelf-тэй хийсэн ажлаа нуусан.

namespace RBA.Services.Accounts.Host
{
   internal class Program
   {
      private static void Main(string[] args)
      {
        HostRunner<Accounts>.Run("RBA.Services.Accounts.Host");

       }
    }
}

Микро үйлчилгээг хуваарилах хоёр дахь арга нь: шинэ асуудлуудыг шийдвэрлэхийн тулд тэдгээрийг бий болгох. Хэрэв нэгэн зэрэг цул ургахгүй бол энэ нь аль хэдийн маш сайн бөгөөд энэ нь бид зөв чиглэлд явж байна гэсэн үг юм. Шинэ асуудлуудыг шийдвэрлэхийн тулд бид тусдаа үйлчилгээ бий болгохыг оролдсон. Хэрэв ийм боломж байсан бол бид өөрсдийн мэдээллийн загвар, тусдаа мэдээллийн санг бүрэн удирддаг илүү "каноник" үйлчилгээг бий болгосон.

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

Микро үйлчилгээг хуваарилах гурав дахь аргаБидний хэрэглэдэг зүйл бол бидний хувьд бага зэрэг онцлог юм. Энэ нь UI давхаргаас бизнесийн логикийг устгах явдал юм. Манай үндсэн UI програм нь ширээний компьютер бөгөөд энэ нь backend шиг C# хэл дээр бичигдсэн байдаг. Хөгжүүлэгчид үе үе алдаа гаргаж, арын хэсэгт байх ёстой логик хэсгүүдийг UI руу шилжүүлж, дахин ашиглах ёстой байв.

Хэрэв та UI хэсгийн кодоос бодит жишээг харвал энэ шийдлийн ихэнх хэсэг нь зөвхөн UI маягтыг бүтээхэд бус бусад процессуудад хэрэг болох бодит бизнесийн логикийг агуулж байгааг харж болно.

Цулаас микро үйлчилгээ рүү шилжих шилжилт: түүх ба практик

Жинхэнэ UI логик нь зөвхөн сүүлийн хоёр мөрөнд л байдаг. Бид үүнийг сервер рүү шилжүүлж, дахин ашиглах боломжтой болж, UI-г багасгаж, зөв ​​архитектурыг бий болгосон.

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

Үйлчилгээг боловсруулалтаас салгах нь хязгаарлагдмал контекст гэсэн ойлголттой салшгүй холбоотой. Энэ бол Domain Driven Design-ийн үзэл баримтлал юм. Энэ нь нэг хэлний бүх нэр томъёог өвөрмөц байдлаар тодорхойлсон домэйн загварын хэсэг гэсэн үг. Даатгал, үнэт цаасны нөхцөлийг жишээ болгон авч үзье. Бидэнд цул програм байгаа бөгөөд бид даатгалын данстай ажиллах шаардлагатай байна. Бид хөгжүүлэгчээс одоо байгаа Account классыг өөр угсралтаас олж, Даатгалын ангиас лавлана гэж хүлээж байгаа бөгөөд бидэнд ажлын код бий болно. DRY зарчмыг дагаж мөрдөж, одоо байгаа кодыг ашиглан ажлыг хурдан гүйцэтгэх болно.

Үүний үр дүнд данс, даатгалын контекст хоорондоо холбоотой болох нь харагдаж байна. Шинэ шаардлага гарч ирэхийн хэрээр энэхүү холболт нь хөгжилд саад болж, бизнесийн аль хэдийн ээдрээтэй логикийн нарийн төвөгтэй байдлыг нэмэгдүүлнэ. Энэ асуудлыг шийдэхийн тулд та кодын контекст хоорондын хил хязгаарыг олж, тэдгээрийн зөрчлийг арилгах хэрэгтэй. Тухайлбал, даатгалын нөхцөлд Төв банкны 20 оронтой дансны дугаар, данс нээлгэсэн огноо хангалттай байх бүрэн боломжтой.

Эдгээр хязгаарлагдмал контекстүүдийг бие биенээсээ салгаж, микро үйлчилгээг цул шийдлээс салгах үйл явцыг эхлүүлэхийн тулд бид програм дотор гадаад API үүсгэх гэх мэт аргыг ашигласан. Хэрэв бид ямар нэгэн модуль нь процессын хүрээнд ямар нэгэн байдлаар өөрчлөгдсөн микро үйлчилгээ болох ёстой гэдгийг мэдэж байсан бол бид гадны дуудлагаар дамжуулан өөр хязгаарлагдмал контекст хамаарах логик руу шууд дуудлага хийсэн. Жишээлбэл, REST эсвэл WCF-ээр дамжуулан.

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

Тодорхой жишээг авч үзье. Бидэнд оркестр гэдэг ойлголт байдаг - "хэрэглээний" аж ахуйн нэгжийг боловсруулдаг дамжуулах хоолой. Тэрээр үйлчлүүлэгч, данс, банкны картыг ээлжлэн бий болгодог. Үйлчлүүлэгч болон дансыг амжилттай үүсгэсэн боловч карт үүсгэх ажиллагаа амжилтгүй болсон тохиолдолд програм "амжилттай" төлөвт шилжихгүй бөгөөд "карт үүсгээгүй" төлөвт үлдэнэ. Цаашид далд үйл ажиллагаа нь үүнийг аваад дуусгах болно. Систем нь тодорхой хугацааны турш тогтворгүй байдалд байсан ч бид үүнд ерөнхийдөө сэтгэл хангалуун байна.

Хэрэв өгөгдлийн зарим хэсгийг тогтмол хадгалах шаардлагатай нөхцөл байдал үүсвэл бид үүнийг нэг процесст боловсруулахын тулд үйлчилгээг нэгтгэх болно.

Микро үйлчилгээг хуваарилах жишээг авч үзье. Үүнийг хэрхэн харьцангуй аюулгүйгээр үйлдвэрлэлд оруулах вэ? Энэ жишээнд бид системийн тусдаа хэсэгтэй - цалин хөлсний үйлчилгээний модуль бөгөөд үүний кодын хэсгүүдийн нэг нь микро үйлчилгээ хийхийг хүсч байна.

Цулаас микро үйлчилгээ рүү шилжих шилжилт: түүх ба практик

Юуны өмнө бид кодыг дахин бичих замаар бичил үйлчилгээ үүсгэдэг. Бид сэтгэл хангалуун бус байсан зарим зүйлийг сайжруулж байна. Бид үйлчлүүлэгчээс бизнесийн шинэ шаардлагыг хэрэгжүүлдэг. Бид UI болон backend хоорондын холболтод API гарцыг нэмсэн бөгөөд энэ нь дуудлага дамжуулах боломжийг олгоно.

Цулаас микро үйлчилгээ рүү шилжих шилжилт: түүх ба практик

Дараа нь бид энэ тохиргоог ашиглалтад оруулав, гэхдээ туршилтын төлөвт байна. Манай ихэнх хэрэглэгчид хуучин бизнесийн үйл явцтай ажилладаг хэвээр байна. Шинэ хэрэглэгчдэд зориулж бид энэ процессыг агуулаагүй цул програмын шинэ хувилбарыг боловсруулж байна. Үндсэндээ бид нэг цул болон микросервисийг хослуулан туршилтын журмаар ажиллаж байна.

Цулаас микро үйлчилгээ рүү шилжих шилжилт: түүх ба практик

Амжилттай туршилт хийснээр шинэ тохиргоо үнэхээр хэрэгжих боломжтой гэдгийг бид ойлгож байна, бид тэгшитгэлээс хуучин цул хэсгийг устгаж, хуучин шийдлийн оронд шинэ тохиргоог үлдээж чадна.

Цулаас микро үйлчилгээ рүү шилжих шилжилт: түүх ба практик

Нийтдээ бид цул эх кодыг хуваах бараг бүх аргыг ашигладаг. Эдгээр нь бүгд програмын хэсгүүдийн хэмжээг багасгаж, шинэ номын сан руу хөрвүүлэх, эх кодыг илүү сайн болгох боломжийг олгодог.

Мэдээллийн сантай ажиллах


Өгөгдлийн сан нь зөвхөн одоогийн схем төдийгүй хуримтлагдсан түүхэн өгөгдлийг агуулдаг тул эх кодоос илүү муу хуваагдаж болно.

Манай мэдээллийн сан нь бусад хүмүүсийн нэгэн адил бас нэг чухал сул талтай байсан - асар том хэмжээтэй. Энэхүү мэдээллийн сан нь янз бүрийн хязгаарлагдмал контекстийн хүснэгтүүдийн хооронд хуримтлагдсан монолитийн бизнесийн нарийн төвөгтэй логикийн дагуу бүтээгдсэн.

Манай тохиолдолд бүх бэрхшээлийг даван туулахын тулд (том мэдээллийн сан, олон холболт, заримдаа хүснэгтийн хоорондох тодорхойгүй хил хязгаар) олон томоохон төслүүдэд тохиолддог асуудал гарч ирэв: хуваалцсан мэдээллийн сангийн загварыг ашиглах. Хүснэгтээс өгөгдлийг харах, хуулбарлах замаар авч, хуулбарлах шаардлагатай бусад систем рүү илгээсэн. Үүний үр дүнд бид хүснэгтүүдийг идэвхтэй ашиглаж байсан тул тэдгээрийг тусдаа схемд шилжүүлж чадсангүй.

Код дахь хязгаарлагдмал контекст болгон хуваах нь биднийг салгахад тусалдаг. Энэ нь ихэвчлэн өгөгдлийн сангийн түвшинд өгөгдлийг хэрхэн задлах талаар маш сайн санаа өгдөг. Аль хүснэгт нь нэг хязгаарлагдмал контекст, аль нь нөгөөд хамаарах болохыг бид ойлгодог.

Бид мэдээллийн санг хуваах дэлхийн хоёр аргыг ашигласан: одоо байгаа хүснэгтүүдийг хуваах, боловсруулалт хийх замаар хуваах.

Өгөгдлийн бүтэц сайн, бизнесийн шаардлагад нийцсэн, хүн бүр үүнд сэтгэл хангалуун байвал одоо байгаа хүснэгтүүдийг хуваах нь сайн арга юм. Энэ тохиолдолд бид одоо байгаа хүснэгтүүдийг тусдаа схем болгон салгаж болно.

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

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

Хоёр цул модуль нь нэг мэдээллийн сантай харьцдаг шийдэлтэй гэж төсөөлөөд үз дээ. Зөвхөн нэг модуль нь тусгаарлагдсан хүснэгтүүдийн хэсэгтэй харьцаж, нөгөө нь API-ээр дамжуулан түүнтэй харилцаж эхэлдэг эсэхийг шалгах хэрэгтэй. Эхлэхийн тулд зөвхөн API-ээр дамжуулан бичлэг хийхэд хангалттай. Энэ бол бичил үйлчилгээний бие даасан байдлын талаар ярихад зайлшгүй шаардлагатай нөхцөл юм. Томоохон асуудал байхгүй л бол унших холболтууд хэвээр үлдэж болно.

Цулаас микро үйлчилгээ рүү шилжих шилжилт: түүх ба практик

Дараагийн алхам бол бид боловсруулалттай эсвэл боловсруулалтгүйгээр тусгаарлагдсан хүснэгтүүдтэй ажилладаг кодын хэсгийг тусдаа бичил үйлчилгээ болгон салгаж, тусдаа процесс буюу контейнерт ажиллуулж болно. Энэ нь цул мэдээллийн сан болон түүнтэй шууд хамааралгүй хүснэгтүүдтэй холбогдсон тусдаа үйлчилгээ байх болно. Цул нь салдаг хэсэгтэй уншихад харилцан үйлчилсээр байна.

Цулаас микро үйлчилгээ рүү шилжих шилжилт: түүх ба практик

Дараа нь бид энэ холболтыг устгах болно, өөрөөр хэлбэл тусдаа хүснэгтүүдээс цул програмаас унших өгөгдлийг API руу шилжүүлэх болно.

Цулаас микро үйлчилгээ рүү шилжих шилжилт: түүх ба практик

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

Цулаас микро үйлчилгээ рүү шилжих шилжилт: түүх ба практик

Сүүлийн алхам бол бүх холболтыг бүрэн арилгах явдал юм. Энэ тохиолдолд бид үндсэн мэдээллийн сангаас өгөгдлийг шилжүүлэх шаардлагатай болж магадгүй юм. Заримдаа бид гадны системээс хуулбарласан зарим өгөгдөл эсвэл сангуудыг хэд хэдэн мэдээллийн санд дахин ашиглахыг хүсдэг. Энэ нь бидэнд үе үе тохиолддог.

Цулаас микро үйлчилгээ рүү шилжих шилжилт: түүх ба практик

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

Цулаас микро үйлчилгээ рүү шилжих шилжилт: түүх ба практик

Энэ схем ажиллахын тулд бидэнд шилжилтийн үе хэрэгтэй болно.

Дараа нь хоёр боломжит арга бий.

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

Хоёр дахь нь: бид өгөгдлийг бизнесийн зарим шалгуурын дагуу хуваадаг. Жишээлбэл, манайд хуучин мэдээллийн санд хадгалагдсан 5 бүтээгдэхүүн системд байсан. Бид шинэ бизнесийн ажлын хүрээнд зургаа дахь нь шинэ мэдээллийн санд байрлуулна. Гэхдээ бидэнд энэ өгөгдлийг синхрончилж, хаанаас, юу авахыг үйлчлүүлэгчид харуулах API гарц хэрэгтэй болно.

Хоёр арга хоёулаа ажилладаг, нөхцөл байдлаас шалтгаалан сонгоно.

Бүх зүйл ажиллаж байгаа гэдэгт итгэлтэй болсны дараа хуучин мэдээллийн сангийн бүтэцтэй ажилладаг цул хэсгийг идэвхгүй болгож болно.

Цулаас микро үйлчилгээ рүү шилжих шилжилт: түүх ба практик

Сүүлийн алхам бол хуучин өгөгдлийн бүтцийг устгах явдал юм.

Цулаас микро үйлчилгээ рүү шилжих шилжилт: түүх ба практик

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

Эх кодтой ажиллах


Бид цул төсөлд дүн шинжилгээ хийж эхлэхэд эх кодын диаграм ийм харагдаж байсан.

Цулаас микро үйлчилгээ рүү шилжих шилжилт: түүх ба практик

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

Тус тусад нь ашиглах боломжтой дэд бүтцийн номын сантай болсон нь бидэнд аз таарсан.

Заримдаа зарим нийтлэг объектууд нь энэ давхаргад хамааралгүй, дэд бүтцийн номын сан байсан тохиолдол гардаг. Энэ нь нэрийг өөрчлөх замаар шийдэгдсэн.

Хамгийн их санаа зовоосон зүйл бол хязгаарлагдмал нөхцөл байдал байв. Нэг Нийтлэг чуулганд 3-4 контекст холилдож, нэг бизнесийн чиг үүргийн хүрээнд бие биенээ ашигласан тохиолдол гарсан. Үүнийг хаана, ямар хилийн дагуу хувааж болох, мөн энэ хуваалтыг эх кодын угсралтад буулгаснаар цаашид юу хийхээ ойлгох шаардлагатай байв.

Бид код хуваах үйл явцын хэд хэдэн дүрмийг боловсруулсан.

Эхнийх нь: Бид үйлчилгээ, үйл ажиллагаа болон залгаасуудын хооронд бизнесийн логикийг хуваалцахыг хүссэнгүй. Бид микро үйлчилгээний хүрээнд бизнесийн логикийг бие даасан болгохыг хүссэн. Нөгөө талаас микросервисийг бүрэн бие даасан үйлчилгээ гэж үздэг. Энэ арга нь зарим талаараа үрэлгэн бөгөөд үүнд хүрэхэд хэцүү гэж би үзэж байна, учир нь жишээлбэл, C# хэл дээрх үйлчилгээнүүд ямар ч тохиолдолд стандарт номын сангаар холбогддог. Манай систем C# хэл дээр бичигдсэн, бид өөр технологио хараахан ашиглаагүй байна. Тиймээс бид нийтлэг техникийн угсралтыг ашиглах боломжтой гэж шийдсэн. Хамгийн гол нь тэд бизнесийн логикийн ямар ч хэлтэрхий агуулаагүй явдал юм. Хэрэв та ашиглаж буй ORM дээр тав тухтай боодолтой бол үүнийг үйлчилгээнээс үйлчилгээ рүү хуулах нь маш үнэтэй болно.

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

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

Дараа нь бид тусдаа агуулахтай загвар руу шилжиж эхлэв. Бизнесийн логик нь үйлчилгээнээс үйлчилгээ рүү урсахаа больж, домэйнууд үнэхээр бие даасан болсон. Хязгаарлагдмал контекстийг илүү тодорхой дэмждэг. Бид дэд бүтцийн номын сангуудыг хэрхэн дахин ашиглах вэ? Бид тэдгээрийг тусдаа репозитор болгон хувааж, дараа нь Nuget багцад оруулаад Artifactory-д оруулсан. Аливаа өөрчлөлт, угсралт, хэвлэлт автоматаар явагдана.

Цулаас микро үйлчилгээ рүү шилжих шилжилт: түүх ба практик

Манай үйлчилгээнүүд дотоод дэд бүтцийн багцуудыг гадаадтай ижил аргаар ашиглаж эхэлсэн. Бид Nuget-аас гадаад номын сангуудыг татаж авдаг. Эдгээр багцуудыг байрлуулсан Artifactory-тай ажиллахын тулд бид хоёр багц менежер ашигласан. Жижиг хадгалах газруудад бид Nuget-ийг бас ашигладаг байсан. Олон үйлчилгээ бүхий репозиторуудад бид модулиудын хооронд илүү их хувилбарын нийцтэй байдлыг хангадаг Paket ашигласан.

Цулаас микро үйлчилгээ рүү шилжих шилжилт: түүх ба практик

Тиймээс эх код дээр ажиллаж, архитектурыг бага зэрэг өөрчилж, хадгалах сангуудыг тусгаарласнаар бид үйлчилгээгээ илүү бие даасан болгодог.

Дэд бүтцийн асуудал


Микро үйлчилгээ рүү шилжихийн ихэнх сул тал нь дэд бүтэцтэй холбоотой байдаг. Танд автоматжуулсан байршуулалт хэрэгтэй болно, дэд бүтцийг ажиллуулахын тулд танд шинэ номын сангууд хэрэгтэй болно.

Хүрээлэн буй орчинд гараар суурилуулах

Эхэндээ бид орчны шийдлийг гараар суулгасан. Энэ үйл явцыг автоматжуулахын тулд бид CI/CD дамжуулах хоолойг үүсгэсэн. Бизнесийн үйл явцын үүднээс тасралтгүй байршуулах нь бидний хувьд хүлээн зөвшөөрөгдөхгүй байгаа тул бид тасралтгүй хүргэх үйл явцыг сонгосон. Тиймээс үйл ажиллагаанд илгээх нь товчлуурыг ашиглан, туршилтын хувьд автоматаар хийгддэг.

Цулаас микро үйлчилгээ рүү шилжих шилжилт: түүх ба практик

Бид Atlassian, Bitbucket программыг эх код хадгалахад, хулсыг барилгад ашигладаг. Бид C#-тэй адилхан учраас Cake дээр бүтээх скрипт бичих дуртай. Бэлэн багцууд Artifactory-д ирдэг бөгөөд Ansible нь туршилтын серверүүд рүү автоматаар ордог бөгөөд үүний дараа тэдгээрийг шууд туршиж үзэх боломжтой.

Цулаас микро үйлчилгээ рүү шилжих шилжилт: түүх ба практик

Тусдаа мод бэлтгэх


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

Цулаас микро үйлчилгээ рүү шилжих шилжилт: түүх ба практик

Filebeat-ийг ашигласнаар бид серверүүдээс бүртгэлээ цуглуулж, дараа нь хувиргаж, Кибана-г ашиглан UI-д асуулга үүсгэж, үйлчилгээнүүдийн хооронд дуудлага хэрхэн явагдсаныг харах боломжтой болно. Trace ID нь үүнд их тусалдаг.

Холбогдох үйлчилгээг турших, дибаг хийх


Эхэндээ бид хөгжүүлж буй үйлчилгээг хэрхэн дибаг хийх талаар бүрэн ойлгоогүй байсан. Монолитын хувьд бүх зүйл энгийн байсан, бид үүнийг орон нутгийн машин дээр ажиллуулсан. Эхлээд тэд микро үйлчилгээтэй ижил зүйлийг хийхийг оролдсон боловч заримдаа нэг микро үйлчилгээг бүрэн эхлүүлэхийн тулд өөр хэд хэдэн үйлчилгээг эхлүүлэх шаардлагатай байдаг бөгөөд энэ нь тохиромжгүй байдаг. Бид зөвхөн дибаг хийхийг хүссэн үйлчилгээ эсвэл үйлчилгээгээ орон нутгийн машин дээр үлдээдэг загвар руу шилжих хэрэгтэй гэдгийг ойлгосон. Үлдсэн үйлчилгээг prod-ийн тохиргоонд тохирох серверүүдээс ашигладаг. Дибаг хийсний дараа туршилтын явцад даалгавар бүрт зөвхөн өөрчлөгдсөн үйлчилгээг туршилтын серверт өгдөг. Тиймээс уусмалыг ирээдүйд үйлдвэрлэлд гарах хэлбэрээр туршиж үздэг.

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

Бид алдартай Specflow номын санг ашиглан автоматжуулсан туршилтын процессыг нэмсэн. Туршилтууд нь Ansible-ээс суулгасны дараа шууд NUnit-ийг ашиглан автоматаар ажилладаг. Хэрэв даалгаврын хамрах хүрээ нь бүрэн автомат бол гараар тест хийх шаардлагагүй болно. Хэдийгээр заримдаа нэмэлт гарын авлагын шалгалт шаардлагатай хэвээр байна. Бид тодорхой асуудалд ямар тест хийхийг тодорхойлохын тулд Jira-д хаягуудыг ашигладаг.

Нэмж дурдахад ачааллын туршилт хийх хэрэгцээ нэмэгдэж, өмнө нь үүнийг ховор тохиолдолд л хийдэг байсан. Бид тест ажиллуулахдаа JMeter, тэдгээрийг хадгалахад InfluxDB, процессын график бүтээхэд Grafana ашигладаг.

Бид юунд хүрсэн бэ?


Нэгдүгээрт, бид "суллах" гэсэн ойлголтоос салсан. Энэхүү аварга том төхөөрөмжийг үйлдвэрлэлийн орчинд байрлуулж, бизнесийн үйл явцыг түр саатуулж байсан хоёр сарын аймшигт хувилбарууд алга болсон. Одоо бид дунджаар 1,5 хоног тутам үйлчилгээгээ байршуулж, зөвшөөрөл авсны дараа ашиглалтад ордог тул бүлэглэж байна.

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

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

Нэмж дурдахад, бид сайжруулалтын томоохон дараалал бүхий асуудлыг эрс багасгасан. Бид одоо зарим үйлчилгээтэй бие даан ажилладаг тусдаа бүтээгдэхүүний багтай болсон. Scrum процесс нь энд аль хэдийн сайн тохирч байна. Тодорхой баг нь түүнд үүрэг даалгавар өгдөг тусдаа Бүтээгдэхүүний эзэнтэй байж болно.

Хураангуй

  • Бичил үйлчилгээ нь нарийн төвөгтэй системийг задлахад тохиромжтой. Явцын явцад бид манай системд юу байгааг, ямар хязгаарлагдмал нөхцөл байдгийг, тэдгээрийн хил хязгаар хаана байдгийг ойлгож эхэлдэг. Энэ нь сайжруулалтыг модулиудын хооронд зөв хуваарилж, кодын будлианаас урьдчилан сэргийлэх боломжийг олгоно.
  • Бичил үйлчилгээ нь байгууллагын ашиг тусыг өгдөг. Тэдгээрийг зөвхөн архитектур гэж ихэвчлэн ярьдаг боловч аливаа архитектур нь бизнесийн хэрэгцээг шийдвэрлэхэд хэрэгтэй болохоос дангаараа биш юм. Тиймээс Scrum одоо маш их алдартай болсон тул бичил үйлчилгээ нь жижиг багуудын асуудлыг шийдвэрлэхэд тохиромжтой гэж хэлж болно.
  • Тусгаарлах нь давтагдах үйл явц юм. Та аппликешн авч микро үйлчилгээнд хувааж болохгүй. Үүссэн бүтээгдэхүүн нь ажиллагаатай байх магадлал багатай. Бичил үйлчилгээг зориулахдаа одоо байгаа өвийг дахин бичих, өөрөөр хэлбэл үүнийг бидэнд таалагдах код болгон хувиргах нь ашигтай бөгөөд үйл ажиллагаа, хурдны хувьд бизнесийн хэрэгцээг илүү хангадаг.

    Жижиг анхааруулга: Микро үйлчилгээ рүү шилжих зардал нэлээд их байна. Дэд бүтцийн асуудлаа дангаараа шийдэх гэж нэлээд хугацаа зарцуулсан. Тиймээс хэрэв танд тусгайлан масштаблах шаардлагагүй жижиг програм байгаа бол, хэрэв та олон тооны үйлчлүүлэгчид танай багийн анхаарал, цагийг эрэлхийлэхийн төлөө өрсөлддөггүй бол микро үйлчилгээнүүд өнөөдөр танд хэрэгтэй зүйл биш байж магадгүй юм. Энэ нь нэлээд үнэтэй юм. Хэрэв та процессыг микро үйлчилгээнүүдээс эхлүүлбэл зардал нь цул бүтээн байгуулалттай ижил төслийг эхлүүлсэнтэй харьцуулахад өндөр байх болно.

    Жич Илүү сэтгэл хөдлөм түүх (мөн танд зориулж байгаа юм шиг) - дагуу холбоос.
    Тайланг бүрэн эхээр нь хүргэж байна.

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

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