rabbitMQ+redis+SpringBoot模擬高併發秒殺(源碼)!!!

效果展示:

模擬併發1000個請求秒殺10個商品

數據庫表信息:

商品數初始值爲10

使用壓測工具Jmeter模擬高併發

併發1000個請求

 

模擬手機號,從15100000000遞增

接口地址,參數設置

開始秒殺-----------------------

商品數量已經爲0

記錄表裏已成功記錄秒殺成功的手機號

源碼下載:

鏈接:https://pan.baidu.com/s/1wAGmTchLloVwGrkJUASRnA 提取碼:ya20  

鏈接:https://pan.baidu.com/s/1wAGmTchLloVwGrkJUASRnA 
提取碼:ya20 

源碼說明:

配置文件內容需改成自己環境的連接信息

 

 

需新建數據庫

表sql:

CREATE TABLE `goods` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(50) DEFAULT NULL COMMENT '商品名稱',
  `count` tinyint(11) NOT NULL DEFAULT '0' COMMENT ' 商品數量 ',
  PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4;
CREATE TABLE `record` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `mobile` varchar(20) DEFAULT NULL COMMENT '手機號',
  `time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '秒殺成功時間',
  PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=26 DEFAULT CHARSET=utf8mb4;

 核心代碼:

 

<?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>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.3.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.todd</groupId>
    <artifactId>demo</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>demo</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>1.8</java.version>
    </properties>

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

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


        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>

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

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>

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

    </dependencies>

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

</project>

application.yml

server:
  port: 8060
spring:
  rabbitmq:
    host: 192.168.159.128
    port: 5672
    username: guest
    password: guest



  datasource:
    url: jdbc:mysql://192.168.159.128:3306/mq?useUnicode=true&characterEncoding=UTF-8&useSSL=false
    username: root
    password: 123456
    platform: org.hibernate.dialect.MySQL5InnoDBDialect

  jpa:
    show-sql: true
    database: mysql
    hibernate:
      ddl-auto: update
  redis:
    host: 192.168.159.128

 

package com.todd.demo.rest;

import com.todd.demo.repository.GoodsDao;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class SeckillRest {


    @Autowired
    private GoodsDao goodsDao;

    @Autowired
    private RabbitTemplate rabbitTemplate;

    @Autowired
    private StringRedisTemplate redisTemplate;

    @RequestMapping(value = "/seckill")
    public String seckill(String mobile) {
        //處理同一手機號重複請求
        if (redisTemplate.hasKey("seckill:" + mobile)) {

            return "已搶到!請勿重複提交!";
        }
        //從redis緩存中判斷活動是否結束
        if (redisTemplate.hasKey("seckill:end")) {

            return "活動已結束!";
        }
        //向隊列中發送消息
        rabbitTemplate.convertAndSend("mobile-queue", mobile);
        //等待MQ處理消息
        try {
            Thread.sleep(500);
        } catch (InterruptedException e) {
            e.printStackTrace();
            return "系統繁忙!";
        }

        //查看是否秒殺成功
        if (redisTemplate.hasKey("seckill:" + mobile)) {

            return "已搶到!";
        }

        //查看活動是否結束
        if (redisTemplate.hasKey("seckill:end")) {

            return "沒搶到!";
        }

        //MQ未處理完消息
        return "系統繁忙!";

    }


}
package com.todd.demo.receive;

import com.todd.demo.entity.GoodsEntity;
import com.todd.demo.entity.RecordEntity;
import com.todd.demo.repository.GoodsDao;
import com.todd.demo.repository.RecordDao;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;

import java.sql.Timestamp;

@Component
public class MQReceive {

    @Autowired
    private GoodsDao goodsDao;

    @Autowired
    private RecordDao recordDao;

    @Autowired
    private StringRedisTemplate redisTemplate;

    /**
     * 處理隊列中的消息
     *
     * @param message
     */
    @RabbitListener(queues = "mobile-queue")
    public void receiveSeckillMessage(String message) {
        //查看活動是否已結束
        if (redisTemplate.hasKey("seckill:end")) {

            return;
        }

        GoodsEntity goodsEntity = goodsDao.findByName("xs");
        //查看商品庫存數量
        Integer count = goodsEntity.getCount();
        if (count > 0) {

            RecordEntity recordEntity = new RecordEntity();

            recordEntity.setMobile(message);

            recordEntity.setTime(new Timestamp(System.currentTimeMillis()));

            recordDao.saveAndFlush(recordEntity);
            count--;
            goodsEntity.setCount(count);

            goodsDao.saveAndFlush(goodsEntity);
            //將秒殺成功的手機號寫入redis緩存
            redisTemplate.opsForValue().set("seckill:" + message, "");

            System.out.println("MQReceive-->OK-->" + message);
        } else {
            //向redis寫入活動結束標識
            redisTemplate.opsForValue().set("seckill:end", "");
        }
    }

}

運行 

package com.todd.demo;

import org.springframework.amqp.core.Queue;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;

@SpringBootApplication
public class DemoApplication {

    @Bean
    public Queue mobileQueue() {

        return new Queue("mobile-queue");
    }

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

}

 

相關資料:

https://blog.csdn.net/MadCode2222222222222/article/details/90479293 

源碼下載:

鏈接:https://pan.baidu.com/s/1wAGmTchLloVwGrkJUASRnA 
提取碼:ya20 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章