Yazılımımızda, web istekleri için oturum kimlikleri ve kullanıcı adları gibi şeyleri izlemek için MDC'yi yaygın olarak kullanıyoruz. Bu, orijinal iş parçacığında çalışırken iyi çalışır. Ancak, arka planda işlenmesi gereken birçok şey var. Bunun için java.concurrent.ThreadPoolExecutor
ve java.util.Timer
sınıflarını, bazı kendi kendine yuvarlanan zaman uyumsuz yürütme hizmetleriyle birlikte kullanıyoruz. Tüm bu hizmetler kendi iş parçacığı havuzunu yönetir.
Bu nedir Logback kılavuzu böyle bir ortamda MDC kullanma hakkında şöyle demektedir:
Eşlenen tanı bağlamının bir kopyası her zaman başlangıç iş parçacığından çalışan iş parçacıkları tarafından devralınamaz. İplik yönetimi için java.util.concurrent.Executors kullanıldığında durum budur. Örneğin, newCachedThreadPool yöntemi bir ThreadPoolExecutor oluşturur ve diğer iş parçacığı havuzlama kodu gibi, karmaşık iş parçacığı oluşturma mantığı vardır.
Bu gibi durumlarda, MDC.getCopyOfContextMap () yönteminin yürütücüye bir görev göndermeden önce orijinal (ana) iş parçacığında çağrılması önerilir. Görev ilk eylemi olarak çalıştığında, özgün MDC değerlerinin depolanan kopyasını yeni Executor yönetilen iş parçacığıyla ilişkilendirmek için MDC.setContextMapValues () öğesini çağırmalıdır.
Bu iyi olurdu, ancak bu aramaları eklemeyi unutmak çok kolaydır ve sorunu çok geç olana kadar tanımanın kolay bir yolu yoktur. Log4j ile tek işaret, günlüklerde eksik MDC bilgilerini almanız ve Logback ile eski MDC bilgilerini almanızdır (sırt havuzundaki iplik MDC'yi üzerinde çalıştırılan ilk görevden devralır). Her ikisi de bir üretim sisteminde ciddi sorunlardır.
Durumumuzu hiçbir şekilde özel görmüyorum, ancak web üzerinde bu sorun hakkında fazla bir şey bulamadım. Görünüşe göre, bu birçok insanın çarptığı bir şey değil, bu yüzden bundan kaçınmanın bir yolu olmalı. Burada neyi yanlış yapıyoruz?