Batzorigt Rentsen
May 11, 2018 · 6 min read

Нэгэн танил минь “Манай багын найз VOD service найдвартай сайн хийж өгөх хүн хайж байгаа гэнэ. Сонирхож байвал … ” гэж холбоо барив. Ингээд захиалагч талтай уулзаад төлөвлөгөө гарган ажиллаж, 4 сар нухсаны эцэст яг 2 жилийн өмнө анхны production release-ээ хийсэн юм.

Захиалагчаас ирсэн хүсэлт

Үндсэн хэрэгцээ шаардлагыг жагсааж бичвэл:

  • Ердөө 2 сарын дотор эхний хувилбарыг гаргах!
  • Хууль бусаар татах, хуулах боломжгүй байх!
  • Web, Android & iOS app-тай байх
  • Хүссэн үедээ төлбөр төлөөд видео үздэг байх
  • Контентыг төрөл жанраар нь ангилан харуулах, full text search хийх боломжтой байх
  • Контентын тухай дэлгэрэнгүй мэдээллийг оруулах, засах, харах боломжтой байх
  • Шинэ контентыг нэмэх, засах, устгах боломжтой байх

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

Миний зүгээс өгсөн хариу

Хоёрхон сарын дотор ямар ч жижиг хэмжээний төслийг хийж дуусгах боломжгүй. Чанартай сайн систем бүтээхийн тулд багаар бодоход 3–6 сар хэрэгтэй. Зөвхөн UI хийхэд л нэг сар болно. Богино хугацаанд эхний хувилбарыг гаргахын тулд функцын тоог зайлшгүй хэрэгтэй хэмжээнд хүртэл цөөлөх нь зүйтэй. Захиалагч, нийлүүлэгч хоёрын анхны төсөөлөл мэдлэг хуримтлагдахын хэрээр олон дахин өөрчлөгднө. Чанартай, хүнд хэрэгтэй зүйл хийе гэвэл захиалагч талын идэвхитэй оролцоо, шуурхай хариу, тусламж дэмжлэг чухал. Хугацаа хожъё гэвэл харагдах байдалд хэт ач холбогдол өгөлгүй, хурдан хийж болох, ойлгомжтой бөгөөд ашиглахад хялбар, цомхон UI-тэй байхаар хийвэл зүгээр гэж зөвлөв.

Тэгээд эхний болон дараа дараачийн релийзээр бэлэн болгож болох функцын жагсаалт, төсөв төлөвлөгөөг танилцууллаа. Төлөвлөгөө ихэд таалагдаж* ажилдаа шуурхайлан оров.

*Гүйцэтгэгч хайж олон газраар орсон боловч над шиг ингэж зөвлөх, төлөвлөгөө гаргаж өгөх хүн олдоогүй. Янз бүрийн үнэ хэлнэ, чадна гэх хэр нь төлөвлөгөө төсөв гаргаад аль гэхээр хариу өгөхгүй таг болдог. Итгэл алдраад больдогийн даваан дээр надтай учирсан тухай захиалагч ярьж байв.

Төслийн баг

Гурван хүний бүрэлдэхүүнтэй баг бүрдүүлж, ажилдаа шамдан оров.

  • Full stack developer: Нэг (би)
  • iOS deveoper: Нэг
  • Android developer: Нэг

Шийдэх ёстой асуудлууд

Хамгийн чухал, эрсдэлтэй, яаралтайгаас нь цувруулж бичвэл:

  • Бүх платформ (android, ios, бүх браузер) дээр дэмжигддэг Video Streaming protocol-г судлах
  • Нууцлал хамгаалалтыг яаж шийдэх вэ?
  • Инфра (cерверийн бүтэц, архитектур) шийдэл гаргах (хаана байршуулах, системд ирэх өндөр ачааллыг хэрхэн тэсэх?)
  • Онлаинаар төлбөрийг хэрхэн хүлээж авах?
  • Ашиглалтын зардлыг хамгийн бага хэмжээнд яаж барих?
  • Домэин моделийг тодорхойлж, back end (restful web service) бэлдэх
  • Mobile & Web UI бэлэн болгох

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

Шийдэл

Судлагаа, өмнөх туршлагадаа дулдуйдан дараах байдлаар сонголт хийсэн.

Video Streaming protocol: Судлагааны үр дүнд HLS хамгийн тохиромжтой протокол болохыг олж мэдэв. MP4 видеог HLS хэлбэр рүү хөрвүүлж, бүх браузер, андроид, iOS төхөөрөмж дээр тоглуулж үзэв. Ямар ч байсан хөгжүүлэлт хийгдэж байх хооронд контентыг HLS format руу хөрвүүлж* хугацаа хожих боломжтой болгов. Браузер дээр HLS video-г үүгээр тоглуулахаар шийдэв.

*Хэрэглэгч AWS Management Console-г ашиглан жинхэнэ эхийг AWS S3 (жинхэнэ эхийг түр байршуулах bucket) дээр байршуулж, Elastic Transcoder-оор HLS рүү хөрвүүлнэ. Transcoder үр дүнгээ өөр bucket руу хуулна.

Нууцлал хамгаалалт: Системд нэвтрэх, хандах эрхийг доорх байдлаар хязгаарлахаар тооцсон болно:

  • Э-шуудан +нууц үг, эсвэл FB login
  • HTTP Basic Authentication + Custom HTTP Header
  • Төлбөр төлөгдсөн тохиолдолд л видео стриймин хийх
  • Сүлжээгээр дамжих өгөгдлийг SSL/TLS-ээр нууцлах: SSL certificate-г Amazon Certificate Manager-с үнэгүй авахын тулд front end серверийг virginia бүсэд байршуулав. Тухайн үед зөвхөн виржиниад л үнэгүй байсан юм.
  • Видео контентыг эвлүүлэн залгах боломжгүй олон жижиг, 5 cекундын урттай хэсэгт (фаил) хувааж цувруулан дамжуулах
  • Жижиглэн хуваасан хэсэг бүрийг тайлж унших боломжгүй болгох (encrypt-лэх). Content encryption тухайн үед Netflix дээр байхгүй, ирээдүйд тийм боломж нэмэхээр төлөвлөсөн тухай google-дэж мэдсэн болно. Энэ тал дээр бид нэг алхам түрүүнд байж, Netflix-c түрүүлж релийз хийж чадсан билээ.
  • Жижиглэн хуваасан хэсэг бүрт харгалзах URL-г хувьсдаг, зөвхөн нэг удаагийн байж, хүчинтэй хугацаа өнгөрсөний дараа дахин ашиглах боломжгүй болгов.

Инфра: Өөрийн хамгийн сайн мэдэх AWS-г сонгов. Хөгжүүлэлт хийж байх үе, хэвийн ачаалалтай үе, ирээдүйд өсч болох ачааллыг тооцоолон доорх архитектурыг гаргав.

Бүрэн хүчин чадлаар ажиллах үед

Агуулгаа S3 дээр гадны шууд хандалтгүй газар байрлуулж, дээр дурдсан олон хамгаалалтыг давсан терминал руу CloudFront-н дэлхий даяар тархсан Edge Server-н хамгийн ойроос нь түгээнэ. Ингэснээр ямар ч хоцрогдолгүйгээр дэлхийн аль ч өнцөг буланд байгаа хэрэглэгч рүү видео стриймин хийж чадна. Front/back end сервер ч гэсэн өндөр ачаалал авахгүй.

Онлаинаар төлбөр хүлээн авах: Эхний хувилбарыг Stripe-аар хийсэн боловч захиалагчийн данс байрших банкны шахалтаар Payeezy дээр дахин хийсэн билээ :( Таньд гэж хэлэхэд Payeezy шиг новшийн хуучинсаг API байхгүй байх. Харин Stripe шиг гоё payment gateway байхгүй болов уу?

Ашиглалтын зардал: Ашиглалтын зардлыг хамгийн бага байлгахын тулд AWS free tier*-н EC2 instance (front end + backend), RDS instance (MySQL)-г тус бүр нэг байлгахаар шийдэв. Ачаалал өсөх үед AWS ELB (ачаалал тэнцвэржүүлэгч-хуваарилагч) -н ард EC2 инстансыг байрлуулж horizontal scale хийхээр тооцсон юм. Шаардлагатай бол front end, back end-г 2 өөр инстанс дээр байршуулж, хооронд нь AWS ELB-ээр холбож болохоор анхнаас нь салгаж хийсэн болно. Дээрх инфрагаар зөвхөн хэрэглээнийхээ хэрээр төлбөр төлөх тул cost effective байж чадна.

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

Бусад өрсөлдөгчид Wowza Streaming Engine ашигладаг. Ашиглалтын зардал өндөр тул үүнийг жагсаалтаас хассан болно.

*AWS free tier-т багтах EC2, RDS instance эхний нэг жил үнэгүй.

Back end: Домэин моделийг тодорхойлж, эхний ээлжинд яаралтай (зэрэгцээ хөгжүүлэлт хийхэд) шаардлагатай RESTful Web Service-г бэлэн болгож, API doc (web service-н URI, оролт гаралтын параметрын тодорхойлолт)-г мобаил хөгжүүлэгчид өгөв. Web Service-г Jersey (JAX-RS), db access layer-г JDBI, HikariCP дээр хийж, Grizzly (web server) дээр ажиллуулахаар сонгов. Серверээс буцаах хариуг (json) gzip-ээр шахах, зөвхөн зөвшөөрөгдсөн хэрэглэгчийн хүсэлтийг хүлээж авахаар security filter бичиж тавьсан.

Web UI: Технологийн сонголтыг доорх байдлаар хийж нэг jar (embedded jetty) болгон ажиллуулж орхив.

  • Vaadin + Spring Boot for front end: Vaadin, Spring Boot 2-н сайн талуудыг шингээсэн, HTML, Javascript-тэй зууралдахгүй, бүтээмжийг өндөр байлгахын тулд Vaadin + Spring Boot хослолыг сонгосон болно. Олон давтагдах хэсгийг UI component болгож, хэрэгтэй бүх газар нь дахин ашиглав. Preprocessor ажиллуулж, олон жижиг фаилыг нэгтгэх, хоосон зайг шахах, оновчилж хэмжээг багасгах, серверээс буцаах хариуг (html, javascript, css, json) gzip-ээр шахах, зэрэг арга хэмжээг авсан болно.
  • Retrofit for Web Service Client: Зөвхөн оролт гаралтын интерфэисийг тодорхойлж өгөөд web service-г хялбархан дуудаж болно.
  • Hazelcast for session replication: Jetty-н session manager DB ашигладаг, Tomcat-н session manager Vaadin-гийн session-г дэмждэггүй. HazelCastSessionManager тухайн үед Vaadin дээр зөв ажилладаггүй байсан учир өөрөө custom implementation хийв.

Мобаил UI: Хурд, найдвартай байдлыг тооцоод native app хийхээр шийдсэн. Android, iOS хөгжүүлэгчид ижил төстэй апын дизаиныг судлаж, богино хугацаанд хийж болох хамгийн энгийн, хялбар хэр нь өнгө үзэмж сайтай дизаин гаргаж өглөө. Андроид апын вэб сервис дуудах хэсэгт ретрофитыг санал болгож өөрийн Web UI дээрх туршлагыг нэвтрүүлэв.

FB Login: Мэдээж Facebook Graph API ашигласан. Гэхдээ scribejava-аар хандсан. Яагаад гэвэл scribejava бусад SNS app-н login api-г дэмждэг, амархан бөгөөд хурдан OAuth library байсан юм.

Хөгжүүлэлтийн арга барил

Хөгжүүлэлтийг Domain Driven буюу гаднаас нь (UI, front end) биш цөмөөс (backend, web service) нь эхлэн гүйцэтгэсэн. Нэг web service-г бичиж дуусгаад Web UI, mobile app-tai холбох (integration test) маягаар инкрементал буюу хэсэгчилэн давтах маягаар үйлдэв. Цаг давчуу тул Unit test-н оронд source code (self*) review, refactoring олон дахин хийсэн болно.

*Нийт алдааны 96% нь self review-ээр илэрдэг гэсэн дата бий.

Ерөнхийдөө Lean, XP-г баримталж хөгжүүлэлтийг хийв. Нийт ажлын суурь, хамгийн чухал хэсэг болох 20%–г зөв тавьбал үлдсэн 80%-нх нь хандах зүг өөрөө тогтно.

Mobile хөгжүүлэлтийг Pair Programming (iOS developer + android developer), integration test-г Triple Programming* (back end developer + iOS developer + android developer)-р тухайн нөхцөл байдалд тохируулан гүйцэтгэсэн.

*Triple Programming-г үйлдэхдээ бичиж дууссан web service-н оролт гаралт, URI, зориулалтыг чатаар мобаил хөгжүүлэлгчдэд дамжуулан, харгалзах лог фаил, дэлгэцийн үр дүнг шалгах маягаар гүйцэтгэв. Ингэснээр iOS app, android app, web app-н хөгжүүлэлт хүлээгдэл багатай ижил хэмнэлээр явагдах бүрэн боломжтой болсон билээ.

Төгсгөлд нь

Анхны релийзээс хойш UI-н шинэчлэл, хямдрал урамшууллын функц, гишүүнчлэлийн сарын хураамж, түүнтэй холбоотой scheduled job гэх мэт шинэчлэлийг шат дараатай хийсэн билээ. Netflix-т 2000 гаран инженер ажилладаг. Харин бид гурвуулханаа хийх гэж үзсэн бөх зүрхтэй гарууд билээ :)

Ингээд Netflix шиг сервис хэрхэн бүтээсэн тухай миний хуваалцах зүйл дуусав. Хэрэв дахиад иймэрхүү зүйл хийхээр бол Front End-г цэвэр HTML, JavaScript, CSS-ээр хийгээд S3 дээр байршуулан Cloud Front-р түгээж, back end-г AWS Lambda* дээр байршуулж болох юм гэсэн бодол төрлөө. Бас контентоо Transcoder-оор биш ffmpeg-ээр хөрвүүлбэл Амазонд мөнгө төлөхгүй нэлээд мөнгө хэмнэх юм байна. AWS-н үйлчилгээний дотор Elastic Transcoder бараг хамгийн өндөр тарифтай нь байх шүү!

*Гэхдээ cold start effect-г сайтар тооцох, tuning хийх хэрэгтэй.

Асуух дэлгэрүүлэх зүйл байвал чөлөөтэй хандаж болно. Энээ хүртэл тэвчээртай уншсан таньд баярлалаа!

Unimedia Solutions

Unique Ideas

Batzorigt Rentsen

Written by

Tech Lead at MLab Mongolia. Former Tech Lead at Unimedia Solutions.

Unimedia Solutions

Unique Ideas

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade