gpt4 book ai didi

java - 在 RabbitMQ 中组接收消息,最好使用 Spring AMQP?

转载 作者:塔克拉玛干 更新时间:2023-11-02 08:03:55 25 4
gpt4 key购买 nike

我从服务 (S) 接收消息,该服务将每个单独的属性更改作为单独的消息发布到实体。一个人为的例子是这样的实体:

Person {
id: 123
name: "Something",
address: {...}
}

如果姓名和地址在同一笔交易中更新,则 (S) 将发布两条消息,PersonNameCorrectedPersonMoved。问题出在接收端,我正在存储此 Person 实体的投影,并且每个属性更改都会导致写入数据库。因此,在此示例中,将有两次写入数据库,但如果我可以在短时间内对消息进行批处理并按 id 对它们进行分组,那么我只需要对数据库进行一次写入。

通常如何在 RabbitMQ 中处理这个问题? Spring AMQP 是否提供更简单的抽象?

请注意,我已经简要地查看了 prefetch但我不确定这是不是要走的路。如果我理解正确的话,预取也是每个连接的基础。我试图在每个队列的基础上实现这一点,因为如果批处理(并因此增加延迟)是可行的方法,我不想将这种延迟添加到我使用的所有队列中服务(但仅适用于那些需要“按 ID 分组”功能的用户)。

最佳答案

对于这种情况,预取无济于事。

考虑使用 Spring Integration它有位于 Spring AMQP 之上的适配器;它还提供了一个聚合器,可用于在将消息发送到管道的下一阶段之前将消息分组在一起。

编辑

这里有一个快速启动应用程序来演示......

@SpringBootApplication
public class So42969130Application implements CommandLineRunner {

public static void main(String[] args) {
SpringApplication.run(So42969130Application.class, args)
.close();
}

@Autowired
private RabbitTemplate template;

@Autowired
private Handler handler;

@Override
public void run(String... args) throws Exception {
this.template.convertAndSend("so9130", new PersonNameChanged(123));
this.template.convertAndSend("so9130", new PersonMoved(123));
this.handler.latch.await(10, TimeUnit.SECONDS);
}

@Bean
public IntegrationFlow flow(ConnectionFactory connectionFactory) {
return IntegrationFlows.from(Amqp.inboundAdapter(connectionFactory, "so9130")
.messageConverter(converter()))
.aggregate(a -> a
.correlationExpression("payload.id")
.releaseExpression("false") // open-ended release, timeout only
.sendPartialResultOnExpiry(true)
.groupTimeout(2000))
.handle(handler())
.get();
}

@Bean
public Jackson2JsonMessageConverter converter() {
return new Jackson2JsonMessageConverter();
}

@Bean
public Handler handler() {
return new Handler();
}

@Bean
public Queue queue() {
return new Queue("so9130", false, false, true);
}

public static class Handler {

private final CountDownLatch latch = new CountDownLatch(1);

@ServiceActivator
public void handle(Collection<?> aggregatedData) {
System.out.println(aggregatedData);
this.latch.countDown();
}

}

public static class PersonNameChanged {

private int id;

PersonNameChanged() {
}

PersonNameChanged(int id) {
this.id = id;
}

public int getId() {
return this.id;
}

public void setId(int id) {
this.id = id;
}

@Override
public String toString() {
return "PersonNameChanged [id=" + this.id + "]";
}

}

public static class PersonMoved {

private int id;

PersonMoved() {
}

PersonMoved(int id) {
this.id = id;
}

public int getId() {
return this.id;
}

public void setId(int id) {
this.id = id;
}

@Override
public String toString() {
return "PersonMoved [id=" + this.id + "]";
}

}

}

代码:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>com.example</groupId>
<artifactId>so42969130</artifactId>
<version>2.0.0-BUILD-SNAPSHOT</version>
<packaging>jar</packaging>

<name>so42969130</name>
<description>Demo project for Spring Boot</description>

<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.2.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>

<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-integration</artifactId>
</dependency>

<dependency>
<groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-amqp</artifactId>
</dependency>

<dependency>
<groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-java-dsl</artifactId>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>

<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>


</project>

结果:

2017-03-23 09:56:57.501  INFO 75217 --- [ask-scheduler-2] .s.i.a.AbstractCorrelatingMessageHandler : 
Expiring MessageGroup with correlationKey[123]
[PersonNameChanged [id=123], PersonMoved [id=123]]

关于java - 在 RabbitMQ 中组接收消息,最好使用 Spring AMQP?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42969130/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com