HikariCP havuzunda bekleyen istekleri Micrometer, JFR ve yük testiyle ayrıştırın; havuz boyutunu Little's Law, sorgu süresi ve veritabanı sınırlarına göre doğrulayın. spring boot eğitimi için üretim odaklı rehber.
Spring Boot'ta HikariCP Kuyruklama, Ölçüm ve Havuz Boyutlandırma
spring boot eğitimi: Sorunun havuzda mı sorguda mı olduğunu ayırın
Bir spring framework eğitimi içinde HikariCP ayarlarını sadece application.yml'e birkaç sayı yazmak olarak ele almak yanıltıcıdır. Önce Actuator ve Micrometer ile havuz beklemesini görünür yapın. hikaricp.connections.pending sıfırdan büyükken active değeri maximumPoolSize'a yakınsa uygulama bağlantı bekliyordur; pending sıfırken HTTP gecikmesi yükseliyorsa neden SQL çalıştırma süresi, kilit veya uygulama CPU'su olabilir. Aşağıdaki ayar Prometheus endpoint'ini test ortamında doğrulamak için yeterlidir:
management:
endpoints:
web:
exposure:
include: health,metrics,prometheus
metrics:
tags:
service: orders-api
spring:
datasource:
hikari:
pool-name: orders-primary
Ardından curl -s http://localhost:8080/actuator/metrics/hikaricp.connections.pending ile metriğin gerçekten üretildiğini kontrol edin. Havuz metrikleri görünmüyorsa DataSource'un uygulama tarafından elle oluşturulup Spring Boot'un gözlemleme zincirinin dışına çıkarılmadığını ve Micrometer registry bean'inin bulunduğunu kontrol edin.PostgreSQL kullanılıyorsa uygulama metriklerini pg_stat_activity ve pg_stat_statements ile eşleyin. Örneğin aynı 60 saniyelik pencerede pending artarken veritabanındaki aktif oturum sayısı sabit kalıyorsa, bağlantı havuzunun maksimumu dar boğazdır. Aktif oturum sayısı yüksek, wait_event_type Lock ise havuzu büyütmek sadece daha fazla sorgunun aynı kilitte birikmesine neden olur. Bu ayrım, spring boot kursu laboratuvarlarında sık görülen 'pending arttı, maximumPoolSize'ı 100 yaptım' hatasını engeller.
SELECT wait_event_type, wait_event, count(*)
FROM pg_stat_activity
WHERE datname = current_database()
GROUP BY 1, 2
ORDER BY 3 DESC;
SELECT calls, mean_exec_time, total_exec_time, query
FROM pg_stat_statements
ORDER BY total_exec_time DESC
LIMIT 10;HikariCP havuz boyutunu Little's Law ve zaman aşımıyla kurmak
Başlangıç boyutunu trafik ve gerçek SQL süresiyle hesaplayın: 180 istek/saniye ve p95'te istek başına 35 ms bağlantı tutuluyorsa beklenen eşzamanlı kullanım yaklaşık 180 x 0.035 = 6.3 bağlantıdır. Bu sayı hedef havuz boyutu değildir; burst, p99 ve birden fazla SQL çağrısı nedeniyle yük testiyle örneğin 12 bağlantı denenebilir. Ancak 12'den 40'a çıkmak, veritabanına paralel 40 pahalı sorgu sokar; CPU doygunluğunda sorgu süreleri uzar, bu da Little's Law gereği daha da fazla eşzamanlı bağlantı ihtiyacı üretir.
Aşağıdaki yapılandırmada connection-timeout kullanıcı isteğinin tamamı için ayrılan süre değildir; yalnızca boş JDBC bağlantısı alma üst sınırıdır. 250 ms sonunda bağlantı yoksa Hikari hata verir ve bunun HTTP katmanında 503 veya sözleşmenizdeki uygun ProblemDetail karşılığına çevrilmesi gerekir. max-lifetime değeri de veritabanı, proxy veya load balancer'ın boş bağlantıyı kesme süresinden kısa tutulmalıdır. Aksi halde uygulama, havuzdan sağlıklı sandığı fakat ağ cihazı tarafından kapatılmış bir socket alabilir.
spring:
datasource:
hikari:
maximum-pool-size: 12
minimum-idle: 4
connection-timeout: 250
validation-timeout: 1000
idle-timeout: 600000
max-lifetime: 1740000
keepalive-time: 300000
leak-detection-threshold: 0
leak-detection-threshold değerini kalıcı izleme aracı gibi açmayın. Uzun raporlama sorgusu veya debugger altında duran bir transaction, gerçek sızıntı olmadığı halde stack trace üreterek log hacmini artırır. Onu kısa süreli teşhis sırasında, beklenen en uzun transaction süresinin biraz üzerinde kullanın.spring mvc ve spring security zincirinde bağlantıyı gereksiz tutmayın
Spring MVC isteğinde en maliyetli hata, transaction içindeyken uzak HTTP çağrısı yapmak veya büyük bir response'u serialize etmektir. Hibernate transaction'a ilk erişimde bağlantıyı alabilir ve işlem bitene kadar aynı thread'e bağlayabilir. Aşağıdaki yanlış örnekte stok servisi 800 ms beklerse, o 800 ms boyunca JDBC havuzundan bir bağlantı tüketilebilir. Bu etki düşük trafikte görünmez, ancak 20 paralel istekte 12 elemanlı havuzu hızla doldurur.
@Service
class CheckoutService {
@Transactional
public Order checkout(UUID cartId) {
Order order = orderRepository.lockByCartId(cartId);
inventoryClient.reserve(order.getSku()); // Uzak çağrı transaction icinde
order.markReserved();
return order;
}
}Uzak doğrulamayı transaction öncesine taşıyın veya kalıcılaştırma sonrası olay akışı kullanın. Aşağıdaki sürümde veritabanı kilidi ve JDBC bağlantısı sadece repository işlemleri arasındaki kısa bölümü kapsar. Uzak sistem ile veritabanı arasında atomiklik gerektiğini varsaymayın; bunun için idempotent rezervasyon anahtarı, telafi işlemi veya outbox gibi ayrı bir protokol gerekir.
@Service
class CheckoutService {
public Order checkout(UUID cartId) {
CartSnapshot cart = cartReader.load(cartId);
inventoryClient.reserve(cart.sku(), cartId.toString());
return persistReservation(cartId);
}
@Transactional
Order persistReservation(UUID cartId) {
Order order = orderRepository.lockByCartId(cartId);
order.markReserved();
return order;
}
}
Spring Security tarafında da JWT doğrulama, denetim kaydı veya yetki sorgusu için filtre içinde repository çağrısı yapılıyorsa bunu ayrı ölçün. http.server.requests etiketi ile hikaricp.connections.pending zaman serisini aynı dashboard'da tutmak, bağlantı kuyruklarının belirli bir authorization endpoint'iyle ilişkisini gösterebilir.microservices mimarisi, spring cloud ve spring rest api için kuyruk bütçesi
microservices mimarisi içinde bir spring rest api isteği, gateway retry'ı, servis istemcisi retry'ı ve uygulama içi retry birleştiğinde beklenenden fazla eşzamanlı çağrı yaratabilir. Örneğin gateway iki deneme, servis istemcisi iki deneme ve uygulama retry'ı iki deneme yaparsa en kötü durumda tek kullanıcı isteği 8 downstream çağrıya dönüşür. spring cloud kullanan sistemlerde retry kararını tek katmanda sahiplenin ve bağlantı havuzu bekleme süresini toplam HTTP deadline'dan küçük tutun. 1 saniyelik endpoint deadline'ında 250 ms JDBC alma süresi, 600 ms SQL timeout ve 500 ms downstream timeout aynı anda tanımlanırsa, çağrı zinciri 1 saniye bütçesini zaten matematiksel olarak aşar.
Resilience4j ile retry sayısını ve beklemeyi sınırlandırın; sadece idempotent operasyonları tekrar deneyin. POST isteği idempotency key olmadan tekrarlandığında aynı siparişin iki kez oluşturulması, havuz ayarından daha ağır bir üretim hatasıdır.
resilience4j:
retry:
instances:
inventory:
max-attempts: 2
wait-duration: 50ms
retry-exceptions:
- java.net.SocketTimeoutException
ignore-exceptions:
- org.springframework.web.client.HttpClientErrorException
Yüksek öncelikli yazma trafiği ile raporlama trafiği aynı DataSource'u kullanıyorsa tek havuzda adil paylaşım beklemeyin. Rapor endpoint'lerini ayrı read replica DataSource'una ve ayrı Hikari havuzuna taşımak, raporun 30 saniye bağlantı tutmasının sipariş yazmalarını kuyruklamasını engeller. Bu ayrımın karşılığında replica gecikmesini endpoint sözleşmesinde açıkça belirtin.java spring eğitimi için önce-sonra profiling ve kabul kriteri
Değişikliği 'daha hızlı hissettiriyor' diye değil, aynı yük profili altında karşılaştırın. Önce mevcut maximumPoolSize ile 10 dakika sabit istek/saniye ve ardından 2 dakika burst çalıştırın; sonra yalnızca havuz ayarını değiştirerek aynı senaryoyu tekrarlayın. Gatling, k6 veya Vegeta kullanılabilir. k6 örneğinde p95 HTTP gecikmesi, hata oranı ve pending tepe değeri birlikte kaydedilmelidir:
import http from 'k6/http';
import { check } from 'k6';
export const options = {
scenarios: {
steady: { executor: 'constant-arrival-rate', rate: 180, timeUnit: '1s',
duration: '10m', preAllocatedVUs: 40, maxVUs: 200 }
}
};
export default function () {
const res = http.get('https://api.example.test/orders/42');
check(res, { 'status is 200': r => r.status === 200 });
}Uygulama tarafında Java Flight Recorder ile aynı test penceresinde kayıt alın: jcmd <pid> JFR.start name=hikari settings=profile duration=120s filename=/tmp/hikari.jfr. JDK Mission Control'da thread park sürelerini, socket read beklemelerini ve CPU örneklerini inceleyin. Prometheus'ta örnek kabul kriteri şudur: aynı 180 RPS altında p95 gecikme düşerken max_over_time(hikaricp_connections_pending[2m]) sıfıra yakın kalmalı, veritabanı CPU'su kalıcı doygunluğa girmemeli ve 5xx oranı artmamalıdır. Sadece pending düşüp SQL p95 yükseliyorsa havuz büyütme kuyruklamayı veritabanına taşımıştır. Bu yaklaşım, java spring eğitimi alan ekiplerin konfigürasyon değişikliğini ölçülebilir bir hipotez olarak ele almasını sağlar.
İ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ğitimi sırasında HikariCP maximumPoolSize kaç olmalı?
Sabit bir sayı kullanmayın. Üretim benzeri yükte istek/saniye ile bağlantının tutulduğu p95 süreyi çarpıp başlangıç eşzamanlılığını bulun, ardından 8, 12 ve 16 gibi adayları aynı k6 veya Gatling senaryosunda karşılaştırın. Kararı hikaricp.connections.pending, SQL p95, veritabanı CPU'su ve hata oranını birlikte izleyerek verin.
spring mvc uygulamasında hikaricp.connections.pending neden yükselir?
En sık nedenler maksimum havuz boyutuna ulaşılması, transaction içinde uzak HTTP çağrısı yapılması, uzun süren SQL veya veritabanı kilididir. Aynı zaman penceresinde pg_stat_activity içindeki wait_event_type değerlerini ve hikaricp.connections.active metriklerini kontrol edin. Pending yüksek, active maksimumda ve Lock beklemeleri fazlaysa havuz büyütmek yerine kilit sırasını veya sorguyu düzeltin.
spring cloud retry ayarları JDBC bağlantı havuzunu etkiler mi?
Evet. Bir isteğin birden fazla kez servis katmanına ulaşması, her denemede transaction açılıyorsa JDBC bağlantı talebini çarpar. Retry'ı tek katmanda sınırlandırın, max-attempts değerini ölçülebilir hata bütçenize göre belirleyin ve idempotent olmayan POST işlemlerinde idempotency key olmadan otomatik tekrar denemeyin.
spring security filtrelerinde repository çağrısı yapmak doğru mu?
Yalnızca gerekli ve ölçülmüşse yapın. Her istekte rol veya audit verisi için repository çağrısı, kimlik doğrulama yoğunlaştığında ana iş trafiğiyle aynı havuzu tüketir. Önce hikaricp.connections.pending ile endpoint bazlı http.server.requests metriklerini karşılaştırın; gerekiyorsa yetki verisini token claim'ine, kısa ömürlü cache'e veya ayrı bir DataSource'a taşıyın.
AI / LLM Discovery
Bu makale Opendart Akademi Spring Framework 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.


