我如何关闭Apache Kafka连接器任务?

时间:2016-10-04 10:01:18

标签: java apache-kafka apache-kafka-connect

现在我正在使用Apache Kafka并完成任务: 我们在目录中有一些csv文件,它是一个小批量文件,每个文件大约25-30 MB。我只需要 - 解析文件并将其放入kafka。

正如我所看到的,Kafka有一些有趣的东西,比如Connector。

我可以创建Source-Connector和SourceTask,但我不明白一件事: 当我处理文件时,我如何停止或删除我的任务?

例如我有虚拟连接器:

public class DummySourceConnector extends SourceConnector {
private static final Logger logger = LogManager.getLogger();

@Override
public String version() {
    logger.info("version");

    return "1";
}

@Override
public ConfigDef config() {
    logger.info("config");

    return null;
}

@Override
public Class<? extends Task> taskClass() {
    return DummySourceTask.class;
}

@Override
public void start(Map<String, String> props) {
    logger.info("start {}", props);
}

@Override
public void stop() {
    logger.info("stop");
}

@Override
public List<Map<String, String>> taskConfigs(int maxTasks) {
    logger.info("taskConfigs {}", maxTasks);

    return ImmutableList.of(ImmutableMap.of("key", "value"));
}

任务:

public class DummySourceTask extends SourceTask {
private static final Logger logger = LogManager.getLogger();

private long offset = 0;

@Override
public String version() {
    logger.info("version");

    return "1";
}

@Override
public void start(Map<String, String> props) {
    logger.info("start {}", props);
}


@Override
public List<SourceRecord> poll() throws InterruptedException {
    Thread.sleep(3000);

    final String value = "Offset " + offset++ + " Timestamp " + Instant.now().toString();

    logger.info("poll value {}", value);

    return ImmutableList.of(new SourceRecord(
            ImmutableMap.of("partition", 0),
            ImmutableMap.of("offset", offset),
            "topic-dummy",
            SchemaBuilder.STRING_SCHEMA,
            value
    ));
}

public void stop() {
    logger.info("stop");
}

但是当我完成任务时我怎么能完成任务呢? 或者也许你可以帮助我完成这项任务的另一个想法。

Thanx为你提供帮助!

2 个答案:

答案 0 :(得分:1)

首先,我建议您查看现有的连接器here。我觉得spooldir连接器会对你有所帮助。您甚至可以直接下载并安装它,而无需编写任何代码。

其次,如果我理解正确,你想要停止任务。我相信this discussion就是你想要的。

答案 1 :(得分:0)

在事件发生时终止任务的一种不太优雅的解决方案是在任务源中检查事件,然后调用System.exit(1)。

尽管如此,我发现的最优雅的解决方案是:

事件发生时,连接器任务将REST调用应用于代理,以停止运行该任务的连接器。

为此,任务本身应该知道运行该任务的连接器的名称,您可以按照此discussion的步骤进行操作。

因此,连接器的名称位于Task的 properties 参数中,存在一个带有“名称”键的属性,其值是执行任务的连接器的名称(我们希望在发生事件时停止)。

最后,我们进行了REST调用,并且如果任务停止,我们将得到204条不包含任何内容的答案。

通话代码是这样的:

 try {

  URL url = new URL("url/" + connectorName);
  HttpURLConnection conn = (HttpURLConnection) url.openConnection();
  conn.setRequestMethod("DELETE");
  conn.setRequestProperty("Accept", "application/json");

  if (conn.getResponseCode() != 204) {
    throw new RuntimeException("Failed : HTTP error code : "
        + conn.getResponseCode());
  }

  BufferedReader br = new BufferedReader(new InputStreamReader(
    (conn.getInputStream())));

  String output;
  System.out.println("Task Stopped \n");
  while ((output = br.readLine()) != null) {
    System.out.println(output);
  }

  conn.disconnect();

  } catch (MalformedURLException e) {

  e.printStackTrace();

  } catch (IOException e) {

  e.printStackTrace();

  }

现在所有连接器任务都停止。

当然,正如前面提到的,您必须记住,每个SourceTask和每个SinkTask的逻辑都是 neverending 。如果发生事件,它们应该永不停止,但是而不是不断地在提供的文件中查找新条目。因此,通常通过REST调用停止它们,如果希望它们在事件发生时停止,则将该REST调用放在自己的代码中。)< / p>