我正在使用Spring Cloud Stream(Edgware.SR5)和Spring Boot(1.5.10.RELEASE)。我的@StreamListener正在处理收到的每条消息两次。
该示例的思想是在队列中发布消息并对其进行处理。
服务:
@EnableBinding(ExampleBindings.class)
@Service
public class ExampleService {
@Publisher(channel = ExampleBindings.OUTPUT)
public String queue(String message){
return message;
}
@StreamListener(ExampleBindings.INPUT)
public void dequeue(String message){
System.out.println("New message: " + message);
}
}
绑定:
public interface ExampleBindings {
String INPUT = "input1";
String OUTPUT = "output1";
@Input(ExampleBindings.INPUT)
SubscribableChannel input();
@Output(ExampleBindings.OUTPUT)
MessageChannel output();
}
application.properties:
spring.cloud.stream.default.group=group1
spring.cloud.stream.default.binder=binder1
spring.cloud.stream.bindings.input1.destination=dest_1
spring.cloud.stream.bindings.output1.destination=dest_1
spring.cloud.stream.binders.binder1.type=rabbit
spring.cloud.stream.binders.binder1.environment.spring.rabbitmq.host=localhost
配置(用于在测试中注入代理服务):
@Configuration
public class ExampleConfig {
@Bean
public PublisherAnnotationBeanPostProcessor publisherAnnotationBeanPostProcessor(){
PublisherAnnotationBeanPostProcessor publisherAnnotationBeanPostProcessor =
new PublisherAnnotationBeanPostProcessor();
publisherAnnotationBeanPostProcessor.setProxyTargetClass(true);
return publisherAnnotationBeanPostProcessor;
}
}
测试:
@RunWith(SpringRunner.class)
@SpringBootTest
public class ExampleServiceTest {
@Autowired
private ExampleService exampleService;
@Test
public void testQueue() throws InterruptedException {
exampleService.queue("Hello!");
Thread.sleep(1000);//Wait for message processing
System.out.println("Ready!");
}
}
我得到了以下输出:
17:19:10.230 [dest1.group1-2] DEBUG o.s.c.s.b.StreamListenerMessageHandler - org.springframework.cloud.stream.binding.StreamListenerMessageHandler@575c3e9b received message: GenericMessage [payload=Hello!, headers={amqp_receivedDeliveryMode=PERSISTENT, amqp_receivedRoutingKey=dest1, amqp_receivedExchange=dest1, amqp_deliveryTag=1, amqp_consumerQueue=dest1.group1, amqp_redelivered=false, id=2f22ce16-bb5a-350c-8b3d-e6c898760888, amqp_consumerTag=amq.ctag-sxu6zQHJTGrsazfwbmol9Q, contentType=text/plain, timestamp=1547583550230}]
New message: Hello!
17:19:10.231 [dest1.group1-1] DEBUG o.s.c.s.b.StreamListenerMessageHandler - handler 'org.springframework.cloud.stream.binding.StreamListenerMessageHandler@575c3e9b' produced no reply for request Message: GenericMessage [payload=Hello!, headers={amqp_receivedDeliveryMode=PERSISTENT, amqp_receivedRoutingKey=dest1, amqp_receivedExchange=dest1, amqp_deliveryTag=1, amqp_consumerQueue=dest1.group1, amqp_redelivered=false, id=788e8bbf-4ae4-86cc-0859-d4f153cb5807, amqp_consumerTag=amq.ctag-fV0aaDzYUZfq08JsODq6pA, contentType=text/plain, timestamp=1547583550230}]
17:19:10.231 [dest1.group1-1] DEBUG o.s.i.channel.DirectChannel - postSend (sent=true) on channel 'input1', message: GenericMessage [payload=Hello!, headers={amqp_receivedDeliveryMode=PERSISTENT, amqp_receivedRoutingKey=dest1, amqp_receivedExchange=dest1, amqp_deliveryTag=1, amqp_consumerQueue=dest1.group1, amqp_redelivered=false, id=788e8bbf-4ae4-86cc-0859-d4f153cb5807, amqp_consumerTag=amq.ctag-fV0aaDzYUZfq08JsODq6pA, contentType=text/plain, timestamp=1547583550230}]
New message: Hello!
17:19:10.232 [dest1.group1-2] DEBUG o.s.c.s.b.StreamListenerMessageHandler - handler 'org.springframework.cloud.stream.binding.StreamListenerMessageHandler@575c3e9b' produced no reply for request Message: GenericMessage [payload=Hello!, headers={amqp_receivedDeliveryMode=PERSISTENT, amqp_receivedRoutingKey=dest1, amqp_receivedExchange=dest1, amqp_deliveryTag=1, amqp_consumerQueue=dest1.group1, amqp_redelivered=false, id=2f22ce16-bb5a-350c-8b3d-e6c898760888, amqp_consumerTag=amq.ctag-sxu6zQHJTGrsazfwbmol9Q, contentType=text/plain, timestamp=1547583550230}]
17:19:10.232 [dest1.group1-2] DEBUG o.s.i.channel.DirectChannel - postSend (sent=true) on channel 'input1', message: GenericMessage [payload=Hello!, headers={amqp_receivedDeliveryMode=PERSISTENT, amqp_receivedRoutingKey=dest1, amqp_receivedExchange=dest1, amqp_deliveryTag=1, amqp_consumerQueue=dest1.group1, amqp_redelivered=false, id=2f22ce16-bb5a-350c-8b3d-e6c898760888, amqp_consumerTag=amq.ctag-sxu6zQHJTGrsazfwbmol9Q, contentType=text/plain, timestamp=1547583550230}]
Ready!
我不知道我的配置有什么问题,或者是否是一些bug,有什么建议吗?
谢谢!
编辑:
我在这里上传了一个(非)工作示例
您可以使用以下命令创建RabbitMQ实例:
docker run -p 5672:5672 -p 15672:15672 rabbitmq:3-management
我在调试模式(intellij)下运行我的应用程序,由于某种原因,偏移量没有得到更新。尝试在运行模式下运行,它解决了我的问题。
我检测到@Publisher正在发布两次,这是因为示例配置中的配置。这个新配置(从这里借用)似乎工作正常:
@Bean
public static BeanFactoryPostProcessor bfpp() {
return bf -> bf.getBean(IntegrationContextUtils.PUBLISHER_ANNOTATION_POSTPROCESSOR_NAME,
PublisherAnnotationBeanPostProcessor.class).setProxyTargetClass(true);
}
从配置来看,我认为,您正试图将相同的消息再次发布到相同的目的地< code>dest_1。
spring.cloud.stream.bindings.input1.destination=dest_1
spring.cloud.stream.bindings.output1.destination=dest_1
从日志中可以清楚地看出,第二条消息具有不同的ID
id=788e8bbf-4ae4-86cc-0859-d4f153cb5807
id=2f22ce16-bb5a-350c-8b3d-e6c898760888
Spring Cloud AWS(1.0.0.rc2)中SimpleMessageListenerContainer类的当前实现似乎会在消息处理程序完成对消息的处理并且方法调用返回之后自动删除消息。 在我们的应用程序中,在从SQS上游队列删除消息之前,我们需要能够处理消息并等待来自下游队列的异步确认。类似于 接收SQS消息->处理消息->将消息发布到RabbitMQ(线程在此完成) 删除SQS消息
我正在寻找一些关于利用Spring Cloud Stream 3 . x/Kafka binder实现的Kafka主题的重放消息策略的指导- > < li> 重播特定消息[例如通过时间戳窗口]。如何为消费者组中的所有或部分消费者重置补偿? 是否可以从主题的特定分区重播[如果我们知道我们有兴趣重放的消息的分区]? 一般来说,关于消息回放的最佳实践是什么。感谢您抽出时间。
流处理和传统消息处理的基本区别是什么?正如人们所说,kafka是流处理的好选择,但本质上,kafka是一个类似于ActivMQ、RabbitMQ等的消息传递框架。 为什么我们通常不说ActiveMQ也适合流处理呢。 消费者消费消息的速度是否决定了它是否是流?
我正试图按照GitHub的建议设置测试 其中StreamProcessor设置为 -->line从不使用在我看来应该在主题“output”上的消息,因为@StreamProcessor有@Sendto(“output”) 我希望能够测试流处理的消息。
Spring Cloud Kafka Streams与Spring Cloud Stream、Spring Cloud Function、Spring AMQP和Spring for Apache Kafka有什么区别?
我的使用者绑定到匿名使用者组,而不是我指定的使用者组。 我的春靴应用 我的输入输出通道接口 我的控制台日志-- :在3.233秒内启动ConsumerApplication(JVM运行于4.004):[使用者Clientid=Consumer-3,Groupid=Anonymous.0D0C87D6-EF39-4BFE-B475-4491C40CAF6D]发现组协调器Singh:9092(ID:2