Как использовать MDC с пулами потоков?

В нашем программном обеспечении мы широко используем MDC для отслеживания таких вещей, как идентификаторы сеансов и имена пользователей для веб-запросов. Это отлично работает при работе в исходном потоке. Однако есть много вещей, которые нужно обрабатывать в фоновом режиме. Для этого мы используем классы java.concurrent.ThreadPoolExecutor и java.util.Timer вместе с некоторыми службами самовращающегося асинхронного выполнения. Все эти службы управляют своим собственным пулом потоков.

Это то, что руководство Logback говорит об использовании MDC в такой среде:

Копия отображенного диагностического контекста не всегда может быть унаследована рабочие потоки из инициирующего потока. Это тот случай, когда java.util.concurrent.Executors используется для управления потоками. Например, Метод newCachedThreadPool создает ThreadPoolExecutor и, как и другой код объединения потоков, имеет сложную логику создания потоков.

В таких случаях рекомендуется, чтобы MDC.getCopyOfContextMap () вызывалась в исходном (главном) потоке перед отправкой задачи в исполнитель. Когда задача запускается в качестве своего первого действия, она должна вызвать MDC.setContextMapValues ​​(), чтобы связать сохраненную копию исходных значений MDC с новым управляемым потоком Executor.

Это было бы хорошо, но это очень легко забудьте добавить эти вызовы, и нет простого способа распознать проблему, пока не станет слишком поздно. Единственным признаком Log4j является то, что в журналах отсутствует информация о MDC, а с помощью Logback вы получаете устаревшую информацию о MDC (поскольку поток в пуле протектора наследует свой MDC от первой задачи, которая была запущена на нем). Оба являются серьезными проблемами в производственной системе.

Я не вижу в нашей ситуации ничего особенного, но я не смог найти много информации об этой проблеме в Интернете. Очевидно, это не то, с чем сталкиваются многие люди, поэтому должен быть способ избежать этого. Что мы здесь делаем не так?

126
задан Lóránt Pintér 20 May 2011 в 13:58
поделиться