iqApp - CMS & Framework

iqApp este produsul mai multor ani de programare in PHP, si dupa ce am facut multe greseli cu el, a ajuns ceea ce este astazi: bazat pe Yii2, modular, multi-language, optimizat pentru viteza, integrat cu CDN, interfata user friendly, iar back-end poate fi inclus in alte aplicatii compilate pentru PC, MacOS, iOs, Android si Linux.

Am inceput sa creez site-uri si aplicatii web in PHP pur. Dupa mult cod si functii reutilizate de la un proiect la altul, am pus bazele unui framework PHP propriu "closed source", pe care l-am denumit qEngine. "q" fiind prima litera a tastaturii "qwerty", iar "engine" pentru ca l-am vazut ca un motor pentru aplicatii web, cu precadere site-uri de prezentare, portaluri si magazine online.

qEngine alpha a reprezentat tot codul pe care l-am scris in PHP pentru diferite proiecte, si nu exista in forma unui framework de sine statator, ci mai multe proiecte avand niste librarii comune.

Aceasta forma a avut si brese de securitate, si intr-una din zile m-am trezit cu un cap de drac pe site-ul unui client. Asa ca m-am apucat serios sa invat despre securitatea in PHP si Apache.

Din nevoia de a separa codul HTML de partea logica, am scris si un template engine propriu, destul de rudimentar.

Timpul de generare a unei pagini varia intre 130ms, pentru un o pagina simpla, si >3s pentru pagina unui portal de job-uri.

 

qEngine v1 a fost o incercare de standardizare a functiilor si a codului in firma unde eram angajat si asociat in 2009. Astfel ca am creat acest framework ca si produs software de sine statator in PHP pur, bazat pe experienta anterioara, extensibil prin module si suporta teme.

Cu acest framework am minimizat HDD IO usage, stocarea pe SSD era prea scumpa la acea vreme, folosind cateva fisiere cu functii specifice scopului: strings, url, array, core, etc. qEngine v1 putea functiona fara o baza de date, paginile fiind stocate in format html. Pentru aplicatii mai complexe precum blog sau magazin online, era nevoie totusi de o baza de date.

Am renuntat la template engine-ul din varianta alpha si am ales Smarty.

Desi functiona excelent si atingea performante mari comparativ cu ce exista la momentul respectiv in materie de CMS cunoscut (Joomla si Wordpress), totusi a prezentat foarte multe inconsistente in cod si organizare neclara. Avea o interfata de administrare ultra-simpla si redusa la minimul necesar de elemente. La inceput folosea doar 2-3mb de memorie.

Modulele si functiile noi le scriam la nevoie, pe masura ce clientii le cereau.

Astfel ca pe qEngine v1 au functionat site-uri de imobiliare, ziar online, anunturi, magazine online, reteaua de advertising Bointer, si multe site-uri de prezentare, etc.

Pe masura ce dezvoltam module pentru qEngine am optimizat framework-ul pentru viteza. Portalul de job-uri care a ramas pe qEngine alpha a ajuns sa genereze pagina cu listare job-uri in 800ms, dar nu era destul. In orele de trafic mare, ingenunchea serverul. Am creat un sistem de caching care a redus generarea paginii de job-uri pana la ~150ms.

In plus, am intampinat greutati sa fac framework-ul multi-language dar si multi-currency pentru modulul de magazin online si modulul de imobiliare. Am reusit, dar a trebuit sa fac niste improvizatii.

Pentru acest framework am creat ~40 de module.

 

La sfarsitul lui 2011, am decis ca trebuie sa imbunatatesc fundamental acest framework. Asa am creat qEngine v2. Avand in minte o imagine mult mai clara cu privire la ceea ce doream de la acest framework nou, am creat qEngine v2 mult mai bine optimizat pentru viteza, structura logica, modular si multi-language.

Interfata de administrare a fost mai atractiva, mai usor de utilizat, user friendly si multi-language.

Tema din back-end nu a fost responsive si a fost creata integral de mine in HTML 4 Transitional si CSS. Am creat elemente predefinite: tabele, butoane, imagini, etc si zona de tutoriale in functie de modul.

Ca template engine am folosit in continuare Smarty.

Toate js-uri si css-urile le-am compactat in cate doua fisiere. Am implementat si un js packer, care comprima la gramada scripturile in timp real si cache pentru a le servi rapid ulterior.

Am continuat lucrul la sistemul de caching si am inventat un sistem de "caching agressive". Prin acest sistem am redus aproape de 0 solicitarea serverului, prin sacrificarea a 1-2 Gb pe server, pentru un site de ~6000 de oferte imobiliare. Partea grea nu a fost salvarea unui document HTML si livrarea lui ulterioara, ci modul de cache refresh ca sa apara pe site modificarile in timp real. Acest cache agressive nu poate fi implementat in orice proiect, pentru ca ar necesita mult prea mult spatiu de stocare.

In plus, am creat un mecanism de predictie a click event, si se acceseaza in fundal pagina pe care urmeaza sa se dea click cu cateva zeci de milisecunde inainte de event, astfel se creaza cache-ul in fundal, iar browserul va incarca pagina din cache. Fa-i o proba: http://acropola-reb.ro/oferte-imobiliare/sale/

Pe server ruleaza un sistem LNAMP, iar Nginx este configurat sa livreze fisierul cache daca exista (chiar si HTML), else trimite requestul spre Apache+PHP. Astfel ca viteza unui site se reduce la latimea de banda a serverului, si nu prea conteaza cati vizitatori acceseaza site-ul. Primul vizitator al unei pagini va genera cache-ul, restul vor accesa pagini din cache. Main server are doar 2Gb Ram, quad core XEON, virtualizare OpenVZ si serveste lejer cam 3 600 000 de requesturi pe luna, in mare parte PHP sau pagini din cache, pentru ca fisierele statice (poze, js, css, etc) sunt cache-uite in Cloudflare. Incarcarea serverului este data de alte site-uri ce folosesc Wordpress sau qEngine v1.

O alta problema a fost ca cei 75Gb SSD se umplusera. Unele site-uri ocupau peste 4Gb, fara cache.

Asa ca am creat o CDN ce consta din mai multe servere VPS de stocare ieftine 128-256Mb ram, si un load balancer NGINX pe serverul master. Acest load balancer verifica prin metoda HEAD existenta fisierelor si distribuie request-urile care serverele slave, astfel ca orice server slave se poate opri/bloca/muta, etc, fisierele din CDN continuand sa se incarce din alte alternative. Pentru anumite site-uri, qEngine v2 face upload automat a continutului media pe serverul master, urmand ca serverul master sa sincronizeze pe serverele slave in 30 minute. Pentru ca load balancer-ul verifica existenta fisierelor inainte de a redirectiona request-ul, CDN poate fi partial sincronizata, continutul se va incarca dintr-un server care are fisierul disponibil.

Acest CDN adauga un mic delay fisierelor media, dar fiindca este pe un alt domeniu decat cel al site-ului, se incarca in paralel cu site-ul si nu afecteaza incarcarea totala paginii. In cele mai multe cazuri, acest delay este insesizabil.

Optimizand in asa maniera qEngine v2, impreuna cu CDN, am incarcat main serverul cu peste 130 de site-uri si inca mai e loc ca utilizare CPU & RAM, in acelasi timp optimizand costurile cu hosting-ul.

Pentru qEngine v2 am creat peste 20 de module: e-commerce, blog, anunturi, galerii foto/video, cataloage, imobiliare, administrare utilizatori, etc.

 

Inca de la inceputul qEngine alpha, mi-a fost greu sa dezvolt module si functionalitati, pentru ca unele necesitau mult timp pe care unele proiecte nu il permiteau. jQuery si multele sale plugin-uri m-au salvat pe parte de Javascript, dar a trebuit sa scriu tot ce tine de PHP. Intr-un fel a fost bine, pentru ca asta mi-a permis sa invat PHP, sa descopar cum trebuie sa fie structura logica a unui framework, sa fac foarte multe greseli si sa invat din ele.

qEngine v2 a fost mult imbunatatit si eram foarte multumit de el, totusi ma omora update-area lui in permanenta cu trendurile. Front-page-ul putea avea orice fel de tema (responsive sau nu), dar back-end-ul necesita timp sa-l trec pe Bootstrap. Luasera avant mobilele si iarasi am avut nevoie sa fac upgrade.

Asa ca la sfarsitul 2014 am decis sa rescriu qEngine v3 bazat pe un framework cu o comunitate solida in spate, pentru a nu mai reinventa roata de fiecare data. Am analizat mai multe framework-uri existente, si cel mai interesant mi s-a parut Yii din urmatoarele puncte de vedere:

  • pregatit pentru PHP7
  • mecanisme de cache
  • rapid si low memory footprint, incarca in memorie aproximativ doar ce foloseste intr-un request
  • suport pentru template engine, desi am renuntat la Smarty in favoarea PHP
  • comunitate activa in spate
  • o multime de module deja scrise
  • suport theming
  • suport i18n
  • learning curve
  • OOP
  • posibilitate de a fi si aplicatie de server

Am facut cateva incercari, dar am renuntat la dezvoltarea qEngine v3, pentru ca se lansase Yii2, care era si mai avansat. Mai ales fully OOP.

iqApp v4Asa ca la inceputul 2015 am creat qEngine v4, pe care l-am redenumit iqApp v4. Un CMS bazat pe Yii2.

Acest nou CMS este caracterizat de:

  • folosirea celor mai noi tehnologii si framework-uri: Yii2, composer, bower, jQuery, Angularjs, Bootstrap, font-awesome, etc.
  • mobile friendly in back-end prin folosirea de Bootstrap si, mai nou, Angularjs
  • PHP ca template engine
  • ulterior, modulele din administrare care folosesc Angularjs, pot fi compilate in programe de Windows, Linux, MacOS, iOs si Android
  • fully OOP
  • i18n
  • form-urile de introducere date in unele module, le vad dinamice, administrate chiar de user

Din lipsa de timp, am finalizat destul de putine proiecte cu acest framework:

  • www.ionut-grecu.com
  • www.cloudpro.ro
    • emitere facturi pentru hosting
    • urmarire incasari si notificari sms si email
    • plata cu cardul si prelungire automata serviciu
    • comanda/prelungire servicii
    • creare cont de hosting, instalare platforma aleasa de catre client si setup cont de servicii pentru facturare
    • inregistrare domenii
    • etc

Mai sunt cateva proiecte nelansate in zona de imobiliare si magazine online, dar nu am apucat sa le finalizez, deocamdata. Voi reveni cu noutati.

La iqApp v4 inca mai am de lucru sa optimizez request-urile catre server, acel caching agressive in varianta Yii2, ceva fix-uri in modulul de administrare, etc.

...

iqApp5 este noul...

Va urma...

Post Gallery