Создание идентификатора глобальной транзакции, доступного через несколько пакетов - PullRequest
0 голосов
/ 17 января 2019

Привет всем экспертам по Java!

Я работаю над внедрением новой блестящей службы визуализации процессов, и мне нужна ваша помощь!

Структура моего проекта выглядит следующим образом:

Пакет услуг зависит от Базового пакета, который зависит от пакета Util. Примерно так:

Услуги
| - | - Core
| - | - | - Util

В пакете приложения есть метод main, с которого начинается наш код. Он вызывает некоторые из основных методов, использующих пакет Util для чтения информации из ввода.

package com.dummy.service;

public void main(Object input) {
     serviceCore.call(input);
}
package com.dummy.core;

public void call(Object input) {
     String stringInput = util.readFromInput(input);
     //Do stuff
}

package com.dummy.util;

public String readFromInput(Object input) {
     //return stuff;
}

Проблема начинается, когда я хочу подключиться к службе визуализации. Одним из требований является использование уникального идентификатора транзакции для каждого вызова службы.

У меня вопрос - как разделить идентификатор процесса между всеми этими методами, не делая слишком много рефакторинга в коде? Чтобы увидеть весь процесс в инструменте визуализации процессов, мне нужно будет использовать один и тот же идентификатор для всего вызова. Мое видение, что это будет что-то вроде:

package com.dummy.service;

public void main(Object input) {
     processVisualization.signal(PROCESS_ID, "transaction started");
     serviceCore.call(input);
     processVisualization.signal(PROCESS_ID, "transaction ended");
}
package com.dummy.core;

public void call(Object input) {
     processVisualization.signal(PROCESS_ID, "Method call is invoked");
     String stringInput = util.readFromInput(input);
     //Do stuff
}

package com.dummy.util;

public String readFromInput(Object input) {
     processVisualization.signal(PROCESS_ID, "Reading from input");
     //return stuff;
}

Я думал о следующем, но все это просто абстрактные идеи, которые я даже не уверен, что может быть реализован. И если да - то как?

  1. Создание нового пакета, от которого будут зависеть все три пакета, и «удержание» идентификатора процесса для каждого вызова. Но как? Должен ли я использовать статический класс в этом пакете? Сингелтон?

  2. Я читал этот пост о переменных ThreadLocal: Когда и как я должен использовать переменную ThreadLocal? , но я не знаком с ними и не уверен, как реализовать эту идею - должна ли она перейти к отдельному пакету, как я упоминал в 1?

  3. Изменение сигнатур метода для передачи идентификатора в качестве переменной. Это, к сожалению, слишком дорого с точки зрения времени и опасности большого рефакторинга.

  4. Использование записи в файл - сохраните идентификатор в каком-нибудь файле, который доступен на протяжении всего процесса.

  5. Построение уникального идентификатора из ввода - я думаю, что это может быть идеальным решением, но мы можем получить один и тот же ввод при отдельных вызовах в службу.

  6. Доступ к JVM для некоторого уникального идентификатора транзакции. Я знаю, что когда мы ведем журнал, у нас в строке журнала печатается RequestId. Это шаблон, который мы используем в конфигурации Log4J: <pattern>%d{dd MMM yyyy HH:mm:ss,SSS} %highlight{[%p]} %X{RequestId} (%t) %c: %m%n</pattern> Этот RequestId является переменной в ThreadContext, которая создается перед заданием. Возможно ли и / или рекомендуется ли получить доступ к этому параметру и использовать его в качестве уникального идентификатора транзакции?

1 Ответ

0 голосов
/ 22 января 2019

В конце мы использовали контекст Thread Log4J. Вероятно, это не лучшее решение, так как мы объединяем цель одного и того же, но вот как мы это сделали:

Идентификатор процесса извлекается так: org.apache.logging.log4j.ThreadContext.get("RequestId");

И инициируется в Цепочке обработки (зависит от того, какую службу вы используете): ThreadContext.put("RequestId", Objects.toString(job.getId(), (String)null));
Это происходит на каждой полученной работе.

Отказ от ответственности: это решение еще не было полностью протестировано, но это направление, в котором мы идем

...