Merhaba değerli Java dostları, bu yazımda spring boot ve embedded tomcat ile çalışırken olası bir getNextJarEntry metodu çağrımı yavaşlığını nasıl çözeceğimizi anlatmaya çalışacağım. Öncelikle süreçte neler oluyor bu hata ile nasıl karşılaştım buna değinmek istiyorum. JSF + spring boot ile çalışırken bazı requestlerde çok geç cevap geldiğini fark ettim. Yavaşlığın nereden kaynaklandığını bulmak için visualvm ile sample aldım. Farklı farklı yerlerden tetiklense de sorun temelde hep embedded tomcat içinde getNextJarEntry metodunu işaret ediyordu. Bu metodun çağrılma nedeni ise oluşturduğunuz managed bean, component, configuration, service gibi sınıflardan objeler oluşturulurken var olan jarlar incelenip devamlı bir bean info arayışı bulunmaktaydı.

Aslında mantık olarak baktığınızda war dosyası içindeki jar dosyaları değişken olmadığı için sürekli surette bunları tekrar tekrar incelemenin ve bean info aramanın mantıksız olduğu kanısına vardım. Yaptığım araştırmalar sonucu aşağıdaki sınıfı koduma eklediğimde sorunun ortadan kalktığını gördüm.

import org.apache.catalina.Context;
import org.apache.catalina.webresources.ExtractingRoot;
import org.springframework.boot.web.embedded.tomcat.TomcatContextCustomizer;
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class EmbeddedTomcatConfiguration {

    @Bean
    TomcatServletWebServerFactory tomcatFactory() {
        return new TomcatServletWebServerFactory() {

            @Override
            protected void postProcessContext(Context context) {
                context.setResources(new ExtractingRoot());
            }
        };
    }

    @Bean
    public WebServerFactoryCustomizer<TomcatServletWebServerFactory> servletContainerCustomizer() {
        return new WebServerFactoryCustomizer<TomcatServletWebServerFactory>() {

            @Override
            public void customize(TomcatServletWebServerFactory container) {
                container.addContextCustomizers(
                        new TomcatContextCustomizer() {
                            @Override
                            public void customize(Context cntxt) {
                                cntxt.setReloadable(false);
                            }
                        });
            }
        };
    }

}

Peki burada ne oluyor neyi tarifledik diye soracak olursanız yaptığımız tarif iki aşamalı bir tarif. İlkinde server up işlemi sırasında jarların çıkartılmasını ve böylece tekrar tekrar bu işlem için vakit harcanmasını engellemiş oluyoruz. İkinci tarifle de reload işlemini ve dolayısıyla bean info arama işlemini ortadan kaldırıyoruz.

Dikkat etmemiz gereken nokta burada bir @Configuration ve iki tane @Bean yardımı ile mevcut embedded tomcat için bazı ayarlar yapıyoruz. Springin bize vermiş olduğu esnek ve ölçeklenebilir yapı burada karşımız çıkıyor. Yukarıda bahsettiğim gibi visuavm ile sorunu tespit ettikten sonra yeni kodunuz ile tekrar bir sample alırsa aradaki farkı daha iyi görmüş oluruz. Benim yaptığım ölçümlerde 3-7 saniye arası beklemeler oluyordu. Server her ne kadar güçlü olsa da burada sonucu hep aynı olacak bir işlemin tekrarlanması biraz can sıkıcı olabiliyor. İşin diğer ilginç tarafı IDE ile çalışmanız sırasında bu yavaşlık yaşanmıyor. Dolayısıyla kullandığınız IDE’ nin de bu sorunu perdelemede etkisi olabiliyor.

Embedded server konusu ile ilgili detaylara buradan ulaşabilirsiniz.

Diğer spring yazılarım için buraya bakabilirsiniz.

http://www.farukbozan.com

Bol Java’ lı günler dileğiyle…

No responses yet

Bir cevap yazın

E-posta hesabınız yayımlanmayacak.