Mostrando postagens com marcador gerência de configuração. Mostrar todas as postagens
Mostrando postagens com marcador gerência de configuração. Mostrar todas as postagens

quinta-feira, 9 de abril de 2015

Windows Nano Server - A maior evolução para o DevOps Microsoft

O grande gargalo para o uso de sistemas Windows em ambientes de nuvem e para uma boa infraestrutura de DevOps fora do Microsoft Azure é sem dúvida o footprint gigantesco do sistema. Manter uma maquina virtual onde apenas processos de backend precisam ser executados demanda a instalação do sistema operacional completo, incluindo ferramentas gráficas e tudo que as suporta, algo completamente desnecessárias nesse tipo de cenário. 

Atualmente, para preparar uma maquina Windows Server precisamos de cerca de 32GB de espaço em disco, com sorte, o que torna praticamente inviável o uso do sistema em muitos cenários, levando à preferência por ambientes mais leves e modularizados, casos das inúmeras distribuições Linux que temos hoje dominando os ambientes de nuvem e containers.

No entanto, neste último dia 8 de Abril, a Microsoft anunciou o desenvolvimento do Windows Nano Server, uma versão reduzida do sistema operacional, contendo apenas aquilo que é de fato necessário para a execução de uma infraestrutura de nuvem, removendo totalmente sua interface gráfica e demais funcionalidades desnecessárias. Com isso o footprint do sistema caiu expressivos 93%, o que nos leva a crer que poderemos ter uma maquina Windows Nano Server, totalmente viável para a execução de sistemas de backend, com razoáveis 2,3GB de espaço em disco, talvez até menos.

Isso torna viável também o uso do Windows Nano Server com Vagrant e, segundo a Microsoft, até Docker, simplificando absurdamente a criação de ambientes de DevOps para softwares desenvolvidos para a plataforma .NET, principalmente considerando o desenvolvimento do novo .NET Core 5 e ASP.NET 5, também bastante reduzidos em tamanho e muito melhor modularizados, se comparados às versões atuais.

A partir do lançamento desse novo sistema, com pouco investimento, será possível a distribuição e gestão do ciclo de vida de serviços de backend executados sobre a plataforma .NET e Windows em ambientes como o IBM BlueMix, ou Amazon AWS, de forma tão prática quanto é feita hoje para sistemas Java executados sobre uma distribuição Linux.

Essa foi sem dúvida a melhor notícia dos últimos tempos para desenvolvedores .NET e administradores de infraestrutura Windows. Ansioso para ver tudo isso funcionando na prática. Que 2016 chegue logo.

Atualização: Na Build 2015, foi anunciado que o Nano Server tem uma imagem de cerca de 400MB, contra quase 5GB da versão Server Core, a menor disponível atualmente. Além disso, o sistema gasta cerca de 40 segundos para ser instalado, 15 segundos para ser inicializado e ocupa apenas 63MB de memória. Números realmente impressionantes, mesmo em comparação ao atual Server Core.

Vejam mais detalhes em:

terça-feira, 15 de abril de 2014

Módulos de Negócio vs Módulos de Infraestrutura

Módulos de Negócio versus Módulos de Infraestrutura. Essa é uma das discussões que me deixam mais empolgados quando o assunto é Arquitetura de Software. Mas antes de mais nada, uma breve revisão sobre o que são Módulos.

Um Módulo de Software pode ser visto como uma peça de software que implementa uma determinada especificação e realiza um determinado trabalho conforme especificado. Tais módulos podem ser compostos por um arquivo, uma classe, uma DLL, ou até mesmo um conjunto de DLLs, dentre outras possibilidades, desde que em conjunto esses artefatos implementem uma dada especificação e realizem um determinado trabalho conforme especificado.

Sempre que falamos em Módulos de Software, é comum alguém fazer a comparação com Módulos de Hardware, e gosto bastante dessa comparação. Um módulo de hardware, um componente eletrônico normalmente, pode ser facilmente substituído por um outro semelhante, desde que este outro implemente as mesmas especificações. Os demais módulos que interagem com aquele que for substituído se quer perceberão a mudança. E este seria o Santo Graal da modularização de software, poder simplesmente remover um módulo e substituí-lo por outro que implemente a mesma especificação, sem que os demais módulos reclamem da mudança.

Infelizmente isso ainda é uma realidade pouco comum. Arrisco dizer que a grande maioria das aplicações desenvolvidas no país, ainda que considerando apenas a pequena amostra a que tive acesso, são mal modularizadas e acabam mantendo um alto acoplamento entre seus módulos. E isso prejudica não apenas a possibilidade de fazer substituições de uma implementação por outra, algo que apesar de muito bonito não é tão necessário assim, mas também a definição das fronteiras do escopo de cada módulo, e é ai que está o grande prejuizo em modularizar mal uma aplicação.

De volta ao tema desta postagem, vamos supor que estamos trabalhando no desenvolvimento de um sistema em que há uma boa modularização, em que o papel de cada módulo está bem definido, o acoplamento está baixo e as fronteiras entre os módulos muito bem definidas.

Se tivermos essa realidade, será fácil identificar a separação entre Módulos de Negócio, aqueles que implementam exclusivamente funcionalidades específicas do negócio que está sendo automatizado pelo software, e Módulos de Infraestrutura, que implementam funcionalidades de suporte, drivers de acesso a bancos de dados ou sistemas de mensageria, ferramentas de log e auditoria, gerenciamento de usuários e tantas outras que estarão presentes, sem muita variação, em praticamente toda aplicação que viermos a desenvolver.

Módulos de Infraestrutura são componentes genéricos, reutilizáveis, que podem ter seu desenvolvimento e manutenção totalmente desacoplado dos sistemas que os utilizam. E ai está a grande vantagem em sermos capazes de fazer essa distinção. Quando baixamos um módulo como o Json.NET ou o FluentAssertions através do NuGet, recebemos uma peça de software pronta que apenas consumiremos. Por que não pode ser assim com os Módulos de Infraestrutura desenvolvidos pela própria equipe que consome esses módulos desenvolvidos por terceiros?

Pense que há na empresa em que você trabalha, e não há porque não haver caso você desenvolva aplicações .NET, um repositório NuGet privado, assim como uma política de Gestão de Reuso que defina que todo Módulo de Infraestrutura deva ser desenvolvido de modo independente das aplicações que os consomem, e que devam ser disponibilizados neste repositório uma vez que atinjam uma versão estável. Isso permitirá que esses módulos sejam utilizados pelas equipes de desenvolvimento da empresa, incluíndo as equipes que os desenvolveram, pois estas também deverão consumí-lo através do repositório NuGet, e não através de referências diretas a projetos da mesma solução.

Num cenário como este, teriamos uma solução limpa, composta apenas por Módulos de Negócio se referenciando entre si e consumindo, via NuGet, os Módulos de Infraestrutura que precisam.
Pensem nas possibilidades que um cenário como esse lhe proporcionaria. Pense em possibilidades como abrir alguns desses módulos como projetos Open Source, ganhando a contribuição de desenvolvedores de todo o mundo. Ou a vantagem de poder vender a seus clientes apenas o que realmente precisa e deve ser entregue exclusivamente a esses clientes: seus Módulos de Negócio. Afinal, se você pode consumir componentes de terceiros não relacionados ao negócio do seu cliente sem ter que fornecer a ele a propriedade sobre o código desses componentes, por que não poderia fazer o mesmo com o código dos Módulos de Infraestrutura que você mesmo desenvolve?

Por hoje era isso! Deixem suas opiniões nos comentários.

quinta-feira, 27 de março de 2014

Arquitetura de Microserviços e DDD

DDD já é velho conhecido de muitos desenvolvedores de software já há mais de 10 anos, no entanto o termo Microservices Architecture tem ganhado popularidade apenas recentemente.

Venho trabalhando em uma arquitetura de micro serviços, desenvolvida sobre o .NET Framework, já há quase 1 ano, desde antes da popularização do termo e até mesmo antes da publicação do Manifesto Reativo. No entanto, essa arquitetura tem se mantido desde o início bem aderente a esses dois conceitos.

Chamada aqui de Plataforma ST (nome real omitido), trata-se de uma arquitetura que permite que pequenos serviços de aplicação coexistam e se comuniquem entre si, de modo seguro, escalável e permitindo que novos serviços possam ser incluídos na plataforma a qualquer momento, complementando as funcionalidades já existentes. Note que não se trata de um único produto composto por múltiplos serviços relacionados, mas sim de uma plataforma de agregação de serviços. É possível haver uma instância da Plataforma ST agregando serviços de CRM, outra agregando serviços de ERP e outra para serviços de POS, cada uma dessas compondo um sistema distinto. Ainda assim, para cada uma delas, existe a possibilidade de se agregar novos serviços, incluindo alguns que sejam responsáveis exclusivamente pela interação entre esses diferentes sistemas.

Segundo as recomendações do DDD, módulos de um sistema, no nosso caso assemblies ou namespaces .NET, não devem conter no seu nome um nome de produto, mas sim a funcionalidade que ele provê, assim como devem conter como prefixo o nome da empresa que os desenvolveu. Assim, um módulo de gerenciamento de projetos ágeis desenvolvido pela empresa Contoso deveria ser nomeado com.contoso.agileprojectmanagement.applicationservice, de acordo com o que fora apresentado por Vaughn Vernon em Implementing Domain-Driven Design. No entanto, o padrão com.nomedaempresa se limita ao mundo Java, linguagem usada pelo autor para ilustrar o livro. Em projetos .NET, não há o costume de acrescentar o nome da empresa nos nomes dos módulos, e muito menos o prefixo com.

Ainda assim, poderíamos adaptar essa terminologia e nomear um dos nossos módulos de Contoso.AgileProjectManagement.ApplicationService, no entanto optei por usar ST.AgileProjectManagement.ApplicationService, e posso justificar essa decisão.

A Plataforma ST requer que os serviços desenvolvidos para executar sobre ela sigam um determinado padrão. Há uma classe abstrata ou no minimo uma interface que precisa ser implementada por todos os serviços, além disso eles precisam ser desenvolvidos levando em consideração o modo como a Plataforma ST irá gerir seu ciclo de vida. E mais, a Plataforma ST não é uma bala de prata, obviamente. Há cenários em que o mais interessante seja usar uma outra plataforma, ou desenvolver o sistema diretamente sobre o .NET Framework, já descartando os casos em que o próprio .NET Framework não seja a melhor opção.

Imagine por exemplo que seja desenvolvido na mesma empresa um sistema de colaboração, uma espécie de Wiki, que se adere aos padrões DDD mas não se encaixa na Plataforma ST. Esse sistema será desenvolvido de modo completamente independente dela, seus módulos serão totalmente incompatíveis. Agora seguindo a recomendação de usar o nome da empresa para determinar o nome dos módulos, teríamos algo como Contoso.Collaboration.ApplicationService, algo muito semelhante aos módulos dos sistemas desenvolvidos sobre a Plataforma ST, mas sem relação alguma com ela.

Por que não usar então Contoso.ST.AgileProjectManagement.ApplicationService? Ai vem um ponto em que discordo da recomendação do Vernon. Usar o nome da empresa, de qualquer modo que seja, na nomenclatura dos módulos, pode ser ruim e prefiro usar em seu lugar não o nome comercial de um serviço, o que concordo não ser recomendável, mas manter o módulo nomeado conforme sua função e prefixá-lo com um nome de projeto ao invés do nome da empresa. Seria algo que identifica todos os módulos que possuem algo em comum e cumpre a mesma função do nome da empresa na recomendação do livro.

Mas por que isso? Já trabalhei em uma empresa que mudou de nome, e via produtos legados com o nome antigo por todos os lados. Há casos de fusões e aquisições, em que o nome do proprietário do produto muda, e mesmo havendo motivações para manter o nome do desenvolvedor original mesmo que ele não exista mais, há o risco de novos módulos que integrem a mesma aplicação passarem a ser nomeados conforme o novo nome da empresa, o que geraria uma combinação de nomes de módulos não muito interessante.

Enfim, era isso que gostaria de compartilhar aqui e gostaria de ouvir a opinião de quem trabalha com DDD e já teve que passar por situações semelhantes às que descrevi. O que vocês tem a dizer?

quinta-feira, 25 de julho de 2013

Substituindo SVN por Git

Após alguns anos trabalhando com ferramentas de controle de versão centralizado, como StarTeam e Subversion (SVN), e já tendo feito algumas experiências com Mercurial e Git, usando BitBucket e GitHub como repositórios remotos, decidi iniciar um novo projeto usando Git, no entanto configurando meu próprio repositório remoto.

Numa empreitada como esta, três desafios normalmente precisarão ser superados:

  1. Configurar um repositório remoto e um repositório local e colocá-los para conversar educadamente. Essa tarefa é bem fácil e detalho mais adiante.
  2. Convencer os membros da equipe, acostumados com a comodidade do TortoiseSVN e com um processo de commit mais simples, que Git irá facilitar a vida deles, não o contrário. Isso também não será difícil, e há um modo suave de se fazer essa transição, que apresentarei a seguir.
  3. Convencer a empresa a aceitar os riscos de substituir o já conhecido SVN pelo Git, ainda que apenas num primeiro projeto. Isso será um pouco mais difícil, mas há algumas alternativas, caso isso não possa ser feito.

Para solucionar o primeiro problema, basta seguir este simples script:

  • Instale o Git, ou "GitHub for Windows", no servidor que será usado como repositório remoto.
  • No servidor onde o Git foi instalado, escolha uma pasta para hospedar o repositório remoto.
  • No Git Shell, navegue para a pasta escolhida e inicialize o repositório remoto com "git init --bare".
  • Instale o Git, ou "GitHub for Windows", em uma estação de trabalho.
  • Nessa estação de trabalho, escolha uma pasta para hospedar o repositório local.
  • No Git Shell, navegue para a pasta escolhida e inicialize o repositório local com "git init".
  • Monte dentro desse repositório a estrutura de pastas para o projeto.
  • Adicione a estrutura do projeto no git com "git add .".
  • Comite os arquivos recém adicionados no git, com "git commit -m 'Primeiro Commit'"
  • Configure o repositório remoto a ser usado pela estação de trabalho com "git config remote.origin.url endereço_do_repositorio_remoto".
  • Envie seu primeiro commit para o repositório remoto com "git push origin master"
  • Concluído. A partir agora você já poderá usar seu repositório local enviando os commits para o repositório remoto.
Para convencer a equipe a ao menos experimentar o Git, pode ser necessária muita conversa sobre as diferenças entre sistemas de controle de versão centralizados e distribuídos.

Apresentar a eles o "Git Game"  também pode ser útil.

No caso de equipes acostumadas a não usar ferramentas de linha de comando, esta será provavelmente a principal barreira. Para isso há duas ferramentas, em ambiente Windows, que podem ajudar. A primeira seria o TortoiseGit, semelhante ao provavelmente já conhecido TortoiseSVN, e a segunda o "GitHub for Windows". Quando trabalho com SVN, utilizo o TortoiseSVN, no entanto nas experiências que já fiz usando o GitHub usei o "GitHub for Windows", e esta será a ferramenta que usarei neste novo projeto.

Fica claro, pelo que disse acima, que o "GitHub for Windows" pode ser usado sem problema com repositórios remotos que não sejam repositórios do GitHub. Phil Haack, desenvolvedor da ferramenta, já falou sobre isso, no entanto utilizando um outro provedor de repositórios remotos, no caso o CodePlex. No nosso caso, precisamos usar o "GitHub for Windows" com um repositório remoto disponível na nossa intranet.

A configuração desse repositório remoto já foi feita acima, e sua utilização com o "GitHub for Windows", não poderia ser mais simples. Basta arrastar o repositório local, já configurado para enviar os commits ao nosso repositório remoto, para dentro da janela do "GitHub for Windows" e clicar no botão "Publish". A partir dai o botão "Sync" ficará disponível e poderá ser usado para sincronizar o repositório local com o repositório remoto. O uso dessa ferramenta pode tornar a aceitação do Git pela equipe bem mais simples.

Já para o terceiro desafio, o processo de convencer a empresa a experimentar o Git pode ser o mesmo usado com a equipe, ressaltando principalmente os ganhos de produtividade devidos a melhor performance e a maior segurança caso um desastre aconteça com o repositório remoto.

No entanto, caso a empresa se mantenha relutante, nada impede o uso misto de Git e SVN. Para isso pode ser usada a ferramenta "git svn", ou simplesmente usar um repositório local Git, e ter todas as vantagens que esse repositório local oferece, como a possibilidade de fazer vários commits, reverter alguns deles e "reordená-lo" antes de enviar ao repositório remoto, e um repositório remoto SVN, sendo sincronizado com o repositório local do modo tradicional. Ou seja, você trabalha localmente com Git até que seu código esteja em condições de ser compartilhado com a equipe, e nesse momento faz esse compartilhamento através de SVN, normalmente. Obviamente que com essa última abordagem, assim como com o uso de "git svn", muitas das vantagens do Git serão perdidas, mas ao menos você poderá fazer uso de parte delas.