İçeriğe geç

Konfigürasyon ve Profiller — Bu Değer Nereden Geldi?

Orta 8 dk Çok sık karşılaşılır

Önce şunu oku: Auto-configuration — Bu Bean Nereden Geldi?

30 saniyede özet

Boot aynı ayarı birçok yerden okuyabilir ve sırada sonra gelen kazanır: komut satırı ortam değişkenini, o da dosyaları ezer. Adını yanlış yazdığın bir değişken ise hata vermez, sessizce yok sayılır.

Canlı sistemde ödeme 3 saniyede zaman aşımına uğruyor, oysa ayarlarda açıkça 5 saniye yazıyor. İki saat boyunca herkes aynı soruyu sordu: bu değer nereden geliyor?

  1. Bayt: Ayarlarda açıkça beş saniye yazıyor, ama ödeme üç saniyede zaman aşımına uğruyor!

  2. Sen: Belki başka bir yerde üç saniye yazıyordur?

  3. Bayt: Boot aynı ayarı birçok yerden okur. Asıl soru hangisinin kazandığı.

  4. Bayt: Mutfakta tarif, şefin notu ve müşterinin isteği çarpışırsa kim kazanır?

Kim kimi ezer?

Boot bir ayarı tek bir yerden okumaz: dosyalar, ortam değişkenleri, komut satırı. Bunların her birine property sourceSpring'in ayar okuduğu bir kaynak: application.yml, profil dosyası, ortam değişkenleri, komut satırı. Aynı anahtar birden çok kaynakta varsa önceliği yüksek olan kazanır.Sözlükte gör → denir; aynı ayar birden çok yerde varsa listede daha aşağıda olan kazanır.

Zayıftan güçlüye doğru sıra şöyle:

  1. Koddaki varsayılan (@DefaultValue)
  2. application.yml
  3. application-prod.yml gibi profil dosyası
  4. Ortam değişkenleri
  5. Komut satırı argümanları

Bu sıra sayesinde aynı imaj her ortamda, dosyaya dokunmadan ortam değişkenleriyle ayarlanır.

Kafam karıştı, daha basit anlat

Aynı ayar birkaç yerde yazılıysa, en güçlü yerdeki kazanır. Komut satırı dosyayı ezer. Böylece kodu değiştirmeden ortam ayarını değiştirebilirsin.

Hızlı kontrolBaşlangıç

payment.timeout hem application.yml'de (2s) hem application-prod.yml'de (3s) tanımlı. prod profili aktif. Uygulama hangi değeri kullanır?

Cevabı biliyor musun?Önce birini seç. Tekrar zamanlaması buna göre ayarlanıyor.

Aynı anahtar application-prod.yml'de, bir ortam değişkeninde ve komut satırında tanımlı. Öncelik sırası (yüksekten düşüğe) hangisi?

Cevabı biliyor musun?Önce birini seç. Tekrar zamanlaması buna göre ayarlanıyor.

Ortam değişkeninin adı

application-prod.yml'de payment.timeout: 3s var. Kubernetes PAYMENT_TIMOUT=5s veriyor. Uygulama hangi değeri kullanır? Cevabı göster

3s. Değişkenin adı hiçbir property’ye eşlenmiyor. Boot onu sessizce yok sayar; ne hata ne uyarı.

Sonra gelen kazanır; yanlış yazılan hiç gelmez.
Adım adım oku
  1. application.yml tarif kitabıdır: timeout iki saniye.
  2. Aktif profilin dosyası application-prod.yml onu ezer: üç saniye.
  3. Ortam değişkeni PAYMENT_TIMEOUT ikisini de ezer: beş saniye.
  4. Değişkenin adında bir harf eksikse Boot onu hiçbir ayara bağlamaz, uyarmaz da. Üç saniye sessizce kazanır.

relaxed bindingBoot'un aynı property'yi farklı yazımlarla eşleştirmesi: payment.timeout ile PAYMENT_TIMEOUT aynı alana bağlanır. Eşleşmeyen ad sessizce yok sayılır.Sözlükte gör → payment.timeout’u PAYMENT_TIMEOUT ile eşleştirir. Kural: noktalar alt çizgi olur, tireler silinir, harfler büyür. my-service.base-url için doğru ad MYSERVICE_BASEURL’dür.

Değerin gerçekte nereden geldiğini tahmin etme. /actuator/env/payment.timeout, değeri ve kaynağını gösterir.

Kafam karıştı, daha basit anlat

payment.timeout ayarı ortam değişkeninde PAYMENT_TIMEOUT olur: nokta alt çizgi olur, harfler büyür. Adı yanlış yazarsan Spring hiçbir şey demeden yok sayar.

Hızlı kontrolOrta

my-service.base-url property'sini Kubernetes'te ortam değişkeniyle vermek istiyorsun. Değişkenin adı ne olmalı?

Cevabı biliyor musun?Önce birini seç. Tekrar zamanlaması buna göre ayarlanıyor.

Kubernetes'te PAYMENT_TIMOUT=5s (yazım hatasıyla) tanımlandı. Uygulama ne yapar?

Cevabı biliyor musun?Önce birini seç. Tekrar zamanlaması buna göre ayarlanıyor.

Kendin gör

payment.timeout kaç?

Tohum 71298
  1. Komut satırı…
  2. Ortam değişkeni…
  3. application-prod.yml…
  4. application.yml…
  5. @DefaultValue (kod)…

Oynat ya da adımla.

Hız
Adım 0

Şu an ne oldu?

Kaynaklar düşükten yükseğe okunuyor

Aynı property birden çok yerde tanımlı olabilir. Boot hepsine bakar; sıralamada sonra gelen kazanır.

Görevler0/3

  • Ortam değişkeni verdiğin hâlde değer dosyadan gelsinaçık

    İpucu

    Değişkenin adına bak.

  • prod profili açıkken değeri ortam değişkeninden alaçık

    İpucu

    Doğru ad, komut satırı yok.

  • Her kaynak açıkken kimin kazandığını göraçık

    İpucu

    Profil, doğru ortam değişkeni ve komut satırı.

Olay günlüğü (0)

Henüz olay yok. Oynat veya adımla.

  1. Varsayılanla oynat. Ortam değişkeni var ama değer dosyadan geldi.
  2. Değişkeni “PAYMENT_TIMEOUT=5s” yap. Ortam değişkeni kazandı.
  3. Komut satırını aç. Hepsini ezdi.
  4. Profili “Yok” yap, diğerlerini kapat. application.yml’e düştü.
Hızlı kontrolOrta

Her ayarın nerede durması gerektiğini seç.

Cevabı biliyor musun?Önce birini seç. Tekrar zamanlaması buna göre ayarlanıyor.

Sınıflandırılmamış

application.yml

Her ortamda aynı, gizli olmayan varsayılanlar.

    Profil dosyası

    Ortama göre değişen, gizli olmayan ayarlar.

      Ortam / secret yöneticisi

      Gizli ya da deploy anında belli olan değerler.

        Tipli ayarlar ve profiller

        @ConfigurationProperties bir önekin altındaki ayarları tek bir record’a bağlar. @Validated ile birlikte kullanınca eksik ya da geçersiz bir değer uygulamayı başlangıçta durdurur.

        Bir profileOrtama göre değişen ayar ve bean kümesi. spring.profiles.active=prod, application-prod.yml dosyasını ve @Profile("prod") bean'lerini devreye alır.Sözlükte gör →, “şu an hangi ortamdayım?” sorusunun cevabıdır: dev, test, prod. Profil değişince hem ayar dosyası hem de yüklenen bean’ler değişebilir; @Profile("dev") bir bean’i yalnızca geliştirme ortamında yükler.

        Kafam karıştı, daha basit anlat

        Profil, “şu an neredeyim” sorusunun cevabıdır: dev, test ya da prod. Hangi ayarların ve hangi bean’lerin yükleneceğini o belirler.

        Hızlı kontrolOrta

        application.yml'de payment.timeout: 5 yazıyor ve ekip 5 saniye beklediğini düşünüyor. Ödeme çağrıları anında timeout alıyor. Hatalı satır hangisi?

        Cevabı biliyor musun?Önce birini seç. Tekrar zamanlaması buna göre ayarlanıyor.

        Hatalı satıra dokun, sonra kontrol et.

        PaymentProperties.java
        Java 21UTF-8LF

        @Value("${payment.timeout}") yerine @ConfigurationProperties + @Validated kullanmanın en önemli kazancı hangisi?

        Cevabı biliyor musun?Önce birini seç. Tekrar zamanlaması buna göre ayarlanıyor.

        Tuzaklar

        Birimsiz süre. Duration’a bağlanan timeout: 5, beş milisaniyedir. Birimi değerin içine yaz: 5s.

        Varsayılan olarak tehlikeli bean. @Profile("!prod") ile işaretli sahte ödeme servisi, profil unutulan her ortamda çalışır. Sahte olanı açık bir profile bağla.

        Git’te parola. application-prod.yml bir sır saklama yeri değildir. Sırlar ortam değişkeni, Kubernetes Secret ya da bir secret yöneticisiyle gelir.

        Aşağıdaki örnek bir e-ticaret şirketinin bankanın sanal POS’una bağlandığı ödeme servisinden. Ayarlar tek bir tipli record’da toplanıyor, başlangıçta doğrulanıyor ve her ortam yalnızca farkları veriyor.

        Derinleş · Sanal POS entegrasyonunun ayarları: uçtan uca 6 dosya · ~95 satır · ilk okumada atlayabilirsin
        Proje dosyaları

        src/main/java/com/fintech/vpos/ VposProperties.java Bütün sanal POS ayarları tek bir record'da. Geçersiz değer uygulamayı başlangıçta durdurur; yanlış terminalle canlıya çıkılmaz.

        src/main/java/com/fintech/vpos/VposProperties.java
        @ConfigurationProperties("vpos")
        @Validated
        public record VposProperties(
        @NotNull URI baseUrl,
        @NotBlank @Pattern(regexp = "\\d{6,12}") String merchantId,
        @NotBlank String terminalId,
        @NotBlank String storeKey, // signs the 3D Secure hash: a secret
        @DefaultValue("10s") @DurationMin(seconds = 2) Duration timeout,
        @DefaultValue ThreeDSecure threeDSecure) {
        // Nested group: vpos.three-d-secure.success-url, vpos.three-d-secure.fail-url
        public record ThreeDSecure(
        @DefaultValue("https://localhost:8443/payments/3d/ok") URI successUrl,
        @DefaultValue("https://localhost:8443/payments/3d/fail") URI failUrl) {
        }
        }

        src/main/java/com/fintech/vpos/ VposClient.java Ayarları kullanan tek yer. @Value yok; record constructor'dan gelir.

        src/main/java/com/fintech/vpos/VposClient.java
        @Component
        class VposClient {
        private final RestClient http;
        private final VposProperties props;
        VposClient(RestClient.Builder builder, VposProperties props) {
        this.props = props;
        var requestFactory = new SimpleClientHttpRequestFactory();
        requestFactory.setConnectTimeout(props.timeout());
        requestFactory.setReadTimeout(props.timeout());
        this.http = builder
        .baseUrl(props.baseUrl().toString())
        .requestFactory(requestFactory)
        .build();
        }
        // Starts a 3D Secure payment: the customer is redirected to the card issuer
        // and comes back to successUrl or failUrl.
        ThreeDStart start(PaymentRequest request) {
        var body = ThreeDStartBody.of(request, props.merchantId(), props.terminalId(),
        props.threeDSecure().successUrl(), props.threeDSecure().failUrl());
        return http.post().uri("/3d/start")
        .header("X-Hash", Hashes.sign(body, props.storeKey())) // key never leaves this class
        .body(body)
        .retrieve()
        .body(ThreeDStart.class);
        }
        }

        src/main/java/com/fintech/ CheckoutApplication.java Record'u kayda sokan satır; tarama yerine açık liste.

        src/main/java/com/fintech/CheckoutApplication.java
        @SpringBootApplication
        @EnableConfigurationProperties(VposProperties.class)
        public class CheckoutApplication {
        public static void main(String[] args) {
        SpringApplication.run(CheckoutApplication.class, args);
        }
        }

        src/main/resources/ application.yml Her ortamda aynı olan, gizli olmayan varsayılanlar: bankanın test ortamı.

        src/main/resources/application.yml
        vpos:
        base-url: https://vpos-test.bank.example # the bank's test environment
        merchant-id: "100200300" # quoted: keeps leading zeros if there are any
        terminal-id: T0001
        timeout: 10s # always write the unit: a bare 10 would mean 10 ms
        three-d-secure:
        success-url: https://checkout.dev.example/payments/3d/ok
        fail-url: https://checkout.dev.example/payments/3d/fail
        logging:
        level:
        com.fintech: INFO

        src/main/resources/ application-prod.yml prod yalnızca farkı söyler. Mağaza anahtarı dosyada değil, ortamdan gelir.

        src/main/resources/application-prod.yml
        # Only what differs in prod. The store key is NOT here:
        # it comes from the environment (VPOS_STOREKEY).
        vpos:
        base-url: https://vpos.bank.example
        merchant-id: "700800900"
        terminal-id: T0042
        three-d-secure:
        success-url: https://checkout.example/payments/3d/ok
        fail-url: https://checkout.example/payments/3d/fail
        logging:
        level:
        com.fintech: WARN

        deploy/k8s/ deployment.yaml Kubernetes: aynı imaj, ortama özel değerler ortam değişkeniyle. Adlar relaxed binding kuralına uygun.

        deploy/k8s/deployment.yaml
        apiVersion: apps/v1
        kind: Deployment
        metadata:
        name: checkout
        spec:
        template:
        spec:
        containers:
        - name: checkout
        image: registry.example/checkout:2.7.0 # the same image in every environment
        env:
        - name: SPRING_PROFILES_ACTIVE
        value: prod
        # vpos.store-key -> VPOS_STOREKEY (dots to _, dashes removed, upper case)
        - name: VPOS_STOREKEY
        valueFrom:
        secretKeyRef: { name: vpos, key: store-key }

        Kendini sına

        Şimşek turu1/5

        Aynı ayar birden fazla yerde varsa listede sonra gelen kazanır.

        Soru 1/2İleri

        Kodda @Profile("!prod") ile işaretli bir FakePaymentGateway bean'i var. Bir ortamda profil yanlışlıkla ayarlanmadı. Ne olur?

        Cevabı biliyor musun?Önce birini seç. Tekrar zamanlaması buna göre ayarlanıyor.

        Aklında kalacak üç şey

        1. 1 Aynı ayar birden çok yerde varsa önceliği yüksek olan kazanır: komut satırı, sonra ortam değişkeni, sonra profil dosyası, sonra application.yml.
        2. 2 Ortam değişkeninin adı Boot'un beklediği biçime uymazsa hiçbir ayara bağlanmaz ve hiçbir hata görünmez.
        3. 3 @ConfigurationProperties ile @Validated, hatalı bir ayarı ilk kullanıcı isteğinde değil, uygulama açılırken yakalar.
        Sonraki kapı İşlenemeyen bir Kafka mesajı birkaç denemeden sonra nereye gider? Spring Kafka Hata Yönetimi — Bozuk Mesaj Partition'ı Durdurur mu? · 9 dk

        5 kart sonraki derste seni bekliyor

        0/5 kart bu dersten toplandı