A gente está a tanto tempo nessa batida, que nem nos questionamos mais, mas há muita gente que ainda tem dúvidas ou precisa de argumentos. Enquanto de um lado sequer cogitamos fazer deploy de aplicações .NET Core no Windows, por outro há quem ainda tenha medo de sair do windows.
Uma carreira baseada no Windows
Eu sei que muita gente que me segue, e que vem aqui ler meus textos tem uma carreira baseada no Windows. Muitos tem uma vasta experiência fazendo deploys no windows. Alguns só fizeram deploys de aplicações .NET no Windows.
Eu também estive nessa posição. Eu também sentei nesse lugar à mesa. De 2002 a 2015~2016 eu também relutei.
Mas o mundo está mudando muito rápido, e o anúncio do que era o Microsoft vNext, hoje .NET Core, com suporte a Linux, era um sinal claro de que a hegemonia dos deploys .NET no Windows estava para ser abalado.
Não está clara qual era (ou é) a estratégia, e quão alinhada está a Microsoft que lida com .NET da Microsoft que lida com Windows Server. É uma empresa enorme. Mas eu arrisco julgar que essa aposta tem uma relação direta com o Azure.
Talvez o conflito de interesses seja proposital. Talvez tornando o .NET multiplataforma, produzisse a cenoura necessária para fazer outra equipe e outro produto se reinventar. E de fato vimos monumentais mudanças no Windows Server, a cada nova release. O Windows Server nunca foi tão bom, e nunca foi tão colocado à prova.
Será que ele resistirá? Sim, não duvido disso.
Mas no meu caso, ele não é mais a primeira opção para hospedar aplicações .NET.
E isso se dá pelas capacidades que ganhei com a adoção do Linux em meus servidores. E principalmente com o advento do Docker.
Agora eu posso, a um custo absurdamente baixo, entregar muito mais, de forma muito mais eficiente.
O texano e seu MacBook
Desde a primeira vez que ouvi falar que .NET rodaria no Linux, me veio à mente uma situação hipotética, quase uma cena de filme. Eu quero lhe trazer a mesma experiência que eu tive visualizando essa situação.
Não é de hoje que a Microsoft está apostando muito no Azure, e os resultados financeiros do Azure apontam o sucesso dessa estratégia.
Eu imaginei, um texano, com seu MacBook Air, usando Microsoft Excel for Mac, em uma reunião sobre o futuro do .NET.
Com seu chapéu, bota e estilo peculiarmente sincero, abre uma planilha que mostra dados do Azure, em especial o consumo de recursos por sistema operacional/tecnolgia vs capacidade de processamento entregue.
No meio dessa reunião, ele faz a seguinte pergunta:
– Vamos fazer o seguinte exercício: E se .NET rodasse no Linux? Quanto de processamento a mais teríamos e quanto de hardware a menos precisaríamos?
Imagino que a resposta para essa pergunta fosse uma “sabonetada” (esquivando-se da resposta), mas forçando a barra sairiam números hipotéticos (30%, 40%, 50%, não sei).
A partir do momento em que esse número aparecesse na discussão, ele apresentaria uma projeção de 5, 10, 15 anos mostrando X milhões ou até bilhões de dólares em de hardware economizado, para entregar Y mais capacidade de processamento. Um número monumental que justificaria toda essa jornada.
Esse é um cenário 100% hipotético, puramente ficcional.
Eu imagino uma cena dessas, estarrecendo todo mundo! Essa é uma daquelas sais justas que tiram o sono das pessoas por semanas. Essa é uma caricatura mental do que poderia ter sido uma hipotética reunião. Eu ainda acho graça disso.
Windows vs Linux – Old War
Estabilidade é o ponto forte do Linux. E muito dessa estabilidade se dá pela forma como são estruturados seus componentes. O Kernel, as suas responsabilidades, os serviços adicionais, a separação de responsabilidades entre Kernel e Distribuição, tudo isso é importante e até fundamental para notarmos essa estabilidade, mas não para aí. Enquanto no Windows, os serviços do sistema operacional são fundamentais para que coisas funcionem, com rede, entre outras coisas, no Linux essas responsabilidades estão no kernel. Essa segregação rígida faz com que a demanda por serviços rodando em background seja muito menor.
Por outro lado, no Linux, não há nada parecido com o registro do windows. Configurações estão dispostas em arquivos texto, a maioria (ou todas) em plain text mesmo. Isso faz com que o Linux seja muito configurável, e muito mais fácil e prático de ser configurado.
Exemplo: Quer trocar o nome do servidor?
echo "nomeservidor" > /etc/hostname
Simples assim. O arquivo /etc/hostname tem o nome do host, altere ele, e altere os arquivos /etc/hosts (loopbaks) e pronto! Acabou.
E essa filosofia se aplica a diversas outras configurações do Linux. E ainda melhor… essa filosofia é ampliada e aplicada aos projetos que nascem no Linux.
O Windows é ruim?
Definitivamente não.
Inclusive é minha recomendação para desktops de desenvolvimento.
Se você é DEV e precisa de um desktop, na minha opinião o Windows 10 é melhor do que QUALQUER DISTRIBUIÇÃO Linux para essa finalidade.
IIS e afins
A esmagadora maioria das aplicações .NET Core que hoje são hospedadas no Linux, naturalmente seriam implantadas no IIS. O ponto é que o IIS não é uma ferramenta desenhada para automação. É desenhada para governança. E isso faz com que tenha tradeoff’s muito peculiares e aumenta em muito a complexidade de gestão, principalmente se comparado com o que temos no NGINX, por exemplo. Solução trivial e comum que acompanha quase todas as implantações ASP .NET Core.
Em O fim do IIS, texto aqui do gaGO.io, eu já falei sobre como o IIS vem sendo abandonado. Claro, está longe do seu fim, mas cada vez menos vemos sua adoção. A cada dia, mais gente toma consciência de que ele mais atrapalha do que ajuda. E isso se dá pela maturidade que estamos ganhando como comunidade e como plataforma.
Talvez você não conheça o mundo sem IIS. Bom, faz parte! Conheço muita gente que não consegue desassociar Web e .NET do IIS.
Web sem IIS? Sempre foi possível, você que nunca questionou
Quando nasceu o .NET, aplicações web eram exclusivamente hospedadas no IIS. Isso se dá porque aplicações ASP.NET produziam como output de build, DLL’s que por sua vez não são auto-executáveis e precisavam de alguém para executar. Esse alguém é o IIS. Na verdade o Aspnet_isapi.dll (outra DLL) escrita em C++ que roda como um plugin no IIS. Toda essa informação é descrita em ASP.NET Overview for IIS e ISAPI Extension Overview.
Mas se olharmos com carinho para a CLR, temos classes no namespace System.Net (de network) com com capacidade de criar um listener TCP, e processar comunicação sobre TCP.
Inclusive, desde o princípio do WCF, logo nas primeiras versões. Era possível produzir serviços self hosted, o que demonstra o suporte do .NET Framework para realizar essa tarefa. Se um serviço WCF consegue hospedar NET TCP e HTTP, não há nada que impeça de hospedar uma aplicação web.
ASP.NET selfhosted?
Talvez precisemos dar um passo atrás e falarmos sobre o processo de escuta de portas, algo que está mais relacionado a sistemas operacionais. E sim, se você programa, há a necessidade de conhecer o mínimo sobre sistemas operacionais e como algumas coisas funcionam.
Como descrevi no post O fim do IIS o IIS rouba usa um atalho ao usar algumas features direto do Kernel para ser mais performático. Inclusive essa é uma reclamação da comunidade, uma reclamação que faz com que NGINX ou APACHE não consigam usar as mesmas features. Mas isso foi antes do IIS 6 e do HTTP.SYS.
A Microsoft também rouba usa um atalho quando cria o WCF Port Sharing (leia mais). Bom, agora com a nova documentação temos transparência sobre essa coisas, hoje só não entende quem não quer, mas no passado isso era informação que não estava pública. Acredito que algumas informações nunca haviam sido documentadas de fato e isso foi assim por muito tempo.
Hoje temos uma documentação incrível na Microsoft que, inclusive, ilustra coisas que escrevi aqui nesse post.
Aqui está uma explicação do Livro The Architecture of Open Source Applications (Volume 2)
A few words about the Windows version of nginx. While nginx works in a Windows environment, the Windows version of nginx is more like a proof-of-concept rather than a fully functional port. There are certain limitations of the nginx and Windows kernel architectures that do not interact well at this time.
The known issues of the nginx version for Windows include a much lower number of concurrent connections, decreased performance, no caching and no bandwidth policing. Future versions of nginx for Windows will match the mainstream functionality more closely.
Algumas palavras sobre a versão do nginx para Windows. Embora o nginx funcione em um ambiente Windows, a versão do nginx para Windows é mais uma prova de conceito do que um porte totalmente funcional. Existem certas limitações das arquiteturas do nginx e Kernel do Windows que não interagem bem no momento.
Os problemas conhecidos da versão nginx para Windows incluem um número muito menor de conexões simultâneas, desempenho reduzido, sem armazenamento em cache e sem política de largura de banda. As versões futuras do nginx para Windows corresponderão mais à funcionalidade principal.
Fonte: http://aosabook.org/en/nginx.html
O ponto é que no .NET Framework para escutar uma porta, precisávamos apenas de um TCP Listener. Com ele tínhamos como fazer comunicação TCP. Mas tínhamos também também as classes de HTTP Listener, que sob o TCP, implementavam HTTP. Embora sejam operações que aconteçam em user mode, eram alicerce de projetos como NancyFX.
Saiba mais sem User mode and kernel mode.
Essa ideia de que basta usar uma classe e chamar um método para receber as requisições HTTP no teu código, é algo muito bem explorado com as demos de hello world de NODEJS. Isso desmistifica muita coisa.
A forma como o IIS abstrai e encapsula a hospedagem e ciclo de vida de projetos web, nos faz analfabetos sobre hospedagem de serviços. Para você ter ideia, chega a causar estranheza falar de ASP.NET selfhosted. Isso não deveria ser assim.
Mas não foi sobre isso que vim falar. O que quero dizer é que no Linux as coisas são mais transparentes. O modelo de ciclo de vida de self hosted é algo natural, normal, cotidiano. Seja com PHP-FPM, node, python, go. Não importa qual a linguagem, isso sempre foi super transparente para o resto do universo, enquanto para nós, era um conteúdo público, mas a forma como lidamos com a tecnologia fazia com que não precisássemos dessa informação. Aliás, há quem leia esse texto aqui e diga que isso é mentira, ou que “mudou recentemente”. Não. A maior parte das informações que estou citando aqui datam de pelo menos a época do .NET Framework 3.5 (faça as contas…)
A autonomia do Kestrel
Embora o HTTP Listener deva entrar em deprecated nos próximos anos, temos o nascimento do Kestrel usando outro ponto de vista completamente diferente. Agora temos um startup, temos uma iteração forte com a forma como as aplicações sobem. Temos o ciclo de vida todo nas nossas mãos. Ufa, que baita mudança. Isso nos habilita a rodar aplicações web no Linux, no Windows e em qualquer lugar.
Saiba mais em Deprecate HttpListener
Todo esse poder vem em uma excelente hora, onde temos também o suporte ao Linux. E aí que vem a questão: Faz sentido ainda usar Windows para hospedar aplicações .NET Core?
Minha resposta é: Não! Não é o default dos meus projetos, não é o default que recomendo para os meus alunos, comunidade, mentorados.
No IIS, temos de lidar com configuração manual, ou operações via chamadas via linha de comando.
No Linux, eu simplesmente escrevo um arquivo com o estado, em vez dos comandos que levam a esse estado.
Sempre que eu uso um arquivo declarativo, em vez de comandos, eu saio ganhando pois alguém precisa lidar com essa troca de estado, ou assumir meu arquivo como configuração (é isso que acontece no linux). Ter um arquivo declarativo faz ser indiferente qual o estado anterior, use esse arquivo aqui e funciona! Ponto.No Windows, embora tenhamos acesso via WMI a todo o sistema operacional, poucos são os arquivos declarativos que podemos usar para expressar o que queremos. Temos de executar comandos e mais comandos, que podem falhar, precisam de supervisão. Isso aumenta a complexidade.
No Linux eu tenho a oportunidade de usar Docker, com imagens que começam em 2.64 mb (alpine). Isso me permite instalar dependências na minha imagem, começando de uma baseline muito enxuta. No Windows, imagens com alguns GB.
Enquanto um container, nada mais é que um processo virtualizado, do lado de outros processos virtualizados ou não, com um file system próprio que o faz parecer uma distro A, B ou C. No Windows as coisas parecem ser mais complexas. Bem mais.
Enquanto eu lido com servidores de 1GB de RAM que já atendem pequenos workloads, com Windows, vamos começar em 4GB.
E isso conta. O quanto da máquina está alí para me atender, para atender às demandas da minha aplicação conta.
Então, com Linux é tudo mais simples. Não tem grandes ferramentas visuais, a ferramenta visual é o VSCODE. Mas fique atento, você pode versionar, não os comandos, mas o ESTADO das configurações que precisa.
Por todos esses motivos, mesmo no Azure, eu uso App Services com instâncias Linux.
E note, eu administrei servidores Windows a vida toda. Estou familiar. Mas se eu passar 1 ano sem fazer nada com ele, vou esquecer os PASSOS. Diferente de um arquivo de configuração, onde a configuração está alí, estática, pronta para uso.
Esses são meus argumentos para a utilização de Linux como default para hospedagem de projetos ASP.NET Core.
Aliás, acredito que a Microsoft tivesse total ciência de que isso poderia acontecer.
E, para quem não pode usar Linux, pois depende de coisas do Windows, como Cristal Reports, e outros recursos. Tudo bem!!! Windows Server não é um problema, o ponto central é que há algo melhor, algo que dá outro conjunto de oportunidades que pode fazer diferença substancial na tua vida, no teu uptime, na capacidade de se manter estável.
Eu fiz 2 posts sobre estratégias de deployment com .NET Core que podem ajudar no entendimento disso.
.NET Core – Estratégias de Deploy – Parte 1
.NET Core – Estratégias de Deploy – Parte 2
E docker?
Docker traz o IaaC (infrastructure as a code) para os requisitos de deployment de sua aplicação. Quais libraries? Quais runtimes? Além de oferecer um modelo de isolamento e abstração que poupa tempo, reduz a dor de cabeça e assegura uma política de fail fast. Empacotar sua aplicação em uma imagem, assegura zero demandas de infraestrutura exclusivas para sua aplicação, seja ela qual for.
Você precisa de um Webserver, .NET Core versão mais recente? Isso deixa de ser relevante para o pessoal de infraestrutura. E se eles lhe perguntarem, responda com a seguinte pergunta:
- DE QUE ISSO É IMPORTANTE PARA VOCÊ?
- O QUE VOCÊ FARÁ COM ESSA INFORMAÇÃO?
Claro, essas coisas são importantes para assegurar que sua imagem é segura ou não tem nenhuma falha de segurança, mas deixa de ser algo relevante em relação à estabilidade dos ambientes computacionais, por possivelmente seu setup causar impacto nos demais serviços.
Docker pode parecer relativamente novo, mas você pode tanto cobrar mais caro pela tecnologia e pelo valor que essa tecnologia trás para o seu cliente, como, pode usar como potencial competitivo pois reduz diversos dos riscos de uma implantação caótica. Saiba mais em O breakeven dos projetos Docker – Sem docker é mais caro.
Tem dezenas de horas de conteúdo aqui no gaGO.io/docker.
Benchmarks
Sendo bem sincero, se o benchmark comparativo em performance fosse similar ou se Linux ainda perdesse por pouco, 10%, 15%, eu ainda manteria minha opinião sobre a estratégia de deployment.
O caso é outro, e você pode acompanhar o benchmark feito por Roberto Prevato.
Mas Ok, pode ser tendencioso?
Que tal um benchmark da Microsoft em github.com/aspnet/benchmarks ?
Vale lembrar que nesse repositório tem link para um board do Power BI com os resultados.
Conclusão
O que nos trouxe até aqui, não necessariamente nos levará ao próximo nível, ao próximo patamar em qualidade, performance e automação.
Os desafios de entender o Linux minimamente a ponto de conseguir fazer deployments, é sim disruptivo e exige antes de mais nada, humildade. Mas se você chegou até aqui e se você lê o conteúdo que eu publico, há boas chances de você ser uma pessoa fora da média que gosta de estudar e aprender. Isso te coloca na frente de uma massa gigantesca.
Nunca foi tão bom ser um desenvolvedor da plataforma .NET, principalmente com o que está disponível para nós. Hoje, inclusive, estou brincando com Roslyn para gerar código para mim, e vou te contar. É incrível!!! Mas isso é outro assunto para um outro post.
0 comentários