所有Java专家向您问好!
我正在努力提供新的闪亮的过程可视化服务,需要您的帮助!
我的项目结构如下:
服务程序包取决于核心程序包,而核心程序包则取决于Util程序包。像这样:
服务
|-|-核心
|-|-|-实用程序
应用程序包的主要方法从我们的代码开始。它正在调用一些使用Util包从输入中读取信息的Core方法。
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;
}
当我想加入可视化服务时,问题就开始了。一个要求是为每次调用该服务使用唯一的交易ID。
我的问题是-如何在所有这些方法之间共享进程ID,而不需要对代码进行过多的重构?要在“流程可视化”工具中查看整个流程,我将在整个调用中使用相同的ID。我的看法是:
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;
}
我在考虑以下内容,但是所有这些只是抽象的想法,我不确定是否可以实现。如果可以,那么如何?
创建一个新的程序包,这三个程序包都将依赖于此程序包,并将“保留”每个调用的进程ID。但是如何?我应该在此软件包中使用静态类吗?一个辛格尔顿?
我已经阅读了有关ThreadLocal变量的这篇文章:When and how should I use a ThreadLocal variable?,但是我对这些并不熟悉,并且不确定如何实现这个想法-应该像我在1中提到的那样去一个单独的程序包吗?
更改方法的签名以将id作为变量传递。不幸的是,这在时间和昂贵的重构方面都太昂贵了。
使用文件写入-将ID保存在整个过程中可访问的某个文件中。
从输入中构造唯一的ID-我认为这可能是完美的解决方案,但我们可能会在对服务的单独调用中收到相同的输入。
访问JVM以获取一些唯一的事务ID。我知道在记录内容时,在日志行中打印了RequestId。这是我们在Log4J配置中使用的模式:
<pattern>%d{dd MMM yyyy HH:mm:ss,SSS} %highlight{[%p]} %X{RequestId} (%t) %c: %m%n</pattern>
此RequestId是ThreadContext上在作业之前创建的变量。是否可以和/或建议访问此参数并将其用作唯一的事务ID?
答案 0 :(得分:0)
最后,我们利用了Log4J的Thread上下文。 这可能不是最好的解决方案,因为我们混合了同一件事的目的,但这是我们做到的方式:
以如下方式提取进程ID:
org.apache.logging.log4j.ThreadContext.get("RequestId");
并在处理程序链上启动(取决于您所使用的服务):
ThreadContext.put("RequestId", Objects.toString(job.getId(), (String)null));
这在收到的每一项工作中都会发生。
免责声明:此解决方案尚未经过全面测试,但这是我们的发展方向