<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: marcelmfa</title>
    <description>The latest articles on DEV Community by marcelmfa (@marcelmfa).</description>
    <link>https://dev.to/marcelmfa</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F871137%2Ff6d3c9c2-4e99-4c18-8240-3fb1a78591a7.jpg</url>
      <title>DEV Community: marcelmfa</title>
      <link>https://dev.to/marcelmfa</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/marcelmfa"/>
    <language>en</language>
    <item>
      <title>Estudo sobre HTTP2 e protocolos binários - parte 4</title>
      <dc:creator>marcelmfa</dc:creator>
      <pubDate>Wed, 03 Aug 2022 19:27:27 +0000</pubDate>
      <link>https://dev.to/marcelmfa/estudo-sobre-http2-e-protocolos-binarios-parte-4-2fkc</link>
      <guid>https://dev.to/marcelmfa/estudo-sobre-http2-e-protocolos-binarios-parte-4-2fkc</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Este post faz parte da seguinte série sobre estudo de HTTP2 e protocolos binários:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://dev.to/marcelmfa/estudo-sobre-http2-e-protocolos-binarios-parte-1-5h9o"&gt;Parte 1&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;
&lt;a href="https://dev.to/marcelmfa/estudo-sobre-http2-e-protocolos-binarios-parte-2-3m8l"&gt;Parte 2&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;
&lt;a href="https://dev.to/marcelmfa/estudo-sobre-http2-e-protocolos-binarios-parte-3-5f9k"&gt;Parte 3&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;
&lt;a href="https://dev.to/marcelmfa/estudo-sobre-http2-e-protocolos-binarios-parte-4-2fkc"&gt;Parte 4&lt;/a&gt; Você está aqui.&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;p&gt;Antes de começarmos gostaria de lhes pedir para dar uma lida rápida sobre o gRPC da &lt;a href="https://grpc.io/docs/what-is-grpc/introduction/"&gt;documentação oficial&lt;/a&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Mas, meu amigo, tu acha mesmo que eu sei inglês?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--z8v-v7WI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://c.tenor.com/ZCpVUbRJs24AAAAC/sorry-i-dont-speak-english-wwe.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--z8v-v7WI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://c.tenor.com/ZCpVUbRJs24AAAAC/sorry-i-dont-speak-english-wwe.gif" alt="Desculpa, eu não sei inglês" width="498" height="240"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Beleza meu patrão, então faça como fiz um tempo atrás e leia pelo menos este &lt;a href="https://blog.lsantos.dev/guia-grpc-1/"&gt;primeiro post&lt;/a&gt; do blog do &lt;a href="https://twitter.com/_staticvoid"&gt;Lucas Santos&lt;/a&gt;. Na boa, lê os demais também, o material tá muito bom e se você está estudando NodeJS então, melhor ainda.&lt;/p&gt;

&lt;p&gt;Da rápida leitura que fizemos do material acima conseguimos entender que:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;É um protocolo que segue um &lt;em&gt;schema&lt;/em&gt; (&lt;a href="https://developers.google.com/protocol-buffers/docs/overview"&gt;&lt;strong&gt;Protocol Buffers&lt;/strong&gt;&lt;/a&gt;) de dados que define como são as entradas e saídas, &lt;em&gt;messages&lt;/em&gt;;&lt;/li&gt;
&lt;li&gt;O &lt;em&gt;schema&lt;/em&gt; citado anteriormente não pertence a domínio de linguagem específica, porém necessita de implementações específicas de cada linguagem que possam implementar o contrato (&lt;em&gt;schema&lt;/em&gt;) citado no item anterior;&lt;/li&gt;
&lt;li&gt;Esta implementação específica irá abstrair a parte de serialização e deserialização destes dados, permitindo que a aplicação faça apenas o preenchimento dos dados como &lt;a href="https://developers.google.com/protocol-buffers/docs/overview#work"&gt;neste exemplo&lt;/a&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;blockquote&gt;
&lt;p&gt;Tá nice, já entendi o básico, mas e agora?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--THTVpElb--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://c.tenor.com/4eO9HfdsmZcAAAAM/shauny-shirley.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--THTVpElb--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://c.tenor.com/4eO9HfdsmZcAAAAM/shauny-shirley.gif" alt="Ok e agora?" width="220" height="220"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Agora vamos ao planejamento das atividades, que são:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Criar a nova aplicação Spring (claro!) com gRPC;&lt;/li&gt;
&lt;li&gt;Criar novo script para o k6 para fazer o benchmark;&lt;/li&gt;
&lt;li&gt;Criar um novo dashboard para visualizar estas métricas (será explicado a seguir);&lt;/li&gt;
&lt;li&gt;Realizar o &lt;em&gt;benchmark&lt;/em&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;h1&gt;
  
  
  Criando a aplicação Spring com gRPC
&lt;/h1&gt;

&lt;p&gt;Primeiramente fui a &lt;a href="https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/"&gt;documentação oficial do Spring Boot&lt;/a&gt; e achei "ZERO" referências a gRPC.&lt;/p&gt;

&lt;p&gt;Aí já fiquei com aquele sentimento: "Vixe..."&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--YvzZT-51--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://c.tenor.com/FWHNaNZkR7gAAAAM/baby-roller-coaster.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--YvzZT-51--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://c.tenor.com/FWHNaNZkR7gAAAAM/baby-roller-coaster.gif" alt="Vixe" width="220" height="123"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Olhando a &lt;a href="https://developers.google.com/protocol-buffers/docs/javatutorial"&gt;documentação oficial do gRPC pra Java&lt;/a&gt;, só é possível ver coisas relacionadas ao &lt;em&gt;schema&lt;/em&gt; (arquivo .proto), ao compilador deste esquema (&lt;em&gt;protoc&lt;/em&gt;), configurações deste compilador, ao código gerado e um exemplo bem simples usando o código gerado.&lt;/p&gt;

&lt;p&gt;Repete o "Vixe..." aí de cima.&lt;/p&gt;

&lt;p&gt;O jeito então foi ampliar a pesquisa (Google) para ver se existe algo específico com gRPC e Spring, donde acabo caindo não só num &lt;a href="https://github.com/yidongnan/grpc-spring-boot-starter"&gt;repositório&lt;/a&gt;, como o cara também fez um &lt;a href="https://yidongnan.github.io/grpc-spring-boot-starter/en/"&gt;site EXCEPCIONAL&lt;/a&gt;, diga-se de passagem e - para quem já é acostumado ao ecossitema Spring Boot - o caboco ainda criou um artefato &lt;em&gt;starter&lt;/em&gt; conforme pode ser observado na &lt;a href="https://yidongnan.github.io/grpc-spring-boot-starter/en/server/getting-started.html#server-project"&gt;declaração do pom&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Olhando na parte de &lt;a href="https://yidongnan.github.io/grpc-spring-boot-starter/en/server/getting-started.html#project-setup"&gt;&lt;em&gt;setup&lt;/em&gt;&lt;/a&gt; é possível perceber que teremos agora pelo menos 2 projetos:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;o projeto Interface que é responsável por conter o contrato e o código gerado pelo compilador do gRPC (&lt;em&gt;protoc&lt;/em&gt;), donde geraremos um JAR para reutilizado em outros projetos que queiram se comunicar usando este contrato;&lt;/li&gt;
&lt;li&gt;e o projeto Server que irá servir o contrato do projeto Interface gerado no item anterior.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Neste caso especificamente usaremos o k6 como Client, então não teremos outra aplicação Java reusando o projeto Interface.&lt;/p&gt;

&lt;p&gt;Vamos ao próximo tópico.&lt;/p&gt;

&lt;h1&gt;
  
  
  Criar script k6 pro gRPC
&lt;/h1&gt;

&lt;p&gt;Esta parte foi tão fácil quanto criar os scripts para o HTTP(S), pois eles tem &lt;a href="https://k6.io/blog/performance-testing-grpc-services/#getting-started"&gt;um artigo no próprio blog&lt;/a&gt; deles sobre o assunto.&lt;/p&gt;

&lt;p&gt;Então bastou pouquíssimas alterações.&lt;/p&gt;

&lt;h1&gt;
  
  
  Métricas e Dashboard no Grafana
&lt;/h1&gt;

&lt;p&gt;Neste tópico surgem alguns pequenos problemas:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Conforme visto no link no item anterior, diferentemente do HTTP temos pouquíssimas métricas para o gRPC, que são de dados trafegados, duração, iterações e VUs. No entanto, &lt;a href="https://k6.io/docs/javascript-api/k6-net-grpc/"&gt;a documentação cita que este módulo está em beta&lt;/a&gt;, então esperemos mudanças para melhorar a observabilidade;&lt;/li&gt;
&lt;li&gt;Por ter métricas diferentes e até mesmo nomes diferentes, precisaremos customizar o dashboard do k6 usado do HTTP;&lt;/li&gt;
&lt;li&gt;Da mesma forma que no client side, o mesmo ocorre no lado do servidor e lá também encontramos uma deficiência semelhante às métricas fornecidas, então criaremos também um dashboard específico dado que são pouquíssimas métricas.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Porém, depois de uma pequena tempestade, vem o alívio.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--yMrxAy45--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://c.tenor.com/g_d3iHyzc68AAAAM/hammaya-relaxed.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--yMrxAy45--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://c.tenor.com/g_d3iHyzc68AAAAM/hammaya-relaxed.gif" alt="Alívio" width="220" height="249"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Não se preocupe, que estes dashboards estarão no repositório para serem importados. Além do mais, a parte da ingestão das métricas vai continuar sendo feita da mesma forma que nos posts anteriores. No client, o k6 continua enviando pro InfluxDB. No server, o Prometheus continua fazendo &lt;em&gt;scrapping&lt;/em&gt; via HTTP.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--mjAvlpMu--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://media1.giphy.com/media/AfXPYfexaPjPsEdsUz/200.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--mjAvlpMu--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://media1.giphy.com/media/AfXPYfexaPjPsEdsUz/200.gif" alt="Confuso" width="200" height="200"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Isto mesmo, nesta aplicação Server do gRPC teremos também um Tomcat embarcado para servir as métricas para o Prometheus via HTTP.&lt;/p&gt;

&lt;h1&gt;
  
  
  Benchmark
&lt;/h1&gt;

&lt;p&gt;Diferentemente dos posts anteriores teremos apenas a execução dos profiles 1 (2cpu, 2Gb) e 2 (4 cpu, 4Gb).&lt;/p&gt;

&lt;p&gt;Como citado anteriormente, criei um dashboard com as métricas do Server gRPC, então teremos 3 gráficos, sendo um do k6 (visão do client) e dois pro servidor, onde um com as métricas padrão do Actuator do Spring Boot e outro (criado do zero) apenas com as métricas específicas do gRPC.&lt;/p&gt;

&lt;h2&gt;
  
  
  Profile 1
&lt;/h2&gt;

&lt;p&gt;Visão do cliente&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Tudih34d--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wj8q12z6nnriqj7cykvz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Tudih34d--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wj8q12z6nnriqj7cykvz.png" alt="Resultados da visão do cliente" width="880" height="481"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Visão da JVM do servidor&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--mFQi0qYq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kdyzcj4vsfi0yepgyb1o.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--mFQi0qYq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kdyzcj4vsfi0yepgyb1o.png" alt="Resultados da visão da JVM" width="880" height="481"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Visão de gRPC do servidor&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--vDmL9IEZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xy50dpzs1zz5g3ma51c0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--vDmL9IEZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xy50dpzs1zz5g3ma51c0.png" alt="Resultados da visão gRPC do servidor" width="880" height="481"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Profile 2
&lt;/h2&gt;

&lt;p&gt;Visão do cliente&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ZiFDDfHZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/iohgiq1a19y6hsyf5u5y.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ZiFDDfHZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/iohgiq1a19y6hsyf5u5y.png" alt="Resultados da visão do cliente" width="880" height="481"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Visão da JVM do servidor&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--gQwPWjDC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/y6foeh4qv78vmwo6dw4a.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--gQwPWjDC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/y6foeh4qv78vmwo6dw4a.png" alt="Resultados da visão da JVM" width="880" height="481"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Visão de gRPC do servidor&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Rgq5jdMQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nik2k5l7jfhjwzdzyyz4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Rgq5jdMQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nik2k5l7jfhjwzdzyyz4.png" alt="Resultados da visão gRPC do servidor" width="880" height="481"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Avaliação simplória dos resultados
&lt;/h1&gt;

&lt;p&gt;No &lt;em&gt;dashboards&lt;/em&gt; de visão do cliente não tem dados de &lt;em&gt;requests per second&lt;/em&gt; dado que esta métrica não existe pro k6 com gRPC, que é inclusive comentado nos &lt;a href="https://community.k6.io/t/grpc-limited-metrics/1902/2"&gt;fóruns do Grafana&lt;/a&gt;. Porém conforme também dito anteriormente, esta API ainda está em Beta, então pode ser que algo mude no futuro.&lt;/p&gt;

&lt;p&gt;A performance com profile 2 foi ligeiramente melhor (chegando próximo das 100 mil requisições), atendendo em torno de 5 mil requisições em relação a do profile 1, porém não é algo significativo dado que reservou o dobro de recursos.&lt;/p&gt;

&lt;p&gt;Quanto ao uso de CPU, o uso se manteve em no máximo 1 para ambos os profiles. Quanto ao uso de memória não foi possível perceber nenhuma diferença significativa entre os profiles. Quanto às métricas de gRPC, a diferença significativa está no &lt;strong&gt;Max Duration&lt;/strong&gt; que no profile 1 chegou a 4s por alguns períodos, enquanto que no profile 2 chegou a no máximo 3s.&lt;/p&gt;

&lt;h1&gt;
  
  
  The End!
&lt;/h1&gt;

&lt;p&gt;Chegamos ao fim desta série e espero que possa ajudar ou ter ajudado você de alguma forma na sua jornada.&lt;/p&gt;

&lt;p&gt;E &lt;a href="https://github.com/marcelmfa/estudo-http2-grpc"&gt;aqui seguem os fontes&lt;/a&gt; assim como arquivos de configuração.&lt;/p&gt;

&lt;p&gt;Nos vemos na próxima série ou tópico.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--sC5Sln92--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://c.tenor.com/-GnZ6NOpsXkAAAAC/thats-all-folks.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--sC5Sln92--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://c.tenor.com/-GnZ6NOpsXkAAAAC/thats-all-folks.gif" alt="Isso é tudo pessoal" width="498" height="278"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>grpc</category>
      <category>java</category>
      <category>monitoring</category>
      <category>performance</category>
    </item>
    <item>
      <title>Estudo sobre HTTP2 e protocolos binários - parte 3</title>
      <dc:creator>marcelmfa</dc:creator>
      <pubDate>Tue, 05 Jul 2022 19:44:46 +0000</pubDate>
      <link>https://dev.to/marcelmfa/estudo-sobre-http2-e-protocolos-binarios-parte-3-5f9k</link>
      <guid>https://dev.to/marcelmfa/estudo-sobre-http2-e-protocolos-binarios-parte-3-5f9k</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Este post faz parte da seguinte série sobre estudo de HTTP2 e protocolos binários:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://dev.to/marcelmfa/estudo-sobre-http2-e-protocolos-binarios-parte-1-5h9o"&gt;Parte 1&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;
&lt;a href="https://dev.to/marcelmfa/estudo-sobre-http2-e-protocolos-binarios-parte-2-3m8l"&gt;Parte 2&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;
&lt;a href="https://dev.to/marcelmfa/estudo-sobre-http2-e-protocolos-binarios-parte-3-5f9k"&gt;Parte 3&lt;/a&gt; Você está aqui.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/marcelmfa/estudo-sobre-http2-e-protocolos-binarios-parte-4-2fkc"&gt;Parte 4&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--IbmO2AsQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://i.gifer.com/UNm2.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--IbmO2AsQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://i.gifer.com/UNm2.gif" alt="Após um longo período" width="480" height="360"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Após um "longo" período após o último post, voltamos pra continuar com esta série. Conforme combinado no post anterior, iremos neste apenas alterar o servidor embarcado - isto é, mudar do padrão que é o Tomcat para o Undertow - que é usado pela aplicação e reexecutar os testes. &lt;/p&gt;

&lt;p&gt;De acordo com o post anterior, já estamos "macetados", já sabemos todos os "paranauê" de acordo, então este post visa ser bem rápido.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--VfXPvoMC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://c.tenor.com/d2YGFjEazDgAAAAC/run-fast.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--VfXPvoMC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://c.tenor.com/d2YGFjEazDgAAAAC/run-fast.gif" alt="Rápido como Sonic" width="498" height="203"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Alterando a aplicação
&lt;/h2&gt;

&lt;p&gt;Abaixo temos toda a mudança que é necessária para usar o Undertow ao invés do Tomcat.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--8x-sztTj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://c.tenor.com/ampW8g8v-vMAAAAd/hack-khaby.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--8x-sztTj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://c.tenor.com/ampW8g8v-vMAAAAd/hack-khaby.gif" alt="Isto" width="550" height="640"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--sfW75rEI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/c1lroj52o84t1brhdk2h.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--sfW75rEI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/c1lroj52o84t1brhdk2h.png" alt="Alterações no pom.xml" width="715" height="368"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Isto acontece porque o Spring Boot usa uma estratégia "Opinativa" (o termo original em inglês é &lt;em&gt;Opionionated&lt;/em&gt;, então sei se a tradução é a mais adequada), que em resumo vai tentar configurar o máximo de coisas possíveis a partir das dependências ou das propriedades de sua aplicação, removendo assim muito de código e configurações que muitas vezes precisamos fazer para cada aplicação.&lt;/p&gt;

&lt;p&gt;Caso deseje saber mais sobre essa estratégia, clique &lt;a href="https://www.fusion-reactor.com/blog/technical-blogs/what-is-spring-boot/#:~:text=Spring%2DBoot's%20Opinionated%20Defaults%20Configuration,based%20on%20the%20dependencies%20requirement."&gt;aqui&lt;/a&gt; ou até mesmo na &lt;a href="https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#getting-started.introducing-spring-boot"&gt;documentação oficial&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Vamos de benchmark
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--yy0G_kFY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://media2.giphy.com/media/LpkBAUDg53FI8xLmg1/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--yy0G_kFY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://media2.giphy.com/media/LpkBAUDg53FI8xLmg1/giphy.gif" alt="Lá vamos nós" width="500" height="269"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Os gráficos seguirão abaixo e da mesma forma como os que fizemos no post anterior.&lt;/p&gt;

&lt;h3&gt;
  
  
  HTTP 1.1 e profile 1
&lt;/h3&gt;

&lt;p&gt;Ponto de vista cliente&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--F3OGj1vb--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ctbktjr4betzw6jy6tbz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--F3OGj1vb--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ctbktjr4betzw6jy6tbz.png" alt="Resultados para ponto de vista cliente" width="880" height="481"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Ponto de vista aplicação&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Dmhz2_mr--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wj6q8m2lhybmf63yw6bh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Dmhz2_mr--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wj6q8m2lhybmf63yw6bh.png" alt="Resultados para ponto de vista aplicação" width="880" height="481"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  HTTP 2 e profile 1
&lt;/h3&gt;

&lt;p&gt;Ponto de vista cliente&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Q2VcXAc1--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ynri9wmibpcfxjp1fhk4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Q2VcXAc1--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ynri9wmibpcfxjp1fhk4.png" alt="Resultados para ponto de vista cliente" width="880" height="481"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Ponto de vista aplicação&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--xtR9hRoh--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ag08l2f14jq9xadgswss.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--xtR9hRoh--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ag08l2f14jq9xadgswss.png" alt="Resultados para ponto de vista aplicação" width="880" height="481"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  HTTP 1.1 e profile 2
&lt;/h3&gt;

&lt;p&gt;Ponto de vista cliente&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--aZJT28y6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7inrim7qz4n3obvxorfx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--aZJT28y6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7inrim7qz4n3obvxorfx.png" alt="Resultados para ponto de vista cliente" width="880" height="481"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Ponto de vista aplicação&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Jy_XUoEZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ydjzk733cg9hkc1oubjr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Jy_XUoEZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ydjzk733cg9hkc1oubjr.png" alt="Resultados para ponto de vista aplicação" width="880" height="481"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  HTTP 2 e profile 2
&lt;/h3&gt;

&lt;p&gt;Ponto de vista cliente&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--OQDWT3G2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3mvccj5de9gxdx4cv9h3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--OQDWT3G2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3mvccj5de9gxdx4cv9h3.png" alt="Resultados para ponto de vista cliente" width="880" height="481"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Ponto de vista aplicação&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--n-AhR0Aw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/sr2gifgeccbhqkgn3qij.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--n-AhR0Aw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/sr2gifgeccbhqkgn3qij.png" alt="Resultados para ponto de vista aplicação" width="880" height="481"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Avaliação simplória dos resultados
&lt;/h2&gt;

&lt;p&gt;Todas as execuções consumiram praticamente mesma quantidade de CPU, apenas 1. O profile 2 que possui dobro recursos computacionais em relação ao profile 1 não trouxe nenhum ganho de performance. O uso de HTTP2 processou em torno de 10 mil requisições a mais que com HTTP1.1 e chegando a marca de 100 mil requisições no teste realizado.&lt;/p&gt;

&lt;p&gt;Um ponto interessante é que este processou mais requisições do que o Tomcat, que vimos no post anterior, em torno de 20k requisições a mais e considerando o profile 1.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--9ZKcgywf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/http://2.bp.blogspot.com/-oP7GIovKL5I/ViDvzDdxaaI/AAAAAAAAcfo/c37NjBamRIc/s1600/fhd997TDA_Keanu_Reeves_032.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--9ZKcgywf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/http://2.bp.blogspot.com/-oP7GIovKL5I/ViDvzDdxaaI/AAAAAAAAcfo/c37NjBamRIc/s1600/fhd997TDA_Keanu_Reeves_032.jpg" alt="Cena do filme advogado do diabo" width="633" height="408"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;No entanto, como costumamos dizer e dando uma de "advogado do diabo", o que sabemos e até mesmo não sabemos sobre o Undertow? Acredito que a comunidade Java e Spring já é tão acostumada ao Tomcat que já conhece vários de seus pontos que necessitam ajustes / tuning.&lt;/p&gt;

&lt;p&gt;Portanto minha dica é: pesquisem bem antes de sair fazendo um &lt;strong&gt;shift&lt;/strong&gt; de todas as suas aplicações de Tomcat para Undertow e façam testes como esse.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--drGEYK65--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/az9z19kbmoqym3bhiajh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--drGEYK65--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/az9z19kbmoqym3bhiajh.png" alt="E se trocarmos tudo por Undertow" width="880" height="495"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Pois bem, chegamos ao final deste post e gostaria de dizer que poderíamos continuar quase que indefinidamente, explorando outros servidores como Netty, o não reativo do Webflux, poderíamos empacotar como WAR e implantar num servidor de aplicação Jboss, por exemplo, com outros frameworks de outras linguagens, etc.&lt;/p&gt;

&lt;p&gt;Para não ficarmos neste loop infinito, vou apenas incluir os fontes das aplicações e as imagens dos benchmarks com os cenários que testei no &lt;a href="https://github.com/marcelmfa/estudo-http2-grpc"&gt;repositório&lt;/a&gt; e lá vocês podem conferir a vontade.&lt;/p&gt;

&lt;p&gt;Próximo post a gente vem brabo e de, finalmente, gRPC.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ZkLUSD1z--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://i2.wp.com/parafraseandolivros.com.br/wp-content/uploads/2018/04/come-with-me.gif%3Ffit%3D500%252C269%26ssl%3D1" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ZkLUSD1z--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://i2.wp.com/parafraseandolivros.com.br/wp-content/uploads/2018/04/come-with-me.gif%3Ffit%3D500%252C269%26ssl%3D1" alt="Continue comigo" width="500" height="269"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>performance</category>
      <category>http2</category>
      <category>java</category>
      <category>monitoring</category>
    </item>
    <item>
      <title>Estudo sobre HTTP2 e protocolos binários - parte 2</title>
      <dc:creator>marcelmfa</dc:creator>
      <pubDate>Thu, 23 Jun 2022 21:11:50 +0000</pubDate>
      <link>https://dev.to/marcelmfa/estudo-sobre-http2-e-protocolos-binarios-parte-2-3m8l</link>
      <guid>https://dev.to/marcelmfa/estudo-sobre-http2-e-protocolos-binarios-parte-2-3m8l</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Este post faz parte da seguinte série sobre estudo de HTTP2 e protocolos binários:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://dev.to/marcelmfa/estudo-sobre-http2-e-protocolos-binarios-parte-1-5h9o"&gt;Parte 1&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;
&lt;a href="https://dev.to/marcelmfa/estudo-sobre-http2-e-protocolos-binarios-parte-2-3m8l"&gt;Parte 2&lt;/a&gt; Você está aqui.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/marcelmfa/estudo-sobre-http2-e-protocolos-binarios-parte-3-5f9k"&gt;Parte 3&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/marcelmfa/estudo-sobre-http2-e-protocolos-binarios-parte-4-2fkc"&gt;Parte 4&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Recomendações (Opcional)
&lt;/h2&gt;

&lt;p&gt;Listo aqui algumas recomendações que podem ajudar vocês:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Se você usa Windows, eu recomendo que usem o WSL2 com alguma distro de sua preferência, caso goste ou queira testar o Ubuntu, só seguir &lt;a href="https://dev.to/erickrock80/pt-br-instalando-oh-my-zsh-no-windows-terminal-3a8l"&gt;este artigo&lt;/a&gt;, que possui um passo a passo bem intuitivo;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://sdkman.io/"&gt;SDKMAN&lt;/a&gt; para gerenciar várias versões de vários softwares, dentre eles JDK, e até mesmo alterar qual versão quer usar. Aproveite e já instale o Java 11;&lt;/li&gt;
&lt;li&gt;a IDE eu não vou opinar, pois vai muito de gosto pessoal, mas eu uso VSCode com algumas extensões do Spring, Java e para o WSL.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Criando aplicação Java + Spring Boot
&lt;/h2&gt;

&lt;p&gt;Como iremos criar uma aplicação Spring Boot, obviamente iremos usar o &lt;a href="https://start.spring.io/"&gt;site oficial&lt;/a&gt; para gerar o &lt;em&gt;boilerplate&lt;/em&gt; inicial e já configurado com algumas dependências. Existe também o CLI e plugins em algumas IDEs que fazem o mesmo, mas o site acredito que seja o mais atualizado.&lt;/p&gt;

&lt;p&gt;Nesta parte é importante apenas selecionar a opção "Java 11" e incluir as seguintes dependências: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Spring Web; &lt;/li&gt;
&lt;li&gt;Spring Boot Actuator; &lt;/li&gt;
&lt;li&gt;Prometheus.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;Mas porquê adicionar essas dependências?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--iUu_vmEZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://c.tenor.com/R_N2FwCFBbcAAAAM/confused-white-persian-guardian.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--iUu_vmEZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://c.tenor.com/R_N2FwCFBbcAAAAM/confused-white-persian-guardian.gif" alt="Mas porquê adicionar essas dependências?" width="220" height="220"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Estas dependências servem respectivamente para criar uma aplicação com um servidor &lt;em&gt;web&lt;/em&gt; embarcado que iremos expor a API, seguindo de outras dependências que irão expor métricas desta aplicação.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ifWaA23I--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://y.yarn.co/690fa569-2cb9-4aa7-a9b3-8f58b7db74b4_text.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ifWaA23I--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://y.yarn.co/690fa569-2cb9-4aa7-a9b3-8f58b7db74b4_text.gif" alt="Cadê o código?" width="400" height="223"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;E agora sem mais delongas.&lt;/p&gt;

&lt;h3&gt;
  
  
  Criando a API
&lt;/h3&gt;

&lt;p&gt;Como dito no post anterior, iremos usar a &lt;em&gt;lib&lt;/em&gt; &lt;a href="https://github.com/DiUS/java-faker"&gt;Java Faker&lt;/a&gt; e o código está representado abaixo.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--nmWUp6VU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/of6ehpd2riemhgxrqu9u.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--nmWUp6VU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/of6ehpd2riemhgxrqu9u.png" alt="Definição do RestController do Spring" width="781" height="624"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--0-7JE6Bt--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/njfm77a4kb2vdi7dajov.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--0-7JE6Bt--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/njfm77a4kb2vdi7dajov.png" alt="Definição do POJO de retorno da API" width="880" height="574"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Ô amigão, o código fonte tá como imagem. Tu tá de &lt;em&gt;brinqueichon uite me&lt;/em&gt;?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--a4pwKXu_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://museudememes.com.br/wp-content/uploads/2021/06/2ubw-2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--a4pwKXu_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://museudememes.com.br/wp-content/uploads/2021/06/2ubw-2.png" alt="Tu tá de brincation?" width="641" height="360"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Na seção final irei deixar o link do repositório no Github.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--rwF9Kh6L--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://c.tenor.com/ixuFRFzUsQ8AAAAM/e-nois-alek.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--rwF9Kh6L--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://c.tenor.com/ixuFRFzUsQ8AAAAM/e-nois-alek.gif" alt="Tamo junto" width="220" height="143"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Habilitando HTTP2
&lt;/h3&gt;

&lt;p&gt;Como já é hábito (cof cof, ou pelo menos a gente tenta XD), na hora de verificar como configurar determinada funcionalidade em um &lt;em&gt;framework&lt;/em&gt; / biblioteca / ferramenta vamos de &lt;a href="https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#howto.webserver.configure-http2"&gt;documentação oficial e na seção específica que trata do assunto&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Como lido na documentação e trazendo de forma bem curta e ligeira, para habilitar HTTP2 será necessário também configurar o TLS desta aplicação, que por sua vez será necessário um certificado, donde usaremos um auto-assinado conforme abaixo.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;keytool &lt;span class="nt"&gt;-genkeypair&lt;/span&gt; &lt;span class="nt"&gt;-alias&lt;/span&gt; spring-http2 &lt;span class="nt"&gt;-keyalg&lt;/span&gt; RSA &lt;span class="nt"&gt;-keysize&lt;/span&gt; 2048 &lt;span class="nt"&gt;-storetype&lt;/span&gt; PKCS12 &lt;span class="nt"&gt;-keystore&lt;/span&gt; spring-http2.p12 &lt;span class="nt"&gt;-validity&lt;/span&gt; 3650 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;E use a senha &lt;code&gt;passwd&lt;/code&gt; quando solicitado e copiar o arquivo criado para a pasta &lt;code&gt;src/main/resources/keystore&lt;/code&gt; na aplicação.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;PS.: Estamos colocando o certificado dentro da aplicação apenas para fins de simplicidade e demonstração, mas o mesmo deveria estar externalizado.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Abaixo as propriedades da aplicação.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--0odkhjlF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rx1etdqggyfsighrdig3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--0odkhjlF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rx1etdqggyfsighrdig3.png" alt="Arquivo de propriedades do Spring Boot" width="880" height="294"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A última propriedade é referente a exposição de &lt;em&gt;endpoints&lt;/em&gt; do &lt;em&gt;actuator&lt;/em&gt;, que para efeitos de simplicidade foram expostos todos para que o Prometheus possa fazer o &lt;em&gt;scrapper&lt;/em&gt; destes dados e assim termos monitoramento da aplicação.&lt;/p&gt;

&lt;p&gt;As demais propriedades são relacionadas a HTTP2, HTTPS e certificado.&lt;/p&gt;

&lt;p&gt;Caso queira testar a aplicação, pode-se usar o &lt;em&gt;Maven wrapper&lt;/em&gt; que vem junto ao projeto do Spring e rodar a aplicação da seguinte forma:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;./mvnw spring-boot:run
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Depois pode-se acessar os seguintes endpoints:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://localhost:8443/ppl"&gt;Testar o recurso REST da API criada&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://localhost:8443/actuator"&gt;Testar o recurso REST de métricas&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Beleza galera, agora foi a parte demorada, agora vai ser à jato.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--4-jTGnlB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://c.tenor.com/Mv2_BcVoH9wAAAAC/gato-a-jato-asas-de-decolagem.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--4-jTGnlB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://c.tenor.com/Mv2_BcVoH9wAAAAC/gato-a-jato-asas-de-decolagem.gif" alt="Imagem do gato a jato do pica-pau" width="480" height="360"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Instalar ferramentas - Prometheus, Grafana, InfluxDB1 e k6
&lt;/h2&gt;

&lt;p&gt;Vamos rever a nossa arquitetura de benchmark que foi apresentada no post anterior, mas está logo aqui abaixo para facilitar o rolê.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ZMZoTd9Q--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2k4ydkb54nhnrfec5g6h.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ZMZoTd9Q--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2k4ydkb54nhnrfec5g6h.png" alt="Arquitetura do benchmark" width="880" height="439"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Vamos instalar o Prometheus, Grafana, InfluxDB1 e k6 e aqui não tem muito mistério pessoal, iremos usar as instruções de instalação e execução de acordo com o site de cada ferramenta conforme os links abaixo:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://prometheus.io/docs/prometheus/latest/getting_started/#downloading-and-running-prometheus"&gt;Instalar Prometheus&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://grafana.com/grafana/download?pg=oss-graf&amp;amp;plcmt=resources"&gt;Instalar Grafana&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.influxdata.com/influxdb/v1.8/introduction/install/#installing-influxdb-oss"&gt;Instalar InfluxDB1&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://k6.io/docs/getting-started/installation/"&gt;k6&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--uc3HBF51--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://c.tenor.com/Hw7f-4l0zgEAAAAM/check-green.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--uc3HBF51--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://c.tenor.com/Hw7f-4l0zgEAAAAM/check-green.gif" alt="Trabalho feito!" width="220" height="215"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Configurando as ferramentas
&lt;/h2&gt;

&lt;p&gt;Com todas as ferramentas instaladas, agora iremos verificar como configurar cada uma delas.&lt;/p&gt;

&lt;h3&gt;
  
  
  Configurando a aplicação
&lt;/h3&gt;

&lt;p&gt;Como temos 2 profiles, então teremos que iniciar a aplicação de forma diferente a cada teste: &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;2cpu, 2Gb RAM - cujo comando será:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;./mvnw spring-boot:run &lt;span class="nt"&gt;-Dspring-boot&lt;/span&gt;.run.jvmArguments&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"-XX:ActiveProcessorCount=2 -Xmx2g -Xms2g"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;4cpu, 4Gb RAM - cujo comando será:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;./mvnw spring-boot:run &lt;span class="nt"&gt;-Dspring-boot&lt;/span&gt;.run.jvmArguments&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"-XX:ActiveProcessorCount=4 -Xmx4g -Xms4g"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Foi incluído o trecho de código abaixo para exibir esses valores de CPU e memória durante a inicialização da aplicação, apenas para confirmar:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--2k6mEoOg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/q4z30derwua3w2j5sevv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--2k6mEoOg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/q4z30derwua3w2j5sevv.png" alt="Comando para imprimir os recursos de CPU e RAM" width="880" height="163"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Configurando o Prometheus
&lt;/h3&gt;

&lt;p&gt;No caso do prometheus, precisa apenas iniciar o serviço com um arquivo de configuração para que o mesmo possa ler as métricas da aplicação. Segue abaixo um exemplo de &lt;em&gt;scrapper&lt;/em&gt; de métricas para esta aplicação em específico.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--bWt2aD1C--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/z96614o2cd66487lhkbm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--bWt2aD1C--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/z96614o2cd66487lhkbm.png" alt="Configuração scrapper Prometheus" width="410" height="221"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Configurando InfluxDB1
&lt;/h3&gt;

&lt;p&gt;Nada aqui, apenas iniciar o serviço.&lt;/p&gt;

&lt;h3&gt;
  
  
  Configurando Grafana
&lt;/h3&gt;

&lt;p&gt;Inicie o serviço do Grafana, abra sua &lt;a href="http://localhost:3000"&gt;interface web&lt;/a&gt;, faça login com tanto usuário e senha &lt;code&gt;admin&lt;/code&gt; e em seguida vamos configurar 2 itens: &lt;em&gt;data sources&lt;/em&gt; e &lt;em&gt;dashboards&lt;/em&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Data sources
&lt;/h3&gt;

&lt;p&gt;Para incluir os data sources, pode-se na tela inicial, vai ter um &lt;em&gt;card&lt;/em&gt; para adicionar o &lt;em&gt;data source&lt;/em&gt; ou pode-se ir no menu lateral. &lt;/p&gt;

&lt;p&gt;Para o Prometheus basta colocar a URL do mesmo &lt;code&gt;http://localhost:9090/&lt;/code&gt; e se o serviço estiver rodando, pode salvar e testar.&lt;/p&gt;

&lt;p&gt;Para o InfluxDB é necessário colocar a URL do mesmo &lt;code&gt;http://localhost:8086&lt;/code&gt; e informar no campo mais abaixo &lt;code&gt;Database&lt;/code&gt; o valor &lt;code&gt;myk6db&lt;/code&gt;, cujos valores serão utilizados na próxima seção para o k6 fazer a ingestão das métricas.&lt;/p&gt;

&lt;h3&gt;
  
  
  Dashboards
&lt;/h3&gt;

&lt;p&gt;Quando estava visitando artigos e a própria documentação do Grafana, notei que existe lá no site oficial uma seção onde as pessoas &lt;a href="https://grafana.com/grafana/dashboards/"&gt;compartilham dashboards&lt;/a&gt;, então usando o conceito de "Não reinvente a roda", então pensei: "deixa eu ver se num já tem um giga painel completão de tudo".&lt;/p&gt;

&lt;p&gt;E a grande motivação de eu ter usado o InfluxDB1 foi justamente por ter encontrado um dashboard pronto pro k6 de id &lt;code&gt;4411&lt;/code&gt;. Quanto ao Spring Boot também achei um muito bacana de id &lt;code&gt;14430&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Para importar esses dashboards, basta vir no menu lateral, no ícone de &lt;code&gt;+&lt;/code&gt; e ir na opção &lt;code&gt;Import&lt;/code&gt;. Só usar os Ids acima e clicar no &lt;code&gt;Load&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Estes serão os dashboards apresentados no benchmark.&lt;/p&gt;

&lt;h3&gt;
  
  
  Configurando k6
&lt;/h3&gt;

&lt;p&gt;Como iremos executar um comparativo entre HTTP1.1 e HTTP2, além de que também teremos métricas de cliente e que sejam enviadas para o InfluxDB, então faremos a execução da seguinte forma:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;HTTP1.1
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;GODEBUG&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;http2client&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;0 k6 run ./k6/http_get.js &lt;span class="nt"&gt;-o&lt;/span&gt; &lt;span class="nv"&gt;influxdb&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;http://localhost:8086/myk6db
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;HTTP2
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;k6 run ./k6/http_get.js &lt;span class="nt"&gt;-o&lt;/span&gt; &lt;span class="nv"&gt;influxdb&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;http://localhost:8086/myk6db
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Como é possível perceber acima, o comando é praticamente o mesmo, porém conforme a documentação, o k6 por padrão tenta executar sempre usando HTTP2, então é necessário forçar o mesmo a usar o HTTP1.1 passando um parametro pro Go.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;O comando acima referencia um aquivo JS que é como o k6 faz as execuções. Abaixo o tal arquivo que define o teste e este foi criado seguindo o exemplo de &lt;a href="https://k6.io/docs/test-types/load-testing/#load-testing-in-k6"&gt;teste de carga (&lt;em&gt;Load Test&lt;/em&gt;) da documentação oficial&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--bD1lFF_m--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/keu5qi2c4bpr0vw3nf0x.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--bD1lFF_m--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/keu5qi2c4bpr0vw3nf0x.png" alt="Arquivo de definição de teste de carga do k6" width="880" height="281"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Agora finalmente, temos todos os serviços instalados e sabemos como executar cada um deles para começar as execuções.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--C_A14Klj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://i.pinimg.com/originals/8d/18/0f/8d180f2f297455ab04500dda1d6800d8.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--C_A14Klj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://i.pinimg.com/originals/8d/18/0f/8d180f2f297455ab04500dda1d6800d8.gif" alt="Mais atividades concluídas" width="800" height="600"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  O famigerado &lt;em&gt;benchmark&lt;/em&gt;
&lt;/h2&gt;

&lt;p&gt;Agora que instalamos tudo, sabemos como iniciar cada serviço, vem a sequência de execuções.&lt;/p&gt;

&lt;p&gt;Iremos priorizar a mudança de protocolo diante um profile e então mudaremos para o próximo profile.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--a8rT7dUH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://i.pinimg.com/originals/a9/1d/e1/a91de123fec53ba74734197d58213e27.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--a8rT7dUH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://i.pinimg.com/originals/a9/1d/e1/a91de123fec53ba74734197d58213e27.gif" alt="Oi? Num entendi." width="402" height="404"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Faremos na seguinte sequência:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;HTTP1.1 e profile 1&lt;/li&gt;
&lt;li&gt;HTTP2 e profile 1&lt;/li&gt;
&lt;li&gt;HTTP1.1 e profile 2&lt;/li&gt;
&lt;li&gt;HTTP2 profile 2&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Organizei desta forma para ficar mais fácil de visualizar os testes de cada profile. Os resultados a seguir serão sempre exibidos com os resultados do lado do cliente e depois da aplicação para cada um dos testes.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;PS.: Os resultados abaixo são os mesmos que preparei para uma apresentação para colegas do trabalho. Realizei todos os testes na minha máquina mesmo para efeitos de demonstração, que devem ser realizados em um ambiente adequado sem que os serviços fiquem competindo entre si.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  HTTP1.1 e profile 1
&lt;/h3&gt;

&lt;p&gt;Ponto de vista cliente&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--4UbNu63H--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yk49vsrd4esgpxvm2fhv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--4UbNu63H--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yk49vsrd4esgpxvm2fhv.png" alt="Resultados do ponto de vista cliente" width="880" height="481"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Ponto de vista aplicação&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--6xWmdxGq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wsv5kxr95xoj5cgsz1e8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--6xWmdxGq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wsv5kxr95xoj5cgsz1e8.png" alt="Resultados do ponto de vista da aplicação" width="880" height="481"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  HTTP2 e profile 1
&lt;/h3&gt;

&lt;p&gt;Ponto de vista cliente&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--MFpZF834--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7j55uqxmsgdk48g2w6mh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--MFpZF834--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7j55uqxmsgdk48g2w6mh.png" alt="Resultados do ponto de vista cliente" width="880" height="481"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Ponto de vista aplicação&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--lJUr0I6z--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/84dhaf7jj4utk0ymt1we.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--lJUr0I6z--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/84dhaf7jj4utk0ymt1we.png" alt="Resultados do ponto de vista da aplicação" width="880" height="481"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  HTTP1.1 e profile 2
&lt;/h3&gt;

&lt;p&gt;Ponto de vista cliente&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ZJIK0GJi--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fzocqqaesgkili0paw6q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ZJIK0GJi--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fzocqqaesgkili0paw6q.png" alt="Resultados do ponto de vista cliente" width="880" height="481"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Ponto de vista aplicação&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--7DQTO5Ab--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/i0shlxx8thy6vft66c7t.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--7DQTO5Ab--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/i0shlxx8thy6vft66c7t.png" alt="Resultados do ponto de vista da aplicação" width="880" height="481"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  HTTP2 e profile 2
&lt;/h3&gt;

&lt;p&gt;Ponto de vista cliente&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--baos_Cgw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mbajpqnd3zd2l4mf9085.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--baos_Cgw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mbajpqnd3zd2l4mf9085.png" alt="Resultados do ponto de vista cliente" width="880" height="481"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Ponto de vista aplicação&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--9jVLDSIE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ejz3zz3npc5k1un9fnod.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--9jVLDSIE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ejz3zz3npc5k1un9fnod.png" alt="Resultados do ponto de vista da aplicação" width="880" height="481"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Avaliação simplória dos resultados
&lt;/h3&gt;

&lt;p&gt;Analisando ambas execuções do profile 1 para HTTP1.1 e HTTP2 os resultados foram praticamente os mesmos, considerando número de requisições, tempos de resposta, uso de CPU e memória.&lt;/p&gt;

&lt;p&gt;Comparando ambas execuções do profile 2 os resultados foram similares à análise anterior.&lt;/p&gt;

&lt;p&gt;Ao comparar as execuções dos profiles 1 e 2, esta respondeu em torno de 10 mil requisições a mais (ou seja, a performance aumentou dado que o tempo de exeução é o mesmo para todos os testes) e consumiu mesma quantidade de CPU do que a do profile 1.&lt;/p&gt;

&lt;p&gt;Para este caso de uso específico, não houve ganho com uso de HTTP2, mas qual seria o problema (se é que tem algum): &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;falta de tuning? &lt;/li&gt;
&lt;li&gt;caso de uso não adequado? &lt;/li&gt;
&lt;li&gt;teria alguma falha no teste de carga? &lt;/li&gt;
&lt;li&gt;O uso da mesma máquina para rodar tudo? &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Essas e outras perguntas podem surgir durante uma avaliação e acredito ser normal. Resta continuar estudando essa disciplina de engenharia de desempenho para tentar elucidar todas as questões acima.&lt;/p&gt;

&lt;h2&gt;
  
  
  Considerações finais
&lt;/h2&gt;

&lt;p&gt;Apenas reforçando o que foi dito anteriormente e para que ninguém considere este resultado uma verdade absoluta:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Os testes, incluindo todas as ferramentas, foram TODOS executados na minha máquina competindo entre si pelos recursos, incluindo o SO;&lt;/li&gt;
&lt;li&gt;O caso de uso específico tem uma quantidade mínima de processamento, apenas gerar 100 itens e retornar; não possui nenhuma dependência de recurso / serviço externo seja I/O ou de rede;&lt;/li&gt;
&lt;li&gt;Não foi aplicada nenhuma configuração de tuning em nenhum dos elementos, foram mantidas todas as configurações padrão.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Enfim, espero não ter sido demasiadamente longo neste post e que tudo apresentado aqui sirva de ajuda ou exemplo para que vocês possam usar de alguma forma no dia a dia.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;As imagens ficaram pequenas aqui, mas irei incluir as mesmas no repositório caso queiram ver os originais.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Por falar em repositório, &lt;a href="https://github.com/marcelmfa/estudo-http2-grpc/"&gt;clique aqui para ver o código fonte&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  FUTURO!?!?
&lt;/h2&gt;

&lt;p&gt;Após este trabalho realizado e apresentado, um colega do trabalho mandou um: "E se a gente testar também com Undertow?".&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--8LJ7kgxL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://c.tenor.com/3vkl4KZo9OYAAAAM/whatif.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--8LJ7kgxL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://c.tenor.com/3vkl4KZo9OYAAAAM/whatif.gif" alt="E se..." width="220" height="142"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Nos vemos na próxima parte, com os testes no Undertow.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--7eFuQIBi--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://media1.giphy.com/media/l1J3CbFgn5o7DGRuE/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--7eFuQIBi--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://media1.giphy.com/media/l1J3CbFgn5o7DGRuE/giphy.gif" alt="Nos vemos em breve" width="480" height="309"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;[Atualizado 24/06] - Incluída configuração de Data Sources e IDs dos dashboards.&lt;/p&gt;

</description>
      <category>performance</category>
      <category>http2</category>
      <category>java</category>
      <category>monitoring</category>
    </item>
    <item>
      <title>Estudo sobre HTTP2 e protocolos binários - parte 1</title>
      <dc:creator>marcelmfa</dc:creator>
      <pubDate>Fri, 17 Jun 2022 20:32:31 +0000</pubDate>
      <link>https://dev.to/marcelmfa/estudo-sobre-http2-e-protocolos-binarios-parte-1-5h9o</link>
      <guid>https://dev.to/marcelmfa/estudo-sobre-http2-e-protocolos-binarios-parte-1-5h9o</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Este post faz parte da seguinte série sobre estudo de HTTP2 e protocolos binários:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://dev.to/marcelmfa/estudo-sobre-http2-e-protocolos-binarios-parte-1-5h9o"&gt;Parte 1&lt;/a&gt; Você está aqui.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/marcelmfa/estudo-sobre-http2-e-protocolos-binarios-parte-2-3m8l"&gt;Parte 2&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/marcelmfa/estudo-sobre-http2-e-protocolos-binarios-parte-3-5f9k"&gt;Parte 3&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/marcelmfa/estudo-sobre-http2-e-protocolos-binarios-parte-4-2fkc"&gt;Parte 4&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;p&gt;Estava iniciando junto a colegas do trabalho um estudo sobre o uso de protocolos binários como gRPC e MessagePack a fim de experimentar e avaliar os mesmos em termos de uso e performance, porém algo antes nos incomodou, que é sobre o uso do HTTP2, que tais protocolos fazem uso.&lt;/p&gt;

&lt;p&gt;E a pergunta que surgiu foi:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;E se antes de experimentarmos esses protocolos, a gente avaliasse o uso de HTTP2 e comparar com o HTTP1.1?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--JZB4VtdB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://c.tenor.com/-HfTRwXMWT0AAAAC/kid-thinking.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--JZB4VtdB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://c.tenor.com/-HfTRwXMWT0AAAAC/kid-thinking.gif" alt="A gente pensando" width="498" height="380"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Eu cheguei a ler artigos como &lt;a href="https://evertpot.com/h2-parallelism/"&gt;este&lt;/a&gt;, que é bem completo, mas acho que ele trata mais do ponto de vista dos &lt;em&gt;browsers&lt;/em&gt;, ou seja, quando alguém acessa um site e como ele se comporta para "baixar" (realizar o &lt;em&gt;download&lt;/em&gt;) de todos aqueles recursos.&lt;/p&gt;

&lt;p&gt;O ponto de vista que eu tava imaginando seria serviço a serviço, algo interno da infraestutura dos produtos, ou seja, seria um consumo lateral de serviços. Dado que era um cenário diferente do artigo supracitado, veio a idéia de criar o meu próprio &lt;em&gt;benchmark&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Beleza então, já tava decidido sobre o "benchmark", agora o lance é planejar como vai ser esse trabalho. Vou precisar de:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;uma aplicação obviamente que vai ter que se comunicar via HTTP1.1 e HTTP2 com o mínimo de alterações e idealmente nenhuma;&lt;/li&gt;
&lt;li&gt;um &lt;em&gt;client&lt;/em&gt; para realizar esse &lt;em&gt;benchmark&lt;/em&gt; e que obviamente possua suporte a HTTP1.1 e HTTP2;&lt;/li&gt;
&lt;li&gt;algo pra monitoramento, que receba as métricas e que eu possa visualizar as mesmas.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Como a linguagem que mais domino é Java e sou um fã / enorme entusiasta do Spring, já ficou fechada essa parte. A aplicação é uma API REST com um recurso GET que retorna uma lista de dados em JSON. Utilizamos o &lt;a href="https://github.com/DiUS/java-faker"&gt;Java Faker&lt;/a&gt; para gerar os dados em runtime, incluí-los numa lista de um POJO e retornar ao solicitante. Pensamos nesta forma para não um retorno de algo estático e ter um mínimo processamento.&lt;/p&gt;

&lt;p&gt;Quanto ao &lt;em&gt;client&lt;/em&gt;, comecei a pesquisa no amigo de todo dia, Google, e me deparei com essa &lt;a href="https://github.com/denji/awesome-http-benchmark"&gt;"pequena" lista de ferramentas&lt;/a&gt;. Testei umas 3 delas e por último cheguei no &lt;a href="https://k6.io/docs/"&gt;k6&lt;/a&gt; que pra minha surpresa é do Grafana Labs.&lt;/p&gt;

&lt;p&gt;Quanto ao monitoramento, onde trabalho estamos investindo e usando Prometheus e Grafana, então veio tudo a calhar com a escolha do k6, que já tem toda uma documentação pronta e com exemplos para esta integração.&lt;/p&gt;

&lt;p&gt;Ficou fechado o esquema que seria da forma abaixo.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ZMZoTd9Q--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2k4ydkb54nhnrfec5g6h.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ZMZoTd9Q--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2k4ydkb54nhnrfec5g6h.png" alt="Arquitetura do benchmark" width="880" height="439"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Podemos ver acima que tem um cara novo e que não citado anteriormente, que é o Influx. Este camarada apareceu aí porque olhando site do Grafana, lá tem vários dashboards prontos e tinha um do k6, porém usava o Influx como base de métricas, então incluí o mesmo para facilitar o trabalho.&lt;/p&gt;

&lt;p&gt;Por fim, como vai ser realizado um trabalho de monitoramento e como o foco deste trabalho seria em cima de máquinas virtuais, então pensamos em estabelecer uma cota de recurso e daí veio a idéia de 2 profiles:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;2cpu, 2Gb RAM&lt;/li&gt;
&lt;li&gt;4cpu, 4Gb RAM&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;O Java 11 possui tais argumentos de VM para poder incluir estas cotas.&lt;/p&gt;

&lt;p&gt;Bem, este foi apenas o primeiro post tanto deste estudo como meu próprio.&lt;/p&gt;

&lt;p&gt;Abaixo uma imagem ilustrativa de como pode ser o próximo post.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--dX4WTK3I--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://i.gifer.com/1Cr1.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--dX4WTK3I--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://i.gifer.com/1Cr1.gif" alt="Cenas dos próximos capítulos" width="498" height="296"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>performance</category>
      <category>http2</category>
      <category>java</category>
      <category>monitoring</category>
    </item>
  </channel>
</rss>
