Redis+RabbitMQは秒殺高同時を解決し、非同期処理を実現
18954 ワード
構想
商品秒殺は典型的な高同時シーンであり、性能を向上するために、データベースへのアクセス回数を減らすことでデータをredisにロードすることができ、redisで商品の在庫を減らすことができ、スレッドセキュリティの問題が存在せず、redisで商品が減少することに成功した後、消息をrabbitMQにプッシュすることができ、非同期でデータベースに同期し、データベースが自分の処理能力に従ってrabbitmqにメッセージを取りに行くことができる.
プロジェクトアーキテクチャ
消費者側はキューを傍受し、メッセージを受信する(ここではメッセージ同期データベースを取得する)
生産者がメッセージを送信
商品秒殺は典型的な高同時シーンであり、性能を向上するために、データベースへのアクセス回数を減らすことでデータをredisにロードすることができ、redisで商品の在庫を減らすことができ、スレッドセキュリティの問題が存在せず、redisで商品が減少することに成功した後、消息をrabbitMQにプッシュすることができ、非同期でデータベースに同期し、データベースが自分の処理能力に従ってrabbitmqにメッセージを取りに行くことができる.
プロジェクトアーキテクチャ
<parent>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-parentartifactId>
<version>2.0.5.RELEASEversion>
<relativePath/>
parent>
<properties>
<project.build.sourceEncoding>UTF-8project.build.sourceEncoding>
<maven.compiler.source>1.8maven.compiler.source>
<maven.compiler.target>1.8maven.compiler.target>
properties>
<dependencies>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-webartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-data-redisartifactId>
dependency>
<dependency>
<groupId>com.alibabagroupId>
<artifactId>druidartifactId>
<version>1.1.1version>
dependency>
<dependency>
<groupId>com.baomidougroupId>
<artifactId>mybatis-plus-boot-starterartifactId>
<version>2.2.0version>
dependency>
<dependency>
<groupId>mysqlgroupId>
<artifactId>mysql-connector-javaartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-amqpartifactId>
dependency>
dependencies>
RabbitMQ ,
@Configuration
public class RabbitmqConfig {
public static final String SPIKE_QUEUE = "SPIKE_QUEUE";
public static final String EXCHANGE_NAME = "SPIKE_EXCHANGE";
/**
*
* ExchangeBuilder fanout、direct、topic、header
*
* @return the exchange
*/
@Bean
public Exchange EXCHANGE_DIRECT() {
//durable(true) ,
return ExchangeBuilder.directExchange(EXCHANGE_NAME).durable(false).build();
}
//
@Bean
public Queue QUEUE_INFORM_SMS() {
Queue queue = new Queue(SPIKE_QUEUE);
return queue;
}
// @Value("${spring.rabbitmq.customizeRoutingKey=spike}")
private String routingKey="spike";
/**
* channel.queueBind(INFORM_QUEUE_SMS,"inform_exchange_topic","inform.#.sms.#");
* .
*
*/
@Bean
public Binding BINDING_QUEUE_INFORM_SMS( ) {
return BindingBuilder.bind(QUEUE_INFORM_SMS()).to(EXCHANGE_DIRECT()).with(routingKey).noargs();
}
}
消費者側はキューを傍受し、メッセージを受信する(ここではメッセージ同期データベースを取得する)
@Component
public class SpikeHandler {
@Autowired
private IPhoneService phoneService;
@RabbitListener(queues = {RabbitmqConfig.SPIKE_QUEUE})
public void synchronizeDB(String message, Message message1, Channel channel) throws IOException {
System.out.println(" " + message);
if (message == null || StringUtils.isEmpty(message)) {
throw new RuntimeException(" ");
}
phoneService.update();
//
long deliveryTag = message1.getMessageProperties().getDeliveryTag();
channel.basicAck(deliveryTag,true);
}
}
生産者がメッセージを送信
rabbitTemplate.convertAndSend(RabbitmqConfig.EXCHANGE_NAME, "spike", " ");