SpringCloud 使用轮询的使用者

2023-11-26 16:09 更新

总览

使用轮询的使用者时,您可以按需轮询PollableMessageSource考虑以下受调查消费者的示例:

public interface PolledConsumer {

    @Input
    PollableMessageSource destIn();

    @Output
    MessageChannel destOut();

}

给定上一个示例中的受调查消费者,您可以按以下方式使用它:

@Bean
public ApplicationRunner poller(PollableMessageSource destIn, MessageChannel destOut) {
    return args -> {
        while (someCondition()) {
            try {
                if (!destIn.poll(m -> {
                    String newPayload = ((String) m.getPayload()).toUpperCase();
                    destOut.send(new GenericMessage<>(newPayload));
                })) {
                    Thread.sleep(1000);
                }
            }
            catch (Exception e) {
                // handle failure
            }
        }
    };
}

PollableMessageSource.poll()方法采用一个MessageHandler参数(通常为lambda表达式,如此处所示)。如果收到并成功处理了消息,它将返回true

与消息驱动的使用者一样,如果MessageHandler引发异常,消息将发布到错误通道,如???”中所述。

通常,poll()方法会在MessageHandler退出时确认该消息。如果该方法异常退出,则该消息将被拒绝(不重新排队),但请参阅“处理错误”一节您可以通过对确认负责来覆盖该行为,如以下示例所示:

@Bean
public ApplicationRunner poller(PollableMessageSource dest1In, MessageChannel dest2Out) {
    return args -> {
        while (someCondition()) {
            if (!dest1In.poll(m -> {
                StaticMessageHeaderAccessor.getAcknowledgmentCallback(m).noAutoAck();
                // e.g. hand off to another thread which can perform the ack
                // or acknowledge(Status.REQUEUE)

            })) {
                Thread.sleep(1000);
            }
        }
    };
}
您必须在某一时刻ack(或nack)消息,以避免资源泄漏。
某些消息传递系统(例如Apache Kafka)在日志中维护简单的偏移量。如果传递失败,并用StaticMessageHeaderAccessor.getAcknowledgmentCallback(m).acknowledge(Status.REQUEUE);重新排队,则重新传递任何以后成功确认的消息。

还有一个重载的poll方法,其定义如下:

poll(MessageHandler handler, ParameterizedTypeReference<?> type)

type是一个转换提示,它允许转换传入的消息有效负载,如以下示例所示:

boolean result = pollableSource.poll(received -> {
			Map<String, Foo> payload = (Map<String, Foo>) received.getPayload();
            ...

		}, new ParameterizedTypeReference<Map<String, Foo>>() {});

处理错误

默认情况下,为可轮询源配置了一个错误通道。如果回调引发异常,则将ErrorMessage发送到错误通道(<destination>.<group>.errors);此错误通道也桥接到全局Spring Integration errorChannel

您可以使用@ServiceActivator订阅任何一个错误通道来处理错误。如果没有订阅,则将仅记录错误并确认消息成功。如果错误通道服务激活器引发异常,则该消息将被拒绝(默认情况下),并且不会重新发送。如果服务激活器抛出RequeueCurrentMessageException,则该消息将在代理处重新排队,并在随后的轮询中再次检索。

如果侦听器直接抛出RequeueCurrentMessageException,则如上所述,该消息将重新排队,并且不会发送到错误通道。

以上内容是否对您有帮助:
在线笔记
App下载
App下载

扫描二维码

下载编程狮App

公众号
微信公众号

编程狮公众号