我用Apache Kafka挖掘Spring Cloud Stream并观察了一些行为让我想知道我做错了什么或是否按预期工作 - 我几乎不怀疑:
错误消息可能会丢失!?
我的设置尽可能简单。单个Kafka代理和仅包含1个分区的主题。具有默认设置的经纪人,主题,生产者和消费者(auto-ack为真)。
testcase 1
message2
message1
message1
,重试message1
,重试message2
,重试message2
,重试message2
,重试message1
,重试message1
,重试message1
,重试message2
,重试message2
,重试message2
,重试message1
,重试按预期工作。
testcase 2
message2
message1
message1
message1
,重试message1
,重试message2
,重试message3
message3
message1
message3
,因为已提交的偏移量已设置为kafka-topics.sh --create --zookeeper localhost:2181 --replication-factor 1 --partitions 1 --topic test-topic
。这让我很烦恼。只要先前的消息未成功处理,我就不希望消费者继续留言。
有没有人遇到过同样的行为和/或可能会指导我如何改变这种行为?
提前致谢!
更新:根据要求提供了一些代码段
创建主题
kafka-console-producer.sh --broker-list localhost:9092 --topic test-topic
连接制片人
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.7.RELEASE</version>
<relativePath/>
</parent>
...
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Dalston.SR4</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-stream-kafka</artifactId>
</dependency>
</dependencies>
使用
创建maven项目application.yml
添加以下spring:
cloud:
stream:
bindings:
input:
destination: test-topic
contentType: text/plain
group: test-group
consumer:
header-mode: raw
kafka:
binder:
zkNodes: localhost:2181
brokers: localhost:9092
Application.java
添加以下@SpringBootApplication
@EnableBinding(Sink.class)
public class Application {
private static final Logger log = LoggerFactory.getLogger(Application.class);
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
@StreamListener(Sink.INPUT)
private void consume(Message<String> message) {
log.info("Received: {}", message.getPayload());
if ("message1".equals(message.getPayload())
throw new RuntimeException();
log.info("Successfully processed message {}", message.getPayload());
}
}
GregorianCalendar today = new GregorianCalendar ();
那应该是它。运行应用程序并使用console-producer生成消息。
答案 0 :(得分:0)
Kafka为您提供运行时,但您有选择的权力。在某些情况下,msgs可能会丢失/跳过,有些可能不会 - 您需要根据需要准备配置。 IMO你应该进一步调查一些Spring Cloud Stream设置。您也可以使用禁用自动提交和提交偏移量#34;手动&#34;。
答案 1 :(得分:0)
在Kafka中,每封邮件都附带一个偏移ID。您的消费者应用程序可以检查偏移量,以及是否跳过或错过任何偏移量而不是消耗下一条消息。您可以使用 consumer.seek 方法获取缺少的特定消息。
偏移本质上是递增的,也是连续的。
在您的情况下使用手动提交。
我可以说使用以下步骤..
在poll方法之后,首先检查先前提交的偏移量和 并请求下一个偏移值
消息成功使用并处理后,请保存 某些内部成功处理的消息的偏移值 记忆或表格。在下次调查期间
以下链接不会用作您的用例,但您可以获得公平的想法
参考Example
答案 2 :(得分:0)
您应该为这种情况配置DLQ。如果您的消息在3次重试后无法消费,则很可能根本不会消费或者需要特殊处理。 设置有毒消息可能落地的DLQ,并且您不会丢失消息