1. Genel Bakış
Bu codelab'de Spring Native projesi hakkında bilgi edinecek, bu projeyi kullanan bir uygulama geliştirip Google Cloud'a dağıtacağız.
Projenin bileşenlerini, projenin yakın geçmişini, bazı kullanım alanlarını ve elbette projeyi projelerinizde kullanmanız için gereken adımları inceleyeceğiz.
Spring Native projesi şu anda deneysel aşamadadır. Bu nedenle, başlamak için bazı özel yapılandırmalar gerekir. Bununla birlikte, SpringOne 2021'de duyurulduğu gibi Spring Native, birinci sınıf destek ile Spring Çerçevesi 6.0 ve Spring Boot 3.0'a entegre edilecektir. Bu nedenle, yayınlanmadan birkaç ay önce projeye daha yakından bakmak için en uygun zamandır.
Tam zamanında derleme, uzun çalışan işlemler gibi özelliklere göre çok iyi optimize edilmiş olsa da, önceden derlenmiş uygulamaların daha iyi performans gösterdiği belirli kullanım alanları da mevcuttur. Bu durumu codelab'de açıklayacağız.
Demoda aşağıdaki işlemleri yapmayı öğreneceksiniz:
- Cloud Shell'i kullanma
- Cloud Run API'yi etkinleştirme
- Spring Yerel uygulaması oluşturma ve dağıtma
- Böyle bir uygulamayı Cloud Run'a dağıtma
Gerekenler
- Etkin bir GCP faturalandırma hesabına sahip bir Google Cloud Platform projesi
- gcloud cli yüklü olmalıdır veya Cloud Shell'e erişim
- Temel Java + XML becerileri
- Yaygın Linux komutlarıyla ilgili bilgi
Anket
Bu eğiticiden nasıl yararlanacaksınız?
Java deneyiminizi nasıl değerlendirirsiniz?
Google Cloud hizmetlerini kullanma deneyiminizi nasıl değerlendirirsiniz?
2. Arka plan
Spring Native projesi, geliştiricilere yerel uygulama performansı sunmak için çeşitli teknolojilerden yararlanır.
İlkbaharda Doğal kullanımı tam olarak anlamak için bu bileşen teknolojilerinden birkaçını, bizim için ne sağladıklarını ve burada birlikte nasıl çalıştıklarını anlamak yararlı olacaktır.
AOT derlemesi
Geliştiriciler, derleme sırasında Javac'yi normal bir şekilde çalıştırdıklarında, .java kaynak kodumuz, bayt kodu ile yazılan .class dosyaları olarak derlenir. Bu bayt kodunun yalnızca Java sanal makinesi tarafından anlaşılması amaçlandığından, kodumuzu çalıştırabilmemiz için JVM'nin bu kodu diğer makinelerde yorumlaması gerekir.
Bu işlem, bize Java'nın imza taşınabilirliğini sağlayarak "bir kez yazıp her yerde çalıştırmamıza" olanak tanır ancak yerel kod çalıştırmaya kıyasla pahalıdır.
Neyse ki JVM çoğu uygulaması, bu yorumlama maliyetini azaltmak için tam zamanında derleme kullanır. Bu işlem, bir işlevin çağrıları sayılarak gerçekleştirilir. İşlev, bir eşiği ( varsayılan olarak 10.000) geçmeye yetecek kadar sık çağrılırsa daha pahalı yorumlamayı önlemek için çalışma zamanında yerel koda derlenir.
Önceden derleme işlemi, erişilebilir olan tüm kodları, derleme sırasında yürütülebilir yerel bir uygulamada derleyerek tam tersi bir yaklaşım uygular. Bu sayede taşınabilirlik yerine çalışma zamanında bellek verimliliği ve performansta daha fazla avantaj elde edilir.
Bu elbette bir ödün vermektir ve her zaman almaya değmez. Ancak AOT derlemesi, aşağıdaki gibi belirli kullanım alanlarında başarılı olabilir:
- Başlatma süresinin önemli olduğu kısa ömürlü uygulamalar
- JIT'in çok maliyetli olabileceği, yüksek düzeyde bellek kısıtlaması olan ortamlar
İşin eğlenceli bir yanı da, AOT derlemesi JDK 9'da deneysel bir özellik olarak kullanıma sunulmuştu. Ancak bu uygulamanın sürdürülmesi pahalıydı ve uzun süre ilgi görmedi. Bu nedenle, yalnızca GraalVM kullanan geliştiricilerin lehine olan Java 17'de AOT derlemesi sessizce kaldırıldı.
GraalVM
GraalVM, son derece hızlı başlatma süreleri, AOT yerel görüntü derlemesi ve geliştiricilerin birden fazla dili tek bir uygulamada birleştirmesine olanak tanıyan çok dilli (çok dilli) özelliklerine sahip, son derece optimize edilmiş bir açık kaynak JDK dağıtımıdır.
GraalVM aktif geliştirme aşamasında olduğu için sürekli yeni beceriler ediniyor ve mevcut becerileri sürekli geliştiriyor. Bu yüzden geliştiricilerin bizi takip etmeye devam etmesini öneririm.
Yakın zamandaki bazı ara hedefler şunlardır:
- Yeni ve kullanıcı dostu bir yerel görüntü derleme çıkışı ( 18.01.2021)
- Java 17 desteği ( 18.01.2022)
- Çok dilli derleme sürelerini iyileştirmek için varsayılan olarak çok katmanlı derlemeyi etkinleştirme ( 20.04.2021)
İlkbahar Yerel
Kısacası Spring Yerel, GraalVM'nin yerel görüntü derleyicisini kullanarak Spring uygulamalarını yerel yürütülebilir dosyalara dönüştürmeyi mümkün kılar.
Bu işlem, uygulamanızda giriş noktasından erişilebilen tüm yöntemleri bulmak için derleme sırasında uygulamanızın statik analizini içerir.
Bu temelde, kapalı bir dünya oluşturur. tüm kodların derleme sırasında bilindiği varsayılan ve çalışma zamanında yeni bir kod yüklenmesine izin verilmediği uygulamanızın konseptini oluşturur.
Yerel görüntü oluşturma işleminin, normal bir uygulamayı derlemekten daha uzun süren, bellek yoğun bir işlem olduğunu ve Java'nın belirli yönlerine sınırlamalar getirdiğini unutmayın.
Bazı durumlarda, uygulamanın Spring Yerel ile çalışması için kod değişikliği gerekmez. Ancak bazı durumlarda düzgün çalışmak için belirli bir yerel yapılandırma gerekir. Böyle durumlarda Spring Yerel, bu işlemi basitleştirmek için genellikle Yerel İpuçları sağlar.
3. Kurulum/Ön Çalışma
Spring Yerel'i uygulamaya başlamadan önce uygulamamızı oluşturup dağıtmamız gerekiyor. Böylece daha sonra yerel sürümle karşılaştırabileceğimiz bir performans temel çizgisi belirleyeceğiz.
1. Projeyi oluşturma
İlk olarak uygulamamızı start.spring.io'dan edineceğiz:
curl https://start.spring.io/starter.zip -d dependencies=web \ -d javaVersion=11 \ -d bootVersion=2.6.4 -o io-native-starter.zip
Bu başlangıç uygulaması, ilkbaharda yerel projenin desteklediği en son sürüm olan Spring Boot 2.6.4 sürümünü kullanır.
GraalVM 21.0.3 sürümünden bu yana bu örnek için de Java 17'yi kullanabileceğinizi unutmayın. İlgili yapılandırmayı en aza indirmek amacıyla bu eğitimde Java 11'i kullanmaya devam edeceğiz.
Zip dosyasını komut satırına yerleştirdikten sonra projemiz için bir alt dizin oluşturabilir ve bu dizindeki klasörü açabiliriz:
mkdir spring-native cd spring-native unzip ../io-native-starter.zip
2. Kod değişiklikleri
Proje başladığında, bize hızlıca bir hareket işareti ekleyecek ve projeyi çalıştırdıktan sonra Baharda Yerel performansı sergileyeceğiz.
DemoApplication.java dosyasını buna uyacak şekilde düzenleyin:
package com.example.demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.context.event.EventListener;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import java.time.Duration;
import java.time.Instant;
@RestController
@SpringBootApplication
public class DemoApplication {
private static Instant startTime;
private static Instant readyTime;
public static void main(String[] args) {
startTime = Instant.now();
SpringApplication.run(DemoApplication.class, args);
}
@GetMapping("/")
public String index() {
return "Time between start and ApplicationReadyEvent: "
+ Duration.between(startTime, readyTime).toMillis()
+ "ms";
}
@EventListener(ApplicationReadyEvent.class)
public void ready() {
readyTime = Instant.now();
}
}
Temel uygulamamız bu noktada kullanıma hazırdır. Bu nedenle, yerel uygulamaya dönüştürmeden önce başlatma süresi hakkında fikir edinmek için bir görüntü derleyip yerel olarak çalıştırabilirsiniz.
Görüntümüzü oluşturmak için:
mvn spring-boot:build-image
Taban resmin boyutu hakkında fikir edinmek için docker images demo
kullanabilirsiniz:
Uygulamamızı çalıştırmak için:
docker run --rm -p 8080:8080 demo:0.0.1-SNAPSHOT
3. Temel uygulamayı dağıtma
Artık uygulamamızı aldığımıza göre onu dağıtacağız ve zamanları not edeceğiz. Bu süreyi daha sonra yerel uygulama başlatma süreleriyle karşılaştıracağız.
Oluşturduğunuz uygulamanın türüne bağlı olarak öğelerinizi barındırmak için farklı seçenekler vardır.
Ancak örneğimiz çok basit ve anlaşılır bir web uygulaması olduğundan işleri basit tutabilir ve Cloud Run'a güvenebiliriz.
Süreci kendi makinenizde kullanıyorsanız gcloud KSA aracının yüklü ve güncel olduğundan emin olun.
İşlemin tamamlanması için Cloud Shell'deyseniz kaynak dizinde aşağıdaki komutu çalıştırmanız yeterlidir:
gcloud run deploy
4. Uygulama Yapılandırması
1. Maven depolarımızı yapılandırma
Bu proje hâlâ deneysel aşamada olduğu için uygulamamızı maven merkezi deposunda bulunmayan deneysel yapıları bulabilecek şekilde yapılandırmamız gerekiyor.
Aşağıdaki öğelerin pom.xml dosyasına eklenmesi gerekir. Aşağıdaki öğeleri istediğiniz düzenleyicide yapabilirsiniz.
Aşağıdaki depoları ve PluginRepositories bölümlerini ponumuza ekleyin:
<repositories>
<repository>
<id>spring-release</id>
<name>Spring release</name>
<url>https://repo.spring.io/release</url>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>spring-release</id>
<name>Spring release</name>
<url>https://repo.spring.io/release</url>
</pluginRepository>
</pluginRepositories>
2. Bağımlılıklarımızı ekleme
Ardından, Spring uygulamasını yerel görüntü olarak çalıştırmak için gerekli olan ilkbaharda yerel bağımlılığı ekleyin. Not: Gradle kullanıyorsanız bu adım gerekli değildir
<dependencies>
<!-- ... -->
<dependency>
<groupId>org.springframework.experimental</groupId>
<artifactId>spring-native</artifactId>
<version>0.11.2</version>
</dependency>
</dependencies>
3. Eklentilerimizi ekleme/etkinleştirme
Şimdi yerel resim uyumluluğunu ve ayak izini iyileştirmek için AOT eklentisini ekleyin ( Daha fazla bilgi):
<plugins>
<!-- ... -->
<plugin>
<groupId>org.springframework.experimental</groupId>
<artifactId>spring-aot-maven-plugin</artifactId>
<version>0.11.2</version>
<executions>
<execution>
<id>generate</id>
<goals>
<goal>generate</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
Şimdi yerel görüntü desteğini etkinleştirmek için spring-boot-maven eklentisini güncelleyeceğiz ve yerel görüntümüzü oluşturmak için paketo oluşturucuyu kullanacağız:
<plugins>
<!-- ... -->
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<image>
<builder>paketobuildpacks/builder:tiny</builder>
<env>
<BP_NATIVE_IMAGE>true</BP_NATIVE_IMAGE>
</env>
</image>
</configuration>
</plugin>
</plugins>
Küçük oluşturucu resminin çeşitli seçeneklerden yalnızca biri olduğunu unutmayın. Saldırı yüzeyimizi en aza indirmeye yardımcı olan, çok az ekstra kitaplık ve yardımcı program içerdiğinden kullanım alanımız için iyi bir seçimdir.
Örneğin, bazı yaygın C kitaplıklarına erişmesi gereken bir uygulama geliştiriyorsanız veya uygulamanızın gereksinimlerinden henüz emin değilseniz tam geliştirici daha uygun olabilir.
5. Yerel uygulama oluşturma ve çalıştırma
Her şey tamamlandığında görüntümüzü derleyip yerel, derlenmiş uygulamamızı çalıştırabiliriz.
Derlemeyi çalıştırmadan önce göz önünde bulundurmanız gereken birkaç nokta aşağıda belirtilmiştir:
- Bu işlem normal bir derlemeden daha fazla zaman alır (birkaç dakika)
- Bu derleme işlemi çok fazla bellek (birkaç gigabayt) kaplayabilir
- Bu derleme işlemi, Docker arka plan programının erişilebilir olmasını gerektirir
- Bu örnekte, süreci manuel olarak ele alıyoruz. Bununla birlikte, derleme aşamalarınızı yerel derleme profilini otomatik olarak tetikleyecek şekilde yapılandırabilirsiniz.
Görüntümüzü oluşturmak için:
mvn spring-boot:build-image
Bu uygulama oluşturulduktan sonra yerel uygulamayı iş başında görmeye hazırız.
Uygulamamızı çalıştırmak için:
docker run --rm -p 8080:8080 demo:0.0.1-SNAPSHOT
Bu noktada, yerel uygulama denkleminin her iki tarafını da görmek için mükemmel bir konumdayız.
Derleme sırasında epey zaman kazanıp ekstra bellek kullanımından tasarruf ettik, ancak bunun karşılığında çok daha hızlı çalışabilen ve (iş yüküne bağlı olarak) önemli ölçüde daha az bellek tüketebilen bir uygulama elde ediyoruz.
Yerel resmin boyutunu orijinalle karşılaştırmak için docker images demo
komutunu çalıştırırsak önemli bir küçülme görebiliriz:
Daha karmaşık kullanım alanlarında, AOT derleyiciyi uygulamanızın çalışma zamanında ne yapacağı konusunda bilgilendirmek için ek değişiklikler yapılması gerektiğini de unutmayın. Bu nedenle, belirli tahmin edilebilir iş yükleri (toplu işler gibi) buna çok uygunken bazılarında daha büyük artış görülebilir.
6. Yerel uygulamamızı dağıtma
Uygulamamızı Cloud Run'a dağıtmak için yerel görüntümüzü Artifact Registry gibi bir paket yöneticisine aktarmamız gerekiyor.
1. Docker depomuzu hazırlama
Bu işleme bir depo oluşturarak başlayabiliriz:
gcloud artifacts repositories create native-image-docker-repo --repository-format=docker \
--location=us-central1 --description="Repository for our native images"
Sonraki adımda, yeni kayıt defterimize aktarmak için kimliğimizin doğrulandığından emin olmak isteyeceğiz.
gcloud KSA bu işlemi oldukça basitleştirebilir:
gcloud auth configure-docker us-central1-docker.pkg.dev
2. Görüntümüzü Artifact Registry'ye aktarıyoruz
Sonra resmimizi etiketleyeceğiz:
export PROJECT_ID=$(gcloud config list --format 'value(core.project)')
docker tag demo:0.0.1-SNAPSHOT \
us-central1-docker.pkg.dev/$PROJECT_ID/native-image-docker-repo/quickstart-image:tag2
Ardından docker push
kullanarak Artifact Registry'ye gönderebiliriz:
docker push us-central1-docker.pkg.dev/$PROJECT_ID/native-image-docker-repo/quickstart-image:tag2
3. Cloud Run'a dağıtma
Artık Artifact Registry'de depoladığımız görüntüyü Cloud Run'a dağıtmaya hazırız:
gcloud run deploy --image us-central1-docker.pkg.dev/$PROJECT_ID/native-image-docker-repo/quickstart-image:tag2
Uygulamamızı yerel görüntü olarak derleyip dağıttığımızdan, uygulamamızın çalışırken altyapı maliyetlerimizden mükemmel bir şekilde yararlandığından emin olabiliyoruz.
Temel uygulamamızın başlatma sürelerini bu yeni yerel uygulama ile kendiniz karşılaştırabilirsiniz.
7. Özet/Temizlik
Google Cloud'da Spring Yerel uygulaması derleyip dağıttığınız için tebrik ederiz.
Bu eğitimin sizi Spring Native projesine daha aşina olmanızı ve gelecekte ihtiyaçlarınızı karşılaması durumunda bu projeyi göz önünde bulundurmaya teşvik edeceğini umuyoruz.
İsteğe bağlı: Hizmeti temizleme ve/veya devre dışı bırakma
İster bu codelab için bir Google Cloud projesi oluşturmuş ister mevcut bir projeyi yeniden kullanıyor olun, yararlandığımız kaynaklardan gereksiz ücretlendirme yapmamaya özen gösterin.
Oluşturduğumuz Cloud Run hizmetlerini silebilir veya devre dışı bırakabilir, barındırdığımız görüntüyü silebilir veya projenin tamamını kapatabilirsiniz.
8. Ek kaynaklar
Spring Native projesi şu anda yeni ve deneysel bir proje olsa da ilk kullanıcıların sorunları gidermesine ve sürece dahil olmasına yardımcı olacak zengin kaynaklar mevcuttur:
Ek kaynaklar
Aşağıda, bu eğitim için alakalı olabilecek çevrimiçi kaynaklar verilmiştir:
- Yerel İpuçları hakkında daha fazla bilgi edinin.
- GraalVM hakkında daha fazla bilgi
- Nasıl katılabilirsiniz?
- Yerel resimler oluşturulurken bellek yetersiz hatası
- Uygulama başlatılamadı hatası
Lisans
Bu çalışma, Creative Commons Attribution 2.0 Genel Amaçlı Lisans ile lisans altına alınmıştır.