POROČILO PRAKTIČNEGA IZOBRAŽEVANJA

Similar documents
Hitra rast hranjenih podatkov

Vodnik skozi Google Analytics Beta verzija 1. del. prehod s stare kode (urchin.js), k novi kodi za sledenje (ga.js)

Lotus Quickr Najhitrejši način izmenjave poslovne vsebine

Sistemske zahteve za SAOP

» Nakup in vzdrževanje Oracle programske opreme «Tehnične specifikacije

DB2 podatkovna baza v praksi

RAZLOG ZA IZVAJANJE PROGRAMA POPRBAZA

Q: Do You made a backup before upgrade? A: Only cowards make backups!

Družina IEEE802 Poddružina IEEE802.1 Priključitev v omrežje IEEE802.1x

Uvod v svetovni splet

Izdelava urejevalnika izvorne kode v oblaku z uporabo tehnologij HTML5

Izdelava spletne aplikacije za video klepet

Transakcije v MariaDB/MySQL (transakcija A)

APLIKACIJE ZA SOCIALNA

Vzpostavitev spletnega vmesnika za prikaz tenziomiografskih meritev

Primerjava izvornega in hibridnega razvoja mobilne aplikacije

Delavnica za konfiguriranje dostopovnih točk Konfiguracija LANCOM L-54 z uporabo orodja LANConfig

POROČILO PRAKTIČNEGA IZOBRAŽEVANJA

VISOKOŠOLSKI STROKOVNI ŠTUDIJ RAČUNALNIŠTVO IN TEHNOLOGIJE KOMUNICIRANJA

VISOKOŠOLSKI STROKOVNI ŠTUDIJ. Računalništvo in informacijske tehnologije POROČILO PRAKTIČNEGA IZOBRAŽEVANJA. HAKL IT, d.o.o.

Delavnica za konfiguriranje dostopovnih točk WEB konfiguracija LANCOM L-54

RAZVOJ ENOSTAVNE SPLETNE APLIKACIJE Z UPORABO FLEKSIBILNEGA OGRODJA NA ODPRTOKODNIH KNJIŢNICAH

ABBYY rešitve za prepoznavo in klasifikacijo dokumentov

Navodila za uporabo izdelkov programske opreme Microsoft

Izdelava hibridnih mobilnih aplikacij z ogrodjem Ionic

IP PACKET QUEUING DISCIPLINES AS BASIC PART OF QOS ASSURANCE WITHIN THE NETWORK

Arhitektura oblaka Upravljanje v oblaku Delovanje v oblaku Arhitekturni okvir računalništva v oblaku

Organizacija računalnikov (OR) UNI-RI, 3.l. RS Vaje. doc.dr. Mira Trebar

Session:E07 GALIO - DB2 index advisor, how we implemented it and what we get from self-made expert tool

Izdelava aplikacij s podporo delovnih tokov za okolje SharePoint Server

RAZVOJ ENOSTRANSKIH SPLETNIH APLIKACIJ S PORTALNO PLATFORMO LIFERAY

Twitter Bootstrap in razvoj spletnega repozitorija za Cacti

Državni izpitni center SPOMLADANSKI IZPITNI ROK *M * NAVODILA ZA OCENJEVANJE. Četrtek, 2. junij 2016 SPLOŠNA MATURA

Primerjava orodij za razvoj mobilnih aplikacij

UNIVERZA NA PRIMORSKEM FAKULTETA ZA MATEMATIKO, NARAVOSLOVJE IN INFORMACIJSKE TEHNOLOGIJE. Razvijalska ogrodja za podporo večim mobilnim platformam

Open IT VARNO POVEZOVANJE SODOBNIH ODPRTIH SPLETNIH APLIKACIJ V OBLAKU TYPO3, MAGENTO, ALFRESCO

Časovno omejevanje dostopa do interneta

POROČILO PRAKTIČNEGA IZOBRAŽEVANJA

Selitev aplikacije iz Oracle Forms v Oracle ADF (Application migration from Oracle Forms to Oracle ADF)

Mobilna aplikacija za pregled informacij o prometu v Sloveniji

SPLETNE SESTAVLJANKE IN POSLOVNI PORTALI

Postavitev in upravljanje zasebnega oblaka z uporabo Microsoft System Center 2012 R2 in Windows Azure Pack za ponudnike storitev

Prirejanje in preverjanje tipov

Poročilo praktičnega izobraževanja v Unior d.d.

UČNI NAČRT PREDMETA / COURSE SYLLABUS (leto / year 2017/18) Spletno programiranje. Študijska smer Study field ECTS

Primerjava uporabe SOAP in REST za potrebe povezave mobilnih naprav s spletnimi storitvami

Ogrodje za razvoj mikrostoritev v Javi in njihovo skaliranje v oblaku

Razvoj orodja za centralni nadzor posodobitev v platformi WordPress

Aplikacija za prikaz prostorskih podatkov

RAZVOJ GENERATORJA POSLOVNIH SPLETNIH APLIKACIJ

UNIVERZA V LJUBLJANI FAKULTETA ZA RAČUNALNIŠTVO IN INFORMATIKO. Dean Črnigoj. Izdelava odjemalca NFS za Windows DIPLOMSKO DELO

Spletna aplikacija za urejanje vadbenih programov v fitnesu

Aplikacija za podporo delovanja svetovalcev

UNIVERZALNI KOMUNIKACIJSKI ODJEMALEC S PODPORO ZA UPORABNIŠKI ENUM

Primerjava spletnih ogrodij Spring MVC, Stripes in Apache Tapestry

Primerjava in analiza učinkovitosti podatkovnih baz DB2 in MySQL

POROČILO PRAKTIČNEGA IZOBRAŽEVANJA v Amis d.o.o., Maribor

New Media & Language Technologies Jozef Stefan International Postgraduate School January Speech apps. Jerneja Žganec Gros

Prenos interaktivnih spletnih vsebin s Flasha na HTML5

BLUETOOTH KOMUNIKATOR ZA WINDOWS MOBILE 6.5

sodobne poslovnoinformacijske rešitve Birokrat Kratka navodila za namestitev demo verzije programa Birokrat

formati slike in branje slike pomen in nekaj primerov EM spekter aplikacije v posameznih delih spektra o matriki slike

Lokacijske storitve na mobilnih napravah

Specification and Implementation of a Light-Weight Internet Content Delivery Platform

Prometno načrtovanje xdsl

Jure Cerjak. Razvoj spletnih aplikacij s platformo Zope

Matej Simčič. Avtomatizacija naročil v taksi službi UNIVERZA V LJUBLJANI FAKULTETA ZA RAČUNALNIŠTVO IN INFORMATIKO

SPLETNA APLIKACIJA ZA SPREMLJANJE PODATKOV O FILMIH

Razvoj napredne spletne trgovine z upoštevanjem zgodovine nakupov

Spletna aplikacija za izdelavo in urejanje spletnih vsebin

Testiranje spletne aplikacije z orodji Selenium in Windmill

Mobilna aplikacija za pregledovanje slik visokih ločljivosti

UPORABA TEHNOLOGIJE VOIP NA MOBILNIH NAPRAVAH SYMBIAN

Uporaba strežnika SharePoint za vodenje poteka dela pri izvajanju kompleksnih projektov

Zasnova spletnega orodja za prijavo na govorilne ure v sistemu Plone

IBM Lotus Notes in Domino 8

Razširitve CMS z lastnimi moduli

UNIVERZA V LJUBLJANI FAKULTETA ZA RAČUNALNIŠTVO IN INFORMATIKO. Matjaž Poljanšek DIPLOMSKO DELO NA UNIVERZITETNEM ŠTUDIJU

SPLETNA REŠITEV ZA POTREBE DRUŠTVA UPOKOJENCEV

NAMESTITEV WINDOWS 7 OKOLJA Z UPORABO MICROSOFT WAIK ORODIJ

Pavle Gartner. Primerjava različnih rešitev za izvedbo spletne trgovine

Druga plat informacijske družbe. Intelektualna lastnina Odprto in prosto programje Linux OpenOffice

Razvoj aplikacij na platformi Google App Engine

PRISOTNOST PRI POUKU S POMOČJO RFID

Razvoj Windows Store aplikacij

Primož Hadalin IZDELAVA SPLETNEGA PORTALA POSLOVNE APLIKACIJE Z UPOŠTEVANJEM RAZLIK MED SPLETNIMI BRSKALNIKI

POROČILO PRAKTIČNEGA IZOBRAŽEVANJA

Luka Žabkar. Razvoj sodobne storitvene spletne strani za sledenje dieti in aktivnostim

POROČILO PRAKTIČNEGA IZOBRAŽEVANJA

Univerza v Mariboru Fakulteta za organizacijske vede. Programska rešitev za grafično prikazovanje najema in rezervacij vozil

POROČILO PRAKTIČNEGA IZOBRAŽEVANJA

Navodila za interaktivne naloge Bober

UNIVERZA V LJUBLJANI PEDAGOŠKA FAKULTETA DIPLOMSKO DELO GREGOR IVANŠEK

Razvoj spletne trgovine z vključitvijo naprednih storitev

IZDELAVA PROGRAMSKEGA PAKETA ZA GRAFIČNI PRIKAZ POMENSKIH SLOVARJEV IN ONTOLOGIJ

Dostop do podatkov Svetovne banke v orodju Orange

Učinkovita rešitev za izdelavo zaščitnih kopij z deduplikacijo in replikacijo

Navodila za nastavitev varne povezave po protokolu SSH

Šolski center Novo mesto Srednja elektro šola in tehniška gimnazija Šegova ulica 112, 8000 Novo mesto. Maturitetna seminarska naloga

Programski jezik Java

Transcription:

VISOKOŠOLSKI STROKOVNI ŠTUDIJ Računalništvo in Informacijske Tehnologije POROČILO PRAKTIČNEGA IZOBRAŽEVANJA V Cloudkick, Inc. - San Francisco, Kalifornija, Združene Države Amerike Čas opravljanja od 26.09.2010 do 10.01.2011 Mentor v GD Paul Querna Študent Tomaž Muraus Vpisna številka E1009462 E pošta tomaz+feri@tomaz.me Telefon +386 40 389 540

1 POGODBA O PRAKTIČNEM USPOSABLJANJU 2 / 37

2 KAZALO Kazalo vsebine 1 Pogodba o praktičnem usposabljanju... 2 2 Kazalo...3 3 Uvod... 5 4 Opis gospodarske družbe in produktov... 6 4.1 Opis produkta...10 5 Opis praktičnega izobraževanja...13 6 Strokovno področje ali projekt... 15 6.1 Izdelava vtičnika za agenta... 15 Uvod in arhitektura agenta...15 Izdelava vtičnika... 18 Testiranje vtičnika... 20 6.2 Cast... 21 Uvod...21 Arhitektura... 25 Razvoj... 26 7 Sklep... 29 8 Povezave...30 9 Priloge...32 9.1 Priloga 1: Izvorna koda vtičnika...32 9.2 Priloga 2 izvorna koda modula s pomožnimi funkcijami za testiranje...36 Kazalo slik Slika 1: Logotip podjetja pred prevzemom... 6 3 / 37

Slika 2: Logotip podjetja po prevzemu...6 Slika 3: libcloud.org - spletna stran projekta libcloud, kjer so našteti podprti ponudniki...9 Slika 4: cloudkick.com - vstopna točka oziroma nadzorna plošča...10 Slika 5: cloudkick.com - pogleda posameznega strežnika...11 Slika 6: Arhitektura agenta... 16 Slika 7: Cast - izpis pri uporabi ukaza "info"... 20 Slika 8: Arhitektura sistema Cast... 22 Slika 9: Dokumentacija generirana s pomočjo orodja JSDoc...23 Slika 10: github.com - prikaz komentarja na spremembi (diff)...24 4 / 37

3 UVOD Svojo prakso sem opravljal oddaljeno v podjetju Cloudkick z sedežem in pisarno v Kaliforniji. Ker je podjetje v času začetka opravljanja moje prakse bilo še manjše (okoli 10 redno zaposlenih) to pomeni, da še ni bilo razdeljeno v več pod-enot in je več zaposlenih delalo na več različnih delih produkta. Tudi sam sem spoznal in vsaj malo sodeloval pri vseh delih produkta. V tem poročilu sem kot projektno delo opisal izdelavo vtičnika za agenta in sodelovanje pri odprto-kodnem projektu za distribucijo, nameščanje in posodabljanje programske kode in aplikacij imenovanem Cast. 5 / 37

4 OPIS GOSPODARSKE DRUŽBE IN PRODUKTOV Cloudkick je bilo v času, ko sem začel z praktičnim usposabljanjem še manjše oziroma tako imenovano startup podjetje z pisarno v Kaliforniji. Leta 2009 je bilo ustanovljeno z strani treh študentov univerze v Oregonu - Alex Polvi, Dan Di Spaltro in Logan Weliver. Velik preobrat se je zgodil decembra 2010, ko je podjetje bilo prevzeto z strani drugega podjetja Rackspace. Rackspace[2] je eno izmed največjih in najstarejših podjetij, ki se ukvarja z gostovanjem in zraven Amazona tudi drugo največje podjetja, ki se ukvarja z nudenjem in prodajanjem storitev povezanih z računalništvom v oblaku. Trenutno je v podjetju Rackspace skupaj zaposlenih okoli 3500 delavcev. Sedež podjetja se nahaja v Teksasu, pisarne podjetja pa se nahajajo tudi na Nizozemskem, Angliji, Avstraliji, Hong Kongu in po prevzemu tudi v San Francisco-u. Slika 1: Logotip podjetja pred prevzemom Slika 2: Logotip podjetja po prevzemu Glavni produkt podjetja je istoimenska spletna aplikacija (SaaS) za upravljanje in nadzor oblačnih (cloud), virtualnih (vps) in klasičnih (dedicated) strežnikov. Moja naloga v podjetju je bila izpopolnjevanje in nadgrajevanje obstoječe spletne aplikacije in pripadajočih servisov ter sodelovanje pri izdelavi odprto-kodnega projekta za distribucijo, posodabljanje in nameščanje aplikacij imenovanega Cast. Pri razvoju glavnega produkta se uporablja veliko različnih programskih jezikov, 6 / 37

tehnologij in orodij. Primarni programski jezik za spletno aplikacijo in storitve je Python, velik del kode na front-u pa je napisan v jeziku JavaScript. Zraven teh dveh jezikov še kar zajeten del kode predstavlja jezik C v katerem je napisan agent, ki se namesti na nadzorovan strežnik, jezik Lua[18] v katerem so napisane določene skripte in vtičniki za agenta ter jezika C++ in Java, ki se uporabljata v nekaterih internih orodjih in storitvah. Večina orodij in tehnologij, ki se uporabljajo v podjetju so prosto dostopne in izdane pod različnimi odprto-kodnimi licencami (Apache 2.0, BSD, MIT, GPL). Nekaj primerov uporabljenih tehnologij in orodij: Django[3] odprto-kodno ogrodje za izdelavo dinamičnih spletnih aplikacij napisano v programskem jeziku Python Twisted[4] odprto-kodno ogrodje napisano v jeziku Python namenjeno izdelavi raznih omrežnih storitev temelječih na asinhronem pristopu Cassandra[5] odprto-kodna podatkovna baza, katere pristopi so pobrani iz Amazon-ove podatkovne baze Dynamo in Google-ove podatkovne baze BigTable Google Closure[6] odprto-kodno ogrodje napisano v jeziku JavaScript namenjeno izdelavi bogatih interaktivnih spletnih aplikacij Scribe[7] odprto-koden strežnik za agregacijo in transformacijo dnevnikov s strani velikega števila strežnikov Solr[8] odprto-koden strežnik za full-text iskanje temelječ na ogrodju Apache Lucence MySQL[9] odprto-kodna relacijska podatkovna baza Apache httpd[10] odprto-koden spletni strežnik RabbitMQ[11] odprto-koden messaging strežnik (MOM) napisan v programskem jeziku Erlang txamqp[12] odprto-kodna knjižnica napisana v programskem jeziku Python namenjena komunikaciji s messaging strežnikom preko protokola AMQP 7 / 37

Esper[13] odprto-koden strežnik za procesiranje dogodkov (complex event processing system) NodeJS[23] ogrodje namenjeno izdelavi visoko-zmogljivih aplikacij napisanih v jeziku JavaScript temelječih na asinhronem pristopu in še veliko drugih Podjetje pa zraven uporabe pri nekaterih projektih tudi aktivno sodeluje. Sodelovanje poteka na različne načine; pomoč z testiranjem in poročanjem napak, izdelava popravkov za razne hrošče in odpiranje lastnih modifikacij za uporabljene projekte ter knjižnjice. Primeri projektov, kjer je podjetje sodelovalo na enega ali več izmed zgoraj opisanih načinov so; Apache Cassandra, Twisted, txamqp, NodeJS. Podjetje je za lastne potrebe tudi razvilo in kasneje odprlo knjižnico libcloud[14]. Ta knjižnica je nastala zaradi potrebe po standardizaciji in poenotenju aplikacijskih vmesnikov ponudnikov storitev v oblaku. Knjižnica je torej nekaj vrste abstrakcija vmesnikov vseh teh ponudnikov storitev v oblaku. Trenutno podpira več kot 15 različnih ponudnikov, med njimi pa so tudi največji ponudniki kot so Amazon, Rackspace in Linode. 8 / 37

Slika 3: libcloud.org - spletna stran projekta libcloud, kjer so našteti podprti ponudniki 9 / 37

4.1 Opis produkta Cloudkick[1] spletna aplikacija (SaaS) za nadzor in upravljanje oblačnih in navadnih strežnikov. Slika 4: cloudkick.com - vstopna točka oziroma nadzorna plošča Glavni del viden uporabnikom je spletna nadzorna plošča, ki uporabniku na pregleden in kompakten način prikaže trenutno stanje njegovih strežnikov. Zraven pregledne nadzorne plošče, ki deluje kot vstopna točka pa aplikacija ponuja tudi veliko druge funkcionalnosti: napredni alarmi, ki uporabniku omogočajo, da si nastavi različne meje o katerih bo obveščen preko e-pošte, tekstovnega sporočila (SMS), Webhook-a ali preko sistema PagerDuty[15] 10 / 37

program CKL, ki administratorjem strežnikov omogoča snemanje sej in beleženje sporočil, ki so nato vidna na grafih v spletnem vmesniku (ta sporočila se se v večini primerov uporabljajo kot neke vrste opombe) API vmesnik, ki drugih razvijalcem omogoča, da na naši platformi gradijo lastne aplikacije Cloudkick Viz[16] sistem, ki uporabnikom omogoča 3D pogled stanja strežnikov v realnem času izdelava lastnih vtičnikov za agenta, ki so lahko napisani v poljubnem programskem jeziku Slika 5: cloudkick.com - pogleda posameznega strežnika 11 / 37

Cast[17] sistem za hitro in varno distribucijo, nameščanje in posodabljanje programske kode ter aplikacij Cast je primarno namenjen podjetjem, ki imajo v lasti večje število strežnikov in željo na njih namestiti svojo programsko kodo in razne aplikacije. Sistem je na voljo zastonj in je izdan pod prosto licenco Apache 2.0. Projekt je še trenutno v zgodnjem razvoju, izvorna koda pa se nahaja na Github-u https://github.com/cloudkick/cast. 12 / 37

5 OPIS PRAKTIČNEGA IZOBRAŽEVANJA Sam sem pri praktičnem izobraževanju vsaj delno sodeloval skoraj pri vseh delih produkta: izdelava vtičnikov za agenta v jeziku Lua izboljšave in popravki v sami izvorni kodi agenta (programski jezik C) sodelovanje pri izdelavi spletne aplikacije (programski jezik Python in ogrodje Django) sodelovanji pri izdelavi različnih storitev (programski jezik Python in ogrodje Twisted) vzdrževanje in konfiguracija velikega števila strežnikov (operacijski sistem Ubuntu, sistem za upravljanje konfiguracije Puppet) sodelovanje pri izdelavi odpro-kodnega projekta za distribucijo in nameščanje aplikacij imenovanega Cast (primarno je Cast napisan v programskem jeziku JavaScript, sistem Scons za namestitev pa je napisan v programskem jeziku Python) Za komunikacijo med delom se v podjetju primarno uporablja IRC kanal, za razne pomembnejše sestanke pa se v večini primerov uporablja video konferenca in program Skype. Manjša ovira pri mojem praktičnem izobraževanju je bila časovna razlika (9 ur), kar pa se je kasneje izkazalo za koristno. Takrat, ko je večina sodelavcev iz Kalifornije spalo sem jaz bil buden kar je pomenilo, da sem lahko v tistem času pomagal tudi pri podpori in raznih incidentih in težavah, ki so se pojavili na naših strežnikih. Za začetek razvoja in aktivnega sodelovanja sem kot prvo moral na svojem prenosniku vzpostavitvi razvojno okolje. Ker se pri delu uporablja veliko število tehnologij in aplikacij je sama vzpostavitev delovnega okolja relativno težavna in vzame kar veliko časa. Meni 13 / 37

osebno je postavitev dela delovnega okolja prvič vzela skoraj cel dan. Po vzpostavitvi delovnega okolja in deloma pred ter med pa sem se počasi tudi začel spoznavati z komponentami sistema, obstoječo izvorno kodo in interno dokumentacijo, ki se nahaja na sistemu wiki. Same izvorne kode je ogromno zato sem na začetku veliko stvari vzel kot črno škatlo, ker sem prvo poskušal razumeti kako je sistem sestavljen in kako deluje kot celota. Kasneje ob raznih zadolžitvah pa sem se poglobil tudi v samo drobovje različnih storitev, tako da sem na koncu praktičnega izobraževanja imel že dobro poglobljeno razumevanje celotnega sistema. 14 / 37

6 STROKOVNO PODROČJE ALI PROJEKT 6.1 Izdelava vtičnika za agenta Uvod in arhitektura agenta Med praktičnim izobraževanjem sem izdelal kar nekaj vtičnikov (check plugin) za agenta, eden izmed njih pa je bil vtičnik za nadzorovanje podatkovne baze Redis[19]. Vsi vtičniki so brez stanja (stateless), njihova naloga pa je, da zbirajo podatke oziroma metrike, katere agente pošlje našim strežnikom. Redis je NoSQL podatkovna baza, ki za razliko od relacijske baze za podatkovni model ne uporablja tabel (stolpci in vrstice) ampak osnovne podatkovne strukture[20]. Primeri teh podatkovnih struktur so: seznam (list), množica (set), urejena množica (sorted set), slovar (hash), vrsta (queue), ipd. Za dostop in urejanje podatkov ne uporabljamo povpraševalnega jezika SQL ampak posebne knjižice, ki so na voljo za večino popularnih programskih jezikov. Večina teh knjižnic pa ima možnost, da te podatkovne strukture razvijalcu izpostavi kot nativne podatkovne strukture tega programskega jezika. Za izdelavo vtičnika sem najprej moral prenesti izvorno kodo agenta in drugih vtičnikov napisanih v programskem jeziku Lua. Lua je skriptni jezik katerega gramatika je relativno preprosta, namenjen pa je za uporabo v raznih vgrajenih napravah z omejenimi viri in drugih programih, kjer se uporablja kot sekundaren skriptni jezik Lua je posebej popularen in uporabljen kot skripti jezik pri grah. Ena izmed iger, ki za izdelavo vtičnikov in razširitev uporablja ta programski jezik je igra World of Warcraft. Pri agentu se je prvoten razvijalec za jezik Lua odločil zato, ker je izdelati vtičnik v programskem jeziku Lua veliko lažje (jezik je interpretiran in dinamično pisan,...) in varneje (ni treba skrbeti za ročno sproščanje pomnilnika, ker ima Lua vgrajenega smetara - Garbage Collector ) kot pa v programskem jeziku C v katerem je napisan sam agent. 15 / 37

Agent deluje tako, da na vsake nekaj časa (privzeto je to 30 sekund) v novi niti zažene enega izmed vtičnikov, ki zbere za nas zanimive podatke nato pa jih pošlje našim strežnikom, ki te podatke shranijo v podatkovno bazo Cassandra. Seveda pa se pred podatkovno bazo nahaja tudi plast za pred-pomnjenje in strežnik memcache, v katerem se po principu write-through shranjujejo metrike in drugi pogosto dostopani podatki. Podatki so iz predpomnilnika odstranjeni po principu LRU. Slika 6: Arhitektura agenta 16 / 37

Izdelava vtičnika Za verzioniranje kode se v podjetju uporablja sistem Git, tako da sem skladišče z izvorno kodo preprosto kloniral na svoj računalnik. Ko je izvorna koda bila klonirana sem se naprej spoznal z delovanjem in izvorno kodo agenta ter obstoječih Lua vtičnikov. Ko sem se spoznal z delovanjem strežnika sem se odpravil na uradno stran projekta Redis, kjer sem dobro preučil dokumentacijo za ukaz INFO [21]. Ukaz INFO vrne razne informacije o Redis strežniku in statistiko o podatkih, ki so trenutno shranjeni. Tukaj je primer izpisa, ki ga vrne ukaz INFO : INFO $988 redis_version:2.0.4 redis_git_sha1:5c3fd23b redis_git_dirty:0 arch_bits:64 multiplexing_api:kqueue process_id:1726 uptime_in_seconds:6263145 uptime_in_days:72 connected_clients:3 connected_slaves:0 blocked_clients:0 used_memory:22949296 used_memory_human:21.89m changes_since_last_save:24 bgsave_in_progress:0 last_save_time:1297039444 bgrewriteaof_in_progress:0 total_connections_received:7269809 total_commands_processed:22781678 expired_keys:45074 hash_max_zipmap_entries:64 17 / 37

hash_max_zipmap_value:512 pubsub_channels:0 pubsub_patterns:0 vm_enabled:1 role:master vm_conf_max_memory:6000000000 vm_conf_page_size:32 vm_conf_pages:134217728 vm_stats_used_pages:0 vm_stats_swapped_objects:0 vm_stats_swappin_count:0 vm_stats_swappout_count:0 vm_stats_io_newjobs_len:0 vm_stats_io_processing_len:0 vm_stats_io_processed_len:0 vm_stats_io_active_threads:0 vm_stats_blocked_clients:0 db0:keys=4,expires=0 db1:keys=641,expires=0 db2:keys=453,expires=49 Kot je razvidno je format preprost in omogoča enostavno parsanje ključi so med seboj ločeni z znakom za novo vrstico (\n), ključ in vrednost pa sta med seboj ločena z dvopičjem (:). Sam ukaz vrne veliko količino podatkov, za nas pa so zanimivi samo nekateri, zato sem sparsal in shranil samo tiste, ki nas zanimajo. Pri izdelavi vtičnika sem si pomagal tudi z dokumentacijo programskega jezika Lua. Pred izdelavo vtičnikov v programskem jeziku Lua nisem naredil še nobenega programa ampak mi učenje ni predstavljajo večjih težav, ker je sama sintaksa večinoma podobna programskemu jeziku Python. Vtičnik deluje tako, da vzpostavi TCP povezavo z Redis strežnikom, pošlje ukaz INFO, iz odgovora sparsa podatke, ki so za nas zanimivi in na koncu zapre TCP povezavo. 18 / 37

Testiranje vtičnika Ko sem vtičnik izdelal sem prvo izvedel nekaj ročnih testov in sicer tako, da sem si na svoj računalnik namestil podatkovno bazo Redis, nato pa sem prevedel agenta in zagnal izdelan vtičnik ter preveril, če se rezultat ujema z pričakovanim. Seveda je bil ročen test samo prvi korak. Po ročnem testiranju pa sem napisal tudi avtomatske teste. Za funkcijsko testiranje Lua vtičnikov se v podjetju uporablja ogrodje Lunit[22]. Izdelal sem dva testa; prvi je klasični funkcijski test, ki testira pravilnost funkcij, ki parsajo podatke, drugi pa je test celotne funkcionalnosti, torej neke vrste integracijski test. Da sem lahko izdelal drugi test sem v programskem jeziku Lua napisal tudi preprost TCP strežnik, kateremu se ob zagonu poda slovar ukazov in odgovorov. Slovar pove kako se bo strežnik ob prihajajočem ukazu odzval. Primer vhodnega slovarja, ki se poda testnemu strežniku: { "INFO": "uptime:287878\nconnected_clients:10\nused_memory:1245567" } Ključ je v tem primeru INFO, vrednost pa je niz, ki se nahaja med narekovaji. 19 / 37

6.2 Cast Uvod Kot drugi del pri projektnem delu pa sem sodeloval pri izdelavi odprto-kodnega sistema za razširjanje, nameščanje in posodabljanje programske kode in aplikacij. Slika 7: Cast - izpis pri uporabi ukaza "info" Sistem je primarno namenjen podjetjem, ki imajo v lasti veliko strežnikov in želijo na njih hitro, varno in zanesljivo namestiti neko aplikacijo ali novo različico izvorne kode lastne aplikacije. Primer takšnega podjetja je na primer Facebook, ki želi na svoje strežnike ali del strežnikov namestiti novo različico spletne aplikacije ali pa želi nadgraditi MySQL podatkovno bazo na določenih strežnikih. 20 / 37

Sistem je napisan v programskem jeziku JavaScript, kot temelj pa uporablja ogrodje NodeJS, ki je primarno namenjeno izdelavi zanesljivih in visoko-zmogljivih omrežnih storitev. Preden sem začel sodelovati pri tem projektu sem z programskim jezikom JavaScript že imel kar nekaj izkušenj zaradi razvoja raznih client-side rešitev ampak v tem primeru je bil JavaScript uporabljen kot server-side jezik. JavaScript je zelo poseben jezik zaradi tega, ker ima zraven dobrih delov (funkcije so prvo-razredni meščani, delno se lahko uporablja kot funkcijski jezik, itd.) tudi veliko slabih, zato je pri razvoju zelo treba paziti katere dele jezika in le-kako se ti uporabljajo. Pred začetkom razvoja sem jaz in ostali, ki sodelujejo pri tem projektu imeli tudi kratko predavanje o pasteh jezika JavaScript s strani Bjorn-a, ki je pri podjetju Cloudkick zaposlen kot front razvijalec. Sam sem malo po začetku razvoja tudi prebral knjigo JavaScript The Good Parts [24] od Douglasa Crockford-a, ki ravno tako kot sem omenil zgoraj opisuje kako uporabiti dobre dele tega jezika, čemu se je treba izogniti in kje so potencialne pasti. 21 / 37

Arhitektura Sistem Cast je sestavljen iz dveh delov odjemalca (client), ki se ponavadi nahaja na računalniku upravitelja oziroma uporabnika in agenta, ki se nahaja na strežnikih in posluša na ukaze poslane z strani odjemalca ali drugih agentov. Slika 8: Arhitektura sistema Cast Trenutno je odjemalec enako kot agent napisan v programskem jeziku JavaScript ampak, ker sama filozofija projekta temelji na tem, da je sistem sestavljen modularno in vso svojo funkcionalnost izpostavi kot spletno storitev preko dobro zastavljenega aplikacijskega vmesnika to pomeni, da se kasneje odjemalec lahko izdela v praktično katerem koli programskem jeziku. 22 / 37

Razvoj Na začetku sva jaz in drugi sodelavec, ki je sodeloval pri tem projektu poiskala različne obstoječe knjižnjice, ki jih bomo pri projektu tudi uporabili. Ker je projekt izdan pod licenco Apache 2.0 to pomeni, da morejo tudi licence ostalih komponent biti kompatibilne s to licenco. Kot primer kompatibilne licence sta licenci BSD in MIT. Uporabijo se lahko tudi komponente izdane pod licenco GPL, ampak to komponente ne smemo distribuirati z našo aplikacijo. Primer take komponente je na primer knjižnica za izdelavo dokumentacije iz komentarjev v kodi, ki se uporabi samo v razvoju kadar se generira dokumentacija. S kolegom sva iskala takšne knjižnice, ki so v aktiven razvoju in imajo za seboj raznoliko in aktivno skupnost. Seveda je tukaj tudi ena majhna past platforma NodeJS je relativno mlada (prva javna različica je izšla leta 2009), kar pomeni, da še na žalost za vsako stvar, ki bi želel ne obstaja dovolj kvalitetna in vzdrževana knjižnjica. Za začetek sva našla knjižnico za testiranje Expreso, sistem za generiranje dokumentacije in komentarjev v kodi JSDoc in knjižnico za kontrolo toka imenovano async. Slika 9: Dokumentacija generirana s pomočjo orodja JSDoc 23 / 37

Ko sva našla nekaj osnovnih komponent, ki nam bodo pomagale pri razvoju sva začela z razvojem. Delo sva si razdelila tako, da je vsak naredil komponento ali del neke komponente. Zraven dela sva bila tudi dosti v stiku preko IRC-a in Skype-a, kjer sva si izmenjavala komentarje in mnenja. Ker je izvorna koda gostovana na Github-u pomeni, da sva lahko uporabila tudi vgrajen sistem za komentiranje sprememb (code reviews). Slika 10: github.com - prikaz komentarja na spremembi (diff) Zraven konstantne komunikacije med nama pa sva tudi trikrat mesečno oziroma po potrebi imela sestanek z Paul-om, ki je vodja tega projekta. Z Paul sva se pogovarjala o samih ciljih projekta in tudi o podrobnostih implementacije 24 / 37

kakšne komponente oziroma problema. Kot sem napisal že na začetku je projekt še v zgodnji fazi in aktivnem razvoju, kar pomeni, da se večje spremembe v tej fazi dogajajo tedensko, razvoju pa se najlažje sledi na Github-u. 25 / 37

7 SKLEP Zahvalil bi se podjetju Cloudkick, ki mi je omogočilo praktično izobraževanje. Veliko tehnologij in produktov, ki se uporabljajo v podjetju sem sicer vsaj delno poznal že prej ampak tukaj sem svoje znanje pri določenih tehnologijah še dodatno poglobil. Dobil sem tudi veliko praktičnih izkušenj pri nadzorovanju velikega števila strežnikov in obdelavi velike količine podatkov. Popolnoma drugače je, če kakšno stvar testiraš sam na nekaj strežnikih ali pa v produkciji s 150 in več strežniki ter veliko količino podatkov, ki vsak dan strmo narašča. Zraven pridobitve velike količine tehničnega znanja pa sem dobil pomembne izkušnje na področju sodelovanja v ekipi. 26 / 37

8 POVEZAVE [1] Cloudkick spletna stran - http://www.cloudkick.com [2] Rackspace spletna stran - http://www.rackspace.com [3] Django ogrodje - http://www.djangoproject.com [4] Twisted ogrodje - http://www.twistedmatrix.com [5] Cassandra podatkovna baza - http://cassandra.apache.org [6] Google Closure ogrodje - http://code.google.com/closure [7] Scribe - https://github.com/facebook/scribe [8] Solr - http://lucene.apache.org/solr [9] Mysql - http://www.mysql.com [10] Apache httpd - http://httpd.apache.org [11] RabbitMQ - http://www.rabbitmq.com [12] txamqp - https://launchpad.net/txamqp [13] Esper - http://esper.codehaus.org [14] libcloud knjižnica - http://www.libcloud.org [15] PagerDuty spletna stran - http://www.pagerduty.com [16] Cloudkick Viz - https://www.cloudkick.com/viz/demo [17] Cast projekt - https://github.com/cloudkick/cast [18] Lua programski jezik - http://www.lua.org [19] Redis podatkovna baza - http://www.redis.io [20] Redis podatkovna baza (opis podatkovnih struktur) - http://www.redis.io/topics/datatypes-intro [21] Redis podatkovna baza (opis ukazov) - http://www.redis.io/commands [22] lunit Lua knjižnica za testiranje - http://www.nessie.de/mroth/lunit 27 / 37

[23] NodeJS ogrodje - http://nodejs.org [24] JavaScript The Good Parts knjiga - http://oreilly.com/catalog/9780596517748 28 / 37

9 PRILOGE 9.1 Priloga 1: Izvorna koda vtičnika -- -- Copyright (c) 2010, Cloudkick, Inc. -- All right reserved. -- module(..., package.seeall); local socket = require 'socket' local helen = require 'helen' local util = require 'util' local Check = util.check local metric_types = { } uptime_in_seconds = Check.enum.uint66, connected_clients = Check.enum.uint64, connected_slaves = Check.enum.uint64, blocked_clients = Check.enum.uint64, used_memory = Check.enum.uint64, -- in bytes bgsave_in_progress = Check.enum.uint64, changes_since_last_save = Check.enum.uint64, bgrewriteaof_in_progress = Check.enum.uint64, total_connections_received = Check.enum.gauge, total_commands_processed = Check.enum.gauge, expired_key = Check.enum.gauge, pubsub_channels = Check.enum.uint64, pubsub_patterns = Check.enum.uint64 local function get_stats(rcheck, host, port, password) local s, status, partial local ip, _ = socket.dns.toip(host) if not ip then 29 / 37

rcheck:set_error('failed resolving hostname to IP address') return rcheck local func = socket.protect(function() local sock, err = socket.connect(ip, port) local try = socket.newtry(function() sock:close() ) if not sock then rcheck:set_error('unable to connect to the redis server') return rcheck sock:settimeout(5) if password then try(sock:s('auth '.. password.. '\n')) s, status, partial = sock:receive('*a') if not partial then error() if not string.find(partial:lower(), 'ok') then rcheck:set_error('could not authenticate. Invalid password?') return rcheck try(sock:s('info\n')) s, status, partial = sock:receive('*a') if not s and not partial then error() if string.find(partial:lower(), 'operation not permitted') then rcheck:set_error('could not authenticate. Missing password?') 30 / 37

for _, line in ipairs(util.split(partial, '[^\n]+')) do repeat local split = util.split(line, '[^:]+') if not split then break local metric, value = split[1], split[2] if not (util.table.contains(metric_types, metric, 'key')) then break rcheck:add_metric(metric, metric_types[metric], tonumber(value)) until true sock:close() ) local rv = pcall(func) if not rv then rcheck:set_error('failed parsing server response') return rcheck function run(rcheck, args) local hostname, port local password = nil if not args.host then host = '127.0.0.1' else 31 / 37

host = args.host[1] if not args.port then port = 6379 else port = tonumber(args.port[1]) if args.password then password = args.password[1] rcheck = get_stats(rcheck, host, port, password) return rcheck 32 / 37

9.2 Priloga 2 izvorna koda modula s pomožnimi funkcijami za testiranje -- -- Copyright 2010, Cloudkick, Inc. -- -- Licensed under the Apache License, Version 2.0 (the "License"); -- you may not use this file except in compliance with the License. -- You may obtain a copy of the License at -- -- http://www.apache.org/licenses/license-2.0 -- -- Unless required by applicable law or agreed to in writing, software -- distributed under the License is distributed on an "AS IS" BASIS, -- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -- See the License for the specific language governing permissions and -- limitations under the License. -- module(..., package.seeall); local lanes = require 'lanes' local util = require 'util' local buffer = alien.buffer() local getcwd = alien.default.getcwd getcwd:types('pointer', 'string') getcwd(buffer) local cwd = tostring(buffer) local local_plugins_path_default = cwd.. '/tests/' local munin_plugins_path_default = cwd.. '/tests/' local function get_conf_object(local_plugins_path, munin_plugins_path) local local_plugins_path = local_plugins_path or local_plugins_path_default local munin_plugins_path = munin_plugins_path or munin_plugins_path_default 33 / 37

local conf = {} conf.local_plugins_path = local_plugins_path conf.munin_plugins_path = munin_plugins_path return conf function get_check_module(check_name, local_plugins_path, munin_plugins_path) local rv, check = pcall(require, check_name) if rv then check.conf = get_conf_object(local_plugins_path, munin_plugins_path) return rv, check local function _run_test_tcp_server(ip, port, timeout, mode, mappings) local ip = ip or '*' local timeout = timeout or.01 local mode = mode or 'line' local mappings = mappings or {} local func = lanes.gen({ cancelstep = true}, function() local client, line, err, command, response socket = require 'socket' local server = assert(socket.bind(ip, port)) local parse_line = function(line, client) line = util.trim(line) if util.table.contains(mappings, line, 'key') then response = mappings[line] client:s(response) 34 / 37

return true return false while true do local client = server:accept() local buffer = '' local match = false client:settimeout(timeout) line, err = client:receive('*l') while line do if mode == 'line' then if not err then if parse_line(line, client) then -- Match found, close the connection client:close() else client:close() buffer = buffer.. line.. '\n' line, err = client:receive('*l') if mode == 'line' then client:close() elseif mode == 'http' then local buffer_lower = buffer:lower() for key,value in pairs(mappings) do local match_pattern = value['match_pattern']:lower() 35 / 37

'\n'.. if string.find(buffer_lower, match_pattern) ~= nil then match = true local response = value['response'] local response_len = string.len(response) local header = 'HTTP/1.1 '.. value['status_line'].. 'Content-type: '.. value['content_type'].. '\n'.. '\n\n' 'Content-Length: '.. response_len.. client:s(header.. response) break if not match then client:s('http/1.1 404 Not found\n\n') ) client:close() local lane = func() -- Wait until the lane is running while lane.status ~= 'running' do return lane function run_test_http_server(ip, port, timeout, routes) local content 36 / 37

for key,value in pairs(routes) do if value['file'] ~= nil then local path = cwd.. '/tests/'.. value['file'] local file = assert(io.open(path, 'r')) content = file:read('*a') file:close() else content = value['response'] routes[key] = { ['match_pattern'] = value['method']:upper().. ' '.. key, ['status_line'] = value['status_line'], ['content_type'] = value['content_type'], ['response'] = content } return _run_test_tcp_server(ip, port, timeout, 'http', routes) function run_test_tcp_server(ip, port, timeout, command_mappings) return _run_test_tcp_server(ip, port, timeout, 'line', command_mappings) function kill_test_server(lane, timeout) local timeout = timeout or 0 lane:cancel(timeout, true) 37 / 37