Szakdolgozat Miskolci Egyetem Gépészmérnöki és Informatikai Kar
Általános Informatikai Tanszék
Intézmény azonosító: FI 87515
3515 Miskolc-Egyetemváros
Feladat címe:
Elosztott közösségi alkalmazás, a Google maps API felhasználással.
Témavezető: Dr. Vincze Dávid
Készítette: Klusóczki Dávid BO5YD2 2015.05.01.
Tartalom 1.
2.
Feladat bemutatása .......................................................................................................................... 4 1.1.
Háttértörténet - Million Dollar Webpage ................................................................................ 4
1.2.
Szakdolgozat ötlete.................................................................................................................. 4
1.3.
Project Maps, mint egy mini Cloud ......................................................................................... 4
Használt programozási nyelvek és rendszerek bemutatása ............................................................. 6 2.1.
HTML...................................................................................................................................... 6
2.2.
PHP.......................................................................................................................................... 7 PHP - FPM ...................................................................................................................... 7
2.2.1. 2.3.
JavaScript ............................................................................................................................... 8 Google maps ........................................................................................................................ 8
2.4. 2.4.1.
JQuery ............................................................................................................................. 9
2.4.2.
Bootstrap ......................................................................................................................... 9
2.5.
MySQL .................................................................................................................................... 9
2.6.
GIT ........................................................................................................................................ 10
3.
Rendszerkövetelmények ................................................................................................................ 12
4.
Google maps API v3 bemutatása .................................................................................................. 13 4.1.
Bemutatás .............................................................................................................................. 13
4.2.
Kezdeti lépések...................................................................................................................... 15
4.3.
API bemutatása...................................................................................................................... 16
4.3.1.
Map Types ..................................................................................................................... 16
4.3.2.
Custom Style ................................................................................................................. 16
4.3.3.
Projection....................................................................................................................... 17
4.3.4.
Eventek .......................................................................................................................... 17
4.4.
Hátrányok, megszorítások ..................................................................................................... 18
5.
Fejlesztési ütemterv ....................................................................................................................... 20
6.
Rendszer áttekintés ........................................................................................................................ 21 6.1.
Backend ................................................................................................................................. 21
6.1.1.
Áttekintő ........................................................................................................................ 21
6.1.2.
Szerverek ....................................................................................................................... 21
6.1.3.
DNS, IP-k, Rendszertérkép ........................................................................................... 22
6.1.4.
Webszerver - Nginx ....................................................................................................... 23
6.1.5.
PHP ................................................................................................................................ 25
6.1.5.1.
Felhasználó kezelés ................................................................................................... 25 2
6.1.5.2. 6.1.6.
Adatbázis ....................................................................................................................... 26
6.1.7.
Hálózati adattár.............................................................................................................. 27
6.1.8.
Képgenerálás ................................................................................................................. 28 Frontend............................................................................................................................. 28
6.2.
7.
Email riport................................................................................................................ 25
6.2.1.
Saját funkciók ................................................................................................................ 28
6.2.2.
GUI ................................................................................................................................ 32
6.2.3.
Interakció a térképpel .................................................................................................... 33
6.2.4.
Helyi felhasználó ........................................................................................................... 33
6.2.5.
Facebook felhasználó .................................................................................................... 34
6.2.6.
Terlület foglalása ........................................................................................................... 34
További fejlesztési tervek .............................................................................................................. 35 7.1.
Paypal, kártyás fizetés ........................................................................................................... 35
7.2.
Google+ felhasználók ............................................................................................................ 35
7.3.
Design.................................................................................................................................... 36
7.4.
Kép linkről beszúrása ............................................................................................................ 36
7.5.
Facebook kép importálás ....................................................................................................... 36
7.6.
Rajzolás 256x256 pixelen...................................................................................................... 37
7.7.
CacheFS................................................................................................................................. 37
7.8.
Daemon működése ................................................................................................................ 38
7.9.
Multi Language ..................................................................................................................... 38
7.10.
Teljes cloud befejezése, PHP, SQL párhuzamosítás ......................................................... 39
8.
Összefoglalás ................................................................................................................................. 41
9.
Summery ....................................................................................................................................... 42
3
1. Feladat bemutatása 1.1. Háttértörténet - Million Dollar Webpage A szakdolgozat témája, illetve ötlet adója, már több mint egy évtizedes, mégis ötletességben és megvalósításban akár mai weboldal is lehetne. Akkoriban szinte egy időben jelentek meg cikkek az oldalról, miszerint az alkotója, Alex Tew, az egyetemi tandíjának finanszírozására létrehozott egy oldalt, ahol is olyan merész célt tűzött ki, hogy ő bizony 1 millió dollárt fog keresni.1 Az elgondolás a következő volt: Egy 1000 x 1000 pixeles képet rakott ki, kezdetben teljesen fehér színben. A szponzorok ezeket a pixeleket vásárolhatták meg, négyzetenként $1-ért. Cserébe beszínezhették az adott pixeleket, és linkké alakíthatták. A később megjelent újságcikkek, híroldalak hatására, megugrott az oldal látogatottsága, és harc indult a szabadon maradt hirdetési felületekért, amik hónapokon belül elfogytak, így készítője elérte
a
célját,
megkereste
az
első
millióját
dollárban.
Ironikusan
a
„milliondollarhomepage.com” domain címet választotta oldalának, ami szintén segíthetett sikerének.
1.2. Szakdolgozat ötlete Voltak további próbálkozások, amik az Alex által kreált érdeklődés szelét próbálták meglovagolni. De egy az egybe másolták az eredeti ötletet, hozzáadott új érték, vagy ötlet nélkül pedig a sikereik nagyságrendekkel elmaradtak az eredetitől. A koncepció mindnél ugyan az volt, adott négyzeteket lehet megvásárolni, más-más designal. Az ötletem kicsit kreatívabb környezetbe helyezi a dolgot. Mégpedig, hogy felosztjuk a Google mapset egységnyi négyzetekre, majd ezeket lehet lefoglalni. és saját képet helyezni, az eredeti térképre.
1.3. Project Maps, mint egy mini Cloud Minden weboldalnál kulcs az egyszerűség, arra kell rávenni a felhasználókat, hogy a lehető legtöbb időt töltsenek el az oldalon, ezért érdekes tartalmat kell elérhetővé tenni rajta.
1
Alex Tew bemutatás, interjú Forrás: http://www.theguardian.com/business/2006/dec/05/newmedia.workandcareers
4
A legegyszerűbb tartalomgenerálás pedig az, hogy ha a felhasználók saját maguknak, szórakoztatásból készítik el az oldal tartalmát. Ezzel a gondolattal indultam neki magának az oldalnak, hogy milyen funkciókat kéne megvalósítania. Még a fejlesztés korai szakaszában a „Project Maps” nevet kapta. Hogy az ötlet sikeres legyen, a marketing részét arra hegyezném ki, hogy bárki a Google Maps-en megváltoztathatja a lakását, vagy ismert emberek házát veheti meg, csupán $1-ért. A megvásárolt egységek végül pedig egy nagy montázst alkotnak a föld felszínén, érdekes lehet majd több hónap után megnézni, hogy miket rajzolnak ki így a feltöltött képek. Az alábbi funkciókat terveztem a rendszerbe: Bárki ingyen, publikusan hozzáférhessen az egész oldalhoz és annak tartalmához. Kattintásra lehessen megvenni egy egységnyi négyzetet a térképen, ahova a felhasználó felülírhatja milyen kép jelenjen meg. Ez ne legyen konkrét regisztrációhoz kötve, plusz adatok megadása nélkül lehetséges legyen. Ne csak fizetős része legyen, lehessen időkorláttal, pl. 2 hétre lefoglalni ingyen is egy négyzetet. Lehető legegyszerűbb megosztási lehetőséget facebookon. Ezzel az ötlettel vágtam bele a weboldalba, ami hamar túlnőtte magát ezen. Egy olyan cloud-szerű rendszert szerettem volna készíteni, ami hasonló felépítésű, mint maga a Google Maps, több szerver közösen dolgozva osztja meg a terhelés, és gyorsítja a kiszolgálást.
5
2. Használt programozási nyelvek és rendszerek bemutatása 2.1. HTML2 A web szabványos xml alapú leíró nyelve. Jelenleg az 5-ös verziójú szabványa a legújabb, és szélesen támogatott. A szabványokat a W3C (World Wide Web Consortium) szervezet állítja össze, nagy cégekkel közösen karöltve együtt tervezik az aktuálisan
megjelenő
webes
tartalmakhoz
elérhető opciókat. Jelen
HTML
5-ös
verziója
a
korábbi
hiányosságait pótolja, mint például a multimédiás tartalmak külső pluginek nélküli támogatása, 1. ábra Forrás: wikipedia.org
mobil eszközök támogatása, vagy gyakrabban használt adattípusok (dátum, szám, stb) natív
használata. Maga a HTML egy statikus weboldal, amely betöltéskor a böngészőbe megjelenik, onnantól programozható logika nincs mögötte, sem pedig lehetőség a HTML szabványon belül a tartalmak dinamikus változtatására. Ezen feladatokra a JavaScript hivatott a webes tartalmaknál. A megjelenítési stílusok pedig CSS-el valósíthatók meg, ezzel lehet olyan stílusbeli szabályokat megadni, amiket a böngésző végrehajtva a végső renderelési folyamatban legenerálja a tartalmat. Futásidőben ezt is csak szintén JavaScript-el lehet változtatni.
2
HTML szabvány bemutatása Forrás: http://w3.org
6
2.2. PHP3 A PHP az egyik jelenleg legelterjedtebb nyelv a dinamikus honlapok körében. Egy szerver oldali szkriptnyelv, amit egyszerű használni, és mivel széles körben használatos, tömérdek dokumentáció és példakód áll a rendelkezésünkre. Elsősorban szerver oldali weboldalakhoz fejlesztették ki, kisebb körben viszont általános programozásban is használják. Elterjedtsége a következő ábrán is megtekinthető:
2. ábra (2013) USA fejlesztői állások programozási-nyelvek szerint Forrás: http://themarble.co.uk/top-10-programming-languages
2.2.1. PHP - FPM A PHP-FPM relatíve egy rövid múltra tekinthet vissza a PHP értelmezők között, lényegében egy minimalizált erőforrás igényű CGI-ről van szó, amiben maga a PHP interpreter elkülönül a webszervertől, és olyan plusz funkciókat ad az adminisztrátorok kezébe, mint a teljesen elkülöníthető PHP processek, vagy a menet közbeni konfiguráció újratöltés.4
3 4
PHP bemutatása Forrás: http://php.net/ PHP-FPM bemutatása. Forrás: http://fastjoomlahost.com/mod_php-fastcgi-php-fpm-server
7
2.3. JavaScript 5 Elsősorban a weboldalak dinamikus tartalmának megjelenítésére, kliens oldali kódok futtatására, aszinkron
kérésküldésekre
használják,
de
manapság már megjelentek a szerver oldali JavaScript futtatására alkalmas rendszerek is. Előfordítatlan nyelv, futásidőben a böngészőbe épített parancsértelmező hajtja végre a kódunkat, soronként haladva. Elvégezhetjük vele például a felhasználók által megadott adatok validálását, 3. ábra Forrás: http://www.iconarchive.com
dinamikusan jeleníthetünk meg objektumokat, vagy
akár
az
egész
oldal
logikáját
is
programozhatjuk benne. 2.4. Google maps6 A Google Maps 2005-ben debütált, mint térkép szoftver, azóta a cég nagyon sok energiát, pénzt és munkaórát fektetett a projektbe. Saját és külső forrású műholdakkal az egész földről készített képeit, utcatérképeit tekinthetjük be, sőt a legújabb fejlesztéseikben akár,
mintha
megtekinthetjük gyalogosan
az a
készített
utcákat
járnánk,
korábban,
autókkal,
panoráma
képeket.
Sokoldalúságát lehetetlen lenne kifejteni pár 4. ábra Forrás: http://logos.wikia.com/wiki/Google_Maps
sorban, útvonaltervezőtől, domborzattérképen keresztül, az általunk készített mini-térképekig
szinte bármit megtehetünk, ami csak igényként felmerülhet egy térkép szoftverben. Szerencsére a Google olyan fejlesztői lehetőségeket is biztosít nekünk, amiben komplett saját alkalmazást írhatunk az övékét kiegészítve, testre szabva.
5 6
JavaScript Forrás: https://developer.mozilla.org/en-US/docs/Web/JavaScript Google Maps Forrás: http://en.wikipedia.org/wiki/Google_Maps
8
2.4.1. JQuery7 A jQuery egy olyan JavaScript könyvtár, ami arra hivatott, hogy a weboldalakon gyakran használt funkciókat, vagy a JavaScript natív hiányosságait pótolja. Felhasználói szemszögből nem nyúlt pluszt, viszont programozó szempontból nagyon kényelmes a használata, gyorsabban lehet benne fejleszteni, és a kiegészítő könyvtárai szinte kifogyhatatlanok. Eseményvezérlésekben gazdag, rövidített kódot, funkciógazdagabb objektumokat kapunk használatával, viszont, ha csak töredékét használjuk ezeknek a funkcióknak, megérheti natív JavaScript kódot alkalmazni. Ennek részletezését későbbiekben bővebben kifejtem. 2.4.2. Bootstrap A Bootstrap egy manapság elterjedt keretrendszer, a webes rendszerekhez. Előre összeállított JavaScript könyvtárral és CSS-el rendelkezik, amivel szintén arra hivatott, hogy a manapság elterjedt responsive weboldalakat, viszonylag könnyen készíthessünk. Beépített ikonjait, weboldal szerkezeteit egyszerűen, a html tagjeit osztályokhoz rendelve használhatjuk.
2.5. MySQL8 A MySQL jelenleg az Oracle tulajdonában lévő több felhasználós relációs adatbázis kezelő program. Nyílt forráskódú, és a webes világban az egyik legelterjedtebb az adatbázisok között. A projekt szempontjából eleinte ez, és a PostgreSQL voltak versenyben az adatbázis betöltésének szerepéért, de végül az Oracle adatbázis kezelő szoftvere miatt, a MySQL 5. ábra Forrás: http://logo-kid.com
Workbench miatt döntötte el a kérdést, mert
sokkal felhasználóbarátabb volt a fejlesztése benne, mint a PostgreSQL szoftverei.
7 8
Hivatalos weboldal Forrás: https://jquery.com/ Hivatalos weboldal forrás: https://www.mysql.com/
9
2.6. GIT9 A GIT egy olyan nyílt forráskódú szoftver, ami
nagy
projektek
fejlesztéskori
verziókövetését teszi lehetővé. Magát a forráskódot tárolja minden projekt esetében, és támogatja azt, hogy egy időben több fejlesztő
dolgozhasson
ugyan
azon
a
feladaton, és a végén az egyedi verziókat összesítve könnyen és gyorsan publikálható a program. Az üres fájloktól kezdve folyamatosan elmenti a sorok változásait, 6. ábra Forrás: https://git-for-windows.github.io/
hogy később bármilyen állapotra vissza
tudjon állni a projekt, illetve minden verzió forráskódja maradéktalanul meg legyen. Habár én egyedül dolgoztam a szoftveren, mégis úgy gondoltam, hogy belekóstolok abba a környezetbe, amiben a nagy projekteket fejlesztik, ha már úgyis nagy rendszert tervezek, valamint, hogy nagyobb rálátást és rutint szerezzek ebben. A legfőbb nyílt forrású projektek, amik szintén GIT-et használnak:
Linux-rendszermag
GNOME
Samba
X.org
VLC media player
Android platform
A forráskódom további külső felhasználását más fejlesztők által nem terveztem elérhetővé tenni, ezért saját GIT szervert állítottam be. Különleges beállításokat nem követel, felinstalláljuk a GIT servert, egy új repositoryt létrehozunk a projektnek, és Linuxos authentikációval már használhatjuk is GIT kliensekből. Mellékhatásként egy olyan historyt is kaptam a szakdolgozatból, amiben szépen visszakövethetők a nagyobb lépések, mérföldkövek.
9
GIT bemutatása Forrás: http://en.wikipedia.org/wiki/Git_%28software%29
10
Két dolog nincs mentve a GIT repositoryban:
Adatbázis szerkezet és azok adatai
Szerver konfigurációs fájlok
Egy érdekességként megfigyeltem a szakdolgozat dokumentációját készítve, mégpedig, hogy az Office állományokat, docx kiterjesztésű dokumentumot nem bináris állományként kezeli, hanem ezt is felismeri, mint szöveges állományt, és képes detektálni a sorok változását.
7. ábra Git, példa a mentett változtatásokról, Sourcetree programban
11
3. Rendszerkövetelmények Operációs rendszer tekintetében, csak a weboldal üzemeltetését nézve lényegtelen, hogy Windows-t, vagy Linux-ot használunk, de a projektem megvalósításához Linux rendszerre van szükség, különböző probléma megoldásaim, skálázhatóság, párhuzamosítás és jövőbeli fejlesztési tervek miatt a Linux tűnt optimális választásnak. Két, már productionben lévő szervert vettem igénybe, ahol:
Debian disztribúciók futnak 3.2.65-1 x64 kernellel.
A további részletezés majd a Backend részletezéséből derül ki. A böngészőkből érkező kérést a webszerver fogja megválaszolni. Ez lehet az egyik legelterjedtebb Apache, de választásom egy újabb fejlesztésre esett:
NGINX 1.6.2-1
A dinamikus tartalomért a PHP a felelős, alapértelmezetten Linuxon tartalmaz egy képkezelő libraryt, amit használok, Windowson külön telepítést igényel Apache-hoz, illetve IIS-hez is.
php5-fpm 5.4.36-0+deb7u1
Image Magick 6.9.1-2 library
Adatbázis közül MySQL-re esett a választás:
MySQL 5.5.40-0+wheezy1
12
4. Google maps API v3 bemutatása 4.1. Bemutatás A Google egyik legnépszerűbb alkalmazásához, a Google Maps-hez elérhető egy olyan függvénykönyvtár, amivel „Build highly customisable maps with your own content and imagery”, 10azaz készíthetünk saját képekkel, tartalommal olyan térképet, amit úgy szabhatunk testre, ahogy mi szeretnénk. Legalább is, ahogy az a függvénykönyvtárukban meg van engedve funkcióik által. Lévén, hogy egy térképről beszélünk, kezdem az alapoknál. A térképen minden egyes pozíciót a koordinátája jelképez, ha kiterítjük a földet síkba, akkor egy körbeérő koordináta rendszert kapunk, amelyben az X tengely a szélesség, Y tengely pedig a hosszúságot mutatja. A földet tekintve egy gömbről beszélünk, ami pedig 360 fokos, így tehát a szélesség koordinátákat egy 360 fokos skálára osztották fel, signed float értékre, ami a -180 és 180 intervallumon vehet fel értéket. Ezzel azt is megoldották, hogy egy egyszerű lépéssel sikerült keleti-nyugati részre felosztani a földet, ami a mínusz tartományban van, az a keleti, utóbbi a nyugati része a földnek. A hosszúsági koordináták hasonlóképp működnek, csak a -85 és 85 skála között vehetnek fel értékeket. Szintén igaz, hogy ezzel az egyenlítő alatti, illetve feletti részeket jelölik. Ezek a koordináták a „World Geodetic System” hivatalos szabványa szerint lettek kialakítva. Ezeket a koordinátákat a „Gall-Peters”11 féle vetületi koordinátákra kell alakítani, hogy ezekből végül pozitív float típusú koordinátákat kapjunk, használhatjuk a dokumentációban szereplő funkciókat. Ez lesz az úgynevezett „World Coordinate”, itt már mind az x, mind az y kordináták 0 és 256 közötti skálán mozognak. A távolból, a lehető legrészletesebb képekig való zoomolást úgy oldották meg, hogy a műholdakkal a lehető legtávolabbtól kezdve fokozatosan egyre közelítve elmentették az összes képet a földről. A kapott képeket felosztották 256 x 256 pixelesével, és így mentették el őket. Végül a Pixel koordinátáknak abban van szerepe, hogy pixelre pontosan megmondhassuk, melyik pixelre kattintott a felhasználó. Az alap 0 zoomnál ez megegyezik a World Coordinate-ekkel, mivel a megjelenő képek összessége 10 11
Google Maps developrt forium alapján Forrás: https://developers.google.com/maps/ Gall – Peters féle koordináta rendszer: http://en.wikipedia.org/wiki/Gall%E2%80%93Peters_projection
13
256x256 pixel. Ahogy viszont zoomolunk, minden kép négyzetesen lesz egyre részletesebb, így a World Coordinate értékeit 2zoom hatvánnyal kell szorozni. Hogy be tudjuk azonosítani pontosan melyik kép az, amelyiket nézi, illetve szeretné módosítani a felhasználó, Tile Coordinate-eket vezettem be. Észak-Amerikától észak nyugatra van az abszolút [x:0, y:0] koordináta, majd Az Antarktisznál, Ausztráliától jóval dél-keletebbre pedig az [x:MAX, y:MAX]. Amit úgy kaphatunk meg, hogy a Pixel Coortinate / 256, mivel a pixel koordináta pixeleket reprezentál, és egy kép 256 pixel széles illetve hosszú, így megkapjuk a pontos sorszámát a képnek. Maga a Google is így tartja nyilván a képeit, ha a böngészőben megfigyeljük a http kéréseket, láthatjuk, hogy a képek betöltésekor hasonló linkeket nyit meg: https://khms1.googleapis.com/kh?v=169&hl=enUS&x=38606&y=49247&z=17&token=94909
Ahol a „hl” és a „token” paraméter elhagyható. Ez a kép már egy mondhatni részletes képet mutat New York Central Parkjáról. Így külön, az API-n kívülről direkt hivatkozásként viszont nem lehet használni a képeket, csak szemléltetésképp mutattam be a működését. Példa koordinátaszámítás:
8. ábra Miskolci Egyetem Főépóletének képe 18-as zoom szinten. Forrás: maps.google.com
14
4.2. Kezdeti lépések Mielőtt neki kezdenénk, szükségünk van egy Google API hozzáférési ellenőrzött biztonságosan
kulcsra, hogy
körülmények lehessen
között, a
Google
szolgáltatásait használni. Ez nem csak a térkép szoftverére igaz, bármilyen szolgáltatást igénybe vehetünk a Google tárházából, csak egy egyedi kulcsot kell
hozzá
generáltatnunk.
Nagy
9. ábra Google Developer Console API kulcs
általánosságban ezeket ingyen szolgáltatják
igénylés
nekünk, viszont cserébe megszorításokat szab, hogy ne használjunk korlátlan erőforrásokat. A következő Google dokumentációból származó példában egy működő térképet hozhatunk létre: <script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?key=KULCS"> function initialize() { var mapOptions = { center: { lat: -34.397, lng: 150.644}, zoom: 8}; var map = new google.maps.Map(document.getElementById('map-canvas'), mapOptions);} google.maps.event.addDomListener(window, 'load', initialize);
A map-canvas azonosítójú div-be fogjuk betölteni a google.maps.Map objektumot, ami, mikor már az oldal betöltése befejeződött fog lefutni.
A mapOptions-ben adhatóak meg az inicializáláskor szükséges alapadatok.
A center a korábban említett koordináták közül a legelső, szélességi-hosszúsági koordináták
A zoom pedig a betöltéskor alkalmazott nagyítási szint.
Ezekről bővebben és az általam használt direktívákról a későbbiekben lesz szó.
15
4.3. API bemutatása Szinte végtelen lehetőséget ad a Google a saját projektjeinek testre szabásában, ez nem csak a maps alkalmazásukra igaz, hanem tényleg szinte minden projektjükre. Elmondható, hogy jó dokumentációkkal rendelkeznek és mivel széles körben használják, developer fórumokon is bőven található információ működésük megértéséhez, hogy optimális módon használhassuk az APIjaikat. A következőkben bemutatnám az API kulcs beállításait, amik fontosak voltak a projekt szempontjából. 4.3.1. Map Types Olyan konstansokat tartalmaz, amellyel megadhatjuk, milyen típusú térképet szeretnénk megjeleníteni, inicializáláskor adható meg, van lehetőség a későbbi váltásra is, de csak az API-n belüli funkció meghívásával. Használhatunk:
Útvonal térképet
Szatelit térképet
Földrajzi térképet
Ezek egyvelegét
A legtetszetősebb hatás kedvéért a szatelit képet használtam. 4.3.2. Custom Style A projektben nem volt szükség az alap megjelenítés felüldefiniálására, de a dokumentáció nagy hangsúlyt fektet rá, hogy tényleg bármilyen kinézetű térképet készíthetünk, mert minden elem, ami megjelenik a térképen, testre szabható. Érdekesség lehet például, hogy az útvonal térképen szinte bármi, utcák, utak, főútvonalak, épületek, a városokat jelölő szövegek, ikonok, folyók megjelenése módosítható.
16
4.3.3. Projection Egyik alap pillére a megjelenítésnek a projekciók. A „Projection” interfésszel valósítható meg a gömb koordinátáinak síkba történő alakítása. Két függvény végzi el a műveletet:
fromPointToLatLng()
fromLatLngToPoint()
Ezek pontos leírása a dokumentációban található, matematikai háttere pedig a „Gall-Peters” féle vetület leírásán alapszik.
A kódban e hivatalos képletek alapján számoltam a „World Coordinate”-eket. 4.3.4. Eventek Hogy
minél
eseménykezelő
pontosabb rendszer
alkalmazást van,
amikre
írhassunk,
az
feliratkozva
API-ba
beépített
bekövetkezésükkor
futtathatjuk a saját kódunkat.
10. ábra Event listenerek Forrás:https://developers.google.com/maps/documentation/javascript/events
17
4.4. Hátrányok, megszorítások Azokkal a megszorításokkal kezdeném, amit magában a licenszben megfogalmazott kritériumok fektetnek le, némelyekre külön fizetős licensz ellenében van megoldás, viszont van olyan is, ami sajnos megkerülhetetlen. A legfontosabb, hogy a weboldalnak mindenki számára publikusan és ingyen elérhetőnek kell lennie, nem lehet olyan funkció az oldalon, ami csak fizetés ellenében jelenik meg a felhasználók egy rétegének, de az olyan extra funkciókért, amiknek mindenki által látható eredménye van pl. egy hirdetés elhelyezése a térképen, ami megjelenik mindenkinek, ez megengedett, tehát ebből a szemszögből nincs akadálya a projektemnek. A második, ami már inkább relevánsabb, az az erőforrás korlátozás, ami pontos számokban napi 25.000 oldal betöltést takar. A kulcsunkkal pontosan számolható, hogy mennyi a napi látogatók száma az oldalon, és minden alkalommal, amikor egy felhasználó betölti a JavaScript állományukat, ez a számláló nő. Ezen szabály pedig arra késztet minden fejlesztőt, hogy minimalizálja az oldal újratöltését, tehát nekem is az volt a feladat, hogy ha már egyszer betöltődött az oldal, többször ne kelljen elnavigálni az oldalról. Így tehát minden kérést AJAX-szal kellett megoldani, amivel az oldal újratöltése nélkül tudunk tartalmat elhelyezni az oldalon. A háttérben egy aszinkron JavaScript kérést küldünk a web szervernek, majd a visszakapott eredményt megjelenítjük, vagy felhasználjuk az oldalon. Ha mégis túllépné az oldal forgalma 90 napon át folyamatosan ezt a 25 ezres limitet, akkor sem kell aggódni, hogy a Google lekapcsolná az oldalt, ilyenkor a dokumentációjuk szerint felveszik velünk a kapcsolatot és javaslatot tesznek a további teendőket illetően. Két módszer között választhatunk:
Havi forgalom utáni számlázás
Google API for Work licensz, ami személyre szabható fix havidíjas előfizetés, egyedi elbírálást igényel
A következő típusú megszorítások, pedig az API felhasználásakor mutatkoznak. A temérdek lehetőség ellenére akad olyan funkció, ami nincs, hibásan van 18
megvalósítva, vagy olyan dologgal is találkoztam, amit nagyon körülményesen lehet csak megoldani, ha lenne befolyásunk az alap térkép kirajzolásához, akkor egy sornyi kóddal helyettesíthető lehetne az a módszer, amivel végül sikerült megoldanom például a kattintott négyzetek jelölését. Van egy érdekes bug a térkép középpontjának átállításakor. Két lépésben adható meg, hogy mit mutasson a térkép. Először megadjuk a helyrajzi-korrdinátákat, majd azt, hogy mennyire zoomoljunk rá a térképre. A dokumentáció szerint 19 a maximum zoom szint, de helyenként, nagyobb városokban készítettek részletesebb képeket is. Viszont amikor gyorsan váltunk koordinátát és zoomszintet is egymás után, akkor oldal betöltés sebességtől függően meglehet, hogy nem érzékeli, hogy a megnyitni kívánt koordinátán van 20-as részletességű szint is, ezért automatikusan a 19-re visszadob minket. A developer forumon többen jelezték a problémát, ami a következő release-ben javításra kerül. Ami egyik oldalról optimalizálás, az a másik oldalról lehet, hogy durva erőforrás pocséklást eredményezhet. A fejlesztők ugyanis úgy írták meg a saját alap térképüket, hogy az a lehető leggyorsabb legyen futásidőben, viszont a testre szabás hiánya nélkül végül csak egy saját workarounddal tudtam megoldani, hogy a négyzetek klikkelésre kijelölhetőek legyenek. Ha egy egyszerű ID-t kaptak volna az eredeti div-ek, amik tartalmazzák a képeket, akkor pont fele annyi objektumot kellene egy időben kezelni, mint most. Úgy volt csak lehetőség az elemeknek azonosítót adni, hogy az új réteg négyzeinek létrehozó függvényét felüldefiniáltam, amiben létrehozok egy azonosítóval ellátott elemet. Ennek hátránya, hogy a Google
-jében van egy üres
, aminek a plusz információja az azonosító, és az általam rátöltött kép. Utóbbihoz nem lett volna feltétlen szükség erre az új elemre.
19
5. Fejlesztési ütemterv A fejlesztésben nagy szerepet kapott a GIT verziókezelő rendszer, úgyhogy a működő Linux rendszer felállítása után ez volt elsőrendű feladata, hogy egy saját működő GIT szervert, hogy a bárhonnan elérhető legyen a forrás, valamint ami fontos, hogy a legfrissebb változata legyen mindig elérhető. Mellékhatásként pontosan visszakövethető, hogy mikor, milyen funkciók készültek el a weboldalból. 51 meghatározó fejlesztési fázis volt, amit végigkövetve eljutunk a szó szerinti semmiből, odáig, hogy egy működő weboldalt kapjunk. Első nagyobb egyedüli fejlesztési projektnél megesik, hogy nem jól tippeljük meg magát a fejlesztés idejét, nagyobb cégeknél, kiadóknál is előfordul, hogy folyamatosan tolják a kiadási határidőket, mert nem tudnák az ígért, vagy elvárt minőséget produkálni. Mikor elsőnek merült fel a projekt megvalósítási idejének a megsaccolása, két hetet mondtam rá, a valóságban pedig mindig eltér a tervtől, mert csak ennyi időbe telt, mire a Google Maps API dokumentációját, funkcióit, és még így is történt olyan, hogy mire befejeztem egy függvényt, találtam meg egy másikat, ami már használatra készen állt a libraryben. Ütemterv:
Működő rendszer, Linux, Nginx, Php, MySQL, GIT.
Google Maps API megismerése.
Adatbázis elkészítése.
Google Maps frontend elkezdése, design kialakítása.
Regisztráció – Login.
Területek lefoglalása.
Képgenerálás.
Tesztelés.
Külső tesztelők bevonása.
Hálózati adattárolás
Hibák javítása.
Új funkciók és párhuzamosítás.
A szép dolog egy jó rendszerben, weboldalban, hogy kiadása, publikálása után folyamatosan van fejlesztés rajta, hiszen a leginkább a nagy közönség használatakor
20
alakulnak ki az igények a valóban hasznos funkciókra. Tehát nagyon kevés projektre mondható el, hogy 100%-ban készek, mivel kiadásuk után is folytatódik életciklusuk.
6. Rendszer áttekintés 6.1. Backend 6.1.1. Áttekintő A rendszer áttekintése talán az egyik legfontosabb része a szakdolgozat témájának, ez az, amitől nem csak egy konkrét weboldalt, hanem egy attól komplexebb, egész rendszert kapunk. Maga a Google Maps is egy iszonyatosan nagy projekt, ami direkt úgy lett megtervezve az alapjaitól, hogy nagy felhasználóbázist tudjon egy időben kiszolgálni. Ezen a szinten már nem elég csak az alkalmazást, a weboldalt átgondolni, hanem az egész rendszert fel kell készíteni a feladatra. Azt tűztem ki célul, hogy amennyire engedik a források, egy mini Google Maps-et hozok létre, ami volumenében ugyan elmarad az eredetitől, de próbálom annyira skálázhatóra kialakítani, amennyire csak lehet. 6.1.2. Szerverek Két, specifikációban megegyező szerveren kezdtem meg munkát. A fő cél a terhelés, és a sávszélesség megosztás. Nyílt forrás, ingyenesség, szervereken való megbízhatósága miatt Linux fut rajtuk, aktuálisan: SMP Debian 3.2.65-1. 2x HP ProLiant 360 G5, konfigurációban:
2x Intel Xeon X5460 – Quad core
32 GB Memory
512 MB Cache RAID card
6x 500GB HDD
21
6.1.3. DNS, IP-k, Rendszertérkép A két szervet IP címe:
87.229.120.59 A fő, master szerver
5.159.232.47 másodlagos szerver
A projekt jelenleg a következő domain-en érhető el:
maps.opx.hu
11. ábra opx.hu Dns konfigurációja forrás: Dotroll.hu
Az elképzelés szerint, a fő szerveren fut minden az eddigi és későbbi felsorolások közüli szerverek közül. A másodlagos szerver, terhelés megosztóként funkcionál, jelenlegi állapotban csak képkocka webszerverként üzemel, de további tervek között szerepel, hogy az olvasási kéréseket a PHP és adatbázis is kiszolgálja. Hogy
elkerüljem
különböző problémákat, másodlagos
a
konkurens a szerver(ek),
csak olvasási műveleteket végeznek.
12. ábra Rendszertérkép 22
6.1.4. Webszerver - Nginx Mivel szinte csak statikus fájlokat szolgálunk ki a weben, ezért esett a választás a népszerű Apache helyett az Nginx-re. Több tucat tesztben bizonyított, hogy statikus fájlok kiszolgálására sokkal hatékonyabb az orosz Nginx priojekt. Míg az Apache alapesetben egy daemonként működik, egy bejövő kérésnél fork-ol egy új processt a kiszolgálásnak, az Nginx egy eseménykezelt, aszinkron módon végzi ugyanezt.
13. ábra Apache vs Nginx, dreamhost.com által végzett saját tesztjük Forrás: http://wiki.dreamhost.com/Web_Server_Performance_Comparison Az Nginx-nek két különböző fájltípust kell kiszolgálnia:
Statikus fájlok, képek, JavaScript-ek
Dinamikus fájlok, PHP szkriptek
Mivel külön nincs PHP értelmező az Nginx-be, így annak a tartalmát egy az egybe átadja majd a PHP5-FPM-nek, az lefut, a php kimenetét visszaadja az Nginx-nek, és így válaszolja majd meg a kérész a felhasználónak. Külön érdekesség, hogy mennyi plusz lehetőség van az Nginxben apró beállításokra, amikkel javítható a kérés kiszolgálása.
23
Én több dologgal is kísérleteztem:
fastcgi_buffers. o A fastcgi direktívák, a PHP-nak átadott információkra vonatkozólag adnak lehetőségeket, mivel csak rövid php szripteket használtam, a buffer mérete lehet alacsony.
gzip beállításai. o Webszerverek kimenetének tömörítésére szokásos modul, fontos, mivel nem számításigényes maga a projekt, ezért megengedhető, hogy a kimenet tömörítése több processzoridőt vegyen időbe, cserébe csökkentve a hálózati terhelést.
open_file_cache direktívák. o Az NGinx által használt statikus fájlok újrabeolvasására vonatkozó cache adatok. Hogy realtime szerű változásokat is tudjunk követni, ezt a cache időt alacsonyra kell venni.
worker_processes. o A kulcspont, amiben különbözik az Apachetól, hogy itt külön dedikált processzek futnak, amik egyenként többszáz-ezer kapcsolatot tudnak kezelni, ideálisan annyi worker process futhat, amennyi processzort a webszerverre szeretnénk szánni.
24
6.1.5. PHP A dinamikus tartalom kiszolgálásért a PHP értelmező fogja végrehajtani a kódot. Köztes réteget képez a webszerver és az adatbázis között, valamint ellenőrző feladatokat hajt végre, a bekért adatok helyességéért. Főbb műveletek:
Regisztráció
Login
Kép feltöltés
Összes zoomszinten képkockák legenerálása
Saját képek lekérdezése
e-mail riport
Ahol adatbázis művelet van, a bevitt adatok helyessége, injection tekintetében le
van
ellenőrizve,
lekérdezésekre
is
mindig
prepared-statementeket
deklaráltam. Jelenleg csak a fő szerveren van a projekt szempontjából futtatható PHP kód, a párhuzamosítás még nem lett megoldva ezen a szinten. Ami gyorsítja a végrehajtást, hogy PHP szinten a SESSION változók a merevelemez helyett a memóriában vannak, a memcached kiegészítő végzi ezen műveleteket. Előnye, hogy vele könnyen szinkronba hozható több szerveren futó PHP interpreterek session adatai. 6.1.5.1.
Felhasználó kezelés Alapvetően kétféleképp tudnak a felhasználók regisztrálni:
Regisztrációs formal
Facebook loginnal
Csak egy mechanizmus más, de alapvetően mindkettő ugyan arra az oldalra küldi el végső soron az adatokat. 6.1.5.2.
Email riport Email riportozási lehetőség arról, ha a képkocka elvesztésének ideje közeleg. Cronba időzített PHP szkript végzi ezt a feladatot. 25
6.1.6. Adatbázis Már korábbi fejezetben felmerült az adatbázis kezelő, ebben a részben a működő és használatban lévő adatbázist mutatnám be, a konkrét táblákat, mezőket, relációjukat, és magyarázatuk.
14. ábra Adatbázis szerkezet
User tábla: o Csak a legfontosabb adatok, felhasználónév, jelszó, email cím és a felhasználó választott nyelve. Többnyelvűség még nincs a projektben, de az adatbázis fel van készítve rá. 26
Purchase tábla: o 1-1 külön lefoglalást jelképez, user-hez van kötve, egy lefoglalás tartalmazhat több képkockát is. Külön felkészítettem az adatbázist a későbbi fizetős lehetőségre, ahol neves szervezeteket is lehet majd támogatni. Az unique_link mező egy olyan terv része, melyben regisztráció nélkül elérhetők a a képkockák szerkesztésre, így akár másnak is ajándékképp lehet ilyen képkockákat vásárolni.
Language tábla: o Külön nyelvi támogatásért, még ki kell egészíteni egy új táblával, ahol a több nyelvű stringeket tárolom.
Purchased blocks: o Ez az a tábla, amiben nyilván vannak tartva a képkockák, amik tartalmazzák azokat az információkat, hogy milyen x és y koordinátán, milyen képkockának kell megjelenni. Ezt a hatékonyság növelése végett megjelenítéskor nem innen olvassuk, hanem a már legenerált képekkel szolgáljuk ki a felhasználókat. A foglalt képkockák lekérdezése viszont erősen olvas ebből a táblából [x,y] koordináta párokat, így terhelés növekedésére elképzelhető, hogy egy memory táblába tükrözöm a tartalmát, és triggerekkel frissítem azt. Maga a lekérdezések pedig a memory táblából keresnének.
6.1.7. Hálózati adattár A legenerált képkockák a fő szerveren vannak helyileg, viszont hálózati adattárként fel vannak csatolva a másik gépre, így egy élő mirrorként működik. A hálózati terhelés megosztást úgy gondoltam, hogy az aktív szerverek közül lapbetöltésekként kiválasztunk egyet, és a weboldal használatakor már csak attól kérjük le a képkockákat. Működő hálózati meghajtó telepítésének leírása az alábbi forráson tekinthető meg:
https://www.howtoforge.com/install_nfs_server_and_client_on_debian_wheezy
27
Az egész projekt megtalálható az adattárolón, így a statikus képek, és a dinamikusan generált PHP szkriptek is megtalálhatók mindkét szerveren, viszont jelenleg a projekt csak a statikus adatokat tudja kiszolgálni terhelésmegosztottan. 6.1.8. Képgenerálás A tervek szerint a feltöltött képek 256x256 pixel méretűek, viszont képet feltölteni csak a maximum, 20-as zoom szintre lehet, a többi kép az ettől kisebbi zoom szinten a feltöltött képek montázsa lesz, tehát szükség van egy olyan programra, ami legenerálja az összes többi képet. Futásidőben a képek előállítása borzalmasan sok időt venne igénybe, ezért jobb, ha már előre le vannak generálva, és statikusan a háttértárról elérhetőek, így bár több helyet foglalnak, cachelhetők lesznek, és kiszolgálásuk nem kerül csak töredék CPU időbe. Annak a megvalósítása, hogy egy cloud-beli képfeldolgozó daemont csináljunk, bonyolultabb feladat, így az lett a koncepció, hogy a rendszerben egy fő szerver lesz, amelyik a képek generálja. Jelenleg ez a funkció hibásan működik, helyette PHP szkript generálja a képeket, ami bár működő megoldás, de erőforrás igényesebb. 6.2. Frontend 6.2.1. Saját funkciók Ebben a részben részletezném azokat a funkciókat, amik esetleg külön magyarázatra szorulnának, illetve a kód kommentjeiből nem derülne ki működésük. Megírásakor inkább a frontendre kellett koncentrálni, mert a logika nagy része a felhasználó oldalon kell, hogy jól működjön. A jQuery bővebb, és gyorsabb fejlesztői lehetőségeket ad, viszont jelentősen lassabb, mint a natív JavaScript kód. Ha hozzávesszük, hogy már a Google Maps is jelentősen erőforrás igényes, optimális, hogy ha a kódot is natív javasciptben írjuk, hogy minél gyorsabb legyen a weboldal működése. Ezért, ahol csak lehetett, a külső library-ket leszámítva JavaScript kódot írtam, nem pedig jQueryt használtam. 28
15. ábra Javacsript vs jQuery performance Forrás:https://freethegnu.wordpress.com/ "jQuery vs JS JavaScript is faster obviously, but it’s a lot faster. getElementById(‘test’) had an average speed of 10-15 million operations per second. The faster jQuery operation, $(‘#test’), maxed out at 1 million ops/sec. That’s a huge performance difference.„12
Az előző oldal tesztjében csak az objektum kiválasztás szerepel, de az AJAX kéréseket is az egysoros egyszerű jQuery helyett a JavaScript beépített xmlhttp objektumán keresztül valósítottam meg. Kódban több sor, viszont futásidőben gyorsabb. Mivel csak a legrészletesebb, 20-as zoomszintű négyzetek foglalhatók le, ezért valahogy meg kellett oldani, hogy távolabb zoomolva is azonosítani lehessen 1-1 négyzetet, amikor ezt a Google Maps API-ja nem teszi elérhetővé. Az ötlet az volt, hogy ezt egy rekurzív függvény fogja majd kirajzolni, ami majd legenerálja a maximum szintig az összes div-et.
12
jQuery és JavaScript teljesítmény összehasonlítása Forrás: https://emersonveenstra.net
29
16. ábra Rekurzív createAllDiv függvény sorrendi kimenete Hátránya, hogy ilyenkor 4^n-ediken darab div-et rajzolunk pluszba a térképre (ahol n = {20 – aktuális zoomszint}), és ezeket folyamatosan, a térképen haladva frissítünk. Ez hirtelen nagyon sok objektum kirajzolását eredményezi a kisebb zoom szinteken, ezért, hogy a weboldalt régebbi számítógépeket használók is meg tudják tekinteni, úgy állítottam be, hogy legalább 18-es zoom szint, vagy e-felett fusson le a kirajzoló függvény, tehát csak ekkor lehet kijelölni egy négyzetet, és lefoglalni. Nagy általánosságban úgy találtam, hogy a lakott területeken ezen a részletességen már található kép a szatellit térképükön. A leghosszabb, és legbonyolultabb function a térképet inicializáláskor fut le. Itt kap helyet a tényleges térkép objektum létrehozása, annak alap beállításai, ami mind működés, mind GUI szempontjából fontos. Hogy néhány dolgot kiemeljek:
Térkép középpontjának megadása
30
Saját elemek elhelyezése a „google.maps.ControlPosition” helyeken
Google térképen kereső box inicializálása
Maps eseménykezelők hozzáadása
Az eseménykezelők közül is a legfontosabb, ami kattintáskor fut le, ugyanis ez fogja majd ellenőrizni, hogy az adott négyzet már lefoglalt-e, illetve ha nem, akkor a kosárba helyezi és egyéb CSS-ben szükséges dolgokat végez, ami ennek a jelzésére szolgál. A kód alján találhatók azok a listenerek, amik akkor hajtódnak végre, mikor már az oldalt betöltötte a böngésző. Ezekben olyan alap beállítások találhatók, amik szükségesek az oldal működéséhez, eseményekre feliratkozások, illetve futásidőben történő inicializálások vannak. A felugró modal ablakok definiálása, vagy a választómenü felkészítése is itt hajtódik végre. Mind annak az érdekében, hogy minimalizáljuk az oldal újratöltését, hogy a Google licenszben foglalt napi 25 ezres limitet optimálisan kihasználjuk. Egy másik érdekes megoldás a foglalt képkockák lekérdezésekor keletkezett. A Google Eventlistenerjei között nem találtam olyat, ami nekem kellett volna, ezért egy saját egyedi megoldást kellett keresnem. A probléma a következő volt: Amikor a felhasználó halad a térképen, folyamatosan le kell kérdezni a már foglalt koordinátájú képeket, és ezeket tiltani, hogy ne lehessen újra lefoglalni őket. Egy AJAX kérést küldönk az aktuális középponttal, és a zoom szintünkkel, amit majd a PHP adatbázisból lekérdezi azon a területen található foglalt képek koordinátáit. A következő eventeknél kell újra lekérni a foglalt kockákat:
center_changed
zoom_changed
Viszont a Google Maps használatakor megesik, hogy folyamatosan haladunk egyik helyről a másik felé, keresve az úti célunkat, az ilyen esetekre lett beleépítve egy timer, ami azt figyeli, hogy az elmúlt fél másodpercben volt-e változás a középpontban, ha nem, csak akkor kérdezi le a foglalt koordinátákat. Lefutása után egyből megszűnik, és csak, ha újra interakcióba lépünk a térképpel, akkor jön létre. 31
6.2.2. GUI Első lépés a Google térkép testre szabása volt. A „mapOptions”-ben megadható az összes beépített elem megjelenése, működésük felüldefiniálása, illetve megszorítások a működésével kapcsolatban. Ezeket részletezve a projekt szempontjából fontos volt, hogy csak az alap 2D-s térképet tudják használni a felhasználók, az úgynevezett „tilt” nézet, ami a kép megdöntését eredményezi, azt ne. Tesztekből kiderült, hogy más-más nézőpontból ugyanarra a képpontra kattintva más-más koordinátákat adott vissza a térkép, dokumentáció hiányában nem lehetett rájönni, hogy mi ennek az oka, ezért el lett távolítva ez a lehetőség. Megjelenítésre impozáns megoldás, de felhasználói beavatkozásokkor már nem működött helyesen. A következő beépített pozíciók érhetők el az API-ban:
17. ábra Beépített pozíciók a Google maps API-ban Forrás: Google maps developer forum
Ezezek közül csak a TOP_RIGHT van használatban a projektben, arra a pozícióra került a jobb oldali container, ami a jobb oldalt lévő tabokat tartalmazza. Eleinte a térkép mellett volt található, azért került rá, hogy elrejtve a tab-okat, nagyobb területet láthassunk scrollozás nélkül.
32
6.2.3. Interakció a térképpel Az alap működésén a térképnek nem változtattam, kezelése teljesen egyenértékű a Google Maps-ével. Egér gomb nyomva tartással tudunk navigálni az aktuális zoom szinten, görgővel, vagy a beépített control panel segítségével tudunk közelíteni, illetve távolítani. A kezelési eseményfigyelők közül csak a sima egérklikk eseménynek van kihatása a projektemre, mégpedig, hogy ha ez bekövetkezik, akkor kijelöljük az aktuális négyzetet lefoglalásra, feltéve, ha már nem foglalt. Ekkor a jobb oldali tabok közül a kosárba kerül. A kosárba helyezett négyzetek, a térképen egy átlátszó png képpel vannak jelölve. A kosárba szerettem volna megjeleníteni a konkrét négyzet képét a Google Maps-ről, de sajnos a licenszelési feltételek miatt külsőleg nem használhatom a tile-ok képét. Erre egy külön API-t lehetne használni, de felhasználási feltételeikben szintén található egy napi limit, amit átlépve fizetni kell a szolgáltatásért. Mivel egy oldal betöltést követően több négyzet is a kosárba kerülhet, ennek használata kritikusabb lett volna, ezért csak egy CSS-ben definiált class-t használtam a kosár tartalmának megjelenítésére. https://developers.google.com/maps/documentation/staticmaps/ Hogy a térkép bármelyik területe linkelhető legyen, HTML hashmarkot használtam, ahol csak a koordinátákat, és a zoom szintet kell azonosítani, a következő példa jól mutatja, milyen formátumban kell elképzelni:
18. ábra Bármely koordináta linkelése 6.2.4. Helyi felhasználó A lehető leggyorsabb módszert kerestem arra, hogy a felhasználók be tudjanak regisztrálni. Maga a bejelentkezés és regisztráció egy közös formba került. Amikor az email cím mezőt kitöltjük, a háttérben elmegy egy http kérés, ami leellenőrzi, hogy a megadott felhasználó szerepel-e már az adatbázisban. Ha 33
szerepel, akkor a bejelentkezési funkciót vesszük igénybe, ha nem, akkor előugrik még egy ellenőrző beviteli mező a jelszó újbóli beírására. Ekkor a regisztrációs szkript fog lefutni. 6.2.5. Facebook felhasználó Aki facebookon keresztül szeretne regisztrálni, egyszer kell megtennie, a facebook API-ját vettem segítségül, kész könyvtárukkal percek alatt integrálható a bejelentkezési és azonosítási funkciói. Egy fontos lépés van, mielőtt használhatnánk a szolgáltatásait, a developer oldaljukon, csak úgy, mint a Google Maps API esetében, itt is regisztrálnunk kell egy kulcsot, ami majd azonosítja az applikációnkat. Ez után, már követve a dokumentációban leírtakat egyszerű megvalósítani a funkciót. Annyi érdekesség még van benne, hogy azonosítás után JavaScript-el még elküldöm az adatokat a saját projektemnek, hogy saját adatbázisban is nyilván legyenek tartva. 6.2.6. Terlület foglalása A térképen megjelenő 256x256 pixeles képkockákat kattintással lehet a kosárba rakni. Ekkor egy átlátszó png képpel jelöltem azt, hogy ki van jelölve az adott képkocka. Ebből a kosárból szedem ki a megrendeléskori koordinátákat, amit majd PHP-ben egy tárolt eljárás fog lefoglalni.
34
7. További fejlesztési tervek 7.1. Paypal, kártyás fizetés Jelenleg csak az ingyenes képek lefoglalása lehetséges, ezzel a lehetőséggel, időkorláttal lehet igénybe venni a szolgáltatásokat, két hét után automatikusan felszabadul a lefoglalt képkocka. A Paypal által elérhető fizetési szolgáltatásokhoz írtam példa kódot, a teszt developer szerverüktől helyes fizetési feltételek mellett jó választ is kaptam, viszont később találtam hozzá egy programozó-barátabb SDK-t, amivel nem kell konkrét socketeket létrehozni a művelethez, hanem csak előre definiált függvényeket hívogatni. Használata egyszerűbb és biztonságosabb, mint a saját socketes megoldás, lévén, hogy egy fizetési opció elég kényes biztonságtechnikából, végül későbbre halasztottam az implementálását. Adatbázisban is külön táblákat kell létrehozni ezen műveletek követésére.
7.2. Google+ felhasználók Hasonló APIja van a Google-nek is, mint a Facebooknak, szintén egy gombbal való bejelentkezést tesz lehetővé, csak Google+ felhasználásával, a developer oldalán kész kódot is találunk, amit csak a saját adatbázisommal kell összekötni és használható is a login funkció. Az API dokumentáció: https://developers.google.com/+/quickstart/php
35
7.3. Design Az egyik legfontosabb a weboldalaknál, hogy milyen GUI tartozik hozzájuk, mennyire megkapóak a színek, és mennyire ötletes, eredeti a dizájnjuk. A fejlesztés során alakultak ki azok a színek, amik most használatban vannak az oldalon, de talán túl szürkére, egyhangúra sikerült. Később választható témák segítik majd a felhasználóknak a legimpozánsabb színek megtalálását.
7.4. Kép linkről beszúrása Javítva a felhasználói élményt olyan tervek vannak még, amiben további kép feltöltési módszereket implementálok a rendszerbe. Egyik ezek közül, hogy ne csak a helyi gépről lehessen feltölteni képet, hanem linkként megadott külső képet töltsön be a JavaScript library, ami a mostani képvágást kezeli. A függvénykönyvtár, amit erre a célra találtam, licenszében nem zárja ki, hogy tovább fejlesszük, átírjuk a kódot, így megoldható, hogy erre a célra ne kelljen komplett új képszerkesztőt keresni, illetve írni.
7.5. Facebook kép importálás Ha a felhasználó nem szeretne bajlódni se a képfeltöltésével, se linkek keresésével, és már egy a facebookon megosztott képét szeretné felhasználni, a legegyszerűbb, ha egy az egyben a facebook API-n keresztül vesszük ezt igénybe. Részletes dokumentáció található a developer weboldalukon: https://developers.facebook.com/docs/graph-api/reference/v2.3/album
36
7.6. Rajzolás 256x256 pixelen Későbbi fejlesztés, hogy ne csak már kész képeket lehessen elhelyezni, hanem kreatív rajzokat is, ehhez a jelenlegi állapot szerint elég csak egy JavaScript könyvtár, magához egy canvasban rajzoláshoz.
19. ábra Open-source rajzpad Javascriptben Forrás: http://drawingwith.me
7.7. CacheFS A CacheFS egy olyan kiegészítés a hálózati fájlrendszerekhez, ami lehetővé teszi azt, hogy a hálózaton megosztott fájlokat ne csak a RAM-ban lehessen elcachelni, hanem konkrétan a kiszolgáló gépek helyi fájlrendszerit használja gyorsító tárnak. Kiszolgáláskor ugyan úgy le kell ellenőriznie, hogy változott-e a fájl, mióta legutóbb használatban volt, viszont ha nem történt változás, és a RAM-ból már kikerült, akkor sem kell a hálózatot terhelni az újbóli lekéréshez, hanem a helyi merevlemezről ki lehet szolgálni a kérést. Hasonlót használ a Google is a világszerte elhelyezett cache szerverein. Az adott területen leggyakrabban keresett, vagy használt tartalmakat nem csak RAM-ban, hanem merevlemezen is tárolja. Én is hasonlót terveztem, arra az esetre, ha megnő az oldal forgalma, ezzel jelentős hálózati erőforrásokat lehet megtakarítani.
37
20. ábra CacheFS működési ábrája Forrás: http://en.wikipedia.org/wiki/CacheFS
7.8. Daemon működése A képgenerálást a jelenlegi PHP helyett, a kezdeti elképzelés szerint egy Linuxon futó szolgáltatás, daemon végezte volna. A PHP kiegészítésként használt Imagemagick projekt nyílt forrású, és szinte az összes programozási nyelvre elérhető a forrása, így tehát az algoritmus is megegyezik. Viszont sajnos a példakódok fordításakor nem várt hibák következtek be, ellentétben a PHP-vel, ami talán a háttérben más függvényeket használhat. Debugolása több időt vett volna igénybe, ezért a működés szempontjából a PHP maradt a projektben, később az erőforrás hatékonyság végett mindenféleképpen működésre kell bírni.
7.9. Multi Language Több dolog kell, hogy többnyelvű legyen az oldal. Már korábban felmerült, hogy a Google licensz feltételei miatt minimalizálni kell a lap újratöltéseket, ezért JavaScript oldalon kell ezt a műveletet is megvalósítani. Az ötlet szerint egy olyan tömböt hozok létre, amibe az értékek maguk a szövegek referenciái. Oldalbetöltéskor automatikusan ezek feltöltődnek az alapértelmezett nyelvvel, az angollal, vagy ha a felhasználó már járt az oldalon, akkor az általa kiválasztottal. Nyelv váltáskor csak egy PHP szkriptet kell meghívni, ami JSON szerializált tömbben visszaadja az összes stringet, majd a korábbi tömbünkön végigmenve a referenciák értékeit frissítjük. Talán ez a funkció az, amelyik a leggyorsabban megvalósítható a tervezettek közül.
38
7.10.
Teljes cloud befejezése, PHP, SQL párhuzamosítás Legfőképp ez a pont volt a projektem fő célja, hogy egy Google Maps szerű párhuzamosított webes rendszert építsek. Nem sok hiányzik ahhoz, hogy ez tényleg maradéktalanul teljesüljön, viszont annál több tesztelést igényel még. A memcached beállításait annyiban kell módosítani, hogy ne az alapértelmezett 127.0.0.1 IP-n figyeljen, hanem a szerver publikus IP-jén. Majd a allow_failover-t 1-es értékre és session_redundancy direktívát annyira állítani, ahány szerveren használjuk plusz 1. Jelen esetben 3-ra állítanám. A PHP beállításait módosítani kell, a php.ini-ben a session.save_path direktívában minden cloudba kapcsolt szerveren megadni az összes szerver ipcímét és a portot, amit a memcached használ. Ezek után úgy működik mindkét gépen PHP sessionje, mintha egy RAID1 diszk volna, tükrözve vannak hálózaton az adatok, annyi különbséggel, hogy ugye a memcached miatt nem a merevlemezen, hanem direkt a RAM-ban tároljuk őket. Így akár egy szerver leállása esetén az is elkerülhető, hogy a session adataink eltűnjenek, mert a többi szerver memóriájában még megtalálhatóak a session adatok. A kiesett szerver helyreállításakor pedig automatikusan leszinkronizálódnak az adatok. Ez után már az azonosítási információk minden gépen elérhetőek, mindegy melyik gépen lép be a felhasználó, ha később másik szolgálná ki, akkor is mentve marad a munkamenete. A hálózati adattár miatt a PHP kódok összessége megtalálható a 2. szerveren is, viszont jelenleg azok nincsenek használatban, működésükhöz további tevékenységek szükségesek. A terv szerint mindenképpen megmaradna a fő szerver funkciója, miszerint adatot csak az rögzíthet, a többi pedig csak olvas, így elkerülve az adatok inkonzisztenciáját, és egyéb szinkronizációs problémákat. A két szerver adatbázisa már most is így van konfigurálva, Master-Slave működéssel, amihez útmutatót az alábbi weboldalon lehet megtekinteni: https://digitalocean.com/community/tutorials/how-to-set-up-master-slave-replication-in-mysql
39
Az adatbázisba kell egy új tábla az elérhető szerverek domain címeiről, valamint a PHP és JavaScript kódokat kell módosítani úgy, hogy minden esetben a fő domain címre történjen az a fajta kérés, ami , ami pedig olvasási szándékú adatlekérés, az valamely logika szerint (pl geolokáció) válasszon ki az összes elérhető szerver közül egyet. Ezen megvalósításokkal lesz teljes a projekt, amit meg szeretnék valósítani, több hónapos fejlesztési időt letudva kijelenthetem, hogy milliónyi buktatója van egy hasonló rendszer kiépítésének, nagyon egyszerű problémák lehet, hogy csak nagyon komplex megoldásokat igényelnek. Már a feladat elején meg kellett tervezni az egész rendszert, ami elláthatja azt a feladatot, hogy egy nagy felhasználó aktivitású oldalt megalkothassunk. A szakdolgozat célja tehát az volt, hogy bemutassam, hogy vált egy egyszerű Google Maps alkalmazásból, egy bonyolult, aprólékosan és átgondoltan megtervezett cloud.
40
8. Összefoglalás Hihetetlenül sok munkaóra és tesztelést követően végre elkészült egy olyan működő rendszer, ami nem csak egy szimpla weboldal, hanem egy konkrét felhő, amely alkalmazás része a jövőben nagy felhasználó-számú alkalmazásként üzemelhet. A projekt leadásáig a GIT szerverben 97 bejegyzett mérföldkő van, ami alapján a semmitől eljutottam egy működő weboldalig, sőt egy működő komplex párhuzamosított rendszerig. Még a későbbi fejlesztéseket betartva büszkén állíthatom, hogy a rendszer a nagy közönség előtt is sikeres lehet. Külön köszönetet szeretnék mondani 3 embernek, akik nélkül a szakdolgozat nem születhetett volna meg:
Dr. Vincze Dávid egyetemi adjunktus, aki témavezetőként segítette a munkát és a rendszertervezést.
Kerekes Edwin, aki munkájával évek alatt bevezetett a komplex problémák megoldásainak programozásába és a Linux rendszerüzemeltetésbe.
Felső Dániel, aki megtanította a JavaScript kódolás trükkjeit.
41
9. Summery After Incredibly large number of work hours, and testing, finally I could finish publishing not only a single website, but a fully functionally working cloud system, that could serve a huge amount of request from users. Up until finishing my thesis, there are 97 milestones captured int he GIT server, where the project can be examined, how it evolved from nothing to it’s current state, not only a working website, but also a complex parallel system. After adding the features that’s been written in this document, the website could be a huge success on the world wide web. I’d like to say special thank for 3 people, without them I couldn’t finish my project:
Dr. Vincze Dávid assistant professor, who was the supervisor, and help designing the whole system
Kerekes Edwin, who introduced me programming complex problems solutions, and taught Linux administration over the years.
Felső Dániel, who tought basic JavaScript tricks.
42