Z perspektywy kodu

Współczesne systemy e-commerce to bardzo złożone organizmy, które oplecione są dziesiątkami najróżniejszych zależności. Tym razem spojrzę na nie oczami programisty.

Mimo tego, że użytkownik końcowy widzi jedynie „najzwyklejsze” sklepy internetowe i to mniej lub bardziej podobne do siebie nawzajem, to w rzeczywistości ich wewnętrzna architektura różni się diametralnie w zależności od konkretnego wdrożenia. Jednym z głównych czynników, które potrafią znacząco podnieść poziom komplikacji projektu (a co za tym idzie – ogólne jego koszty) są nieprecyzyjnie, albo przeciwnie – zbyt precyzyjnie sformułowane wymagania. Szczególnie, gdy ich rzeczywiste znaczenie dla całej realizacji zostanie niewłaściwie ocenione. Jak na tego rodzaju problemy zapatrują się programiści i dlaczego za ich sprawą „trywialne” sprawy urastają czasem do rangi klęsk żywiołowych skutkujących opóźnieniem projektu – o tym postaram się pokrótce opowiedzieć m.in. na podstawie doświadczeń nabytych w Grupie Unity.

dziecko-programowanie

Operacja na otwartym sercu

Większość projektów e-commerce o odrobinę większej skali niż sklep prowadzony przez jakiegoś niezbyt popularnego blogera, który oferuje swoim czytelnikom koszulki z nadrukowanymi złotymi myślami własnego autorstwa, musi zmagać się z problemem dużego, a przynajmniej nieregularnie skaczącego ruchu. Innymi słowy musi być przygotowana na to, by niezależnie od zainteresowania klientów w danym dniu, każdy z nich mógł w ich serwisie przejrzeć ofertę, a najlepiej również dokonać zakupu bez długotrwałego oczekiwania, czy oglądania białych stron i komunikatów o błędach. Nie zawsze da się to osiągnąć w najprostszy możliwy sposób, czyli przez zakup lepszych serwerów. Niekoniecznie z powodów ekonomicznych. W przypadku dużych serwisów samo ulepszenie maszyn zazwyczaj nie wystarcza, a jeśli nawet to na krótko. Alternatywne rozwiązanie, czyli dokładanie dodatkowych komputerów nie jest jednak możliwe bez zmian w architekturze aplikacji. Okazuje się to często bardzo trudnym problemem, szczególnie jeśli na etapie projektowania nie wzięto takiego scenariusza pod uwagę lub gorzej – gdy wiele typowych recept na przeprojektowanie problematycznego procesu zostanie wykluczonych przez restrykcyjną specyfikację wymagań.

 

Między szybkością a dokładnością

1387982_circuit_board_1

Jednym z typowych oczekiwań względem zespołu realizującego projekt, jest minimalny czas propagacji zmian i ciągła aktualność treści. Co to oznacza mówiąc „po ludzku”? Coś niesłychanie prostego – zapewnienie, że jeśli operator serwisu coś „wyklika”, to błyskawicznie pojawi się to w formie widocznej dla jego klientów i zostanie uwzględnione we wszystkich transakcjach. Dlaczego jest to tak problematyczne? Ano dlatego, że jedną z głównych technik optymalizacyjnych stosowanych w aplikacjach internetowych jest stosowanie tzw. cache. Cache to inaczej pamięć podręczna, do której program zapisuje wyniki długotrwałych lub mocno obciążających obliczeń, tak by przy następnym do nich odwołaniu nie trzeba było przeliczać ich na nowo. W zależności od charakteru tych obliczeń cache przyjmuje bardzo różne kształty. Może być w nim przechowywana cała strona główna serwisu, jeśli jest prezentowana tak samo dla każdego odwiedzającego, może znaleźć się w nim jakaś forma pośrednia danych służących do obliczania ostatecznej ceny produktu, lub cokolwiek innego. Różne są też metody przechowywania takiej pamięci podręcznej. Czasem stosuje się zwykłe pliki, czasem alternatywne bazy danych, a czasem jakieś dedykowane, niesłychanie skomplikowane rozwiązania. Niczym niezwykłym nie jest także stosowanie tzw. czasu życia (ang. lifetime), czyli wymóg automatycznego odświeżenia danych w cache po upływie określonego czasu. W zależności od charakteru problemu wdrożenie takiego rozwiązania lub rezygnacja z niego może nieść za sobą sporo problemów, warto więc zawczasu zastanowić się nad urealnieniem swoich żądań. Zapewnienie odświeżenia danych najpóźniej po 10 minutach jest często równie korzystne biznesowo jak odświeżanie ich natychmiast, ale realizacyjnie w żadnym wypadku nie jest to bez znaczenia.

Chcę wiedzieć, co robisz

Kolejnym klasycznym źródłem problemów jest wymóg nieograniczonego monitoringu poczynań użytkowników. Owszem, historie ich transakcji, dane statystyczne i inne tego rodzaju informacje mają niebagatelne znaczenie dla zleceniodawcy systemu, bywają też uwarunkowane prawnie. Wątpliwości powinny jednak pojawić się w chwili, gdy pojawi się pomysł zażądania zapisu historii „wszystkich” operacji. Trudności jest przy tym cała masa. Pierwszą z nich jest objętość takiego dziennika. Przy założeniu, że serwis ma około 500 odwiedzin dziennie (nie tak dużo), z których każda skutkuje wykonaniem około 100 żądań przez przeglądarkę (nic nadzwyczajnego, jeśli liczyć pobieranie przez nią obrazów z serwisu, asynchroniczne doładowywanie treści etc.) i każde z tych żądań powinno być zapisane w historii i opatrzone takimi danymi jak adres IP klienta, data i godzina, adres URL żądania i status odpowiedzi (absolutne minimum, razem mniej niż 500 bajtów), to nasz serwis dziennie będzie produkować ok. 25MB danych, co daje prawie 9GB rocznie (równowartość 2 filmów na DVD). Już tak minimalna objętość danych jest trudna do analizy w czasie rzeczywistym. A co w sytuacji, gdy ruch będzie większy, a dane bardziej szczegółowe, opatrzone np. dokładnymi informacjami o zalogowanym użytkowniku celem późniejszej identyfikacji? Osiągnięcie setek gigabajtów rocznie jest łatwiejsze niż można by przypuszczać. Oczywiście można by machnąć na to ręką i powiedzieć, że pamięć dyskowa jest przecież tania i że tych dzienników nie trzeba przechowywać w nieskończoność. To wszystko prawda, ale problem z zapisywaniem wszystkiego ma też zupełnie inne, poważniejsze konsekwencje. Przede wszystkim utrudnia korzystanie z cache. Zapis informacji historycznych wyklucza bowiem ograniczenie angażowania głównego serwera w przygotowywanie odpowiedzi na żądania o jakiekolwiek zasoby. Utrudnia przenoszenie multimediów na dedykowane im  maszyny. Spowalnia zwracanie odpowiedzi, bo zapis dziennika wymaga czasu. Jednym słowem wywołuje mnóstwo problemów, które można by niesłychanie prosto rozwiązać jasno określając, jaki rodzaj danych historycznych jest naprawdę niezbędny.


Systemy zewnętrzne i synchronizacja

732365_business_meeting

Kolejnym problemem jest specyfikacja współdziałania z systemami zewnętrznymi. To codzienność dużych systemów e-commerce. Współpracują one z różnymi programami firm zewnętrznych, np. systemami typu ERP, CRM, starymi aplikacjami odpowiedzialnymi za gospodarkę magazynową, nowoczesnymi kombajnami do analiz z zakresu business intelligence, z dostawcami różnych usług jak kurierzy, czy operatorzy płatności internetowych etc. Każde z ogniw takiego łańcucha może mieć jakieś słabe punkty, a im więcej danych między nimi przepływa, tym więcej problemów może to rodzić. Naturalna staje się potrzeba kontroli tej komunikacji, ale czasami jesteśmy w stanie mocno uprościć projekt, przyjmując nieco bardziej liberalne założenia biznesowe. Programiści zwykle są, oczywiście, w stanie zrealizować przedłożone im specyfikacje, ale czasem zapewnienie pewnej tolerancji dla niektórych anomalii może być znaczącym ułatwieniem realizacyjnym, a co za tym idzie mocno obniżyć koszty. Dobrą ilustracją takiej sytuacji jest powiadamianie jednego systemu o zdarzeniach w drugim. Często luźne założenie w rodzaju „jeśli powiadomienie nie zostanie odebrane poprawnie, to trudno”, jest wystarczająco dobre biznesowo, nie ma poważnych konsekwencji i nie okazuje się gorsze od „jeśli powiadomienie nie zostanie odebrane poprawnie, to ponawiaj do skutku”. W drugim przypadku należy stworzyć kompletny system automatycznego ponawiania, analizować statusy, przetwarzać komunikaty o niepowodzeniach… Poziom komplikacji rośnie w sposób niewspółmierny do wagi problemu.

Co z rozbudową?

Ostatnim punktem, który trzeba mieć na uwadze podczas przygotowywania wymagań jest kwestia późniejszej rozbudowy programu. Należy pamiętać, że im więcej wysiłku poświęcimy by osiągnąć jedne cele, tym trudniej będzie nam uzyskać inne, a czasem będzie to w ogóle niemożliwe bez kompletnej przebudowy aplikacji. Wprowadzenie jednej zmiany może wykluczyć wprowadzenie innej, oczywiście przy tych samych założeniach początkowych. Idealne rozwiązania nie istnieją, ale nie chodzi przecież o to, by osiągnąć ideał, tylko o to by wraz z ekspertami zbudować rozwiązanie, które podoła naszym rzeczywistym oczekiwaniom. Będzie użyteczne dla klientów, zrealizuje nasze cele biznesowe i na dodatek zmieści się w budżecie. Żeby to jednak nastąpiło, musimy zdawać sobie sprawę z konsekwencji formułowanych przez nas oczekiwań, tak żeby realizacja ich spisanej wersji rzeczywiście odpowiadała temu, co wyobrażaliśmy sobie na starcie projektu. Nie musimy dokładnie znać wszystkich szczegółów technicznych, ale dla własnego dobra powinniśmy zaufać specjalistom. Sukces całego wdrożenia leży w końcu również w ich interesie.

 

Tagi: , , ,

O Autorze

Adam Kopeć

Programista PHP w Grupie Unity. Wiedzę teoretyczną zdobył dzięki studiom Informatyki Stosowanej na Wydziale Inżynierii Metali i Informatyki Przemysłowej AGH. W praktyce systemy e-commerce poznaje dzięki pracy w Grupie Unity. Prywatnie fan gitary, postmodernizmu w literaturze i jazzu.

Back to Top