RabbitMQ easy start

čtvrtek 26. června 2014

Už nějaký čas si hraju s message brokerem, konkrétně tedy s RabbitMQ. Tady je pár tipů pro práci s ním.

Instalace

Klasický instalation guide je k nalezení na oficiálních stránkách

Po nainstalování budete mít prázdný konfigurační soubor v
config file(s) : /etc/rabbitmq/rabbitmq.config

Buďto tedy projdete všechny možné konfigurační volby nebo zkusíte použít nějaké GUI.

RabbitMQ má docela šikovnou grafickou nástavbu v pluginu rabbitmq_management

Povolíte jej jednoduchým příkazem
rabbitmq-plugins enable rabbitmq_management

Poté je možné se přihlásit na adrese
http://example.com:15672/
pozn. Dejte si pozor na firewall, port 15672 obvykle nebývá odblokovaný :)

Přihlásíte se můžete loginem guest / guest.

Měli byste vidět takového GUI

První co důrazně doporučuji je vytvořit si nového administrátora v Admin/Users a guest přístup zablokovat.

Producer, Exchanges, Queues, Consumer

Chvilku mi trvalo než jsem pochopil jakej je v tom rozdíl a co to vlastně je. Producer zprávu odesílá na exchange což je jenom takový pošťák, který na základě routovacích pravidel doručí zprávu do patřičné queue.

Máme dvě aplikace jedna je signup, která chce odesílat důležité emaily o registraci uživatele apod. A pak máme aplikaci, která chce rozesílat newsletter.

Když newsletter dorazí o půl hodiny později, pravděpodobně se svět nezboří, ale neplatí to naopak u signup. Pokud uživatel čeká na daný email, tak asi není vhodné aby čekal pul hodiny.

Proto využijeme routingu a emaily budeme posílat s route "email.low" nebo "email.top". Aplikace tedy pošle zprávu na exchange s nějakou routou a o víc se nestará.

Exchange v sobě drží pravidla o routování a na základě charakteru té zprávy je přiřadí konkrétní Queue. Z Queue potom putuje ke konkrétnímu Consumerovi, který ji zpracuje a odešle jako email dále do světa. 

Producer - vytváří zprávy pro rabbita
Exchange - pošták který na základě route nebo argumentů zprávu zařadí do Queue
Queue - FIFO list zpráv
Consumer - Konzumuje zprávy z Queue.

RabbitMQ Simulator

Asi by bylo fajn kdybyste si mohli nasimulovat chování v Rabbitu bez nutnosti provozování všech consumerů a producerů. 
Existuje utilitka RabbitMQ Simulator, která vám toto umožní.

Vyzkoušet si ji můžete na www.tryrabbitmq.com. Pokud budete chtít importy / exporty nastavení do vašeho rabbita tak si ji musíte rozběhat na serveru jako nodeJS aplikaci. Instalace a zdrojáky jsou na github.com/RabbitMQSimulator/RabbitMQSimulator

Zprávy

Queue mohou být dvojího typu.
  • Durable - zprávy jsou v Rabbitu zapsány na disk a v případě restartu serveru jsou obnovena z disku
  • Transient - zprávy se ztratí po restartu serveru
V momentě kdy RabbitMQ zprávu doručí, tak jí trvale maže a není možné jí obnovit. Co to ale znamená, že jí doručí? Záleží na parametrech zprávy, jsou opět dva.
  • Non-persistent - zpráva je odeslána na consumera a smazána
  • Persistent - rabbit po odeslání zprávy čeká na potvrzení od consumera. Pokud toto potvrzení nedostane do definovaného času, tak ji zkusí doručit znovu.
Best practise - Vždy potvrzujte zprávu až potom co ji zpracujete, nikoliv v momentě kdy ji přijmete! Mohlo by se totiž stát, že v průběhu zpracování zprávy vám consumer spadne a vy nebudete schopni tuto operaci dokončit. Čímž o zprávu přijdete.

Jak dál?

Tématika Rabbitu je opravdu rozsáhlá, dalo by se napsat ještě spousta věcí například o HA clusteru, posílání odpovědí, topic/direct, virtual host atd.
Buďto se mrkněte do oficiálních tutoriálů www.rabbitmq.com/getstarted.html nebo piště do komentářů.

Záměrně jsem se vyhnul textu o producerech a consumerech v PHP, protože jej napsal můj kamarád Filip Procházka na svém blogu http://filip-prochazka.com/blog/kdyby-rabbitmq-aneb-asynchronni-kdyby-events

Přijímání zaměstnanců není černobílá věc

pondělí 21. dubna 2014

Tak už jsme našli vývojáře. Původně jsme hledali pouze jednoho vývojaře, ale dorazilo několik desítek žádostí, tak jsme vzali hned 3 z nich.
Ale hezky od začátku, spousta z nich se eliminovala sama, viz. předchozí blogpost Jak rozhodně nežádat o práci.

Z téhle skupiny lidí jsme vybrali 5 lidí, kteří postoupí do dalšího kola. Zbytek byl nemilosrdně eliminován, někdy i kvůli maličkostem (SQL injection v ukázkovém kódu atd.), bohužel bylo to potřeba nějak protřídit.

Následoval pohovor se 3. Jeden neměl zájem spolupracovat dlouhodobě. Další bohužel nemohl ze zdravotních důvodů, což byla velká škoda (myslím, že i pohovorem by prošel bez problému).

Pohovor s jedním dopadl výborně dle očekávání. U zbývajících dvou to bylo slabší. V ten moment jsme se ale rozhodli, že otevřeme více vývojářských pozic.

Do původní pětice přibili ještě dvě jména. Shodou okolností, oba jsme nakonec přijali, i když jsem je nechtěl pustit do druhého kola. Ale měl jsem asi slabší chvilku a řekl jsem si, že ten pohovor zkusím, inu vyplatilo se.

Pohovor

Připravil jsem si sadu otázek (konkrétní znění sem nebudu dávat, ať je můžu použít i příště :)).
Dal jsem si za úkol zjistit o uchazeči tyhle věci
  • Jak sám sebe vzdělává, jak sleduje aktuální dění na poli PHP atd.
  • Jak umí pracovat s API (soap - rest, json - xml)
  • Jak zná bezpečnost (hashe, šifry, útok na web atd.)
  • Jestli má pokročilé znalosti objektově orientovaného návrhu aplikací
  • Znalost SQL dotazů - človek by nevěril, že nedaj dohromady jakej je rozdíl mezi inner a left join :(
  • Doctrine2 - par dotazů ohledně entit, trošku věcí pod pokličkou - k čemu je proxy atd.
  • Optimalizace databáze (indexy, view, triggery, explain command atd.)

Informování uchazečů

Koho ve finále vybrat bylo strašně těžký. Jasno jsme měli akorát u jednoho (perfektní reference, znalosti a zkušenosti), u zbytku to bylo mnohonásobně těžší. Ale docela mě překvapili dvě odpovědi, když jsem jim zaslal zprávu, že jsme je nepřijali.
OK dik za info, tak snad jste vybrali lepe :) Na pohovor jsem se mohl asi pripravit a dopadlo by to mozna jinak, no nevadi.
Jak to vidím já, tak evidetně o tu práci zájem neměl. Když mi napíše, že se na ten pohovor ani nepřipravil. Pokud by mu na té práci záleželo, tak se aspoň na ten pohovor zkusí připravit. Jednoznačně si tenhle člověka pohoršil na pomyslném žebříčku budoucích uchazečů.

Odpověd od druhého zájemce
Nic ine som necakal, je to spravodlive, uz v priebehu rozhovoru mi to bolo jasne :)
Neberem to ako prehru, ale ako vyzvu, hlavne v teorii pokulhavam, zistil som kde mam medzery, ako som povedal nemam problem sa ucit, ale clovek sa vacsinou uci to co priamo potrebuje k praci, hned na druhy den som objednal nejake knihy a studujem po nete problematiku, kazdopadne dakujem za skusenost, doteraz som v podstate na takomto pohovore nebol. Nieco mi to urcite dalo, znova ma to posunie o trosicka v pred.
Drzim palce a prajem vela uspechov!

Když jsem četl toto, tak jsem i zapřemýšlel jestli bychom neotevřeli i 4. místo pro vývojáře. Bohužel 3 vývojáři už je dost. Každopádně tenhle člověk se automaticky posunul na první místo v pomyslném žebříčku a když se uvolní místo vývojaře, tak mu jdu okamžitě napsat. Což se může stát relativně brzo :)

Jednoduchý webový cluster pomocí HaProxy

pondělí 7. dubna 2014

HaProxy

HaProxy je jedna z nejrozšířenějších služeb používaných například aplikacemi
typu Twitter, Github, Instagram, Reddit, Tumbrl.
Pro účely tohoto článku potřebujeme k dispozici tři virtuální servery pro demonstraci příkladů.


Instalace

Na stanicích s nainstalovanými Ubuntu stačí spustit příkaz apt-get install haproxy.
Konfigurační soubor se nachází v /etc/haproxy/haproxy.cfg. Ukázkovou konfiguraci, která je již uvedena v souboru můžeme klidně smazat.

Ukázková konfigurace klasického loadbalacingu

Základní loadbalancing, který každý požadavek posílá na náhodný webový server. 

HaProxy.cfg
global
        daemon
        maxconn 256

    defaults
        mode http
        timeout connect 5000ms
        timeout client 50000ms
        timeout server 50000ms

    frontend http-in
        bind *:80
        default_backend cluster1

    backend cluster1
        server webserver 192.168.1.107:80
        server webserver2 192.168.1.108:80
        balance roundrobin

Máme definovaný cluster1, který obsahuje dva servery a veškeré příchozí požadavku na portu *:80 posíláme právě na definovaný cluster1.

Statistiky

Pro získání detailních statistik, z HaProxy stačí přidat tento kousek konfigurace do HaProxy.cfg.
listen  lb_stats
        bind    *:8080
        mode    http
        balance roundrobin
        stats   uri /
        stats   realm "HaProxy Stats"
        stats   auth user:pass

Statistiky poté nalezneme na adrese http://192.168.1.106:8080.
Jak je vidět z konfigurace používáme port 8080 (port 80 je obsazen pro vyřizování příchozích požadavků na cluster1). Také je dobré z hlediska bezpečnosti nastavit login a heslo, v našem případě se jedná o přístupové jméno user heslo pass.



Jak rozhodně nežádat o práci

Díky inzerátu, že do Shipita hledáme nového kolegu se mi ozvalo docela velké množství lidí. Ovšem některé žádosti jsou tak kouzelné, že bych se rád s vámi o ně podělil, protože takhle opravdu ne.

Buďte si jisti

Vaše nabídka mě velice zaujala, ale nejsem si jist, zda jsem pro Vás ten pravý uchazeč.
Tohle vážně není dobrá druhá věta. Pokud o tu práci máte zájem, tak se snažte hledat důvody, proč jste ten pravý uchazeč. A né hned vypálit, že na to vlastně nemáte

Technologie pište bez překlepů

Symphony a Doctrine jsem nikdy nepouzival. Naposledy jsem delal v PHP za casu vysoke skoly, mel jsem brigady, kde jsem pouzival PHP a ZendFramework. 
Nevadí, že tu technologii neumíte, není problém se ji doučit. Ale ukažte entusiasmus, že se ji chcete naučit. A ne prostě ja jí neumím a ještě ji napíšete blbě (je to Symfony).

Nezmiňujte fail projekty a už vůbec né ty první

V PHP programuji více jak 10 let. První zkušenosti jsem získal ještě při studiu na VŠ, kde jsme s kolegou připravili stránky o fauně středozemního moře ( http://web.archive.org/web/20020831062526/tady-byla-url-webu). I skrze WayBack Machine je poznat, že šlo o dost nedokonalou aplikaci, kde není ani využita databáze pro ukládání dat.
Každý jsme nějak začínali, i můj první web do teď běží a je prošpikovaný SQL Injection, XSS apod. Ale probůh to není referenční projekt, raději napiště, že žádný projekt nemůžete zveřejnit kvůli NDA. Nechte si poslat nějaké testovací zadání. Je docelá smutné, že po 10 letech programování v PHP zmiňujete první zkušenost.

Nepodceňujete se 

Zaujal me inzerat na tuhle pracovni pozici na strankach fora Nette. Tusim, ze pravdepodobne hledate nekoho s co nejlepsimi zkusenostmi, nebo profesionalniho programatora, ale i tak mi prislo, ze za zkousku nic nedam.
Hned ve druhé větě se podcenit vám moc kreditu nepřidá. Pište o plusech a ne o mínusech (ty stejně časem vyplynou na povrch, ale už to může být za situace, že máte přiklepnutou práci).



Celkově mi přijde, že se lidi v čechách neumí vůbec prodávat. V US je každý průměrný dělník mistr prodeje. Snaží se sám sebe prodat v co nejlepšim světle.

Tohle je úryvek z Johnovi knížky, který to úplně nádherně vystihuje.
Lidé v USA umí velmi dobře prodávat
Tím „prodávat“ myslím, že umí prodávat sami sebe. Už ve školách se
studenti učí, jak absolvovat pohovory nebo jak psát resumé. Na pohovory
(v USA se jim říká interview) mi chodí většinou perfektně oblečení lidé, kteří
dokážou přesvědčit svým nadšením, perfektním jednáním, výbornými referencemi
a úsměvem na tváři. 
Hodně často se mi však stalo, že když jsem takového člověka zaměstnal
a on pak přišel do práce, tak jsem ho ani nepoznal. Úsměv a nadšení se vytratily
v okamžiku, kdy dotyčný začal pracovat. Přístup, že nic není problém, úplně
zmizel. Neříkám, že se to stane u každého uchazeče, ale stává se to často. 
Lidé se dokonale připravují, než jdou na job interview. Jdou ke kadeřníkovi,
oblečou si nejlepší šaty, naučí se perfektní odpovědi – prostě dokážou
všechno udělat na jedničku. Během pohovoru je extrémně těžké udělat si
o uchazeči přesný obrázek. Proto je potřeba nenechat se oslnit takovým perfektním
uchazečem. Je potřeba přesně zjistit, kdo je nejlepší člověk na danou
práci.

Pozn. článek není myšlen nijak posměvačně, jen se snažím poukázat na chyby. Snad to někdy někomu pomůže :)

ORM Designer 2.2

úterý 7. ledna 2014


Tak jsem si vyzkousel ORM Designer 2.2, myslenka je dobra ale pro realnou praci to ma az moc chyb a nedodelku.
  • Neni mozne udelat undo/redo  nova verze uz to zvlada
  • Vygenerovanym tridam nejde nastavit automaticky namespace, takze si vsechny musim otevrit a pridat do nich spravne namespace
  • Neumi to generovat constructor, takze vsechny kolekce stejne nefungujou (nejsou to nainicializovany tridy ArrayCollection)
  • Neumi to gettery / settery a vsechny property jsou private, takze v kazdy entite je potreba vygenerovat potrebne metody
  • Nedokazu vsechno spravne pojmenovat napoprve, takze pri navrhu treba 5x prepisu jmeno entity, jenze to nijak neovlivni vazby (ostatni entity jsou porad vazany na neexistujici jmeno entity - tedy te stare).
  • Nejde zmenit typ projektu, jakmile ho jednou definujete jako Cake tak uz na dosmrti zustane jako Cake a nepredelate ho na Symfony2. Vsechny entity musite rucne prepsat. Vyzkousel jsem si to na projektu se Symfony2 a neni tam vubec zadne napojeni. Proste to vygeneruje entity, zadnou vazbu na S2 jsem nenasel, takze totalne nechapu proc to nejde zmenit.
  • Pokud rucne zmenite entity a pak omylem kliknete na button Export to ORM, tak prijdete o vsechnu praci! (vyzkouseno za vas).

    Vygenerovalo mi to neco takovedleho, coz je nejakej hybrid mezitim co jsem tam mel ja a co je verze z ORM Designeru
class Type
{
    /** 
     * @ORM\Id
     * @ORM\Column(type="integer")
     */
    private $id;

    /** 
     * @ORM\Column(nullable=true)
     */
    private $name;

    /** 
     * @ORM\OneToMany(targetEntity="Trip", mappedBy="tripTypes")
     */
    private $trips;
}

/** 
 * 
 */
class Type
{
    /** 
     * 
     * 
     */
    private $id;

    /** 
     * 
     */
    private $name;

    /** 
     * 
     */
    private $trips;
}