Біз отандық компаниялардың сайттарынан үнемі табатын топ-5 архитектуралық "балдақтар" (костыльдер)
Жылдар бойы ОЗАТ зертханасы қазақстандық компаниялар үшін — шағын жергілікті интернет-дүкендерден бастап, миллиондаған қолданушылары бар ірі логистикалық порталдар мен қарқынды дамып келе жатқан финтех-стартаптарға дейін ондаған күрделі IT-инфрақұрылым аудитін жүргізді. Біздің тәжірибеміз көрсеткендей, отандық нарықтағы цифрлық трансформация өте жоғары жылдамдықпен жүріп жатыр. Алайда, осы жылдамдықтың өз құны бар. Көптеген компаниялар нарыққа тезірек шығуды (Time-to-Market) бірінші орынға қойып, жүйенің ішкі сапасына, қауіпсіздігіне және болашақтағы масштабталу мүмкіндігіне тиісті деңгейде көңіл бөлмейді.
Және әр жолы кезекті жобаның "капотының астына" қараған кезде, біз 80% ықтималдықпен бірдей архитектуралық қателер мен жүйелік осалдықтарды табамыз. Бұл жай ғана "әдемі емес жазылған код" немесе эстетикалық кемшіліктер емес. Бұл — "Қара жұма" немесе басқа да ірі маркетингтік науқандар кезінде серверлердің жаппай құлауына, миллиондаған теңге шығынға, пайдаланушылардың дербес деректердің ағып кетуіне және бұлтты хостинг провайдерлерінен келетін орасан зор шоттарға әкелетін, жүйе ішіне жасырылған баяу жарылатын бомбалармен тең.
Көбінесе бұл проблемалар бизнестің әзірлеушілерден "тез арада өнімді шығаруды" талап етуінен туындайды. Сәулетшілер мен инженерлер уақыттың тығыздығынан масштабтау мен қауіпсіздік принциптерін құрбан етіп, ең аз қарсылық жолын таңдайды. Осылайша, жүйеде "архитектуралық қарыз" (Architectural Debt) жинақтала береді. Бұл мақалада біз қазақстандық нарықта ең жиі кездесетін және ең қауіпті 5 архитектуралық "балдақтарды" (костыльдерді) егжей-тегжейлі талдап, олардың тудыратын қауіптерін сипаттаймыз және олардан құтылудың нақты техникалық шешімдерін ұсынамыз.
1. "Бәрі бір бөтелкеде" немесе Барлығына арналған монолитті деректер базасы
Классикалық сценарий: компания өзінің алғашқы электрондық коммерциялық платформасын немесе қызмет көрсету порталын іске қосады. Бастапқы кезеңде әзірлеуді жеңілдету үшін барлық ақпарат — тауарлар каталогы, транзакциялар, тапсырыстар тарихы, пайдаланушылардың профильдері, жүйелік әрекеттердің логтары, аналитикалық көрсеткіштер және сессиялар деректері — бір ғана орталықтандырылған PostgreSQL немесе MySQL деректер базасында сақталады. Барлық кестелер бір-бірімен тығыз байланысқан (foreign keys), ал сұраныстар ортақ ресурстар үшін күреседі.
Мұның қаупі неде? Жүйеге түсетін жүктеме қалыпты жағдайда бұл тәсіл жақсы жұмыс істеуі мүмкін. Бірақ маркетингтік науқан басталған кезде немесе белсенді жарнама кезеңінде сайтқа бір уақытта 10 есе немесе 100 есе көп пайдаланушы келеді. Олардың басым бөлігі тауарларды іздеумен, сүзгілерді қолданумен және өнім сипаттамаларын қараумен айналысады. Бұл ауыр іздеу сұраныстары (күрделі SELECT және JOIN операторлары) деректер базасының процессоры мен жедел жадын (CPU/RAM) толығымен иемденіп алады. Нәтижесінде, деректер базасының қосылымдар пулы (connection pool) таусылып, жаңа сұраныстар кезекке тұрады. Базаның жүктемесі 100% шегіне жеткенде, ол жауап беруді тоқтатады. Ең сорақысы — пайдаланушылар тек іздеу функциясын ғана жоғалтып қоймайды, сонымен қатар сатып алуды рәсімдеу (INSERT/UPDATE транзакциялары) және төлем жасау мүмкіндігінен де айырылады. Тіпті компанияның менеджерлері де тапсырыстарды өңдеу үшін әкімшілік панеліне кіре алмай қалады. Бүкіл бизнес процесі тоқтап, компания қаржылық және репутациялық шығындарға ұшырайды.
Қалай дұрыс жасау керек: Шешім — деректер базасын бизнес-домендер бойынша бөлу (Database-per-service pattern) және әрбір тапсырма үшін оңтайландырылған арнайы құралдарды пайдалану.
- Пайдаланушылардың тауарларды жылдам әрі икемді іздеуі үшін Elasticsearch, OpenSearch немесе Meilisearch сияқты мамандандырылған іздеу жүйелерін енгізу қажет. Олар негізгі реляциялық базаға түсетін іздеу жүктемесін толығымен өз мойнына алады.
- Пайдаланушы сессияларын, себеттерді және жиі қолданылатын кэш деректерін сақтау үшін жедел жадта жұмыс іштетін Redis немесе KeyDB сияқты NoSQL қоймаларын пайдалану керек.
- Жүйелік логтар мен аналитикалық деректер сияқты үлкен көлемді жазу операцияларын қажет ететін ақпаратты сақтау үшін бағандық (columnar) деректер базаларын, мысалы, ClickHouse немесе Google Cloud BigQuery жүйелерін қолданған жөн.
- Негізгі реляциялық база (мысалы, PostgreSQL) тек қана маңызды транзакциялық деректермен (тапсырыстар, төлемдер, қаржылық баланстар) айналысуы тиіс. Сондай-ақ, оқу жүктемесін азайту үшін негізгі базаның репликаларын (Read Replicas) жасап, сұраныстарды бағыттауды оңтайландыру қажет.
Бұлтты инфрақұрылымда, мысалы, Google Cloud Platform-да бұл архитектура өзара тәуелсіз масштабталатын басқарылатын қызметтер арқылы оңай жүзеге асырылады: транзакциялар үшін Cloud SQL, кэштеу үшін Memorystore (Redis), ал аналитика үшін BigQuery қолданылады.
Жүктеме кезіндегі сұраныс жылдамдығы (Latency)
Пайдаланушылар саны артқан кездегі монолитті және үлестірілген деректер базасының жауап беру уақыты (миллисекундпен).
2. Ауыр тапсырмаларды синхронды өңдеу
Тағы бір жиі кездесетін қателік — ұзақ уақытты алатын немесе ресурсты көп қажет ететін операцияларды пайдаланушының HTTP-сұранысы аясында тікелей синхронды түрде орындау. Мысалы, әкімшілік панельдегі менеджер 100 000 тауар позициясы бар үлкен Excel немесе CSV файлын жүктейді. Ол "Жүктеу және жаңарту" түймесін басады, содан кейін веб-браузер серверден жауап күтіп, 10-15 минут бойы "қатып" қалады.
Мұның қаупі неде? Бұл жағдайда веб-сервер (мысалы, Nginx артында тұрған Gunicorn, uWSGI немесе Node.js процесі) файлды өңдеуге, деректер базасына мыңдаған сұраныстар жіберуге және әр жолды талдауға барлық күшін жұмсайды. Осы уақыт ішінде бұл процесс басқа пайдаланушылардың сұраныстарын өңдей алмайды. Егер бірнеше менеджер бір уақытта осындай ауыр файлдарды жүктеуді бастаса немесе жүйеде үлкен көлемді PDF-шоттарды генерациялау, клиенттерге жаппай SMS немесе Email хабарламаларын жіберу сияқты синхронды операциялар іске қосылса, веб-сервердің жұмысшы пулы (worker pool) толығымен сарқылады. Нәтижесінде, қарапайым пайдаланушылар сайтты аша алмайды, оларға 502 Bad Gateway немесе 504 Gateway Timeout қателері көрсетіледі. Сондай-ақ, егер осы ұзақ процесс кезінде желілік үзіліс орын алса немесе сервер қайта іске қосылса, барлық орындалып жатқан жұмыс жоғалады және оны қайтадан басынан бастауға тура келеді.
Қалай дұрыс жасау керек: Мұндай мәселелерді шешу үшін асинхронды кезектер архитектурасын (Message Queues / Message Brokers) енгізу қажет. Бұл Event-Driven Architecture (оқиғаларға негізделген архитектура) деп аталатын базалық паттернге жатады.
Жұмыс принципі келесідей болуы тиіс:
Kaspi Жұма және Қара Жұма: интернет-дүкенді х10 трафикке қалай дайындап, құлап қалмауға болады
- Пайдаланушы файлды жүктеген кезде, веб-сервер оны жылдам түрде бұлттық объектілік қоймаға (мысалы, Google Cloud Storage немесе кез келген S3-үйлесімді қоймаға) сақтайды.
- Веб-сервер хабарлама брокеріне (мысалы, RabbitMQ, Apache Kafka немесе Google Cloud Pub/Sub) "Жаңа файл жүктелді, оны өңдеу керек" деген шағын JSON-тапсырманы жібереді.
- Пайдаланушыға бірден дерлік (миллисекундтар ішінде) "Файл сәтті қабылданды және өңделуде. Дайын болған кезде хабарлаймыз" деген жауап қайтарылады. Пайдаланушы интерфейсі блокталмайды, ол сайтты әрі қарай қолдана береді.
- Фондық режимде жұмыс істейтін арнайы қызметтер — воркерлер (Workers, мысалы, Python-дағы Celery немесе Go-дағы жеке горутиналар) кезектегі тапсырманы алып, файлды асықпай, сенімді түрде өңдейді. Егер өңдеу барысында қателік кетсе немесе база уақытша қолжетімсіз болса, кезек жүйесі тапсырманы автоматты түрде қайта орындауға (retry mechanism) жібере алады. Өңдеу аяқталғаннан кейін пайдаланушыға WebSockets немесе Push-хабарлама арқылы нәтиже көрсетіледі.
Ауыр файлдарды өңдеу уақыты
Файл өлшеміне байланысты синхронды және асинхронды өңдеу кезіндегі HTTP қосылымының бос тұру уақыты (секундпен).
3. Қатаң тігілген кілттер мен құпия сөздер (Hardcoded Secrets)
Бұл — қауіпсіздік тұрғысынан ең сорақы және ең жиі кездесетін қателіктердің бірі. Жобаларды аудиттеу барысында біз әзірлеушілердің бастапқы кодтың ішіне деректер базасының құпия сөздерін, төлем шлюздерінің (мысалы, Kaspi, PayBox немесе Stripe) API кілттерін, пошталық серверлердің логиндерін және бұлттық инфрақұрылымға қол жеткізуге мүмкіндік беретін Service Account токендерін тікелей жазып қойғанын (hardcoding) көреміз.
Мұның қаупі неде? Егер бұл код кездейсоқ немесе қасақана GitHub немесе GitLab сияқты платформалардағы ашық (немесе тіпті жабық) репозиторийлерге түсіп кетсе, қаскөйлер автоматтандырылған сканерлердің көмегімен бұл құпияларды бірнеше секунд ішінде тауып алады. Осыдан кейін олар сіздің деректер базаңызды толығымен көшіріп алып, серверлерді шифрлап, бопсалауы мүмкін, немесе сіздің бұлттық аккаунтыңыздың атынан криптовалюта өндіру (crypto mining) үшін жүздеген қуатты виртуалды машиналарды іске қосып, сізге миллиондаған теңге шығын келтіруі мүмкін. Сонымен қатар, егер компаниядан ренжіп кеткен әзірлеуші жұмыстан шықса, ол бұл құпия сөздерді өзімен бірге алып кетіп, кейіннен жүйеге зиян келтіру үшін пайдалана алады.
Қалай дұрыс жасау керек: Ешқашан құпия деректерді кодтың ішінде сақтамаңыз. Қолданбаның коды мен оның баптаулары (Configuration) бір-бірінен толығымен бөлек болуы тиіс (бұл әйгілі Twelve-Factor App методологиясының негізгі ережесі).
- Әзірлеу және тестілеу кезеңінде құпияларды жүйелік орта айнымалылары (Environment Variables) арқылы беру үшін
.envфайлдарын пайдаланыңыз және бұл файлдарды ешқашан.gitignoreтізіміне қосуды ұмытпаңыз. - Продакшн (орнатылған нақты жұмыс) ортасында құпияларды басқарудың мамандандырылған жүйелерін қолданыңыз. Google Cloud Platform-да бұл үшін өте ыңғайлы және қорғалған Secret Manager қызметі бар. Басқа балама ретінде HashiCorp Vault жүйесін қарастыруға болады.
- Қолданба іске қосылған кезде немесе жұмыс барысында қажетті құпия сөздерді осы қорғалған қоймадан API арқылы динамикалық түрде сұрап алуы керек.
- Әзірлеушілердің өздеріне продакшн базаның нақты құпия сөздерін білудің қажеті жоқ. Қол жеткізу құқықтары қатаң түрде рөлдік модельге негізделген IAM (Identity and Access Management) саясаттарымен реттелуі тиіс.
4. Жүктелген файлдарды серверде локальді түрде сақтау
Бұл архитектуралық қателік әсіресе бұрыннан келе жатқан, дәстүрлі PHP немесе Monolithic Python жобаларында жиі кездеседі. Пайдаланушылар сайтқа өздерінің аватарларын, келісімшарттардың сканерленген нұсқаларын немесе өнімдердің суреттерін жүктейді, ал веб-қосымша бұл файлдарды тікелей өзі жұмыс істеп тұрған виртуалды машинаның жергілікті қатты дискісіне, мысалы, /var/www/site/uploads папкасына жазады.
Мұның қаупі неде? Мұнда екі үлкен мәселе туындайды. Біріншіден, виртуалды машинаның немесе физикалық сервердің дискілік кеңістігі шектеулі. Пайдаланушылар белсенді түрде файлдар жүктей бастағанда, ерте ме, кеш пе диск толады. Диск 100% толған сәтте операциялық жүйе жаңа деректерді, тіпті уақытша логтарды да жаза алмай қалады, нәтижесінде жүйе "No space left on device" қатесімен толық тоқтайды.
Екіншіден, бұл тәсіл жүйені көлденең масштабтауға (Horizontal Scaling) мүлдем мүмкіндік бермейді. Егер сіздің сайтыңызға келетін трафик артып, жүктемені көтеру үшін екінші және үшінші серверлерді іске қоссаңыз (және олардың алдына Load Balancer қойсаңыз), бірінші серверге сурет жүктеген пайдаланушының файлы екінші серверде болмайды. Екінші серверге бағытталған келесі сұраныс кезінде пайдаланушы өзінің суретін көре алмай, 404 Not Found қатесін алады. Сондай-ақ, егер виртуалды машина істен шығып, оны қайта жасау қажет болса, дискідегі барлық пайдаланушы файлдары біржола жойылады.
Қалай дұрыс жасау керек: Заманауи бұлттық архитектурада қолданбалы серверлер әрқашан "күйсіз" (Stateless) болуы тиіс. Бұл дегеніміз, сервердің дискісінде ешқандай бірегей пайдаланушы деректер сақталмауы керек.
- Барлық жүктелген файлдарды бірден сыртқы объектілік қоймаға жіберу қажет. Бұл үшін Google Cloud Storage немесе AWS S3 сияқты шешімдер қолданылады. Мұндай қоймалардың сыйымдылығы іс жүзінде шексіз, олар өте арзан және жоғары деңгейдегі сенімділікті (99.999999999% durability) қамтамасыз етеді.
- Файлдарды пайдаланушыларға тікелей сервер арқылы емес, жаһандық контентті тарату желісі (CDN - Content Delivery Network) арқылы тарату керек. Бұл сіздің негізгі веб-серверіңізді статикалық файлдарды өңдеу жүктемесінен толық босатады және файлдардың жүктелу жылдамдығын айтарлықтай арттырады.
- Қауіпсіздікті арттыру үшін, файлдарды тікелей сервер арқылы өткізбей, клиенттік браузерден бірден бұлттық қоймаға жүктеуге мүмкіндік беретін уақытша қолтаңбасы бар сілтемелерді (Signed URLs) пайдалануға болады.
5. Мониторингтің болмауы және "соқыр" деплой
Бұл — көптеген отандық әзірлеу топтарының ауыратын жері. Жаңа функцияны немесе қателіктерді түзетуді (hotfix) серверге шығару процесі келесідей сипатталады: әзірлеуші қолмен SSH арқылы өндірістік серверге қосылады, /var/www/site папкасына өтіп, git pull командасын орындайды, содан кейін қолданбаны қайта іске қосады. Егер кодта қате кетіп, жүйе бұзылса, әзірлеушілер бұл туралы тек ашуланған клиенттер қолдау қызметіне немесе басшылыққа телефон соға бастағанда ғана біледі. Жүйенің қаншалықты жылдам жұмыс істеп тұрғаны, қанша жедел жад (RAM) тұтынып жатқаны және деректер базасына қандай сұраныстар ең баяу орындалып жатқаны туралы ешкімде нақты ақпарат болмайды.
Мұның қаупі неде? Бизнес өз клиенттерін жоғалтады, өйткені кез келген қателікті анықтау және оны жою процесі сағаттарға, кейде күндерге созылуы мүмкін. Инженерлер мәселенің қай жерде екенін білмей, сервердегі шашыраңқы лог файлдарын қолмен ақтарып, уақыт жоғалтады. Сонымен қатар, қолмен жасалған деплой кезінде адам факторының әсерінен маңызды файлдардың жойылып кету немесе қате конфигурацияның орнатылу қаупі өте жоғары.
Қалай дұрыс жасау керек: Өнімнің сенімділігі мен тұрақтылығын қамтамасыз ету үшін заманауи CI/CD (Continuous Integration / Continuous Delivery) және Observability (бақылағыштық) тәжірибелерін енгізу қажет.
- Кодты серверге жеткізу процесі толығымен автоматтандырылуы тиіс. Бұл үшін GitLab CI, GitHub Actions немесе Jenkins сияқты құралдарді пайдалану керек.
- Жаңа нұсқаны шығарған кезде пайдаланушылар үшін сайттың тоқтап қалмауын (zero-downtime) қамтамасыз ететін Blue-Green немесе Canary deployment стратегияларын қолданыңыз. Егер жаңа кодта қате табылса, жүйе автоматты түрде алдыңғы тұрақты нұсқаға (rollback) қайта оралуы тиіс.
- Барлық жүйелік логтарды, қосымшаның қателерін және метрикаларын бір орталыққа жинақтаңыз. Google Cloud Platform ортасында бұл үшін қуатты Google Cloud Operations Suite (бұрынғы Stackdriver) құралы бар. Ол нақты уақыт режимінде серверлердің жүктемесін бақылауға, сұраныстардың өту жолдарын бақылауға (Distributed Tracing) және қателіктер саны күрт артқан кезде Telegram немесе Slack арналарына жедел ескертулер (alerts) жіберуге мүмкіндік береді. Сондай-ақ, қолданба деңгейіндегі қателерді бақылау үшін Sentry, ал метрикаларды визуализациялау үшін Prometheus пен Grafana жұбын қолдану ұсынылады.
Өз жобаңызды осы тармақтардың бірінен таныдыңыз ба?
Архитектуралық қарыз жинақталу қасиетіне ие, және оны неғұрлым кеш қайтарсаңыз, соғұрлым қымбатқа түседі. ОЗАТ зертханасы IT-инфрақұрылымға терең аудит жүргізеді. Біз "тар жерлерді", ықтимал қауіпсіздік қатерлерін табамыз және заманауи, масштабталатын архитектураға көшу бойынша егжей-тегжейлі жоспар жасаймыз.
Инфрақұрылым аудитіне тапсырыс беру
Рустам Шарафутдинов
Google Cloud архитектурасы саласындағы сарапшы және 15 жылдан астам тәжірибесі бар Senior Full-Stack әзірлеушісі. Ақауға төзімді архитектураларға, жоғары жүктемелі жобаларды оңтайландыруға және AI (Vertex AI) интеграциясына маманданған.