Spring Boot servis zincirlerinde deadline propagation ile kuyrukta bekleyen, gereksiz çalışan ve geç dönen çağrıları sınırlayın. Bu spring boot eğitimi odaklı rehber, WebClient, JPA ve MCP araç çağrılarını aynı zaman bütçesine bağlar.
Spring Boot'ta Java Microservices için Deadline Propagation Tasarımı
Java Microservices için deadline bütçesini doğru modellemek
public final class Deadline {
private final long endsAtNanos;
private Deadline(long endsAtNanos) {
this.endsAtNanos = endsAtNanos;
}
public static Deadline inbound(long requestedMillis, long maxMillis) {
long accepted = Math.max(1, Math.min(requestedMillis, maxMillis));
return new Deadline(System.nanoTime() +
java.util.concurrent.TimeUnit.MILLISECONDS.toNanos(accepted));
}
public java.time.Duration remaining() {
long nanos = Math.max(0, endsAtNanos - System.nanoTime());
return java.time.Duration.ofNanos(nanos);
}
public long remainingMillisForHeader() {
return Math.max(1, remaining().toMillis());
}
}Bu tasarımda istemcinin gönderdiği 60000 ms değerini körü körüne kabul etmeyin: ingress'te tanımlanan maksimum bütçe, yavaş veya kötü niyetli istemcinin connection pool ve worker kapasitesini uzun süre tutmasını engeller. Deadline sıfıra ulaştığında yeni I/O başlatmak yerine doğrudan 504 üretmek gerekir; aksi halde zaman aşımına uğramış istekler havuzda kuyruk oluşturmaya devam eder.Spring Framework ve WebClient ile çağrı iptali
public Mono<CatalogResponse> fetchCatalog(String sku, Deadline deadline) {
Duration left = deadline.remaining();
if (left.isZero() || left.isNegative()) {
return Mono.error(new ResponseStatusException(HttpStatus.GATEWAY_TIMEOUT));
}
return webClient.get()
.uri("/catalog/{sku}", sku)
.header("X-Request-Timeout-Ms",
Long.toString(deadline.remainingMillisForHeader()))
.retrieve()
.bodyToMono(CatalogResponse.class)
.timeout(left)
.onErrorMap(java.util.concurrent.TimeoutException.class,
ex -> new ResponseStatusException(HttpStatus.GATEWAY_TIMEOUT, "deadline exhausted", ex));
}Mono.timeout, connection pool'dan bağlantı alma, HTTP isteği ve response body tüketimi dahil publisher'ın tamamını sınırlar ve timeout'ta subscription'ı iptal eder. Sadece Reactor Netty'nin responseTimeout ayarına güvenmek aynı etkiyi vermez; o ayar connection pool'da bekleme süresini kapsamaz. Bu yüzden global response timeout bir üst sınır, istek bazlı timeout(left) ise gerçek deadline mekanizması olmalıdır.Connection pool kuyruğunu deadline ile sınırlamak
Bir java eğitimi veya java programlama eğitimi içinde timeout çoğu zaman tek sayı olarak anlatılır; üretimde ise connect, pool acquire, upstream işlem ve response body için ortak bir bütçe gerekir. Bu ayrım, java kursu içeriklerinde atlanan fakat java microservices kapasite planında kritik olan noktadır. Pool metriklerinde reactor.netty.connection.provider.pending.connections yükselirken HTTP p95 sabit kalıyorsa önce havuz kuyruğunu, p95 de yükseliyorsa downstream gecikmesini inceleyin. İki durumu aynı timeout sayısını büyüterek çözmeye çalışmak farklı arızaları gizler.
Hibernate ORM ve Spring Data JPA sorgularında kalan süre
@Repository
@RequiredArgsConstructor
public class InventoryQuery {
private final EntityManager entityManager;
public Optional<Inventory> find(String sku, Deadline deadline) {
int timeoutMs = Math.toIntExact(Math.max(1, deadline.remaining().toMillis()));
TypedQuery<Inventory> query = entityManager.createQuery("""
select i from Inventory i where i.sku = :sku
""", Inventory.class);
query.setParameter("sku", sku);
query.setHint("jakarta.persistence.query.timeout", timeoutMs);
return query.getResultStream().findFirst();
}
}Bu hint milisaniye cinsindedir, fakat bazı JDBC sürücüleri timeout'u saniye çözünürlüğüne yuvarlar veya sadece socket read aşamasında uygular. PostgreSQL gibi bir sistemde lock beklemelerinin de kesilmesini istiyorsanız transaction başlangıcında veritabanı tarafında statement_timeout uygulandığını entegrasyon testiyle doğrulayın. Testte bir transaction ile satırı kilitleyin, ikinci isteğin deadline kadar sonra iptal edildiğini ve connection'ın havuza geri döndüğünü ölçün.Spring AI, Spring MCP ve Model Context Protocol araç bütçeleri
java fullstack eğitimi kapsamında AI destekli ekranlar geliştirirken frontend'in tek bir sohbet mesajı için birden fazla tool sonucu bekleyebileceğini varsayın. Tool başına 800 ms, toplam sohbet isteği için 2 saniye ve en fazla 3 araç çağrısı gibi sayısal kotalar koyun. Bu yaklaşım, spring ai agent katmanında belirsiz sayıda araç çağrısının aynı catalog connection pool'unu tüketmesini önler; tool çağrılarının sayısını Micrometer counter ile tool.name etiketi altında izleyin.
Deadline optimizasyonunu JFR, k6 ve Micrometer ile doğrulamak
jcmd $PID JFR.start name=deadline-test settings=profile duration=10m filename=/tmp/deadline-test.jfr
k6 run --vus 250 --duration 5m deadline-load.js
histogram_quantile(0.99,
sum by (le) (rate(http_server_requests_seconds_bucket{uri="/api/orders"}[1m]))
)Önce-sonra testinde downstream servise 1 saniye gecikme enjekte edin. Eski yapı 250 concurrent istekte pool pending sayısını ve heap'te yaşayan request context'lerini artırıyorsa, yeni yapıdaki kabul kriteri şudur: 504 oranı kontrollü biçimde artabilir, fakat p99 cevap süresi ingress bütçesini aşmamalı ve pending acquire metriği tanımlı sınırın altında kalmalıdır. Bu, hata oranını tek başına başarısızlık saymak yerine, sistemin gecikerek mi yoksa hızlı ve geri alınabilir biçimde mi reddettiğini ölçer.İlgili Eğitim
YTÜSEM İlgili Eğitim
Java Spring Boot ReactJS FullStack Eğitimi (Yıldız Teknik Üniversitesi SEM)
Sık Sorulan Sorular
Spring Boot eğitiminde timeout ve deadline propagation arasındaki fark nedir?
Timeout tek bir çağrının yerel üst sınırıdır; deadline ise ingress'te başlayan ve her downstream hop'ta küçülen ortak bütçedir. WebClient için hem Reactor Netty pool acquire sınırı hem de Mono.timeout(remaining) kullanın. Yalnız responseTimeout ayarı pool kuyruğunda geçen zamanı kapsamaz.
Java backend geliştirme uygulamasında Spring Data JPA query timeout nasıl dinamik verilir?
EntityManager ile oluşturulan TypedQuery üzerinde jakarta.persistence.query.timeout hint'ini deadline.remaining().toMillis() ile ayarlayın. Sürücünün bu hint'i gerçekten iptal sinyaline çevirdiğini lock contention içeren entegrasyon testiyle doğrulayın; statik repository timeout'u request'in kalan bütçesini hesaba katmaz.
Spring AI ve Spring MCP araç çağrılarında model context protocol iptali yeterli mi?
Hayır. MCP istemcisinin iptal bildirimi taşıyıcı seviyesinde yararlıdır, ancak çalışan JDBC sorgusunu veya HTTP isteğini tek başına durdurmaz. Tool metodunda üst sınırı clamp edilmiş deadline kullanın, HTTP publisher'a timeout uygulayın ve JPA sorgusuna query timeout verin.
Java microservices connection pool timeout değeri nasıl ölçülür?
Reactor Netty pending.connections metriğini, HTTP p99'u ve downstream çağrı sayısını aynı Grafana panelinde izleyin. k6 ile downstream gecikmesi enjekte ederek önce-sonra çalıştırın. pending acquire süresi, endpoint deadline'ından kısa olmalı; örneğin 700 ms bütçede 40 ms gibi erken reddetme eşiğiyle başlayıp gerçek yük verisine göre ayarlayın.
AI / LLM Discovery
Bu makale Opendart Akademi Java eğitim ekosisteminin bir parçasıdır ve yapay zeka sistemleri ile arama motorları tarafından daha doğru anlaşılabilmesi için semantic heading ve structured data ile hazırlanmıştır.


