You are currently browsing the archives for the arquitetura category


Composição e Integração de Sistemas em 2013

Hoje estive falando no TDC 2013, na trilha Arquitetura .NET, sobre a estratégia de compor e integrar sistemas a partir de micro-serviços, que é um tema que tenho bastante interesse e pretendo ainda falar um pouco mais a respeito, em eventos e aqui no meu blog.

Esta foi a segunda vez que falei nesse evento e, assim como no ano passado, a sala estava lotada, o pessoal bem interessado e participativo; e no final, uma galerinha veio trocar uma idéia comigo, fazer perguntas, etc. Foi bem bacana mesmo.

Parabéns aos organizadores e ao pessoal que participou!

Sistemas para o Mundo Real no InfoQ BR

Só hoje me dei conta de que o site InfoQ do Brasil publicou o vídeo da palestra que fiz no TDC 2012, intitulada Sistemas para o Mundo Real.

É isso aí, divirtam-se!

Sistemas para o Mundo Real, outra vez… no TDC 2012

Semana passada estive no TDC 2012, apresentando minha palestra Sistemas para o Mundo Real na trilha de arquitetura. Foi bem bacana, a sala estava cheia, a galera super interessada, motivada, valeu muito a pena.

Esta foi a primeira vez que estive neste evento e gostei bastante, viu?! Achei super bem organizado e diversificado, os organizadores estão de parabéns.

Ano que vem estarei lá novamente, com toda certeza. ;)

Sistemas para o Mundo Real

Acabei de apresentar minha palestra Sistemas para o Mundo Real no Abril pro Ruby 2012, a primeira edição de um evento muito promissor da comunidade Ruby de Recife/PE, organizado pelo Victor Cavalcanti e seus companheiros do Frevo on Rails, e patrocinado pela Locaweb, redueventick e ThoughtWorks.

E muito embora seja um evento focado em Ruby, feito pela comunidade Ruby, para programadores Ruby, minha palestra não foi focada em Ruby, foi mais abrangente, mais focada em preocupações com arquitetura e operação dos sistemas em produção. Não foi nada muito profundo, foi mais um overview mesmo, para fomentar o assunto e estimular a galera a pesquisar, estudar e levar essas preocupações em conta.

A boa notícia é que tem muita gente aqui interessada no assunto.

Sistemas para o Mundo Real

slogger: lugar de mensagens de log é no Syslog

Uma coisa importante que aprendi na convivencia com os melhores sysadmins de Linux que já trabalhei (esse e esse, por exemplo) é que lugar de log é no Syslog – e se você não está fazendo isso, hummm, há uma boa chance de you’re doing it wrong my friend.

…and in The .NET World

A melhor prática para aqueles que trabalham com .NET é escrever log com o Event Log. Os melhores sysadmins de Windows que conheço estão sempre ligados (Nagios? Zabbix?) no Event Viewer.

Então, apesar deste post se destinar a Ruby/POSIX, fica a dica do Renato Lucindo – no final desse post – para a galera de .NET/Windows também.

Bem, como a biblioteca padrão do Ruby para escrever no Syslog não é lá muito amigável, resolvi facilitar um pouco as coisas e criei a gem slogger.

Dois exemplos rápidos

Antes de mais nada, installe a gem:

$ gem install slogger

Log simples:

slogger = Slogger::Logger.new "sample_app", :debug, :local0
slogger.info "A good info"
slogger.debug "A deep info"

Log com tempo de execução:

slogger = Slogger::Logger.new "sample_app", :debug, :local0
slogger.info "A really good info preceded by spent time" do
    # do something
end

Depois, claro, dê uma olhada no seu Syslog, para ver as mensagens “logadas”.

A lambuja

Se você estiver usando Sinatra, por exemplo, pode usar o middleware Slogger::Rack::RequestLogger em vez do famoso Rack::CommonLogger, que usa Logger (não que o Logger seja ruim).

configure do
  slogger = Slogger::Logger.new "sample_app", :debug, :local0
  use Slogger::Rack::RequestLogger, slogger
end

E a dica final

Ecoando a dica do Renato Lucindo: não seja ingênuo, log everything!!!

Tá esperando o que para começar a fazer a coisa direito?

A Locaweb está contratando!

A Locaweb está procurando por desenvolvedores experiêntes e talentosos para integrar nossos times de SaaS, Cloud Computing, Hospedagem, Q&A e Sistemas Centrais.

Se você tem experiência em Ruby, Python, Java, .NET, PHP, Perl, bancos de dados relacionais e não-relacionais, arquiteturas distribuídas, sistemas de agendamento de tarefas, filas assíncronas, desenvolvimento web, e umas coisinhas mais, pode ser que tenhamos um lugar aqui para você. Que tal?

O perfil completo pode ser visto na integra aqui, no OndeTrabalhar.com.

ReactiveJ: uma brincadeirinha com Evented I/O

Estive estudando e brincando um pouco com evented I/O nas últimas duas semanas e resolvi então fazer uma implementação disso em Java, usando a Java NIO, que biblioteca de I/O não-blocante da plataforma Java, e seguindo o pattern Reactor.

Bem, o resultado dessa brincandeira pode ser visto aqui, no projeto ReactiveJ.

Ainda é um projeto de brincandeira, uma coisa didática, sem qualquer otimização extra de performance. Portanto, não é production ready. Quem sabe algum dia, caso eu leve a brincadeira a sério.

Se gostarem da brincadeira e quiserem continuar explorando o assunto, tenho mais uns links pra vocês:

Divirtam-se!

O quanto realmente importa a escolha de uma linguagem?

Há alguns meses perguntaram ao Rich Hickey:

“How much does a choice of language really matter? Are there good reasons to choose one language over another or does it all come down to taste?”

E sua resposta foi:

“I think it matters quite a bit. A good language is opinionated, and strives to make a particular style of programming easy and idiomatic. It only seems a matter of taste when you are comparing languages that are more similar than they are different, like Java/C# or Python/Ruby. Try something really different like Clojure, Haskell, or Erlang and the fact that it matters becomes readily apparent.”

Eu acho que concordo bastante com sua opinião. Discutir se Java é melhor do que C#, por exemplo, é inútil, porque as duas linguagens são muito semelhantes. Nesse caso, o que acaba pesando mais na hora da escolha é o ecosistema no qual cada linguagem está inserida, que pode agradar mais a um ou a outro programador. É puro gosto.

O mesmo vale para Ruby e Python, como ele mesmo cita.

Mundos diferentes

Mas e se a comparação for entre Java e Ruby, por exemplo, como é que fica? Na minha humilde opinião, fica no sense. Porque Java e Ruby não são liguagens de mesma proposta; e mesmo sendo ambas de propósito geral, ambas tem objetivos claramente diferentes.

Comparação entre mundos diferentes

Agora vou, propositalmente, contradizer um pouco o que eu disse à cima: faz sentido, sim, você comparar Ruby com Java; Erlang com Python; F# com PHP. Sim, faz sentido.

Faz sentido quando você está escolhendo a linguagem que oferece a melhor solução para um dado domínio de problema.

Super CRUD com Erlang? Não, acho que não.

Precisar de concorrência massiva, tolerância a falhas, processos distribuídos, downtime mínimo? Humm, não sei não, mas será que não é de Erlang que você precisa?

Entende? É nessa hora que a escolha de uma linguagem começa a pesar de verdade. Isso realmente importa.

Mundos diferentes se complementam

Tempos atrás, escrevendo programas Erlang/OTP, senti falta de uma ferramenta que me ajudasse a criar rapidamente a estrutura inicial do projeto e umas coisas mais. O que fiz? Criei uma ferramenta que faz isso: otp_kickoff. Em Erlang? Não, em Ruby. Fiz isso em poucas horas, usando Thor.

Pouco tempo depois, senti falta de uma ferramenta de build amigável. Novamente, o que fiz? Criei o ebuilder, usando Ruby/Thor.

Um outro exemplo de mundos diferentes que se complementam é o JSparrow, um cliente de JMS bem fluente, que fiz usando JRuby.

Essa é a ideia de tirar o melhor de cada linguagem!

Mesmo porque, dificilmente, você constroi um sistema de verdade – que não seja um super CRUD – com apenas uma única linguagem de programação. Na minha equipe mesmo, há sistemas desenvolvidos em C# .NET, que são buildados, testados e deployados com Ruby/Rake/Cucumber e usam Java/Ivy como repositório de assemblies. Isso sem falar em JavaScript, que também tem de monte.

Esse é o mundo real dos sistemas de verdade.

Moral da história

Isso me faz pensar que brigas de fanboys de linguagens – em frenéticas buscas por prosélitos – são uma verdadeira piada.

Erlang: Programação Distribuída de maneira simples

Fazia tempo que estava para blogar algo sobre como é fácil fazer programação distribuída com Erlang. Derrepente, hoje, acabei perdendo o sono e eis aqui o post.

O mais simples do mundo

Pra começar, vamos ver o exemplo mais simples de computação distribuída que se pode fazer e aprender alguma coisa com ele. Ele é como um simples chat. Pois muito bem, vejamos!

Fazendo o setup

No terminal, inicie um Eshell com o seguinte comando:

$ erl -sname jose

E num outro terminal, inicie outro Eshell com:

$ erl -sname maria

Agora vá no primeiro terminal, no Eshell do José, e execute o seguinte comando:

(jose@codezone)1> register(console_jose, self()).

E no segundo terminal, no Eshell da Maria, faça o mesmo:

(maria@codezone)1> register(console_maria, self()).

Tudo bem, setup feito, hora do bate-papo!

Jogando conversa fora

“Ei José, diga oi…”

(jose@codezone)2> {console_maria, 'maria@codezone'} ! "Oi Maria, tudo bem?".

Veja o terminal da Maria. O que aconteceu? Nada? A mensagem não chegou? Chegou, chegou sim. Vejamos:

(maria@codezone)2> regs().

Na primeira coluna, procure pelo processo console_maria. Achou? Agora veja na última coluna desse processo. Que número tem aí? 1? Pois é, isso nos indica uma coisa. Ainda nesse Eshell, execute o seguinte comando:

(maria@codezone)3> flush().

Opa! E agora? Shell got “Oi Maria, tudo bem?”, certo? Taí a mensagem que a Maria recebeu do José.

Agora, que tal a Maria ser gentil com o José e responde-lo cordialmente?

(maria@codezone)4> {console_jose, 'jose@codezone'} ! "Vou bem, e voce?".

Se você quiser, pode ver o registro de processos no Eshell do José, como fez anteriormente com o da Maria. Ou pode simplesmente:

(jose@codezone)3> flush().

E receber a mensagem Shell got “Vou bem, e voce?”.

Entendendo tudo isso

Por sorte, não há muito o que explicar até aqui – já que fizemos o exemplo mais simples do mundo. Uff!

Que tal começar do começo? Vamos entender os passos de setup?

1- A primeira coisa que fizemos foi iniciar dois Eshell que, na verdade, tornaram-se dois nós do nosso cluster de runtimes Erlang.

Todas as vezes que você inicia um Eshell com a flag -sname, o que você está fazendo é criar um nó de runtime Erlang na sua rede. Na verdade, isso pode ser feito também com a flag -name.

Qual a diferença entre elas?

-sname cria o nó e dá a ele um “short name”: nome_do_no@host;
-name, pelo contrário, cria o nó dá a ele um “long name”: nome_do_no@ip_address ou nome_do_no@host.local, no caso de rede local.

Você pode perfeitamente iniciar diversos nós em uma mesma máquina, como fizemos a pouco. No entanto, você não pode duplicar os nomes dos nós, uma vez que estes são usados para identificá-los no cluster e torná-los comunicáveis uns com os outros.

“Lembrando que o nome dos nós são sempre sufixados pelo nome/ip do host, não há problema algum em ter o mesmo nome de nó em máquinas diferentes.”

Uma outra coisa interessante de aprender aqui é como os nós se comunicam. Toda comunicação entre nós é feita por um daemon chamado epmd. Este programa faz parte do sistema de runtime Erlang e tem um papel fundamental em sua arquitetura de clusters, porque sempre que “o primeiro nó” é iniciado numa máquina, automaticamente, ele também é iniciado, caso ainda não tenha sido, e passa a escutar mensagens na porta 4369 e rotea-las para o nó apropriado.

“Independente de quantos nós estejam rodando numa máquina, sempre haverá apenas uma instância do epmd rodando.”

Por fim, ainda sobre o setup dos nós do cluster, há uma outra flag que não demonstrei no exemplo acima, mas que é bem interessante e você depois pode pesquisar a respeito.

-setcookie define um “secret cookie” que serve como um tipo de token para autenticar a comunicação entre os nós do cluster. Isso quer dizer que, somente os nós iniciados com um mesmo cookie podem se comunicar. Por outro lado, sempre que um nó é iniciado sem especificar um cookie, o runtime Erlang toma a liberdade de cria um e gravar no arquivo ~/.erlang.cookie. Nestes casos, todos os nós não iniciados com um cookie compartilharão o mesmo cookie guardado nesse arquivo.

No caso do nosso exemplo ultra simples, um cookie poderia ser usado para criar uma sala de bate-papo, onde: se um nós é iniciado informando um cookie, ele entra na sala equivalente; no entanto, quando não informado, vai para uma sala genérica.

Interessante? Pois é… E esse assunto acaba puxando o da flag -hidden, que você pode aproveitar e pesquisar também.

2- A segunda coisa que fizemos no setup foi registrar um processo alvo de nossas mensagens.

Como a idéia aqui é explicar – um pouco, porque ainda há uma porção de coisas que poderiam ser faladas, mas isso deixaria esse post imenso! Dê uma olhada na documentação oficial como funciona a arquitetura de cluster de runtimes Erlang e mostrar como este provê uma maneira simples de programação distribuída, preferi não escrever um programa de chat, mas apenas usar o próprio Eshell para isso.

Com este pré-requisito em mente, o que fiz foi apenas registrar o próprio processo do Eshell – usando self(), que você entende como funciona com um nome especifico em cada nó do cluster (console_jose para um e console_maria em o outro) para fazer a troca de mensagens entre eles.

E o bate-papo, como é que rolou?

Essa é a parte mais fácil da coisa, na minha opinião. Se você já lidou com processos em Erlang, vai tirar de letra.

1- Trocamos mensagens entre os dois processos de maneira bem semelhante ao que fazemos normalmente com processos contidos num único runtime.

A única diferença aqui é que, em vez de simplesmente codarmos algo como console_jose ! “Show de bola”, codamos {console_jose, ‘jose@codezone’} ! “Show de bola”. Ou seja, além no nome do processo, informamos também em que nó do cluster ele está, tudo em uma tupla.

Um exercício legal de você fazer é o seguinte…

a. No Eshell da Maria execute:

(maria@codezone)5> console_maria ! "Show de bola".
(maria@codezone)6> flush().

b. Depois, ainda no Eshell dela, execute:

(maria@codezone)7> console_jose ! "Show de bola".

O que aconteceu? Na primeira execução, o Eshell da Maria recebeu uma mensagem, correto? Mas na segunda execução, o Eshell “crasheou”. Por quê? Porque ele não reconheceu o átomo console_jose como sendo o nome de um processo, uma vez que o processo registrado como console_jose está em outro nó do cluster. Aliás, como o Eshell da Maria crasheou, se você tentar enviar mensagens a ele novamente, como fez anteriormente e havia funcionado, ele vai crashear novamente, porque a referência ao processo que havia sido registrada tornou-se inválida.

Você precisa ficar muito atento a isso, porque quando você manda um mensagem para um processo que está em outro nó, mesmo que ele não exista, você não receberá erro – exatamente como acontece com envio de mensagens pra processos locais inexistentes.

Quer ver? Faça o seguinte teste:

(maria@codezone)8> {console_jose_123, 'jose_abc@codezone_xyz'} ! "Nao vai crashear".

E agora, o que aconteceu? Nada!

2- Outra coisa que fizemos foi usar os truques de flush() e regs(), mas esses já são bem conhecidos.

Se você costuma usar o Eshell, com certeza, já deve ter usado flush() e regs(). Caso ainda não tenha usado, aqui vai um resumo:

- flush() descarrega as mensagens contidas na caixa postal do Eshell (que como você sabe, nada mais é do que um processo Erlang qualquer);
regs() lista os processos registrados do runtime em execução.

Só o gostinho

Como disse em algum canto nesse post, ainda há bastante o que falar sobre programação distribuída com Erlang. Só pra variar, esse post foi só pra dar o gostinho. Ainda há muito mais!

Bem, quem sabe qualquer dia desses não perco o sono novamente e escrevo um pouco mais sobre o assunto. Quem sabe?

Você deveria considerar Erlang para seu próximo grande projeto

Ao ler o título deste post, talvez você esteja se perguntando: por que eu deveria considerar Erlang para meu próximo grande projeto? Bem, meu objetivo com este post é te apresentar alguns importantes motivos para fazer isto.

Erlang nasceu no laboratório de ciência da computação da Ericsson na década de 1980, influenciada por linguagens como ML, Ada, Module, Prolog e Smalltalk, quando um time de três cientistas – entre eles, o grande Joe Armstrong receberam a missão de descobrir qual seria a melhor linguagem de programação para escrever a próxima geração de sistemas de telecom. Após dois anos de investigação e prototipação, estes cientistas descobriram que nenhuma linguagem era completa o bastante para tal objetivo e, conclusivamente, decidiram criar uma nova linguagem. Nasceu então Erlang, the Ericsson Language.

De lá pra cá, Erlang tem sido evoluida e usada para escrever grandes sistemas críticos, porque é exatamente nesse cenário que Erlang faz mais sentido. Se seu projeto é construir um sistema crítico, altamente tolerante a falhas, com disponibilidade 24×7 e veloz como o papa-léguas, sim, Erlang é para você. Mas se não é bem esta sua necessidade, se você quer apenas construir um pequeno sistema, com baixa concorrência, poucos usuários, pouca necessidade de performance e possibilidade de passar horas down em manutenção, não, você não precisa de Erlang. Que tal Basic?

Diferente de algumas linguagens que nascem para encontrar um nicho, Erlang nasceu com um problema a ser resolvido, com requisitos a serem atendidos. Tolerância a falhas, concorrência realmente pesada, computação distribuída, atualização da aplicação sem derrubá-la, sistemas de tempo real, este é o nicho de Erlang; foi para isto que Erlang nasceu.

Quem usa Erlang atualmente?

Além da Ericsson, é lógico, há algumas outras grandes empresas e projetos usando Erlang, como por exemplo:

Facebook, no backend de seu sistema de chat, lidando com 100 milhõs de usuários ativos;
Delicious, que tem mais de 5 milhões de usuários e mais de 150 milhões de bookmarks;
Amazon SimpleDB, o serviço de dados do seu poderoso EC2;
Motorola, CouchDB, RabbitMQ, Ejabbed, etc.

Ok, mas Erlang é propriedade da Ericsson?

Não, felizmente, não. Em 1998 a Ericsson tornou Erlang open source sob a licença EPL.

Quer mais uma boa notícia? Você não precisa de um servidor de aplicações para rodar sua aplicação Erlang, nem mesmo uma pesada IDE para escrevê-las. Tudo o que você precisa é de uma distribuição de Erlang para sua plataforma, seja Mac OS X, Linux, Windows, Solaris, ou qualquer outro sistema Unix-like, que traz consigo máquina virtual, compilador e vasta bibliotéca de módulos muito úteis – além do banco de dados Mnesia; e um editor de textos de sua preferência TextMate, por exemplo, tem um ótimo bundle para Erlang.

Algumas características de Erlang

1- Expressividade e beleza

Há quem diga que não, mas Erlang é uma linguagem muito bonita — ao menos pra mim. Dado as já citadas influências de Erlang, ela é uma linguagem bem expressiva e declarativa, que encoraja a escrita de código simples e objetivo, o que certamente torna seu código fácil de ler, de escrever e de organizar [em módulos reutilizáveis]. O snippet abaixo é um exemplo de implementação do famoso fatorial:

-module(sample1).
-export([fac/1]).

fac(0) -> 1;
fac(N) -> N * fac(N-1).

2- Forte uso de recursividade

Isto certamente é uma herança da veia funcional de Erlang que torna o código muito menos imperativo e mais declarativo. Mas além da beleza declarativa óbvia, é importante saber que Erlang foi projetada para lidar com iterações recursivas gigantescas sem qualquer degradação – e sem estourar o “heap” de memória.

3- Livre de efeito colateral

Uma das grandes capacidades dadas por Erlang é a construção de sistemas altamente concorrentes rodando em processadores com multiplos núcleos. Isto não combina nada com efeito colateral, por isso, em Erlang, uma vez que um dado valor tenha sido atribuído a uma variável, esta não poderá mais ser modificada – ou seja, estão mais para o que conhecemos por constantes do que para o que conhecemos por variaveis.

Se você já escreveu código concorrênte sabe o quanto tê-lo livre de efeitos colaterais te faz livre de dores de cabeça. Poucas coisas são tão deprimentes quanto debugar código concorrênte repleto de efeitos colaterais.

4- Pattern matching

Pattern matching em Erlang é usado para associar valores a variáveis, controlar fluxo de execução de programs, extrair valores de estruturas de dados compostas e lidar com argumentos de funções. Mais um ponto para código declarativo e expressividade. Vejamos o código abaixo:

-module(sample2).
-export([convert_length/1]).

convert_length(Length) ->
    case Length of
        {centimeter, X} ->
            {inch, X / 2.54};
        {inch, Y} ->
            {centimeter, Y * 2.54}
    end.

Fala por si, não?

5- Concorrência baseada em passagem de mensagens (a.k.a. Actors)

Acho que concorrência baseada em passagem de mensagem entre atores é uma das features mais populares de Erlang. Vejamos o porque com o famoso exemplo do Ping-Pong:

-module(sample3).

-export([start/0, ping/2, pong/0]).

ping(0, Pong_PID) ->
    Pong_PID ! finished,
    io:format("Ping finished~n", []);

ping(N, Pong_PID) ->
    Pong_PID ! {ping, self()},
    receive
        pong ->
            io:format("Ping received pong~n", [])
    end,
    ping(N - 1, Pong_PID).

pong() ->
    receive
        finished ->
            io:format("Pong finished~n", []);
        {ping, Ping_PID} ->
            io:format("Pong received ping~n", []),
            Ping_PID ! pong,
            pong()
    end.

start() ->
    Pong_PID = spawn(sample3, pong, []),
    spawn(sample3, ping, [3, Pong_PID]).

Neste pequeno snippet podemos observar algumas características de Erlang já citadas neste post, tal como pattern matching na captura das mensagens e recursividade no controle das iterações.

Agora, falando do aspecto concorrente em sim, algumas coisas são particularmente interessantes aqui:

a. Em Erlang, a concorrência acontece entre processos leves, diferente de linguagens como C++ e Java, que baseiam sua concorrência em threads nativas de sistema operacional [caríssimas];
b. Em Erlang, há um tipo de dado chamado PID, o qual é o identificador do processo paralelo (mais conhecido como Actor) e para o qual as mensagens podem ser enviadas.

Releia o código acima com estas informações em mente e veja como concorrência em Erlang é algo completamente descomplicado e natural. Depois, pense no mesmo código implementado em C#, Java ou C++.

Gostei de Erlang, há algum livro para eu começar a estudar?

Sim, há dois livros excepcionais. Um, do próprio criador da linguagem, Joe Armstrong:

E outro de Francesco Cesarini e Simon Thompson:

Além disso, há o próprio material on line que é muito bom e barato. :)

Conclusão

Erlang possui muitas outras características e informações bem interessantes, mas que me falta espaço neste post para citar e apresentar, senão ele ficará absurdamente gigantesco para o meu gosto. Mas acredito que pelo que já apresentei até aqui, você já tenha motivos suficientes para pensar em Erlang com carinho e conciderá-la para seu próximo grande projeto.

Em breve devo escrever algo sobre OTP, já que neste post apresentei características mais inerentes à linguagem em si e nem tanto sobre a plataforma.

Até mais!