Spring Cloud Stream消费失败后的处理策略(四):使用DLQ队列(Kafka版)

Spring Cloud Stream消费失败后的处理策略(四):使用DLQ队列(Kafka版)

之前写了一个一个DLQ的rabbit版本,接下来说一下kafka版本的。因为kafka的管理监控界面没有那么详细(我太菜,没找到)。

动手试一下:

准备一个会消费失败的例子,可以直接沿用前文的工程。也可以新建一个,然后创建如下代码的逻辑:

public class TestController {
    @Autowired
    private TestTopic testTopic;
    @RequestMapping("entity")
    public void TestEntity(@RequestParam String message){
        Message message1 = new Message("1", message, new Date()); testTopic.output1().send(MessageBuilder.withPayload(message1).build());
    }
}

@Data
@NoArgsConstructor
@AllArgsConstructor
public class Message implements Serializable {
    String id;
    String msg;
    Date date;
}

public interface TestTopic {
    String OUTPUT1 = "example-topic-output1";
    String INPUT1 = "example-topic-input1";
    String ERRORINPUT = "errorChannelInput";
    String ERROROUTPUT = "errorChannelOutput";

    @Output(OUTPUT1)
    MessageChannel output1();

    @Input(INPUT1)
    SubscribableChannel input1();

    @Input(ERRORINPUT)
    SubscribableChannel errorInput();

    @Output(ERROROUTPUT)
    MessageChannel errorOutput();
}

@Slf4j
@Component
@EnableBinding(TestTopic.class)
public class TestListener {
    @StreamListener(TestTopic.INPUT1)
    public void receiveEntity(Message message) {
        log.info("Received payload : {}", message);
        throw new RuntimeException("Message consumer failed!");
    }
}

消息消费的时候主动抛出了一个异常来模拟消息的消费失败。

在启动应用之前,还要记得配置一下输入输出通道对应的物理目标(topic名)、并设置一下分组,比如:

# 为消费者设置组,防止重复消费
spring.cloud.stream.bindings.example-topic-input1.group=Service-A
spring.cloud.stream.bindings.errorChannel.group=Service-A
# 为example-topic-input通道绑定topic
spring.cloud.stream.bindings.example-topic-input1.destination=greeting1
spring.cloud.stream.bindings.errorChannelInput.destination=errorTopic
# example-topic-input通道发送消息失败时的重试次数
spring.cloud.stream.bindings.example-topic-input1.consumer.max-attempts=1
# 输出example-topic-output通道绑定的topic
spring.cloud.stream.bindings.example-topic-output1.destination=greeting1
spring.cloud.stream.bindings.errorChannelOutput.destination=errorTopic
# kafka服务器地址
spring.cloud.stream.kafka.binder.brokers=ip:port
server.port=8080
# 是否绑定死信队列,会立即转发至死信队列,若失败则会发送3次
spring.cloud.stream.kafka.bindings.example-topic-input1.consumer.enable-dlq=true
spring.cloud.stream.kafka.bindings.example-topic-input1.consumer.dlq-name=errorTopic

这里加入了两个重要配置

spring.cloud.stream.kafka.bindings.example-topic-input1.consumer.enable-dlq=true

spring.cloud.stream.kafka.bindings.example-topic-input1.consumer.dlq-name=errorTopic

用来开启DLQ(死信队列)并指明死信队列名。完成了上面配置之后,启动应用并访问`localhost:8080/entity?message=aaa

最后打印日志:

2019-09-18 16:37:13.129  INFO 9184 --- [container-0-C-1] c.c.f.stream.listener.TestListener       : Received payload : Message(id=1, msg=aaaAASAsa, date=Wed Sep 18 16:37:13 CST 2019)

org.springframework.messaging.MessagingException: Exception thrown while invoking com.chinatower.framework.stream.listener.TestListener#receiveEntity[1 args]; nested exception is java.lang.RuntimeException: Message consumer failed!
	at org.springframework.cloud.stream.binding.StreamListenerMessageHandler.handleRequestMessage(StreamListenerMessageHandler.java:63) ~[spring-cloud-stream-2.0.1.RELEASE.jar:2.0.1.RELEASE]

Caused by: java.lang.RuntimeException: Message consumer failed!
	at com.chinatower.framework.stream.listener.TestListener.receiveEntity(TestListener.java:26) ~[classes/:na]


2019-09-18 16:37:13.131 ERROR 9184 --- [container-0-C-1] o.s.integration.handler.LoggingHandler   : org.springframework.messaging.MessagingException: Exception thrown while invoking com.chinatower.framework.stream.listener.TestListener#receiveEntity[1 args]; nested exception is java.lang.RuntimeException: Message consumer failed!, failedMessage=GenericMessage [payload=byte[66], headers={kafka_offset=39, scst_nativeHeadersPresent=true, kafka_consumer=org.apache.kafka.clients.consumer.KafkaConsumer@3a3d1789, kafka_timestampType=CREATE_TIME, kafka_receivedMessageKey=null, kafka_receivedPartitionId=0, contentType=application/json, kafka_receivedTopic=greeting1, kafka_receivedTimestamp=1568795833086}]
	at org.springframework.cloud.stream.binding.StreamListenerMessageHandler.handleRequestMessage(StreamListenerMessageHandler.java:63)

Caused by: java.lang.RuntimeException: Message consumer failed!
	at com.chinatower.framework.stream.listener.TestListener.receiveEntity(TestListener.java:26)


2019-09-18 16:37:13.173  INFO 9184 --- [container-0-C-1] c.c.f.stream.listener.TestListener       : errorReceive payload : {"id":"1","msg":"aaaAASAsa","date":"2019-09-18T08:37:13.084+0000"}

如此一来,就可以做到自己接受死信队列里的消息,做预防措施。

Spring Cloud Stream 是一个用于构建消息驱动微服务的框架,对于配置文件的要求如下: 1. 配置消息中间件的连接信息,如 RabbitMQ、Kafka 等。可通过 `spring.cloud.stream.bindings.<channelName>.destination` 属性指定消息目标地址。 2. 配置消息通道的输入输出信息。可通过 `spring.cloud.stream.bindings.<channelName>.xxxx` 属性指定消息通道的相关参数,如 content-type、group、destination、producer、consumer 等。 3. 配置应用程序的消费者和生产者信息。可通过 `spring.cloud.stream.<functionName>.xxxx` 属性指定应用程序的相关参数,如定义消息处理器的 Bean、消息处理器的函数名、消息的序列化方式、自定义的消息转换器等。 4. 配置消息的序列化方式。可通过 `spring.cloud.stream.bindings.<channelName>.contentType` 属性指定消息的序列化方式,如 JSON、XML、Protobuf 等。 5. 配置消息的路由信息。可通过 `spring.cloud.stream.bindings.<channelName>.destination` 属性指定消息的路由信息,如路由键、主题等。 6. 配置消息的消费组信息。可通过 `spring.cloud.stream.bindings.<channelName>.group` 属性指定消息的消费组信息,如消费组名称等。 7. 配置消息的超时时间。可通过 `spring.cloud.stream.bindings.<channelName>.consumer.max-attempts` 属性指定消息的最大重试次数和最大消费次数。 8. 配置消息的错误处理方式。可通过 `spring.cloud.stream.bindings.<channelName>.destination.dlqName` 属性指定消息的 DLQ(Dead Letter Queue)信息,如 DLQ 名称、是否启用 DLQ 等。 以上是 Spring Cloud Stream 的常用配置文件,具体配置可根据实际需求进行调整。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值