【发布时间】:2019-06-11 04:12:11
【问题描述】:
向所有 Java 专家致敬!
我正在开发一个新的、闪亮的流程可视化服务,我需要你的帮助!
我的项目结构是这样的:
Service Package 依赖于 Core Package,Core Package 又依赖于 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;
}
当我想加入可视化服务时,问题就开始了。一项要求是对服务的每次调用使用唯一的事务 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?
【问题讨论】:
标签: java static transactions thread-local