ITSimplified: Site-ul de e-commerce
Acum 9-10 ani doream să cumpăr ceva de pe net. Nu era ceva enorm sau complicat, nici ceva teribil de scump, însă în dimineața aceea nefastă mi-a fost imposibil. Când am plasat comanda site-ul s-a stricat de tot – atât de tare încât site-ul nu se mai încărca deloc, și nu a mers vreme de vreo oră.
Erau începuturile e-commerce-ului în România, și lucrurile erau interesante – oamenii își dădeau numerele de telefon pentru că nimeni nu avea încredere să plaseze comanda doar online((Plată cu cardul? Hai să fim serioși, doar prin 2007-2008 a apărut prima soluție românească de plată cu cardul.)). Așa că am pus mâna pe telefon((Nokia 3310, pentru curioși, cu Badinerie ca ringtone)) și am sunat, și acolo o secretară agitată mi-a răspuns: „ați plasat comanda? ăăă, stați să vedem, acum pornește PC-ul cu icomersu’”. Nu e glumă, femeia de servici le mișcase ștecherul care alimenta serverul. Unul singur.
Spuneam în articolul anterior că o să vorbim despre cum arată un site de e-commerce făcut de o persoană și de ce alte site-uri de e-commerce cer o echipă de 5-10 oameni vreme de câțiva ani pentru a fi implementate. Cred că exprimarea mea e greșită: posibil ca cele două site-uri să arate la fel. Mai important este să subliniem care sunt diferențele.
Fascinația cu e-commerce e naturală. O afacere vrea să-și facă un magazin online – cerere există întotdeauna. Există și oferte: azi până și Facebook încearcă să-ți vândă spațiu de magazin online((evitați, Facebook e otrava internetului, o să ajungeți să plătiți mai mult decât câștigați)). Dar problema pornește din facultățile de IT, unde una din temele favorite pentru lucrările de licență e „site de e-commerce”. Aparent, toată lumea știe să facă, pentru că e vorba de ceva simplu. Și, serios, e vorba de ceva simplu. Ia uitați-vă pe site-ul Amazon: Ai o pagină cu ofertele speciale, după care ai o pagină pentru fiecare produs în parte, care are recomandări cu alte produse, un buton de căutare, după care ai check-out-ul și ‘coșul de cumpărături’. Mai sunt și alte chestii, dar mărunte.
Fiecare student care termină o facultate de calculatoare e ferm convins că poate implementa un site de e-commerce și cel mai des o și face. Ce e mai grav e că aproape fiecare antreprenor din România crede același lucru: că un magazin online e o treabă simplă, și crede că ar trebui să investească mai mult în alte părți decât în magazinul propriu-zis.
Și când defalchezi problema magazinului online e o chestie foarte simplă, Ai cinci-șase tipuri de pagini care trebuie să meargă bine. Studentul ăla e ferm convins că e ușor de făcut, și uite-l cum a venit cu o soluție care, e adevărat, merge cam prost pe laptopul lui. Luăm un calculator mai puternic și gata. Antreprenorul chiar are un gust amar de satisfacție în gură, pentru că simte că a făcut ceva foarte biznis: „a aruncat bani în problemă” (adică a luat un calculator mai puternic). Magazinul online e gata, și îl pune să-l vadă toată lumea.
Cei mai mulți se opresc aici și foarte multe site-uri nici măcar nu au propriul PC pe care stau – au un calculator închiriat într-un data-center, cel mult, și și pe acela poate îl au în regim VPS (adică spațiul și timpul de calcul e împărțit cu mai multe domenii). Comenzile încep să curgă (cinci-zece comenzi pe zi e un vârf pentru un magazin online la început) și antreprenorul e mulțumit. Când site-ul începe să se miște prost cumpără un calculator mai puternic, și unul mai puternic până când ajunge la o limită la care își dă seama că, stai, când ai doi clienți simultan în site își amestecă comenzile între ele pentru că studentul a gândit lucrurile școlărește((situație întâlnită în realitate)). După ce se chinuie cu studentul care e de negăsit să-i repare site-ul, antreprenorul merge la o firmă de apartament, care are mai multă experiență.
Mai toate firmele de apartament au o soluție de e-commerce. Nu poți să-ți faci firmă de apartament fără o soluție de e-commerce, o lucrare de diplomă oribilă a unui membru fondator al firmei, sau ceva similar. O soluție bastardizată, cu tehnologii ceva mai scumpe sau mai complicate, care ar putea satisface un client mediu (care vrea mai mult de doi oameni simultan pe serverul lui). Genul de soluție pentru care ai concedia un angajat, dar fiind soluția construită de membrul fondator al firmei e o soluție venerată, refolosită. Evident, nimeni nu are curajul să îi spună că e o porcărie pentru că în IT, ca în toate domeniile, nimic nu merge mai bine decât lașitatea și lingușirea.
Așa că firmele de apartament vin cu soluțiile astea „enterprise”, soluții slabe calitativ care nu rezolvă probleme precum scalabilitate. Asta pentru că orice angajat care ar ști să scrie „scalabilitate” s-a dus deja la o firmă mare. Așa că pentru antreprenorul nostru soluția funcționează până când vrea să scoată la vânzare de Black Friday trei cutii de pește aproape de termenul de expirare. Atunci vin la tine pe site 20-30 de oameni și ți-l dărâmă, pentru că lucrul făcut prost e făcut prost de la început. Așa că antreprenorul merge la firmele mari unde află că o soluție de e-commerce are un preț care se scrie cu cel puțin șase zerouri în coadă, și în monedă euro.
De ce?
Am vorbit mai sus despre ce se întâmplă, dar nu am explicat coordonatele eșecului pentru fiecare din pașii respectivi. Vorbesc despre trei probleme diferite, trei elemente foarte importante din poveste: dificultățile problemei, capacitatea programatorilor de a produce programe performante și capacitatea antreprenorului de a controla dezvoltarea soluției.
Dificultățile unui site de e-commerce
O soluție de e-commerce e un exemplu clasic de „interfață prietenoasă peste o bază de date”. Pe scurt, o bază de date e un sistem în care se stochează informațiile. Toate informațiile sunt puse „într-un singur loc”. Asta înseamnă că informațiile despre utilizator, de exemplu, sunt de obicei în același loc cu informațiile despre produse și cu toate celelalte date necesare pentru un site funcțional.
Bazele de date trebuie să asigure consistența datelor, și pentru asta genul de „gimnastică” pe care softul de baze de date trebuie să-l facă devine foarte complex, mai ales când ai doi clienți care vor să scrie și să citească în același timp. Iar faptul că soluția de baze de date are probleme complexe de rezolvat o face o soluție lentă.
Acum închipuiți-vă următorul lucru: un utilizator face o cerere pe site-ul vostru. Programul care ascultă cererea începe și face câteva cereri către baza de date (să valideze drepturi de acces, să citească informațiile despre produse, să modifice coșul de cumpărături, etc.). Fiecare cerere ia câteva milisecunde, doar că într-o secundă sunt doar 1000 de milisecunde. Asta înseamnă că un client care dă un click pe un produs ar putea să-ți ocupe serverele vreme de 200-300 de milisecunde (într-un caz fericit). Dacă o astfel de cerere ia 300 de milisecunde, înseamnă că nu poți deservi mai mult de 3 clienți într-o secundă, adică undeva la 200 de clienți într-un minut. Și asta în condiții ideale.
Realitatea e însă mult mai complexă, și e foarte posibil ca anumite cereri să poată fi executate în paralel. Există extreme – există baze de date gigantice (de exemplu Google) unde cererile unor clienți sunt satisfăcute în 400 de milisecunde (uitați-vă la timpul pe care îl afișează Google după fiecare căutare), și există baze de date de dimensiuni mici (undeva la 2-5 MB de date) unde pentru a face anumite operațiuni durează mai mult de 24 de ore. Pentru că oricâtă performanță ar avea sistemele de baze de date sau serverele web, liantul este programatorul care le pune în valoare.
Programatorii nu au niciodată controlul aplicațiilor pe care le dezvoltă
Există o problemă în lumea programatorilor: e programarea inginerie sau muncă de creație? Din multe puncte de vedere e inginerie, însă inginerie fără nicio noimă. E foarte mult „trial and error” în munca de programare, prea mult pentru a fi ceva la fel de precis precum ingineria, unde planificarea trebuie să prevadă problemele pe care produsul final le va întâmpina. În multe feluri e mai ușor să construiești o casă decât o soluție software. Pe de altă parte mulți programatori consideră că munca lor e muncă de creație, pentru că în ciuda identificării unor șabloane, unor soluții standard, soluțiile trebuie întotdeauna adaptate. Nimeni nu merge la muncă să facă de două ori același lucru. Cel puțin teoretic.
Ce e cel mai important e că munca de programator nu e întotdeauna o muncă precisă. Un programator care îți va scrie o bucată de cod nu va putea să îți spună că o anumită operație se va executa în atâtea milisecunde pentru că sunt nenumărate variabile care pot influența timpul de execuție al programului. Din punctul ăsta de vedere mie mi-e greu să văd munca de programare ca și inginerie.
Se râde întotdeauna de această incapacitate a programatorilor de a estima comportamentul programelor pe care le scriu, însă povestea nu e deloc amuzantă. Gândiți-vă că fiecare șurub pe care îl pune un programator în construcția lui e gândit de un alt om. Nu fiecare șurub e rotund, nu toate au capul la fel și fiecare vine cu cheia lui pentru închidere. O interfață de programare poate avea câteva mii de intrări, fiecare cu documentația ei, fiecare făcând o operație diferită.
Ăsta este motivul pentru care programatorii adoptă foarte repede așa-numitele framework-uri, care sunt menite să ușureze munca programatorului, să îl facă mai productiv. Fiecare din framework-uri însă e suficient de limitat încât în momentul în care ai nevoie de ceva special sau de mai multă performanță, va trebui să coboare la un nivel mai jos și să-și facă munca într-o zonă în care nu se simte deloc confortabil.
Cel mai des, framework-urile care îi fac productivi la început îi fac mult mai lenți după aceea. Gândiți-vă că framework-ul e o casă care vine gata făcută, tu trebuie doar să pui ceva material ici-colo ca să arate cum vrei tu. În momentul în care ai de mutat un perete, de spart, sunt șanse ca toată casa să se dărâme, că ție ți-a venit scheletul de-a gata și dacă îi muți ceva s-ar putea să dărâmi construcția cu totul. Sigur, vorbind de software, totul poate fi făcut configurabil.
Așa că framework-urile astea devin un iad de configurabilitate, de opțiuni, și programatorii încep și investesc toată energia pe care o au în cunoașterea acelui framework pentru a-l folosi cât mai eficient și pentru a-i afla limitările. Numai că invariabil toată lumea ajunge la un punct unde nu se poate scoate mai mult din unealta pe care o folosește. Uneori nu poți rezolva totul cu un ciocan, e nevoie de o bormașină. Dar nu poți folosi în același proiect și un ciocan și o bormașină, nu când vine vorba de software.
Acesta e doar unul din motivele pentru care programatorii nu devin stăpânii uneltelor pe care le folosesc, ci sclavii lor. Opțiunile programatorilor sunt limitate de unelte. Dar de ce e nevoie de unelte atât de complicate?
O soluție software permite prea multă flexibilitate
Cerințele proiectelor software sunt în continuă schimbare și din cauza programatorii trebuie să fie pregătiți să adapteze proiectul la cerințele noi. De ce atâta flexibilitate? Pentru că e simplu să faci anumite schimbări în software și să satisfaci clientul cu o schimbare mică. Numai că antreprenorul nu știe niciodată care schimbări vor necesita să arunce ce s-a muncit până acum la gunoi sau nu. Un font mai mare? Sigur. Un font diferit între diversele produse? Se poate, un pic mai greu (și un pic mai costisitor ca performanță). Mutat articolul ăla la stânga cu doi centimetri? Uneori poate fi imposibil. Produs cu același nume și poză diferită? Depinde. O pagină dinamică cu produse care se schimbă? Da, sigur, dar asta înseamnă că baza ta de date va fi ocupată non-stop cu faptul că produsele sunt tot cerute și re-cerute la infinit.
Din nou, simplificăm. Ideea e simplă: antreprenorii nu au habar cum se conduce un proiect software, și poate că nici nu ar trebui. Dar de foarte multe ori cineva care are un contact cu „omul cu bani” va ezita să spună „nu”, în ideea că acesta ar trebui să-l mulțumească pe cel care plătește. Corect din multe puncte de vedere, dar odată cu această flexibilitate cresc costurile invizibile pentru client la momentul dezvoltării precum performanța și costul de exploatare a soluției.
Echivalentul ar fi că antreprenorul merge la McDonalds și comandă un sandwich. Nu știe ce anume vrea, așa că omul de la McDonalds îi arată zece machete de posibile sandwich-uri. Antreprenorul ia în mână sandwich-ul dorit (machetă), îl miroase și spune: „ăsta, dar aș vrea să miroasă un pic mai bine”. Omul de la McDonalds însă nu poate să meargă să facă de la început un sandwich, pentru că antreprenorul, agitat, spune că uite, sandwich-ul e aproape gata, de ce durează atât de mult? El a vrut sandwich-ul ăla și doar să miroasă un pic mai bine. Evident că nu poți să-i dai macheta, dar ar trebui sa ai zece sandwich-uri gata făcute, să i le și servești. Să zicem că le ai, și i-l servești. Antreprenorul se uită la el și zice: „Da, e fain, numai că aș vrea carnea să fie un pic mai groasă, un pic mai albicioasă, brânza ceva mai puțin topită și legumele să fie ca la sandwich-ul ălălalt”. Așa că îi mai faci unul, și încă unul, și încă unul pentru că se poate.
Site-ul de e-commerce e cea mai mare capcană în care poate intra cineva. E genul de proiect pe care poate să ți-l facă și un student, dar care a făcut pe Amazon să aibă mii de programatori angajați. În site-uri de e-commerce intră direct sau indirect milioane de linii de cod (luând în calcul și framework-urile folosite). Și se discută pe internet că fiecare linie de cod are un potențial de vreo două buguri. Doar gândiți-vă la cifrele astea.
Aștept întrebări și sugestii pe viitor. În urma votului de săptămâna trecută, următoarele două teme sunt mitul programatorului genial și cât de tari sunt programatorii de la firmele mari. Cum ziceam, aștept în continuare întrebări și sugestii; și am o întrebare pentru voi: Ați asculta un podcast pe tema asta?