├── README.md
├── pics
├── atomicInteger
│ ├── result_1.png
│ ├── result_2.png
│ └── result_3.png
├── data-config.png
├── origin.png
├── pessLockInMySQL
│ ├── result_1.png
│ ├── result_2.png
│ └── result_3.png
├── posiLockInMySQL
│ ├── result_1.png
│ ├── result_2.png
│ └── result_3.png
└── posiLockInRedis
│ ├── result_1.png
│ ├── result_2.png
│ └── result_3.png
├── pom.xml
└── src
├── main
├── java
│ └── com
│ │ └── lc
│ │ └── seckill
│ │ ├── SecKillApp.java
│ │ ├── cache
│ │ ├── RedisCacheHandle.java
│ │ └── RedisLoaderListener.java
│ │ ├── common
│ │ ├── GlobalExceptionHandler.java
│ │ ├── Head.java
│ │ ├── Message.java
│ │ └── SecKillEnum.java
│ │ ├── concurrent
│ │ └── AtomicStock.java
│ │ ├── config
│ │ ├── MyBatisConfig.java
│ │ ├── RabbitmqCallBackConfig.java
│ │ └── RedisCacheConfig.java
│ │ ├── constant
│ │ ├── RabbitMQPropertyConst.java
│ │ ├── RedisCacheConst.java
│ │ └── SecKillStateConst.java
│ │ ├── controller
│ │ └── SecKillController.java
│ │ ├── entity
│ │ ├── DataObject.java
│ │ ├── Product.java
│ │ ├── Record.java
│ │ └── User.java
│ │ ├── exception
│ │ └── SecKillException.java
│ │ ├── mapper
│ │ └── SecKillMapper.java
│ │ ├── mq
│ │ ├── RabbitMQReceiver.java
│ │ └── RabbitMQSender.java
│ │ ├── service
│ │ └── SecKillService.java
│ │ ├── utils
│ │ └── SecKillUtils.java
│ │ └── web
│ │ ├── req
│ │ └── SecKillRequest.java
│ │ └── vo
│ │ └── SecKillResponse.java
└── resources
│ ├── application.properties
│ └── dao
│ └── SecKillMapper.xml
└── test
└── java
└── JUnitTest.java
/README.md:
--------------------------------------------------------------------------------
1 | # SeckillSystem
2 | Java 秒杀设计方案
3 |
4 | ## 具体内容
5 | 对高并发高负载情形下的应用场景进行分析,以高效地处理资源竞争为目的,设计一个秒杀与抢购模型。 本项目提供了四种解决方案来比较系统的性能:
6 | 1.利用MySQL的update行锁实现悲观锁。
7 | 2.MySQL加字段version实现乐观锁。
8 | 3.使用Redis作为原子计数器(watch事务+decr操作),RabbitMQ作为消息队列记录用户抢购行为,MySQL做异步存储。
9 | 4.基于AtomicInteger的CAS机制
10 |
11 | ## 压测图片
12 | 
13 | 
14 | ***
15 |
16 | ## 实验结果
17 | ### MySQL悲观锁
18 | 
19 | 
20 | 
21 | ***
22 |
23 | ### MySQL乐观锁
24 | 
25 | 
26 | 
27 | ***
28 | ### AtomicInteger实现CAS
29 | 
30 | 
31 | 
32 | ***
33 | ### Redis的watch监控
34 | 
35 | 
36 | 
37 | ***
38 |
--------------------------------------------------------------------------------
/pics/atomicInteger/result_1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GoldenLiang/SeckillSystem/3d5ca490d30ef1732af2124bae3d213ec7ad2275/pics/atomicInteger/result_1.png
--------------------------------------------------------------------------------
/pics/atomicInteger/result_2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GoldenLiang/SeckillSystem/3d5ca490d30ef1732af2124bae3d213ec7ad2275/pics/atomicInteger/result_2.png
--------------------------------------------------------------------------------
/pics/atomicInteger/result_3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GoldenLiang/SeckillSystem/3d5ca490d30ef1732af2124bae3d213ec7ad2275/pics/atomicInteger/result_3.png
--------------------------------------------------------------------------------
/pics/data-config.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GoldenLiang/SeckillSystem/3d5ca490d30ef1732af2124bae3d213ec7ad2275/pics/data-config.png
--------------------------------------------------------------------------------
/pics/origin.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GoldenLiang/SeckillSystem/3d5ca490d30ef1732af2124bae3d213ec7ad2275/pics/origin.png
--------------------------------------------------------------------------------
/pics/pessLockInMySQL/result_1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GoldenLiang/SeckillSystem/3d5ca490d30ef1732af2124bae3d213ec7ad2275/pics/pessLockInMySQL/result_1.png
--------------------------------------------------------------------------------
/pics/pessLockInMySQL/result_2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GoldenLiang/SeckillSystem/3d5ca490d30ef1732af2124bae3d213ec7ad2275/pics/pessLockInMySQL/result_2.png
--------------------------------------------------------------------------------
/pics/pessLockInMySQL/result_3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GoldenLiang/SeckillSystem/3d5ca490d30ef1732af2124bae3d213ec7ad2275/pics/pessLockInMySQL/result_3.png
--------------------------------------------------------------------------------
/pics/posiLockInMySQL/result_1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GoldenLiang/SeckillSystem/3d5ca490d30ef1732af2124bae3d213ec7ad2275/pics/posiLockInMySQL/result_1.png
--------------------------------------------------------------------------------
/pics/posiLockInMySQL/result_2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GoldenLiang/SeckillSystem/3d5ca490d30ef1732af2124bae3d213ec7ad2275/pics/posiLockInMySQL/result_2.png
--------------------------------------------------------------------------------
/pics/posiLockInMySQL/result_3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GoldenLiang/SeckillSystem/3d5ca490d30ef1732af2124bae3d213ec7ad2275/pics/posiLockInMySQL/result_3.png
--------------------------------------------------------------------------------
/pics/posiLockInRedis/result_1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GoldenLiang/SeckillSystem/3d5ca490d30ef1732af2124bae3d213ec7ad2275/pics/posiLockInRedis/result_1.png
--------------------------------------------------------------------------------
/pics/posiLockInRedis/result_2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GoldenLiang/SeckillSystem/3d5ca490d30ef1732af2124bae3d213ec7ad2275/pics/posiLockInRedis/result_2.png
--------------------------------------------------------------------------------
/pics/posiLockInRedis/result_3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GoldenLiang/SeckillSystem/3d5ca490d30ef1732af2124bae3d213ec7ad2275/pics/posiLockInRedis/result_3.png
--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 4.0.0
6 |
7 | groupId
8 | SecKillSystem
9 | 1.0-SNAPSHOT
10 |
11 |
12 | org.springframework.boot
13 | spring-boot-starter-parent
14 | 1.4.1.RELEASE
15 |
16 |
17 |
18 |
19 | com.alibaba
20 | fastjson
21 | 1.2.31
22 |
23 |
24 |
25 | org.springframework.boot
26 | spring-boot-starter-redis
27 |
28 |
29 |
30 | org.springframework.boot
31 | spring-boot-starter-web
32 |
33 |
34 |
35 | org.springframework.boot
36 | spring-boot-starter-test
37 |
38 |
39 |
40 | junit
41 | junit
42 | 4.12
43 |
44 |
45 |
46 | org.projectlombok
47 | lombok
48 | 1.16.6
49 |
50 |
51 |
52 | org.slf4j
53 | slf4j-api
54 | 1.7.21
55 |
56 |
57 |
58 | com.alibaba
59 | druid
60 | 1.0.18
61 |
62 |
63 |
64 | mysql
65 | mysql-connector-java
66 | 5.1.39
67 |
68 |
69 |
70 | org.mybatis.spring.boot
71 | mybatis-spring-boot-starter
72 | 1.1.1
73 |
74 |
75 |
76 | commons-beanutils
77 | commons-beanutils
78 | 1.9.2
79 |
80 |
81 |
82 | com.rabbitmq
83 | amqp-client
84 | 3.6.4
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 | src/main/java
93 |
94 | **/*.properties
95 | **/*.xml
96 |
97 | false
98 |
99 |
100 |
101 |
102 | org.apache.maven.plugins
103 | maven-compiler-plugin
104 |
105 | 1.7
106 | 1.7
107 |
108 |
109 |
110 |
111 |
112 |
--------------------------------------------------------------------------------
/src/main/java/com/lc/seckill/SecKillApp.java:
--------------------------------------------------------------------------------
1 | package com.lc.seckill;
2 |
3 | import org.mybatis.spring.annotation.MapperScan;
4 | import org.springframework.boot.SpringApplication;
5 | import org.springframework.boot.autoconfigure.SpringBootApplication;
6 |
7 | @SpringBootApplication
8 | @MapperScan("")
9 | public class SecKillApp {
10 | public static void main(String[] args) {
11 | SpringApplication.run(SecKillApp.class,args);
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/src/main/java/com/lc/seckill/cache/RedisCacheHandle.java:
--------------------------------------------------------------------------------
1 | package com.lc.seckill.cache;
2 |
3 | import org.springframework.beans.factory.annotation.Autowired;
4 | import org.springframework.stereotype.Component;
5 | import redis.clients.jedis.Jedis;
6 | import redis.clients.jedis.JedisPool;
7 |
8 | @Component
9 | public class RedisCacheHandle {
10 |
11 | @Autowired
12 | private JedisPool jedisPool;
13 |
14 | public Jedis getJedis(){
15 | return jedisPool.getResource();
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/src/main/java/com/lc/seckill/cache/RedisLoaderListener.java:
--------------------------------------------------------------------------------
1 | package com.lc.seckill.cache;
2 |
3 | import com.alibaba.fastjson.JSON;
4 | import com.alibaba.fastjson.TypeReference;
5 | import com.lc.seckill.constant.RedisCacheConst;
6 | import com.lc.seckill.entity.Product;
7 | import com.lc.seckill.entity.User;
8 | import com.lc.seckill.mapper.SecKillMapper;
9 | import lombok.extern.slf4j.Slf4j;
10 | import org.springframework.beans.factory.annotation.Autowired;
11 | import org.springframework.stereotype.Component;
12 | import redis.clients.jedis.Jedis;
13 |
14 | import javax.annotation.PostConstruct;
15 | import java.util.List;
16 | import java.util.Map;
17 |
18 | @Slf4j
19 | @Component
20 | public class RedisLoaderListener {
21 |
22 | @Autowired
23 | private RedisCacheHandle redisCacheHandle;
24 |
25 | @Autowired
26 | private SecKillMapper secKillMapper;
27 |
28 | @PostConstruct
29 | public void initRedis(){
30 | Jedis jedis = redisCacheHandle.getJedis();
31 | List productList = secKillMapper.getAllProduct();
32 | for (Product product:productList) {
33 | Map map = JSON.parseObject(JSON.toJSONString(product), new TypeReference