Skip to main content

Service Discovery Yapılandırması

Service Discovery, bir domain adının çağrılabilir bir endpoint'e nasıl dönüştüğünü ve domain'in registry'e nasıl kayıt olduğunu kontrol eder. Tek kök: ServiceDiscovery.

{
"ServiceDiscovery": {
"Enabled": false,
"BaseUrl": "http://localhost:3001/api/v1",
"Domain": "discovery",
"RegistryFlow": "domain-registration",
"Provider": "http",
"TimeoutSeconds": 5,
"MaxRetryAttempts": 3,
"RetryDelayMilliseconds": 1000,
"CircuitBreakerFailureThreshold": 5,
"CircuitBreakerTimeoutSeconds": 30,
"DiscoveryEndpointTemplate": "/discovery/functions/domain-lookup?key={0}",
"ValidateSsl": true,
"Dapr": {
"NamespaceTemplate": "",
"PreferRegistryAppId": true,
"RequireRegistryEntry": false,
"CacheSeconds": 60,
"DomainOverrides": {}
},
"Cache": {
"Enabled": false,
"L1Enabled": true,
"L1TtlSeconds": 60,
"TickIntervalSeconds": 60,
"RefreshIntervalSeconds": 3600,
"L2TtlSeconds": 7200,
"WarmupLockLeaseSeconds": 30,
"BulkPageSize": 100,
"MaxPages": 20
}
}
}

Alanlar

AnahtarTipVarsayılanAçıklama
EnabledbooleanfalseUygulama başlangıçta registry'e otomatik kayıt olur mu
BaseUrlstring""Registry'yi barındıran vNext instance'ının base URL'i
Domainstring""domain-registration workflow'unun tanımlı olduğu domain (genelde discovery)
RegistryFlowstring""Registry workflow adı
Providerhttp | daprhttpAşağıdaki "Provider" bölümüne bakın
TimeoutSecondsinteger5HTTP istek timeout'u — Cache:Enabled=false iken her cross-domain çözümlemenin önünde durur
MaxRetryAttemptsinteger3Başarısız isteklerde yeniden deneme sayısı
RetryDelayMillisecondsinteger1000Denemeler arası gecikme
CircuitBreakerFailureThresholdinteger5Circuit'in açılması için ardışık hata sayısı
CircuitBreakerTimeoutSecondsinteger30Circuit'in açık kaldığı süre
DiscoveryEndpointTemplatestring/discovery/functions/domain-lookup?key={0}Tekil domain çözümleme endpoint şablonu ({0} = domain adı)
ValidateSslbooleantrueTLS sertifika doğrulaması

Provider

Provider, bir domain adının nasıl çağrılabilir bir endpoint'e dönüştüğünü — ve dolayısıyla çağrının hangi taşıma üzerinden gideceğini — seçer.

DeğerAçıklama
httpVarsayılan. Registry'nin sağladığı baseUrl üzerinden düz HTTP. Eski davranışla birebir aynıdır
daprvnext-{domain}-app[.{namespace}] konvansiyonuyla türetilen Dapr app-id; çağrı DaprClient.CreateInvokeHttpClient() üzerinden yerel sidecar'a gider (Name Resolution + mTLS)

Tanınmayan bir Provider değeri http'ye geriler — okunaksız bir provider adı prod trafiğini sessizce yeni bir transport'a taşıyamaz.

dapr provider

{
"ServiceDiscovery": {
"Provider": "dapr",
"Dapr": {
"NamespaceTemplate": "stage-vnext-{domain}",
"PreferRegistryAppId": true,
"RequireRegistryEntry": false,
"DomainOverrides": { "legacy-domain": "url" }
}
}
}
AnahtarTipVarsayılanAçıklama
Dapr.NamespaceTemplatestring""Cross-namespace app-id'yi ({appId}.{namespace}) oluşturmak için şablon; tek token {domain}. Boş = tek-namespace (app-id çıplak kullanılır). Helm chart, release namespace'inden render eder
Dapr.PreferRegistryAppIdbooleantrueRegistry'den gelen boş olmayan bir appId'nin konvansiyonu override etmesine izin verir. Yalnızca RequireRegistryEntry=true iken anlamlıdır
Dapr.RequireRegistryEntrybooleanfalsefalse: registry hiç okunmaz — çözümleme saf konvansiyon (+ DomainOverrides), ağ çağrısı yok, registry kesintisine bağışık. true: registry her çözümlemede okunur (CacheSeconds boyunca cache'lenir), kayıtsız bir domain DomainEndpointNotFound ile başarısız olur
Dapr.CacheSecondsinteger60RequireRegistryEntry=true iken pozitif sonuç cache ömrü (0 = kapalı). Hatalar asla cache'lenmez
Dapr.DomainOverridesobject{}Domain adına göre override. Değer "url" ise o domain http provider'a geri döner; başka bir değer verilirse doğrudan hedef app-id olarak kullanılır — rollout/rollback dial'ı

Sidecar ERR_* hataları remote_network_error'a normalize edilir: sidecar hedefe ulaşamadığında HTTP 500 + {"errorCode":"ERR_DIRECT_INVOKE",…} döner, DaprRemoteTransport bunu HttpRequestException'a çevirir, böylece error boundary'ler transport hatası olarak görmeye devam eder.

Retry profilleri: okuma çağrıları (instance/data/state/view/hierarchy/list) retry edilir; mutasyonlar (start, subflow-forward, transitions, sub/*, busy, retry) tek deneme ile çağrılır — bu, RemotePolicyFactory'de yaşar çünkü Dapr resiliency hedefleri yalnızca app-id ve status code'a göre filtreler, mutasyon-tekilliğini ifade edemez.

registry (kayıt / health)

Enabled: true iken uygulama başlangıçta registry'e (yukarıdaki BaseUrl/Domain/RegistryFlow ve retry/circuit-breaker alanlarıyla) kayıt olmaya çalışır; başarısız olursa uygulama başlamaz (fail-fast).

Üretimde localhost yasağı: production ortamında BaseUrl (ve vNextApi:BaseUrl) localhost / 127.0.0.1 / ::1 gösteremez — uygulama başlangıçta reddeder. Development'ta izinlidir.

Cache

Cache, yalnızca http provider'da çalışır. dapr provider zaten registry'yi çağırmadığından (varsayılan RequireRegistryEntry=false) burada bir kazancı yoktur; kendi kısa ömürlü app-id cache'ini kullanır.

{
"ServiceDiscovery": {
"Cache": {
"Enabled": true,
"L1Enabled": true,
"L1TtlSeconds": 60,
"TickIntervalSeconds": 60,
"RefreshIntervalSeconds": 3600,
"L2TtlSeconds": 7200,
"WarmupLockLeaseSeconds": 30,
"BulkPageSize": 100,
"MaxPages": 20
}
}
}
AnahtarTipVarsayılanAçıklama
EnabledbooleanKod: false; Orchestration host'ta: trueTek rollback anahtarı. false: eski (cache'siz) davranış birebir geri gelir
L1EnabledbooleantrueProcess-içi katman
L1TtlSecondsinteger60L1 girişinin ömrü — RefreshIntervalSeconds'tan küçük olmalı
TickIntervalSecondsinteger60Her pod'un ne sıklıkla yenileme değerlendirdiği — yenileme hızı değil
RefreshIntervalSecondsinteger3600İki cluster-wide bulk yenileme arasındaki minimum süre — bir shared marker ile cluster genelinde tekilleştirilir
L2TtlSecondsinteger7200Bir kaydın "yok" sayılmadan önceki maksimum yaşı — dead-man's switch, RefreshIntervalSeconds'ın en az + WarmupLockLeaseSeconds fazlası olmalı
WarmupLockLeaseSecondsinteger30Bulk-refresh lock'unun lease süresi — RefreshIntervalSeconds'tan küçük olmalı
BulkPageSizeinteger100Bulk okuma sayfa boyutu (API maksimumu ile aynı)
MaxPagesinteger20Bir yenilemede çekilecek maksimum sayfa sayısı (runaway koruması)

Bu invaryantlar startup'ta doğrulanır (ServiceDiscoveryOptionsValidator) — her biri bozulduğunda cache'i sessizce ya durdurur ya da penceresini genişletir; bu yüzden bir yorum değil, bir sözleşmedir.

Katmanlar: L1 (in-process) → L2 (dağıtılmış) → registry. FetchedAtUtc her girişe damgalanır ve okumada kontrol edilir (dağıtılmış cache'in kendi TTL desteği olmayabilir, sessizce yoksayabilir). Saatte bir (varsayılan) tüm kayıtlar bir distributed lock altında bulk okunur.

baseUrl değişince (bir domain taşındığında) cache'in bir saatlik penceresini beklemek yerine senkron zorla yenileme yapın:

curl -X POST localhost:4201/api/v1/utilities/discovery/refresh

Yanıt: {"outcome": "Refreshed"} (veya SkippedNotOwner, Failed, disabled).

warning

Cache.AcceptedStatuses varsayılanı ["A"]'dır, ama metadata.status registration workflow instance'ının durumudur, bir health sinyali değildir. Registration flow'unuz bir Finish state'e ulaşıyorsa instance'lar C'ye geçer ve warm-up bu domain'leri atlar (yine de bir miss canlı registry'ye düşer, sadece warm-up'ın kazancı olmaz).

Gözlemlenebilirlik: Discovery.Resolve/{domain} span'i vnext.discovery.provider (http|dapr) ve vnext.discovery.resolution (convention|registry|cache) tag'lerini taşır.

Sorun Giderme

  1. Registry endpoint doğrulama:

    curl https://discovery.production.com/health
  2. Ağ bağlantısı kontrolü:

    ping discovery.production.com
  3. Uygulama loglarını inceleme:

    docker logs vnext-app-core | grep "Service Discovery"
  4. Development'ta geçici devre dışı bırakma:

    { "ServiceDiscovery": { "Enabled": false } }
  5. Cache'i tamamen geri alma:

    { "ServiceDiscovery": { "Cache": { "Enabled": false } } }

    Restart sonrası düz registry client'ı devreye girer; flip öncesi yazılmış bir giriş bile artık okunamaz.

İlgili

  • Caching — component/state/instance function cache (bu sayfadaki registry cache'inden bağımsız)
  • Telemetry — Dapr sidecar tracing yapılandırması