我有一个基于流程Consume-> Process-> Produce的大数据应用程序。我在提取管道中使用Kafka,并在使用事务生成器来生成消息。我的应用程序的所有部分都运行良好,但是为事务生成器生成ID时存在一个小问题。场景:
假设我的应用程序在一台机器上运行,我实例化了两个拥有自己生产者的使用者,因此例如可以说 生产者1的交易ID为-> Consumer-0-Producer 生产者2的交易ID为-> Consumer-1-Producer 现在,这两个生产者发起的交易不会互相干扰,这就是我所希望的。伪代码看起来像这样:
ExecutorService executorService// responsible for starting my consumers
for (int i = 0; i < 2; i++) {
prod_trans_id = "consumer-" + str(i) + "-producer"
Custom_Consumer consumer = new Custom_Consumer(prod_trans_id)
executorService.submit(consumer)
}
如果我的应用程序可以在单台机器上运行,则可以很好地工作,但是不是这样,因为该应用程序需要在多台机器上运行,所以当同一代码在第二台机器上运行时,生产者将由消费者实例化。机器2的事务ID与机器1上的事务ID相同。我希望产生一种事务ID,使其彼此不冲突且可重复,这意味着如果应用程序崩溃/停止(例如有人先service application stop
,然后再service application start
),当它重新联机时,它应该使用以前使用的相同的交易ID。我想到了基于UUID的方法,但是,当一台计算机上的应用程序死亡并重新联机时,UUID是随机的,并且不会相同。
答案 0 :(得分:0)
private final static String HOSTNAME_COMMAND = "hostname";
public static String getHostName() {
BufferedReader inputStreamReader = null;
BufferedReader errorStreamReader = null;
try {
Process process = Runtime.getRuntime().exec(HOSTNAME_COMMAND);
inputStreamReader = new BufferedReader(new InputStreamReader(process.getInputStream()));
errorStreamReader = new BufferedReader(new InputStreamReader(process.getErrorStream()));
if (errorStreamReader.readLine() != null) {
throw new RuntimeException(String.format("Failed to get the hostname, exception message: %s",
errorStreamReader.readLine()));
}
return inputStreamReader.readLine();
} catch (IOException e) {
try {
if (inputStreamReader != null) {
inputStreamReader.close();
}
if (errorStreamReader != null) {
errorStreamReader.close();
}
} catch (IOException e1) {
LogExceptionTrace.logExceptionStackTrace(e1);
throw new RuntimeException(e1);
}
LogExceptionTrace.logExceptionStackTrace(e);
throw new RuntimeException(e);
}
}
然后使用主机名,如下所示:
final String producerTransactionalID = String.format("%s_producer", this.consumerName);
消费者名称设置如下:
for (int i = 0; i < NUMBER_OF_CONSUMERS; i++) {
String consumerName = String.format("%s-worker-%d", hostName, i);
Executor executor = new Executor(
Configuration, consumerName
);
Executors.add(executor);
futures.add(executorService.submit(executor));
}