
De um tradutor: como o Spring Framework é um dos principais frameworks nos quais construímos o CUBA , as notícias sobre os novos recursos do Spring não passam despercebidas por nós. A inicialização lenta é uma maneira de reduzir o primeiro tempo de inicialização do aplicativo, o que, em nossa era do uso generalizado de microsserviços, é uma métrica importante. Para aqueles que preferem ler vídeos, há uma apresentação de 10 minutos de Josh Long sobre o tópico do artigo.
O lançamento do primeiro marco recentemente anunciado do Spring Boot 2.2 adiciona suporte à inicialização lenta. Neste artigo, examinaremos as novas funcionalidades e explicaremos como ativá-las.
O que significa ser preguiçoso?
O Spring Framework oferece suporte à inicialização lenta desde que seu código-fonte mudou para o git onze anos atrás. Por padrão, quando o contexto do aplicativo é atualizado, cada bean é recriado e suas dependências são implementadas. Por outro lado, se um compartimento estiver configurado para inicialização lenta, ele não será criado e suas dependências não serão descartadas até que isso seja necessário.
Habilitando a inicialização lenta
Em qualquer versão do Spring Boot, é possível ativar a inicialização lenta, se você não se importa de sujar as mãos com o BeanFactoryPostProcessor
. O Spring Boot 2.2 simplesmente simplifica esse processo, introduzindo uma nova propriedade - spring.main.lazy-initialization
(também existem métodos equivalentes no SpringApplication
e SpringApplicationBuilder
). Quando essa propriedade é configurada como true
, os beans de aplicativo serão configurados para usar a inicialização lenta.
Os benefícios da inicialização lenta
A inicialização lenta pode reduzir significativamente o horário de início do seu aplicativo, pois nesse estágio menos classes são carregadas e menos compartimentos são criados. Por exemplo, um pequeno aplicativo da Web que usa o Actuator e o Spring Security geralmente inicia 2,5 segundos. E com inicialização lenta, esse processo leva 2 segundos. Os valores exatos da aceleração variarão de aplicativo para aplicativo, dependendo da estrutura do gráfico de dependência do compartimento.
Nota do tradutor: executei este exemplo , escrevendo Spring Boot 2.2 nas dependências, e o tempo de inicialização com inicialização lenta foi de 3 segundos, e sem ela 4. Acho que em aplicativos mais sérios, um ganho significativo no tempo de inicialização devido ao uso de inicialização lenta nós não vamos ver. Upd: seguindo as orientações de alek_sys, desativou a validação e atualização do esquema do banco de dados e ativou a inicialização lenta do JPA nos dois casos - resultou em 2,7 e 3,7 segundos antes da Started WebApplication in...
O Spring Boot DevTools fornece aceleração de desenvolvimento significativa. Em vez de reiniciar a JVM e o aplicativo toda vez que você altera algo, o DevTools faz uma “reinicialização a quente” do aplicativo na mesma JVM. Uma vantagem significativa dessa reinicialização é que ela oferece ao JIT a oportunidade de otimizar o código que é executado quando o aplicativo é iniciado. Após várias reinicializações, o tempo inicial de 2,5 segundos diminui quase 80% a 500 ms. Com a inicialização lenta, as coisas ficam ainda melhores. A configuração da propriedade spring.main.lazy-initialization
mostra o tempo de reinicialização diretamente no IDE igual a 400 ms.
O outro lado da inicialização lenta
Como mostrado acima, a inclusão da inicialização lenta pode reduzir seriamente o tempo de inicialização do aplicativo. E talvez você tenha um desejo irresistível de usá-lo constantemente, ou pelo menos se perguntará por que a inicialização lenta não está ativada por padrão. Existem vários efeitos negativos possíveis que são melhor esclarecidos imediatamente.
O fato de as classes não serem carregadas e as bandejas não serem criadas até serem necessárias pode mascarar problemas que poderiam ter sido identificados anteriormente no estágio de inicialização do aplicativo. Por exemplo, pode ser a falta da classe necessária, excesso de memória ou um erro associado à configuração incorreta.
Em aplicativos da Web, configurações lentas podem aumentar a latência de solicitações HTTP que causam a inicialização do compartimento. Geralmente, essa é a primeira solicitação, mas pode haver efeitos indesejados adicionais que afetam o balanceamento de carga ou o dimensionamento automático.
Isso está incluído?
Se você não tem certeza de como exatamente a inicialização lenta afeta seu aplicativo ou deseja verificar se outros aspectos da estrutura são adequados para você e fazer o que você precisa, será útil usar um depurador para isso. Ao definir um ponto de interrupção no construtor do compartimento, você pode ver em que momento exato o compartimento é inicializado. Por exemplo, em um aplicativo Web escrito em Spring Boot e com a inicialização lenta ativada, é possível ver que os @Controller
marcados com a anotação @Controller
não @Controller
criados até a primeira solicitação ao DispatcerServlet
Spring MVC ou ao DispatchHandler
Spring WebFlux.
Quando ativar a inicialização lenta?
Como vimos acima, a inicialização lenta oferece melhorias notáveis durante o lançamento do aplicativo, mas também existem desvantagens, portanto, você precisa usar esse recurso com muito cuidado.
Uma área em que a inicialização lenta pode pagar dividendos (com quase nenhuma sobrecarga) é o processo de desenvolvimento de aplicativos. Enquanto você estiver escrevendo um aplicativo, o tempo de reinicialização reduzido fornecido pela inicialização lenta em combinação com o DevTools pode economizar muito tempo.
Onde mais você pode obter os benefícios do uso da inicialização lenta - isso é nos testes de integração. Você já pode estar usando o fatiamento de teste para reduzir o tempo de execução limitando o número de beans inicializados em alguns tipos de testes. A inicialização lenta fornece uma oportunidade alternativa para alcançar o mesmo resultado. Se você estiver na posição errada para alterar a estrutura do aplicativo para testes de "fatia", ou para seus testes específicos não houver uma "fatia" adequada, a inclusão de uma inicialização lenta limitará o número de posições às usadas apenas no seu teste. Isso reduzirá o tempo de execução do teste, especialmente se eles forem executados em um ambiente isolado durante o desenvolvimento.
Ative a inicialização lenta no último produto. E, se você decidir fazê-lo, faça-o com cuidado. Para aplicativos da Web, o gerente de contêiner pode confiar no ponto de entrada /health
, que geralmente responde com bastante rapidez, mas lembre-se de que, potencialmente, as primeiras chamadas podem demorar mais que o normal. Você também deve se lembrar do tamanho da memória alocada para a JVM, para que você não encontre excesso quando todos os componentes forem inicializados.