<?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: Matheus Henrique</title>
    <description>The latest articles on DEV Community by Matheus Henrique (@mathstylish).</description>
    <link>https://dev.to/mathstylish</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%2F1874264%2F08fde240-45a2-4565-990a-5306f4cdaf81.jpg</url>
      <title>DEV Community: Matheus Henrique</title>
      <link>https://dev.to/mathstylish</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/mathstylish"/>
    <language>en</language>
    <item>
      <title>Melhorando o desempenho de aplicações Spring Boot - Parte II</title>
      <dc:creator>Matheus Henrique</dc:creator>
      <pubDate>Tue, 27 Aug 2024 17:20:06 +0000</pubDate>
      <link>https://dev.to/mathstylish/melhorando-o-desempenho-de-aplicacoes-spring-boot-parte-ii-nbi</link>
      <guid>https://dev.to/mathstylish/melhorando-o-desempenho-de-aplicacoes-spring-boot-parte-ii-nbi</guid>
      <description>&lt;p&gt;Na primeira parte deste artigo, aprendemos a como estar melhorando o desempenho das nossas aplicações, substituindo o &lt;em&gt;Tomcat&lt;/em&gt; pelo &lt;em&gt;Undertow&lt;/em&gt;, que é um servidor web de alta performance, além de habilitar e configurar a compressão de dados, para reduzir o tamanho das respostas HTTP que trafegam pela rede.&lt;/p&gt;

&lt;p&gt;Agora, iremos falar sobre como melhorar o desempenho de aplicação Spring Boot na parte de persistência, mas antes precisamos entender o que é &lt;em&gt;JPA&lt;/em&gt;, &lt;em&gt;Hibernate&lt;/em&gt; e &lt;em&gt;Hikari&lt;/em&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  JPA
&lt;/h2&gt;

&lt;p&gt;JPA ou &lt;em&gt;&lt;strong&gt;Java Persistence API&lt;/strong&gt;&lt;/em&gt;, que posteriormente foi renomeada para &lt;em&gt;&lt;strong&gt;Jakarta Persistence&lt;/strong&gt;&lt;/em&gt;, é um padrão da linguagem Java que descreve uma interface comum para &lt;em&gt;frameworks&lt;/em&gt; de persistência de dados.&lt;/p&gt;

&lt;p&gt;A especificação &lt;em&gt;JPA&lt;/em&gt; define o mapeamento relacional de objetos internamente, em vez de depender das implementações de mapeamento específicas do fornecedor.&lt;/p&gt;

&lt;h2&gt;
  
  
  Hibernate
&lt;/h2&gt;

&lt;p&gt;O &lt;em&gt;&lt;strong&gt;Hibernate&lt;/strong&gt;&lt;/em&gt; é um dos frameworks de &lt;strong&gt;&lt;em&gt;ORM&lt;/em&gt;&lt;/strong&gt; que faz a implementação concreta da especificação &lt;em&gt;JPA&lt;/em&gt;, ou seja, se nessa especificação é descrito que é preciso de métodos para &lt;strong&gt;persistir&lt;/strong&gt;, &lt;strong&gt;remover&lt;/strong&gt;, &lt;strong&gt;atualizar&lt;/strong&gt; e &lt;strong&gt;buscar dados&lt;/strong&gt;, quem vai de fato construir esses comportamentos é o &lt;strong&gt;&lt;em&gt;Hibernate&lt;/em&gt;&lt;/strong&gt;, assim como o &lt;em&gt;&lt;strong&gt;EclipseLink&lt;/strong&gt;&lt;/em&gt;, que é outro &lt;strong&gt;&lt;em&gt;ORM&lt;/em&gt;&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Hikari
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;&lt;strong&gt;Hikari&lt;/strong&gt;&lt;/em&gt; é um framework de &lt;em&gt;connection pooling&lt;/em&gt;, que é responsável pelo gerenciamento de conexões com o banco de dados, mantendo-as abertas para que possam ser reutilizadas, ou seja, é um &lt;em&gt;cache&lt;/em&gt; de conexões para solicitações futuras, tornando o acesso ao banco de dados mais rápido e reduzindo o número de novas conexões a serem criadas.&lt;/p&gt;

&lt;h2&gt;
  
  
  Configurando Hikari, JPA e o Hibernate
&lt;/h2&gt;

&lt;p&gt;Uma configuração que podemos estar realizando para melhorar o desempenho é a seguinte:&lt;/p&gt;

&lt;p&gt;Usando &lt;code&gt;application.yml&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;spring&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;hikari&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;auto-commit&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
    &lt;span class="na"&gt;connection-timeout&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;250&lt;/span&gt;
    &lt;span class="na"&gt;max-lifetime&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;600000&lt;/span&gt;
    &lt;span class="na"&gt;maximum-pool-size&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;20&lt;/span&gt;
    &lt;span class="na"&gt;minimum-idle&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;10&lt;/span&gt;
    &lt;span class="na"&gt;pool-name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;master&lt;/span&gt;

  &lt;span class="na"&gt;jpa&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;open-in-view&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
    &lt;span class="na"&gt;show-sql&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
    &lt;span class="na"&gt;hibernate&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;ddl-auto&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;none&lt;/span&gt;
    &lt;span class="na"&gt;properties&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;hibernate.connection.provider_disables_autocommit&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
      &lt;span class="na"&gt;hibernate.generate_statistics&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Usando &lt;code&gt;application.properties&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight properties"&gt;&lt;code&gt;&lt;span class="py"&gt;spring.datasource.hikari.auto-commit&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;false&lt;/span&gt;
&lt;span class="py"&gt;spring.datasource.hikari.connection-timeout&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;50&lt;/span&gt;
&lt;span class="py"&gt;spring.datasource.hikari.max-lifetime&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;600000&lt;/span&gt;
&lt;span class="py"&gt;spring.datasource.hikari.maximum-pool-size&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;20&lt;/span&gt;
&lt;span class="py"&gt;spring.datasource.hikari.minimum-idle&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;10&lt;/span&gt;
&lt;span class="py"&gt;spring.datasource.hikari.pool-name&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;master&lt;/span&gt;

&lt;span class="py"&gt;spring.datasource.jpa.open-in-view&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;false&lt;/span&gt;
&lt;span class="py"&gt;spring.datasource.jpa.show-sql&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;true&lt;/span&gt;

&lt;span class="py"&gt;spring.datasource.jpa.hibernate.ddl-auto&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;none&lt;/span&gt;
&lt;span class="py"&gt;spring.jpa.properties.hibernate.generate_statistics&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;true&lt;/span&gt;
&lt;span class="py"&gt;spring.jpa.properties.hibernate.connection.provider_disables_autocommit&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Agora vamos a um breve um resumo das opções:&lt;/p&gt;

&lt;h3&gt;
  
  
  Hikari
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;spring.datasource.hikari.auto-commit&lt;/code&gt;: Se for &lt;code&gt;false&lt;/code&gt;, toda conexão que for retornada pelo &lt;em&gt;connection pool&lt;/em&gt; virá com &lt;em&gt;auto-commit&lt;/em&gt; desabilitado.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;spring.datasource.hikari.connection-timeout&lt;/code&gt;: Tempo, em milissegundos, que o cliente aguardará por uma conexão do &lt;em&gt;pool&lt;/em&gt;. É preferível configurar um tempo curto para falhar rapidamente e retornar uma mensagem de erro, em vez de manter o cliente esperando indefinidamente.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;spring.datasource.hikari.max-lifetime&lt;/code&gt;: Tempo máximo que uma conexão pode permanecer ativa. Configurar esse parâmetro é crucial para evitar falhas por conexões problemáticas e aumentar a segurança, já que conexões ativas por muito tempo são mais vulneráveis a ataques.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;spring.datasource.hikari.maximum-pool-size&lt;/code&gt;: Tamanho máximo do &lt;em&gt;pool&lt;/em&gt;, incluindo conexões ociosas e em uso, determinando o número máximo de conexões ativas com o banco de dados. Se o pool atingir esse limite e não houver conexões ociosas, chamadas para &lt;em&gt;getConnection()&lt;/em&gt; serão bloqueadas por até &lt;em&gt;connectionTimeout&lt;/em&gt; milissegundos antes de falharem.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Encontrar um valor adequado é importante, pois muitas pessoas acham que vão ter um ótimo desempenho definindo 50, 70 ou até 100. O ideal é ter 20 no máximo, que é a quantidade de &lt;em&gt;threads&lt;/em&gt; em paralelo utilizando as conexões.&lt;/li&gt;
&lt;li&gt;Quanto maior o valor, mais difícil vai ser para banco de dados gerenciar essas conexões e muito provavelmente não conseguiremos ter &lt;em&gt;throughput&lt;/em&gt; suficiente para utilizar todas essas conexões.&lt;/li&gt;
&lt;li&gt;É importante entender que do ponto de vista do &lt;em&gt;RDBMS&lt;/em&gt; (&lt;em&gt;Relational Database Management System&lt;/em&gt;) é difícil manter uma conexão aberta com ele mesmo, imagine n quantidade de conexões.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;&lt;p&gt;&lt;code&gt;spring.datasource.hikari.minimum-idle&lt;/code&gt;: Número mínimo de conexões que o pool mantém quando a demanda é baixa. O pool pode reduzir as conexões até 10 e recriá-las conforme necessário. No entanto, para desempenho máximo e melhor resposta a picos de demanda, é recomendado não definir esse valor, permitindo que o Hikari funcione como um pool de tamanho fixo. Padrão: igual ao &lt;code&gt;spring.datasource.hikari.maximum-pool-size&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;&lt;code&gt;spring.datasource.hikari.pool-name&lt;/code&gt;: Nome definido pelo usuário para o &lt;em&gt;pool&lt;/em&gt; de conexão e aparece principalmente em consoles de gerenciamento de registro e &lt;em&gt;JMX&lt;/em&gt; para identificar &lt;em&gt;pools&lt;/em&gt; e suas configurações.&lt;/p&gt;&lt;/li&gt;

&lt;/ul&gt;

&lt;h3&gt;
  
  
  JPA
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;spring.datasource.jpa.open-in-view&lt;/code&gt;: Quando o &lt;em&gt;OSIV&lt;/em&gt; (&lt;em&gt;Open Session In View&lt;/em&gt;) está ativado, uma sessão é mantida durante toda a requisição, mesmo sem a anotação &lt;code&gt;@Transactional&lt;/code&gt;. Isso pode causar problemas de desempenho, como a falta de respostas da aplicação, pois a sessão mantém a conexão com o banco de dados até o fim da requisição.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;spring.datasource.jpa.show-sql&lt;/code&gt;: Exibe o &lt;code&gt;logging&lt;/code&gt; do SQL que está sendo executado em nossa aplicação. Geralmente deixamos ativado em desenvolvimento, mas desativado em produção.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;spring.datasource.jpa.hibernate.ddl-auto&lt;/code&gt;: Configura o comportamento do &lt;strong&gt;&lt;em&gt;Hibernate&lt;/em&gt;&lt;/strong&gt; em relação ao &lt;em&gt;schema&lt;/em&gt; do banco de dados. Ela pode ter os seguintes valores:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;none&lt;/code&gt;: Não faz nada. Gerenciamos manualmente o schema do banco.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;validate&lt;/code&gt;: Valida o &lt;em&gt;schema&lt;/em&gt; do banco de dados, mas não faz alterações. Isso é útil para garantir que o &lt;em&gt;schema&lt;/em&gt; atual esteja de acordo com as entidades que mapeamos.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;update&lt;/code&gt;: Atualiza o &lt;em&gt;schema&lt;/em&gt; do banco de dados para refletir mudanças nas entidades.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;create&lt;/code&gt;: Cria o &lt;em&gt;schema&lt;/em&gt; do banco de dados. Se o &lt;em&gt;schema&lt;/em&gt; já existir, ele vai remover e criar novamente.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;create-drop&lt;/code&gt;: Cria o &lt;em&gt;schema&lt;/em&gt; do banco de dados e, ao finalizar a aplicação, remove o &lt;em&gt;schema&lt;/em&gt;. Útil para testes, onde desejamos um banco de dados limpo a cada teste.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;&lt;p&gt;&lt;code&gt;spring.jpa.properties.hibernate.generate_statistics&lt;/code&gt;: Serve para coletar informações detalhadas sobre o Hibernate, como tempos de execução de consultas, número de consultas executadas, e outras métricas.&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;&lt;code&gt;spring.jpa.properties.hibernate.connection.provider_disables_autocommit&lt;/code&gt;:  Informa ao &lt;em&gt;&lt;strong&gt;Hibernate&lt;/strong&gt;&lt;/em&gt; que desabilitamos o &lt;em&gt;auto-commit&lt;/em&gt; dos &lt;em&gt;providers&lt;/em&gt; (&lt;em&gt;PostgreSQL&lt;/em&gt;, &lt;em&gt;MySQL&lt;/em&gt;, etc). Isso impacta no desempenho, porque o &lt;strong&gt;&lt;em&gt;Hibernate&lt;/em&gt;&lt;/strong&gt; precisará obter uma conexão do &lt;em&gt;pool&lt;/em&gt; para saber se o &lt;em&gt;auto-commit&lt;/em&gt; está ou não está habilitado, para toda transação que ele fizer.&lt;/p&gt;&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;Com isso, fechamos a segunda parte do artigo. Nem todas as configurações presentes foram sobre desempenho, mas as que realmente impactam são as configurações do &lt;strong&gt;&lt;em&gt;Hikari&lt;/em&gt;&lt;/strong&gt; como &lt;em&gt;auto-commit&lt;/em&gt; e &lt;em&gt;pool size&lt;/em&gt;, as do &lt;em&gt;&lt;strong&gt;JPA&lt;/strong&gt;&lt;/em&gt; e &lt;em&gt;&lt;strong&gt;Hibernate&lt;/strong&gt;&lt;/em&gt; como &lt;em&gt;OSIV&lt;/em&gt; (&lt;em&gt;Open Session In View&lt;/em&gt;) e informar que desabilitamos o &lt;em&gt;auto-commit&lt;/em&gt; dos &lt;em&gt;providers&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Na próxima parte vamos falar sobre exceções e como elas podem ser configuradas, para poupar recursos da &lt;em&gt;JVM&lt;/em&gt; (&lt;em&gt;Java Virtual Machine&lt;/em&gt;).&lt;/p&gt;

&lt;p&gt;Referências:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://en.wikipedia.org/wiki/Jakarta_Persistence" rel="noopener noreferrer"&gt;https://en.wikipedia.org/wiki/Jakarta_Persistence&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.ibm.com/docs/pt-br/was/8.5.5?topic=SSEQTP_8.5.5/com.ibm.websphere.nd.multiplatform.doc/ae/cejb_persistence.htm" rel="noopener noreferrer"&gt;https://www.ibm.com/docs/pt-br/was/8.5.5?topic=SSEQTP_8.5.5/com.ibm.websphere.nd.multiplatform.doc/ae/cejb_persistence.htm&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/brettwooldridge/HikariCP" rel="noopener noreferrer"&gt;https://github.com/brettwooldridge/HikariCP&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/corona-warn-app/cwa-server/issues/556" rel="noopener noreferrer"&gt;https://github.com/corona-warn-app/cwa-server/issues/556&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://medium.com/@rafaelralf90/open-session-in-view-is-evil-fd9a21645f8e" rel="noopener noreferrer"&gt;https://medium.com/@rafaelralf90/open-session-in-view-is-evil-fd9a21645f8e&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>springboot</category>
      <category>java</category>
      <category>backend</category>
      <category>performance</category>
    </item>
    <item>
      <title>Melhorando o desempenho de aplicações Spring Boot - Parte I</title>
      <dc:creator>Matheus Henrique</dc:creator>
      <pubDate>Thu, 22 Aug 2024 03:49:44 +0000</pubDate>
      <link>https://dev.to/mathstylish/melhorando-a-performance-de-aplicacoes-spring-boot-parte-i-58jl</link>
      <guid>https://dev.to/mathstylish/melhorando-a-performance-de-aplicacoes-spring-boot-parte-i-58jl</guid>
      <description>&lt;p&gt;Ao iniciar aplicações Spring Boot, normalmente usamos as configurações padrão fornecidas pelos starters, o que é suficiente para a maioria dos casos. No entanto, se estamos precisando de desempenho, há ajustes específicos que podem ser feitos, como será demonstrado na primeira parte deste artigo.&lt;/p&gt;

&lt;h2&gt;
  
  
  Substituindo o &lt;em&gt;Tomcat&lt;/em&gt; por outro &lt;em&gt;servlet container&lt;/em&gt;
&lt;/h2&gt;

&lt;p&gt;Aplicações &lt;em&gt;web&lt;/em&gt;, &lt;em&gt;RESTFul&lt;/em&gt;, que utilizam o &lt;em&gt;Spring MVC&lt;/em&gt;, geralmente adicionam a dependência &lt;code&gt;spring-boot-starter-web&lt;/code&gt;, que por padrão utiliza o Tomcat como servidor &lt;em&gt;web&lt;/em&gt;. Entretanto, existem alternativas mais interessantes, como o &lt;em&gt;Undertow&lt;/em&gt;, que é um servidor &lt;em&gt;web&lt;/em&gt; de alta performance, de arquitetura assíncrona e não-bloqueante, que permite lidar com um grande número de conexões simultâneas de forma eficiente, tornando-o adequado para aplicações de alto desempenho. Não estamos dizendo que o &lt;em&gt;Tomcat&lt;/em&gt; é ruim, mas podemos dar uma chance para o &lt;em&gt;Undertow&lt;/em&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Adicionando o &lt;em&gt;Undertow&lt;/em&gt; no &lt;em&gt;Spring&lt;/em&gt;
&lt;/h3&gt;

&lt;p&gt;Para que utilizemos o &lt;em&gt;Undertow&lt;/em&gt; como servidor &lt;em&gt;web&lt;/em&gt;, precisamos ignorar a dependência &lt;code&gt;spring-boot-starter-tomcat&lt;/code&gt; que o &lt;code&gt;spring-boot-starter-web&lt;/code&gt; já adiciona e então adicionar o &lt;code&gt;spring-boot-starter-undertow&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Utilizando &lt;code&gt;pom.xml&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;dependencies&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;org.springframework.boot&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;spring-boot-starter-web&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;exclusions&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;exclusion&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;org.springframework.boot&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;spring-boot-starter-tomcat&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;/exclusions&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/exclusions&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;org.springframework.boot&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;spring-boot-starter-undertow&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/dependencies&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Utilizando &lt;code&gt;build.gradle&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight groovy"&gt;&lt;code&gt;&lt;span class="n"&gt;dependencies&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;implementation&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'org.springframework.boot:spring-boot-starter-web'&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;exclude&lt;/span&gt; &lt;span class="nl"&gt;module:&lt;/span&gt; &lt;span class="s1"&gt;'spring-boot-starter-tomcat'&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;implementation&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'org.springframework.boot:spring-boot-starter-undertow'&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;p&gt;Através do &lt;code&gt;application.properties&lt;/code&gt; ou o &lt;code&gt;application.yml&lt;/code&gt;, podemos configurar quantas &lt;em&gt;IO threads&lt;/em&gt; e quantas &lt;em&gt;worker threads&lt;/em&gt; queremos que o servidor utilize.&lt;/p&gt;

&lt;p&gt;Utilizando &lt;code&gt;application.yml&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;server&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;undertow&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;threads&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;io&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;4&lt;/span&gt;
      &lt;span class="na"&gt;worker&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;64&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Utilizando &lt;code&gt;application.properties&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;server.undertow.threads.io=4
server.undertow.threads.worker=64
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I/O &lt;em&gt;Threads&lt;/em&gt; executam operações não-bloqueantes e nunca devem realizar operações de bloqueio, pois são responsáveis por ouvir as conexões que chegam na aplicação, para então enviá-las para uma fila de processamento. Um valor comum é duas I/O &lt;em&gt;Threads&lt;/em&gt; por núcleo de CPU.&lt;/p&gt;

&lt;p&gt;Já as &lt;em&gt;worker threads&lt;/em&gt; executam operações bloqueantes, como requisições Servlet que foram mandadas para a fila de processamento pelas I/O &lt;em&gt;Threads&lt;/em&gt;. O valor ideal depende da carga de trabalho, mas geralmente é recomendado configurar cerca de 10 threads por núcleo de CPU.&lt;/p&gt;

&lt;p&gt;Para informações mais detalhadas e mais opções que podem ser exploradas, basta ir na &lt;a href="https://undertow.io/undertow-docs/undertow-docs-2.1.0/index.html#listeners-2" rel="noopener noreferrer"&gt;documentação&lt;/a&gt; do &lt;em&gt;Undertow&lt;/em&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Comprimindo respostas HTTP
&lt;/h2&gt;

&lt;p&gt;Compressão de dados é uma funcionalidade visa reduzir o tamanho do corpo das respostas HTTP, que por sua vez, pode melhorar o desempenho da nossa aplicação ao reduzir a quantidade de dados transmitidos pela rede.&lt;/p&gt;

&lt;p&gt;Configurar compressão de dados no Spring Boot é uma tarefa trivial, por ele trazer suporte a essa funcionalidade.&lt;/p&gt;

&lt;p&gt;Utilizando &lt;code&gt;application.yml&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;server&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;compression&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;enabled&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
    &lt;span class="na"&gt;mime-types&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;text/html,text/xml,text/plain,text/css,text/javascript,application/javascript,application/json&lt;/span&gt;
    &lt;span class="na"&gt;min-response-size&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1024&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Utilizando &lt;code&gt;application.properties&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;server.compression.enabled=true
server.compression.mime-types=text/html,text/xml,text/plain,text/css,text/javascript,application/javascript,application/json
server.compression.min-response-size=1024
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;server.compression.enabled&lt;/code&gt;: Habilita/desabilita a compressão.&lt;br&gt;
&lt;code&gt;server.compression.mime-types&lt;/code&gt;: Lista dos MIME types que devem ser comprimidos.&lt;br&gt;
&lt;code&gt;server.compression.min-response-size&lt;/code&gt;: Tamanho mínimo do "&lt;em&gt;Content-Length&lt;/em&gt;" que é necessário para a compressão ser feita.&lt;/p&gt;

&lt;p&gt;Com isso, fechamos a primeira parte do artigo. Na próxima parte, vamos conhecer melhor o Hikari, JPA e o Hibernate e aprender a configurá-los, afim de melhorar ainda mais o desempenho de aplicações Spring Boot.&lt;/p&gt;

&lt;p&gt;Referências:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.spring.io/spring-boot/how-to/webserver.html" rel="noopener noreferrer"&gt;https://docs.spring.io/spring-boot/how-to/webserver.html&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://undertow.io/undertow-docs/undertow-docs-2.1.0/index.html#listeners-2" rel="noopener noreferrer"&gt;https://undertow.io/undertow-docs/undertow-docs-2.1.0/index.html#listeners-2&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>springboot</category>
      <category>java</category>
      <category>backend</category>
      <category>performance</category>
    </item>
  </channel>
</rss>
