11/01/2018

Микросервис архитектур байгуулах ба тулгарах хүндрэлүүд

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

Яагаад MSA (микросервис архитектур) гэж?
Ердөө л 100 хүн амьдрадаг газар байна гэж төсөөлье. Бүгд худгаас усаа аваад, айл бүр гэртээ галаа түлж дулаацаад, ариун цэврийн асуудлаа дор бүрнээ шийдээд амьдраад байх боломжтой. Харин 1000000 хүн амьдардаг газар байна гэж төсөөлье. Ус, дулааны шугам сүлжээнээс авхуулаад хотжилтийн өндөр зохион байгуулалттай дэд бүтэц хэрэг болно.
Товчхондоо яг л үүнтэй адил програм хангамж өргөжин тэлэх үед илүү нарийн зохион байгуулалт хэрэгтэй болно. Иймд тэлэлтийн асуудлыг шийдэх нэгэн шийдэл нь MSA юм.

Программйн тэлэлт гэж тухайн программийн хэрэглэгчдийн тоо болоод түүнээс хамаарах ачаалал, бизнес процесс, техник хангамж ба програм хангамжийн нөөц нэмэгдэх үйл явцийг хэлнэ. Scalability буюу чадлийн цараа гэж системийн тэлэх боломж, потенциалийг хэлдэг. Scalability нь MSA -д зайлшгүй байх ёстой хамгийн эхний чанар(feature). Scalability -г хэрхэн шийдхээс хамаарч програм хангамжийн хөгжүүлэлт, хяналт, арчилгаатай холбоотой маш олон чанрыг MSA агуулах хэрэгтэй болдог.

Миний судлаж, мэдсэнээр одоо байгаа хамгийн хүчтэй MSA -г хэрэгжүүлж байгаа нээлттэй технологиуд нь Kubernetes болон Spring Cloud Netflix. Иймд хоёуланг нь сайтар ойлгохийг хичээж, мөн туршиж ажиллуулж үзсэн. Ийм боломжийг олгосон ITZONE компани болон төслийн багийнхандаа баярлалаа :p

MSA хувьд систем нь сервис буюу дэд системүүдээс тогтох бөгөөд тэлэлтийн асуудлыг  шинээр сервис үүсгэх замаар шийддэг. Ингэснээр сервисүүд тус тусдаа тархмал байдлаар байрших боломжтой болж систем маань өрөө физик-сервер компьютерийн хязгаарлалтаас мултарна. Ачаалал өндөртэй сервисийн хувьд тухайн сервисийг олон хувьлаж ачааллыг багасгадаг. Энэ нь бусад сервисийн хувьд нэг сервис шиг харагдах боловч угтаа нэг сервисийн нэрийн доор параллел сервисүүд ачаалаа хувааж байдаг гэсэн үг. Энэ бол load balancing(ачаалал тэнцвэржүүлэлт). Сервисүүдийн хооронд гинжин хэлхээ маягийн холболт үүсэх ба холболт бүрийн дунд load balancing хийгдэх шаардлагатай.
Олон тусдаа бие даасан сервисүүд гэхээр програм хангамж хөгжүүлэлт болоод арчилгаа, хяналт, тохиргоо гээд бүгд төвлөрсөн бус болж хувирна. Энэ нь MSA -г хэрэгжүүлэхэд тулгарах нэг том асуудал. Төвлөрсөн бус(decentralized) байдлыг төвлөрүүлэхийн(centralized) тулд нэмэлт шийдлүүд хэрэгтэй.
Сервисүүдийг зохион байгуулахдаа аль болох бие даасан буюу модулар(modular) байдлыг дээшлүүлж, ерөнхий тохиолдолд ашиглагдахаар царааг нь бодолцож зохиох нь зүйтэй болов уу.

Мэдээж ерөнхий програм хангамжийн архитехтур учраас заавал Kubernetes ч юм уу Spring Cloud ашиглаж байж MSA болно гэсэн үг биш. Хүсвэл өөрийнхөө шаардлагад тааруулж MSA -г хөгжүүлж болно.

Харин MSA нь доорхи чанруудыг агуулсан байх ёстой.
  • Scheduling & Deployment (Тархалт болоод суурьлуулалтын хуваарь)
  • Auto Scaling & Self Healing (Автоматжуулсан тэлэлт, Автоматжуулсан эмчилгээ)
  • Config Management (Тохиргооны менежмент)
  • Service Discovery & LB (Сервисийн бүртгэл, түгээлт ба Ачаалал тэнцвэржүүлэлт)
  • Resilience & Fault Tolerance (Алдаанд тэсвэртэй болоод уян хатан байх)
  • API Management (API менежмент)
  • Service Security (Сервисийн аюулгүй байдал)
  • Centralized Logging (Төвлөрсөн лог, бүртгэл)
  • Centralized Metrics (Төвлөрсөн үзүүлэлтүүд)
  • Distributed Tracing (Тархсан хяналт)
Энэ бүгдийг сайтар зохион байгуулна гэдэг зөвхөн програм хангамжийн инженер эсвэл системийн архитехтурийн мэдлэг дангаар хийхэд хэцүү ба програмчлал, сүлжээ, аюулгүй байдал, devops зэрэг олон төрлийн туршлага, мэдлэг оролцох хэрэгтэй болдог.
Магадгүй ийм болоод ч тэрүү Netflix -н хувьд бүх хөгжүүлэгчидээ full stack биш full-cycle хөгжүүлэгч болгохоор шахдаг байх.

Container тухай сонсож байгаагүй бол: What is a Container?
Virtual Machine үүд үеээ өнгөрөөж бүгдийн контейнарт л чихдэг болж дээ :p

Kubernetes буюу K8s

Google -н арав гарам жил програм хөгжүүлэлтэндээ ашиглаж, сайжруулж ирсэн аргачлал. Google -д Borg гэж ашиглагддаг, kubernetes -г Borg -н нэгэн branch гэж ойлгож болно.

Kubernetes өөрийгөө container orchestrator гэж танилцуулдаг. Тэр ч утгаараа container үүдийг зохион байгуулж ажиллагааг нь нэгтгэж өгдөг.
Kubernetes маш олон ойлголтуудыг агуулсан том технологи байсан учраас хаанаас нь эхлэж яаж ойлгох гээд нэлээдгүй хүндрэлүүдтэй тулгарсан. Янз бүрийн блог уншина, бүгд өөр өөр юм бичсэн ч юм шиг. Тэгсэн хэрнээ их ерөнхий юм ойлгоод байгаа болхоор тэр хэрээрээ хүссэнээрээ хэрэгжүүлж чадахгүй бүдэг бадаг. Нарийн ойлгоё гэхээр мэдэхгүй зүйлстэй тулгараад. Ажиллуулж үзсэн ч цэгцтэй биш алаг цог энд тэндээс мэдээд байгаа болхоор бас л болж өгөхгүй. Энэ маягаараа бүтэхгүйн гээд шууд udemy -с хичээл авч үзсэн.
Үүний дараа бүх юм хамаагүй цэгцтэй болж хувирсан.
Хөгжүүлэгчид гэхээсээ илүү систем админ, devops ийнхонд зориулагдсан юм байна лэ.

Сервисүүд буюу container -үүд нь kubernetes -н хувьд pod, node, service, cluster гэх нэгжүүдэд шаталсан байдлаар ангилагдана. Kubernetes нь дангаараа бүгдийг хийх боломжгүй бөгөөд гол ажиллагаа нь сервисүүдийг зохион байгуулахад л төвлөрнө. Харин бусад зүйлсэд зориулж API үүд гаргасан байх ба үүнтэй нь гуравдагч/дэмжиж ажиллах програмууд add-on хэлбэрээр сууж хамтарч ажилладаг. Бүх ажиллагаа descriptor файлуудаар зохицуулагдах боломжтой байдаг.

Жишээ нь: kubernetes дотроо сервисүүдийнхаа хооронд дэд сүлжээний бүтэц байгуулах хэрэгтэй болно. Мөн тэдгээрийн хооронд load balancing хийх, хяналт хийх зэрэг дээр дурьдагдсан чанруудыг хэрэгжүүлэх хэрэгтэй. Тэр бүгдэд нэмэлт add-on ууд хэрэглэнэ. Харин сервисийн аюулгүй байдлыг хувьд нэгдсэн шийдэл байдаггүй. Учир нь container дотор ямар ч програмчлалын хэлээр, яаж хөгжүүлсэн нь сервисийн өөрийн асуудал болно. Энэ нь нөгөө талаасаа Spring Cloud тай харьцуулвал програмчлалын хэл болоод дурийн санг ашиглах эрх чөлөөг олгодог.

Мэдэж хэд хэдэн kubernetes cluster -ууд хоорондоо нийлж холбогдон ажиллах боломжтой.

Kubernetes дотор тухайн сервис ажиллах боломжгүй болж хариу өгөхгүй байх эсвэл алдааны улмаас унтарсан тохиолдолд тухайн сервисийг автоматаар устгаад сервисийг анх суулгасан deployment descriptor ийн тусламжтайгаар шинээр үүсгэдэг. Мөн сервисүүдийг хүссэнээрээ хувьлан тоог ихэсгэж, багасгах боломжтой. Нөгөө талаас ачаалал ихсэх үед өөрөө автоматаар сервисүүдийг хувьладаг. Хувьлаж сервисүүдийн тоог нэмэгдүүлэх явцийг kubernetes -т тэлэх (scale) хийх гэдэг. Мөн тухайн нэг сервис унтарсан ч хуулбарууд нь ажиллаж байх боломжийг бүрдүүлнэ. Энэ маягаар шинэ хувилбар байршуулах зэрэг программийн шинэчлэл нь одоо ажиллаж байгаа системийг доголдуулахгүйгээр нэвтэрдэг. (Солиотой юм байна лээ)

Kubernetes container үүдийг descriptor -н тусламжтайгаар шинээр үүсгэдэг гэдгийг анзаарсан байх. Мөн шууд устгах боломжтой. Энэ нь тухайн container -т ямар ч файл, кеш зэргийг хадгалж болохгүй гэсэн үг. Тэгэхээр бүх сервис маань ямар ч төлөв хадгалдаггүй stateless байх ёстой болно. Иймд энэ асуудлыг шийдэж сервисүүдийг stateful болгохын тулд volume гэх нэгжийг оруулж ирдэг. Volume нь kubernetes -г ямар нэг файл системтэй холбож өгдөг нэгж бөгөөд тухайн volume устаж, шинээр үүссэн ч файл системтэй холбоотой хэвээр байдаг. Ихнэхдээ өгөдлийн санг volume байдлаар байршуулахад зориулагдсан.

Тохиогоо болоод нэвтрэх эрх зэргийг нэгдсэн байдлаар хадгалаж ,түгээхдээ kubernetes secret гэх хувьсагчуудыг хадгалах ба secret -үүдээ тухайн сервисрүү environment variable эсвэл file system -д оруулах замаар түгээх боломжтой.

Харин  ingress controller(gateway сервисийн үүрэг гүйцэтгэгч гэж ойлгож болно) болон load balancer -ууд нь зөвхөн Amazon Web Service, Google Cloud Engine, Microsoft Azure зэрэг cloud provider ууд дээр суулгаж байж ажиллах боломжтой байсан учраас цаашид физик-сервер (bare-metal server) дээр ажиллах боломжгүйг ойлгоод kubernetes -ээс татгалзсан.

Spring Cloud Netflix

Spring Framework суурьлаж Netflix OSS -н хөгжүүлсэн Spring Cloud Netflix шийдэл.

Spring Cloud Netflix тухай бичихээс өмнө Java -г сайтар мэдэх хэрэгтэй. Зөвхөн Java -г ашигласнаар веб технологи хөгжүүлэх, програмчлахад бусад технологиудтай харьцуулахад хамаагүй олон давуу талыг эдлэнэ. JavaSE, JavaEE -н хүчтэй API уудаар хангагдаж Central Maven Repository -д байх баялаг сангууд болон технологийн интеграцууд, нэмээд Spring өөрийнх аюулгүй байдал, тохиргооны суурь бүтэц, эмбэддэд веб сервер зэргийг үүнд дурьдаж болно.

Spring Cloud шийдэл нь Spring framework -ийг суурь бүтцээ болгож ашигласан олон төрлийн бүтээгдэхүүн байх бөгөөд бүгд MSA -г хэрэгжүүлэх тус тусын үүрэгтэй оролцоно. Мөн өөр хоорондоо хоршиж ажиллах зориулалттай.

Сервисүүд нь Eureka гэх сервис дээр зангилагдах бөгөөд энэ нь сервисийн бүртгэл болоод бусад сервисүүдийг хооронд нь холбох үүргийг гүйцэтгэнэ. Харин бусад сервис үүд нь Eureka client болж холбогддог. Spring Cloud хувьд сервисүүд нь бүгд нэг програмчлалын хэл, нэг платформ ашиглаж байгаа учраас үүнийг дагаад kubernetes -тэй харьцуулахад хэд хэдэн давуу талууд бий болдог.

Үүнд баталгаажуулалт(auth) -н сервистэй Zuul гэж нэрлэгдэх gateway сервис нь нэгдэж ажилласнаар аюулгүй байдал болон баталгаажуулалтыг MSA хувьд бүхэлд хангах нь хангах боломжтой. Мэдээж хэрхэн яаж хэрэгжүүлэхээсээ хамаараад өөр өөр байж болно. Миний хувьд auth сервис маань токен шинээр үүсгэх ажил л хийнэ. Харин токен шалгалтийг gateway сервис дээрээ филтерлэж шалгана. Gateway сервисээр дамжиж бүх хүсэлт орж ирэх болхоор ингээд лонхны хүзүүн дээр нэг удаа боогоод өгчихөж байгаа санаа. Мөн нэгдсэн log, хяналт болон алдаанд тэсвэртэй байх, уян хатан ажиллаагааг Turbine, Hystrix, Atlas зэрэг Spring дээр суурьласан бусад технологиуд нь шийдэж өгдөг.

Харин автоматаар алдаа гарсан сервисийг kubernetes тэй ижил зарчмаар эмчлэх боложмгүй, байдаг яагаад гэвэл сервис бие даасан байх ба тухайн сервист гаднаас нь нөлөөлөх механизм байхгүй. Иймд мөн автоматаар сервисүүдийг хувьлаж тэлэх боломжгүй. Сервисүүдийг хувьлах болон өөрөө өөрийгөө эмчлэх үйлдэл нь механик байдаг. Энэ тохиолдолд Eureka сервистэй холбогдож мэдээлэл авч. Шинээр сервис хувьлах асаах зэрэг үйлдүүдийг зохицуулдаг програм хөгжүүлэх боломжтой.

Энэ сул талаа нөхөхийн тулд сервисүүдийн хяналт, алдаанд тэсч үлдэх байдал зэргийг маш сайн бэлдэж өгсөн. Зөвхөн Spring @Service @Controller функц(метод) дээр нөөцийн хуваарлалт хийж, тухайн функц дээр сервисийн хувьд хэр их ачаалал өгч байгааг хянах боломжтой. Үүнийг Turbine болон Hystrix тусламжтайгаар хялбар хэрэгжүүлнэ.

Ачаалал тэнцвэржүүлэгчийн хувьд Eureka сервис эсвэл gateway дээр биш, client сервисүүд дээрээ зүгээр л annotation тавьж хэрэгжүүлж байгаа нь маш таалагдсан.

Миний хувьд бусад програмчлалын хэлийг бодвол java  -г илүү эзэмсэн JavaEE болон Spring дээр туршлагатай байсан, мөн түрүүлж kubernetes -г судлаад MSA -н ойлголтуудыг авсан байсан болхоор Spring Cloud хэрэгжүүлэхэд тийм ч их хүндрэлтэй тулгараагүй. Мөн элдэв янзийн тохиргоо, tool гэхээсээ илүү бусад технологиудаа кодчилж, кодон дотроо хийж байгаа нь илүү ойр санагдсан.

----------------------o----------------------



Spring дээр ELK, Sleuth, Zipkin энэ тэр гээд туршиж үзээгүй ба мэдэхгүй зүйлс байнөө байна. Харин kubernetes -н хувьд ойлгоогүй үлдсэн зүйлс нэлээдгүй байгаа болов уу.









3 comments :

3 comments :

  1. nice nice, chinii bichsen ymiig jiliin daraa l oilgoh ymdaa hehe

    ReplyDelete
    Replies
    1. hehe buruu bichsen yum baiwal zasaj ogoorei

      Delete
  2. Very informative thank you

    ReplyDelete