mirror of
https://github.com/qiurunze123/miaosha.git
synced 2023-11-19 22:41:03 +08:00
分布式锁的演进与讲解
This commit is contained in:
parent
5a8573ba8e
commit
a07f9a4cba
1073
.idea/workspace.xml
1073
.idea/workspace.xml
File diff suppressed because it is too large
Load Diff
15
README.md
15
README.md
|
@ -135,4 +135,17 @@ redis的数量不是库存,他的作用仅仅只是为了阻挡多余的请求
|
|||
开发(dev)
|
||||
测试(test)
|
||||
线上(prod)
|
||||
在环境部署中为了防止人工修改的弊端! spring.profiles.active=@activatedProperties@
|
||||
在环境部署中为了防止人工修改的弊端! spring.profiles.active=@activatedProperties@
|
||||
|
||||
### redis 分布式锁实现方法
|
||||
|
||||
我用了四种方法 , 分别指出了不同版本的缺陷以及演进的过程 orderclosetask
|
||||
|
||||
v1---->>版本没有操作,在分布式系统中会造成同一时间,资源浪费而且很容易出现并发问题
|
||||
V2--->>版本加了分布式redis锁,在访问核心方法前,加入redis锁可以阻塞其他线程访问,可以
|
||||
很好的处理并发问题,但是缺陷就是如果机器突然宕机,或者线路波动等,就会造成死锁,一直
|
||||
不释放等问题
|
||||
V3版本-->>很好的解决了这个问题v2的问题,就是加入时间对比如果当前时间已经大与释放锁的时间
|
||||
说明已经可以释放这个锁重新在获取锁,setget方法可以把之前的锁去掉在重新获取,旧值在于之前的
|
||||
值比较,如果无变化说明这个期间没有人获取或者操作这个redis锁,则可以重新获取
|
||||
V4---->>采用成熟的框架redisson,封装好的方法则可以直接处理,但是waittime记住要这只为0
|
||||
|
|
23
miaosha.iml
23
miaosha.iml
|
@ -40,7 +40,7 @@
|
|||
<orderEntry type="library" name="Maven: org.slf4j:jul-to-slf4j:1.7.25" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.slf4j:log4j-over-slf4j:1.7.25" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.springframework:spring-core:4.3.12.RELEASE" level="project" />
|
||||
<orderEntry type="library" scope="RUNTIME" name="Maven: org.yaml:snakeyaml:1.17" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.yaml:snakeyaml:1.17" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-tomcat:1.5.8.RELEASE" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.apache.tomcat.embed:tomcat-embed-core:8.5.23" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.apache.tomcat:tomcat-annotations-api:8.5.23" level="project" />
|
||||
|
@ -51,7 +51,6 @@
|
|||
<orderEntry type="library" name="Maven: com.fasterxml:classmate:1.3.4" level="project" />
|
||||
<orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-databind:2.8.10" level="project" />
|
||||
<orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-annotations:2.8.0" level="project" />
|
||||
<orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-core:2.8.10" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.springframework:spring-web:4.3.12.RELEASE" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.springframework:spring-aop:4.3.12.RELEASE" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.springframework:spring-beans:4.3.12.RELEASE" level="project" />
|
||||
|
@ -93,6 +92,26 @@
|
|||
<orderEntry type="library" name="Maven: org.springframework.retry:spring-retry:1.2.1.RELEASE" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.springframework.amqp:spring-amqp:1.7.4.RELEASE" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.springframework:spring-tx:4.3.12.RELEASE" level="project" />
|
||||
<orderEntry type="library" name="Maven: joda-time:joda-time:2.3" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.redisson:redisson:2.14.0" level="project" />
|
||||
<orderEntry type="library" name="Maven: io.netty:netty-common:4.1.30.Final" level="project" />
|
||||
<orderEntry type="library" name="Maven: io.netty:netty-codec:4.1.30.Final" level="project" />
|
||||
<orderEntry type="library" name="Maven: io.netty:netty-buffer:4.1.30.Final" level="project" />
|
||||
<orderEntry type="library" name="Maven: io.netty:netty-transport:4.1.30.Final" level="project" />
|
||||
<orderEntry type="library" name="Maven: io.netty:netty-resolver:4.1.30.Final" level="project" />
|
||||
<orderEntry type="library" name="Maven: io.netty:netty-resolver-dns:4.1.30.Final" level="project" />
|
||||
<orderEntry type="library" name="Maven: io.netty:netty-codec-dns:4.1.30.Final" level="project" />
|
||||
<orderEntry type="library" name="Maven: io.netty:netty-handler:4.1.30.Final" level="project" />
|
||||
<orderEntry type="library" name="Maven: javax.cache:cache-api:1.0.0" level="project" />
|
||||
<orderEntry type="library" name="Maven: io.projectreactor:reactor-stream:2.0.8.RELEASE" level="project" />
|
||||
<orderEntry type="library" name="Maven: io.projectreactor:reactor-core:2.0.8.RELEASE" level="project" />
|
||||
<orderEntry type="library" name="Maven: io.reactivex.rxjava2:rxjava:2.1.13" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.reactivestreams:reactive-streams:1.0.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:2.8.10" level="project" />
|
||||
<orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-core:2.8.10" level="project" />
|
||||
<orderEntry type="library" name="Maven: net.bytebuddy:byte-buddy:1.8.17" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.jodd:jodd-bean:3.7.1" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.jodd:jodd-core:3.7.1" level="project" />
|
||||
<orderEntry type="library" scope="PROVIDED" name="Maven: org.projectlombok:lombok:1.18.2" level="project" />
|
||||
</component>
|
||||
</module>
|
11
pom.xml
11
pom.xml
|
@ -117,6 +117,17 @@
|
|||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-amqp</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>joda-time</groupId>
|
||||
<artifactId>joda-time</artifactId>
|
||||
<version>2.3</version>
|
||||
</dependency>
|
||||
<!-- https://mvnrepository.com/artifact/org.redisson/redisson -->
|
||||
<dependency>
|
||||
<groupId>org.redisson</groupId>
|
||||
<artifactId>redisson</artifactId>
|
||||
<version>2.14.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
|
|
|
@ -2,8 +2,10 @@ package com.geekq.miaosha;
|
|||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.scheduling.annotation.EnableScheduling;
|
||||
|
||||
@SpringBootApplication
|
||||
@EnableScheduling
|
||||
public class GeekQMainApplication {
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
|
|
23
src/main/java/com/geekq/miaosha/common/Constanst.java
Normal file
23
src/main/java/com/geekq/miaosha/common/Constanst.java
Normal file
|
@ -0,0 +1,23 @@
|
|||
package com.geekq.miaosha.common;
|
||||
|
||||
public class Constanst {
|
||||
public static String CLOSE_ORDER_INFO_TASK_LOCK = "CLOSE_ORDER_INFO_KEY";
|
||||
|
||||
public enum orderStaus{
|
||||
ORDER_NOT_PAY("新建未支付");
|
||||
|
||||
orderStaus(String name){
|
||||
this.name=name;
|
||||
}
|
||||
|
||||
private String name;
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -4,6 +4,8 @@ import com.geekq.miaosha.domain.MiaoshaOrder;
|
|||
import com.geekq.miaosha.domain.OrderInfo;
|
||||
import org.apache.ibatis.annotations.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Mapper
|
||||
public interface OrderDao {
|
||||
|
||||
|
@ -21,5 +23,9 @@ public interface OrderDao {
|
|||
@Select("select * from order_info where id = #{orderId}")
|
||||
public OrderInfo getOrderById(@Param("orderId")long orderId);
|
||||
|
||||
|
||||
@Select("select * from order_info where status=#{status} and create_Date<=#{createDate}")
|
||||
public List<OrderInfo> selectOrderStatusByCreateTime(@Param("status")Integer status, @Param("createDate") String createDate);
|
||||
|
||||
@Select("update order_info set status=0 where id=#{id}")
|
||||
public int closeOrderByOrderInfo();
|
||||
}
|
||||
|
|
14
src/main/java/com/geekq/miaosha/redis/DistributedLocker.java
Normal file
14
src/main/java/com/geekq/miaosha/redis/DistributedLocker.java
Normal file
|
@ -0,0 +1,14 @@
|
|||
package com.geekq.miaosha.redis;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public interface DistributedLocker {
|
||||
|
||||
void lock(String lockKey);
|
||||
|
||||
void unlock(String lockKey);
|
||||
|
||||
void lock(String lockKey, int timeout);
|
||||
|
||||
void lock(String lockKey, TimeUnit unit , int timeout);
|
||||
}
|
|
@ -1,22 +1,64 @@
|
|||
package com.geekq.miaosha.redis;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import redis.clients.jedis.Jedis;
|
||||
import redis.clients.jedis.JedisPool;
|
||||
import redis.clients.jedis.ScanParams;
|
||||
import redis.clients.jedis.ScanResult;
|
||||
import redis.clients.jedis.*;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@Service
|
||||
@Slf4j
|
||||
public class RedisService {
|
||||
|
||||
@Autowired
|
||||
JedisPool jedisPool;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 设置失效时间
|
||||
* @param key
|
||||
* @param value
|
||||
* @return
|
||||
*/
|
||||
public Long setnx(String key ,String value){
|
||||
Jedis jedis =null;
|
||||
Long result = null;
|
||||
try {
|
||||
jedis = jedisPool.getResource();
|
||||
result = jedis.setnx(key,value);
|
||||
}catch (Exception e){
|
||||
log.error("expire key:{} error",key,e);
|
||||
jedisPool.returnResource(jedis);
|
||||
return result;
|
||||
}
|
||||
jedisPool.returnResource(jedis);
|
||||
return result;
|
||||
|
||||
}
|
||||
/**
|
||||
* 设置key的有效期,单位是秒
|
||||
* @param key
|
||||
* @param exTime
|
||||
* @return
|
||||
*/
|
||||
public Long expire(String key,int exTime){
|
||||
Jedis jedis = null;
|
||||
Long result = null;
|
||||
try {
|
||||
jedis = jedisPool.getResource();
|
||||
result = jedis.expire(key,exTime);
|
||||
} catch (Exception e) {
|
||||
log.error("expire key:{} error",key,e);
|
||||
jedisPool.returnBrokenResource(jedis);
|
||||
return result;
|
||||
}
|
||||
jedisPool.returnResource(jedis);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当个对象
|
||||
* */
|
||||
|
@ -33,7 +75,37 @@ public class RedisService {
|
|||
returnToPool(jedis);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public String get(String key){
|
||||
Jedis jedis = null;
|
||||
String result = null;
|
||||
try {
|
||||
jedis = jedisPool.getResource();
|
||||
result = jedis.get(key);
|
||||
} catch (Exception e) {
|
||||
log.error("expire key:{} error",key,e);
|
||||
jedisPool.returnBrokenResource(jedis);
|
||||
return result;
|
||||
}
|
||||
jedisPool.returnResource(jedis);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
public String getset(String key,String value){
|
||||
Jedis jedis = null;
|
||||
String result = null;
|
||||
try {
|
||||
jedis = jedisPool.getResource();
|
||||
result = jedis.getSet(key,value);
|
||||
} catch (Exception e) {
|
||||
log.error("expire key:{} error",key,e);
|
||||
jedisPool.returnBrokenResource(jedis);
|
||||
return result;
|
||||
}
|
||||
jedisPool.returnResource(jedis);
|
||||
return result;
|
||||
}
|
||||
/**
|
||||
* 设置对象
|
||||
* */
|
||||
|
@ -119,7 +191,23 @@ public class RedisService {
|
|||
returnToPool(jedis);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public Long del(String key){
|
||||
Jedis jedis = null;
|
||||
Long result = null;
|
||||
try {
|
||||
jedis = jedisPool.getResource();
|
||||
result = jedis.del(key);
|
||||
} catch (Exception e) {
|
||||
log.error("del key:{} error",key,e);
|
||||
jedisPool.returnBrokenResource(jedis);
|
||||
return result;
|
||||
}
|
||||
jedisPool.returnResource(jedis);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
public boolean delete(KeyPrefix prefix) {
|
||||
if(prefix == null) {
|
||||
return false;
|
||||
|
|
42
src/main/java/com/geekq/miaosha/redis/RedissLockUtil.java
Normal file
42
src/main/java/com/geekq/miaosha/redis/RedissLockUtil.java
Normal file
|
@ -0,0 +1,42 @@
|
|||
package com.geekq.miaosha.redis;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* redis分布式锁帮助类
|
||||
*
|
||||
*/
|
||||
public class RedissLockUtil {
|
||||
private static DistributedLocker redissLock;
|
||||
|
||||
public static void setLocker(DistributedLocker locker) {
|
||||
redissLock = locker;
|
||||
}
|
||||
|
||||
public static void lock(String lockKey) {
|
||||
redissLock.lock(lockKey);
|
||||
}
|
||||
|
||||
public static void unlock(String lockKey) {
|
||||
redissLock.unlock(lockKey);
|
||||
}
|
||||
|
||||
/**
|
||||
* 带超时的锁
|
||||
* @param lockKey
|
||||
* @param timeout 超时时间 单位:秒
|
||||
*/
|
||||
public static void lock(String lockKey, int timeout) {
|
||||
redissLock.lock(lockKey, timeout);
|
||||
}
|
||||
|
||||
/**
|
||||
* 带超时的锁
|
||||
* @param lockKey
|
||||
* @param unit 时间单位
|
||||
* @param timeout 超时时间
|
||||
*/
|
||||
public static void lock(String lockKey, TimeUnit unit , int timeout) {
|
||||
redissLock.lock(lockKey, unit, timeout);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,76 @@
|
|||
package com.geekq.miaosha.redis;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.redisson.Redisson;
|
||||
import org.redisson.api.RedissonClient;
|
||||
import org.redisson.config.Config;
|
||||
import org.redisson.config.SentinelServersConfig;
|
||||
import org.redisson.config.SingleServerConfig;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
@Configuration
|
||||
@ConditionalOnClass(Config.class)
|
||||
@EnableConfigurationProperties(RedissonProperties.class)
|
||||
public class RedissonAutoConfiguration {
|
||||
|
||||
@Autowired
|
||||
private RedissonProperties redssionProperties;
|
||||
|
||||
/**
|
||||
* 哨兵模式自动装配
|
||||
* @return
|
||||
*/
|
||||
@Bean
|
||||
@ConditionalOnProperty(name="redisson.master-name")
|
||||
RedissonClient redissonSentinel() {
|
||||
Config config = new Config();
|
||||
SentinelServersConfig serverConfig = config.useSentinelServers().addSentinelAddress(redssionProperties.getSentinelAddresses())
|
||||
.setMasterName(redssionProperties.getMasterName())
|
||||
.setTimeout(redssionProperties.getTimeout())
|
||||
.setMasterConnectionPoolSize(redssionProperties.getMasterConnectionPoolSize())
|
||||
.setSlaveConnectionPoolSize(redssionProperties.getSlaveConnectionPoolSize());
|
||||
|
||||
if(StringUtils.isNotBlank(redssionProperties.getPassword())) {
|
||||
serverConfig.setPassword(redssionProperties.getPassword());
|
||||
}
|
||||
return Redisson.create(config);
|
||||
}
|
||||
|
||||
/**
|
||||
* 单机模式自动装配
|
||||
* @return
|
||||
*/
|
||||
@Bean
|
||||
@ConditionalOnProperty(name="redisson.address")
|
||||
RedissonClient redissonSingle() {
|
||||
Config config = new Config();
|
||||
SingleServerConfig serverConfig = config.useSingleServer()
|
||||
.setAddress(redssionProperties.getAddress())
|
||||
.setTimeout(redssionProperties.getTimeout())
|
||||
.setConnectionPoolSize(redssionProperties.getConnectionPoolSize())
|
||||
.setConnectionMinimumIdleSize(redssionProperties.getConnectionMinimumIdleSize());
|
||||
|
||||
if(StringUtils.isNotBlank(redssionProperties.getPassword())) {
|
||||
serverConfig.setPassword(redssionProperties.getPassword());
|
||||
}
|
||||
|
||||
return Redisson.create(config);
|
||||
}
|
||||
|
||||
/**
|
||||
* 装配locker类,并将实例注入到RedissLockUtil中
|
||||
* @return
|
||||
*/
|
||||
@Bean
|
||||
DistributedLocker distributedLocker(RedissonClient redissonSingle) {
|
||||
RedissonDistributedLocker locker = new RedissonDistributedLocker();
|
||||
locker.setRedissonClient(redissonSingle);
|
||||
RedissLockUtil.setLocker(locker);
|
||||
return locker;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
package com.geekq.miaosha.redis;
|
||||
|
||||
import org.redisson.api.RLock;
|
||||
import org.redisson.api.RedissonClient;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public class RedissonDistributedLocker implements DistributedLocker {
|
||||
|
||||
private RedissonClient redissonClient;
|
||||
|
||||
@Override
|
||||
public void lock(String lockKey) {
|
||||
RLock lock = redissonClient.getLock(lockKey);
|
||||
lock.lock();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unlock(String lockKey) {
|
||||
RLock lock = redissonClient.getLock(lockKey);
|
||||
lock.unlock();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void lock(String lockKey, int leaseTime) {
|
||||
RLock lock = redissonClient.getLock(lockKey);
|
||||
lock.lock(leaseTime, TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void lock(String lockKey, TimeUnit unit ,int timeout) {
|
||||
RLock lock = redissonClient.getLock(lockKey);
|
||||
lock.lock(timeout, unit);
|
||||
}
|
||||
|
||||
public void setRedissonClient(RedissonClient redissonClient) {
|
||||
this.redissonClient = redissonClient;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,98 @@
|
|||
package com.geekq.miaosha.redis;
|
||||
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
|
||||
@ConfigurationProperties(prefix = "redisson")
|
||||
public class RedissonProperties {
|
||||
|
||||
private int timeout = 3000;
|
||||
|
||||
private String address;
|
||||
|
||||
private String password;
|
||||
|
||||
private int connectionPoolSize = 64;
|
||||
|
||||
private int connectionMinimumIdleSize=10;
|
||||
|
||||
private int slaveConnectionPoolSize = 250;
|
||||
|
||||
private int masterConnectionPoolSize = 250;
|
||||
|
||||
private String[] sentinelAddresses;
|
||||
|
||||
private String masterName;
|
||||
|
||||
public int getTimeout() {
|
||||
return timeout;
|
||||
}
|
||||
|
||||
public void setTimeout(int timeout) {
|
||||
this.timeout = timeout;
|
||||
}
|
||||
|
||||
public int getSlaveConnectionPoolSize() {
|
||||
return slaveConnectionPoolSize;
|
||||
}
|
||||
|
||||
public void setSlaveConnectionPoolSize(int slaveConnectionPoolSize) {
|
||||
this.slaveConnectionPoolSize = slaveConnectionPoolSize;
|
||||
}
|
||||
|
||||
public int getMasterConnectionPoolSize() {
|
||||
return masterConnectionPoolSize;
|
||||
}
|
||||
|
||||
public void setMasterConnectionPoolSize(int masterConnectionPoolSize) {
|
||||
this.masterConnectionPoolSize = masterConnectionPoolSize;
|
||||
}
|
||||
|
||||
public String[] getSentinelAddresses() {
|
||||
return sentinelAddresses;
|
||||
}
|
||||
|
||||
public void setSentinelAddresses(String sentinelAddresses) {
|
||||
this.sentinelAddresses = sentinelAddresses.split(",");
|
||||
}
|
||||
|
||||
public String getMasterName() {
|
||||
return masterName;
|
||||
}
|
||||
|
||||
public void setMasterName(String masterName) {
|
||||
this.masterName = masterName;
|
||||
}
|
||||
|
||||
public String getPassword() {
|
||||
return password;
|
||||
}
|
||||
|
||||
public void setPassword(String password) {
|
||||
this.password = password;
|
||||
}
|
||||
|
||||
public String getAddress() {
|
||||
return address;
|
||||
}
|
||||
|
||||
public void setAddress(String address) {
|
||||
this.address = address;
|
||||
}
|
||||
|
||||
public int getConnectionPoolSize() {
|
||||
return connectionPoolSize;
|
||||
}
|
||||
|
||||
public void setConnectionPoolSize(int connectionPoolSize) {
|
||||
this.connectionPoolSize = connectionPoolSize;
|
||||
}
|
||||
|
||||
public int getConnectionMinimumIdleSize() {
|
||||
return connectionMinimumIdleSize;
|
||||
}
|
||||
|
||||
public void setConnectionMinimumIdleSize(int connectionMinimumIdleSize) {
|
||||
this.connectionMinimumIdleSize = connectionMinimumIdleSize;
|
||||
}
|
||||
}
|
||||
|
146
src/main/java/com/geekq/miaosha/redis/RedissonService.java
Normal file
146
src/main/java/com/geekq/miaosha/redis/RedissonService.java
Normal file
|
@ -0,0 +1,146 @@
|
|||
package com.geekq.miaosha.redis;
|
||||
|
||||
import org.redisson.api.*;
|
||||
import org.redisson.config.Config;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* redisson操作类
|
||||
*/
|
||||
@Service("redissonService")
|
||||
public class RedissonService {
|
||||
|
||||
@Autowired
|
||||
private RedissonClient redissonClient;
|
||||
|
||||
public void getRedissonClient() throws IOException {
|
||||
Config config = redissonClient.getConfig();
|
||||
System.out.println(config.toJSON().toString());
|
||||
}
|
||||
|
||||
/**`
|
||||
* 获取字符串对象
|
||||
*
|
||||
* @param objectName
|
||||
* @return
|
||||
*/
|
||||
public <T> RBucket<T> getRBucket(String objectName) {
|
||||
RBucket<T> bucket = redissonClient.getBucket(objectName);
|
||||
return bucket;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取Map对象
|
||||
*
|
||||
* @param objectName
|
||||
* @return
|
||||
*/
|
||||
public <K, V> RMap<K, V> getRMap(String objectName) {
|
||||
RMap<K, V> map = redissonClient.getMap(objectName);
|
||||
return map;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取有序集合
|
||||
*
|
||||
* @param objectName
|
||||
* @return
|
||||
*/
|
||||
public <V> RSortedSet<V> getRSortedSet(String objectName) {
|
||||
RSortedSet<V> sortedSet = redissonClient.getSortedSet(objectName);
|
||||
return sortedSet;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取集合
|
||||
*
|
||||
* @param objectName
|
||||
* @return
|
||||
*/
|
||||
public <V> RSet<V> getRSet(String objectName) {
|
||||
RSet<V> rSet = redissonClient.getSet(objectName);
|
||||
return rSet;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取列表
|
||||
*
|
||||
* @param objectName
|
||||
* @return
|
||||
*/
|
||||
public <V> RList<V> getRList(String objectName) {
|
||||
RList<V> rList = redissonClient.getList(objectName);
|
||||
return rList;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取队列
|
||||
*
|
||||
* @param objectName
|
||||
* @return
|
||||
*/
|
||||
public <V> RQueue<V> getRQueue(String objectName) {
|
||||
RQueue<V> rQueue = redissonClient.getQueue(objectName);
|
||||
return rQueue;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取双端队列
|
||||
*
|
||||
* @param objectName
|
||||
* @return
|
||||
*/
|
||||
public <V> RDeque<V> getRDeque(String objectName) {
|
||||
RDeque<V> rDeque = redissonClient.getDeque(objectName);
|
||||
return rDeque;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取锁
|
||||
*
|
||||
* @param objectName
|
||||
* @return
|
||||
*/
|
||||
public RLock getRLock(String objectName) {
|
||||
RLock rLock = redissonClient.getLock(objectName);
|
||||
return rLock;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取读取锁
|
||||
*
|
||||
* @param objectName
|
||||
* @return
|
||||
*/
|
||||
public RReadWriteLock getRWLock(String objectName) {
|
||||
RReadWriteLock rwlock = redissonClient.getReadWriteLock(objectName);
|
||||
return rwlock;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取原子数
|
||||
*
|
||||
* @param objectName
|
||||
* @return
|
||||
*/
|
||||
public RAtomicLong getRAtomicLong(String objectName) {
|
||||
RAtomicLong rAtomicLong = redissonClient.getAtomicLong(objectName);
|
||||
return rAtomicLong;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取记数锁
|
||||
*
|
||||
* @param objectName
|
||||
* @return
|
||||
*/
|
||||
public RCountDownLatch getRCountDownLatch(String objectName) {
|
||||
RCountDownLatch rCountDownLatch = redissonClient.getCountDownLatch(objectName);
|
||||
return rCountDownLatch;
|
||||
}
|
||||
|
||||
}
|
|
@ -6,12 +6,17 @@ import com.geekq.miaosha.domain.MiaoshaUser;
|
|||
import com.geekq.miaosha.domain.OrderInfo;
|
||||
import com.geekq.miaosha.redis.OrderKey;
|
||||
import com.geekq.miaosha.redis.RedisService;
|
||||
import com.geekq.miaosha.utils.DateTimeUtils;
|
||||
import com.geekq.miaosha.vo.GoodsVo;
|
||||
import org.apache.commons.lang3.time.DateUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import static com.geekq.miaosha.common.Constanst.orderStaus.ORDER_NOT_PAY;
|
||||
|
||||
@Service
|
||||
public class OrderService {
|
||||
|
@ -52,6 +57,13 @@ public class OrderService {
|
|||
return orderInfo;
|
||||
}
|
||||
|
||||
public void closeOrder(int hour){
|
||||
Date closeDateTime = DateUtils.addHours(new Date(),-hour);
|
||||
List<OrderInfo> orderInfoList = orderDao.selectOrderStatusByCreateTime(Integer.valueOf(ORDER_NOT_PAY.ordinal()), DateTimeUtils.dateToStr(closeDateTime));
|
||||
for (OrderInfo orderInfo:orderInfoList){
|
||||
System.out.println("orderinfo infomation "+orderInfo.getGoodsName());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
114
src/main/java/com/geekq/miaosha/timeTask/OrderCloseTask.java
Normal file
114
src/main/java/com/geekq/miaosha/timeTask/OrderCloseTask.java
Normal file
|
@ -0,0 +1,114 @@
|
|||
package com.geekq.miaosha.timeTask;
|
||||
|
||||
import com.geekq.miaosha.dao.OrderDao;
|
||||
import com.geekq.miaosha.redis.RedisService;
|
||||
import com.geekq.miaosha.redis.RedissonService;
|
||||
import com.geekq.miaosha.service.OrderService;
|
||||
import jodd.util.PropertiesUtil;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.redisson.api.RLock;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.scheduling.annotation.Scheduled;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import static com.geekq.miaosha.common.Constanst.CLOSE_ORDER_INFO_TASK_LOCK;
|
||||
|
||||
@Component
|
||||
@Slf4j
|
||||
public class OrderCloseTask {
|
||||
|
||||
@Autowired
|
||||
private OrderDao orderDao ;
|
||||
@Autowired
|
||||
private RedisService redisService;
|
||||
|
||||
@Autowired
|
||||
private OrderService orderService;
|
||||
@Autowired
|
||||
private RedissonService redissonService;
|
||||
|
||||
|
||||
// @Scheduled(cron = "0/1 * * * * ?")
|
||||
private void closeOrderTaskv1(){
|
||||
int hour = 2;
|
||||
orderService.closeOrder(hour);
|
||||
log.info("关闭订单定时任务结束");
|
||||
}
|
||||
// @Scheduled(cron = "0/1 * * * * ?")
|
||||
// public void closeOrderTaskV2(){
|
||||
// log.info("关闭订单定时任务启动");
|
||||
// long lockTime = 5000;
|
||||
// Long setnxResult = redisService.setnx(CLOSE_ORDER_INFO_TASK_LOCK,String.valueOf(System.currentTimeMillis()+lockTime));
|
||||
// //代表获取了锁
|
||||
// if(setnxResult !=null && setnxResult ==1){
|
||||
// closeOrder(CLOSE_ORDER_INFO_TASK_LOCK);
|
||||
// }else {
|
||||
// log.info("没有获得分布式锁:{}",CLOSE_ORDER_INFO_TASK_LOCK);
|
||||
// }
|
||||
// log.info("关闭订单定时任务结束");
|
||||
// }
|
||||
|
||||
// @Scheduled(cron = "0/1 * * * * ?")
|
||||
// public void closeOrderTaskV3(){
|
||||
// log.info("关闭订单定时任务启动");
|
||||
// long lockTime = 5000;
|
||||
// Long setnxResult = redisService.setnx(CLOSE_ORDER_INFO_TASK_LOCK,String.valueOf(System.currentTimeMillis()+lockTime));
|
||||
// //代表获取了锁
|
||||
// if(setnxResult !=null && setnxResult ==1){
|
||||
// closeOrder(CLOSE_ORDER_INFO_TASK_LOCK);
|
||||
// }else {
|
||||
// log.info("没有获得分布式锁:{}",CLOSE_ORDER_INFO_TASK_LOCK);
|
||||
// String lockValueStr = redisService.get(CLOSE_ORDER_INFO_TASK_LOCK);
|
||||
// if(lockValueStr!=null&&System.currentTimeMillis() > Long.parseLong(lockValueStr)){
|
||||
// //把之前的释放在新加入锁
|
||||
// String getSetResult = redisService.getset(CLOSE_ORDER_INFO_TASK_LOCK,String.valueOf(System.currentTimeMillis()+lockTime));
|
||||
//
|
||||
// if(getSetResult == null || (getSetResult != null && StringUtils.equals(lockValueStr,getSetResult))){
|
||||
// closeOrder(CLOSE_ORDER_INFO_TASK_LOCK);
|
||||
// }else {
|
||||
// log.info("没有获取到分布式锁:{}",CLOSE_ORDER_INFO_TASK_LOCK);
|
||||
// }
|
||||
// }else {
|
||||
// log.info("没有获取到分布式锁:{}",CLOSE_ORDER_INFO_TASK_LOCK);
|
||||
// }
|
||||
// }
|
||||
// log.info("关闭订单定时任务结束");
|
||||
// }
|
||||
@Scheduled(cron="0 */1 * * * ?")
|
||||
public void closeOrderTaskV4(){
|
||||
RLock lock = redissonService.getRLock(CLOSE_ORDER_INFO_TASK_LOCK);
|
||||
boolean getLock = false;
|
||||
try {
|
||||
if(getLock = lock.tryLock(0,50, TimeUnit.SECONDS)){
|
||||
log.info("Redisson获取到分布式锁:{},ThreadName:{}",CLOSE_ORDER_INFO_TASK_LOCK,Thread.currentThread().getName());
|
||||
int hour = 2;
|
||||
// iOrderService.closeOrder(hour);
|
||||
}else{
|
||||
log.info("Redisson没有获取到分布式锁:{},ThreadName:{}",CLOSE_ORDER_INFO_TASK_LOCK,Thread.currentThread().getName());
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
log.error("Redisson分布式锁获取异常",e);
|
||||
} finally {
|
||||
if(!getLock){
|
||||
return;
|
||||
}
|
||||
lock.unlock();
|
||||
log.info("Redisson分布式锁释放锁");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
private void closeOrder(String lockName){
|
||||
redisService.expire(lockName,5);
|
||||
log.info("获取{},当前线程名称!" ,lockName,Thread.currentThread().getName());
|
||||
int hour = 2;
|
||||
orderService.closeOrder(hour);
|
||||
redisService.del(CLOSE_ORDER_INFO_TASK_LOCK);
|
||||
log.info("===============================");
|
||||
|
||||
}
|
||||
}
|
61
src/main/java/com/geekq/miaosha/utils/DateTimeUtils.java
Normal file
61
src/main/java/com/geekq/miaosha/utils/DateTimeUtils.java
Normal file
|
@ -0,0 +1,61 @@
|
|||
package com.geekq.miaosha.utils;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.joda.time.DateTime;
|
||||
import org.joda.time.format.DateTimeFormat;
|
||||
import org.joda.time.format.DateTimeFormatter;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* Created by geely
|
||||
*/
|
||||
public class DateTimeUtils {
|
||||
|
||||
//joda-time
|
||||
|
||||
//str->Date
|
||||
//Date->str
|
||||
public static final String STANDARD_FORMAT = "yyyy-MM-dd HH:mm:ss";
|
||||
|
||||
|
||||
|
||||
public static Date strToDate(String dateTimeStr,String formatStr){
|
||||
DateTimeFormatter dateTimeFormatter = DateTimeFormat.forPattern(formatStr);
|
||||
DateTime dateTime = dateTimeFormatter.parseDateTime(dateTimeStr);
|
||||
return dateTime.toDate();
|
||||
}
|
||||
|
||||
public static String dateToStr(Date date,String formatStr){
|
||||
if(date == null){
|
||||
return StringUtils.EMPTY;
|
||||
}
|
||||
DateTime dateTime = new DateTime(date);
|
||||
return dateTime.toString(formatStr);
|
||||
}
|
||||
|
||||
public static Date strToDate(String dateTimeStr){
|
||||
DateTimeFormatter dateTimeFormatter = DateTimeFormat.forPattern(STANDARD_FORMAT);
|
||||
DateTime dateTime = dateTimeFormatter.parseDateTime(dateTimeStr);
|
||||
return dateTime.toDate();
|
||||
}
|
||||
|
||||
public static String dateToStr(Date date){
|
||||
if(date == null){
|
||||
return StringUtils.EMPTY;
|
||||
}
|
||||
DateTime dateTime = new DateTime(date);
|
||||
return dateTime.toString(STANDARD_FORMAT);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public static void main(String[] args) {
|
||||
System.out.println(DateTimeUtils.dateToStr(new Date(),"yyyy-MM-dd HH:mm:ss"));
|
||||
System.out.println(DateTimeUtils.strToDate("2010-01-01 11:11:11","yyyy-MM-dd HH:mm:ss"));
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -44,13 +44,17 @@ spring.resources.chain.gzipped=true
|
|||
spring.resources.chain.html-application-cache=true
|
||||
spring.resources.static-locations=classpath:/static/
|
||||
#redis
|
||||
redis.host=192.168.1.116
|
||||
redis.host=localhost
|
||||
redis.port=6379
|
||||
redis.timeout=100
|
||||
redis.password=123456
|
||||
redis.poolMaxTotal=1000
|
||||
redis.poolMaxIdle=500
|
||||
redis.poolMaxWait=500
|
||||
|
||||
# redisson lock
|
||||
redisson.address=redis://localhost:6379
|
||||
redisson.password=123456
|
||||
#rabbitmq
|
||||
spring.rabbitmq.host=localhost
|
||||
spring.rabbitmq.port=5672
|
||||
|
|
|
@ -44,13 +44,17 @@ spring.resources.chain.gzipped=true
|
|||
spring.resources.chain.html-application-cache=true
|
||||
spring.resources.static-locations=classpath:/static/
|
||||
#redis
|
||||
redis.host=192.168.1.116
|
||||
redis.host=localhost
|
||||
redis.port=6379
|
||||
redis.timeout=100
|
||||
redis.password=123456
|
||||
redis.poolMaxTotal=1000
|
||||
redis.poolMaxIdle=500
|
||||
redis.poolMaxWait=500
|
||||
|
||||
# redisson lock
|
||||
redisson.address=redis://localhost:6379
|
||||
redisson.password=123456
|
||||
#rabbitmq
|
||||
spring.rabbitmq.host=localhost
|
||||
spring.rabbitmq.port=5672
|
||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -1,5 +0,0 @@
|
|||
#Generated by Apache Maven
|
||||
#Sat Oct 27 23:31:07 CST 2018
|
||||
version=0.0.1-SNAPSHOT
|
||||
groupId=com.geekq
|
||||
artifactId=miaosha
|
|
@ -1,66 +0,0 @@
|
|||
com/geekq/miaosha/domain/MiaoshaUser.class
|
||||
com/geekq/miaosha/controller/RateLimiterController.class
|
||||
com/geekq/miaosha/redis/MiaoshaKey.class
|
||||
com/geekq/miaosha/common/ServerResponse.class
|
||||
com/geekq/miaosha/service/MiaoShaUserService.class
|
||||
com/geekq/miaosha/rabbitmq/MQReceiver.class
|
||||
com/geekq/miaosha/controller/OrderController.class
|
||||
com/geekq/miaosha/config/WebConfig.class
|
||||
com/geekq/miaosha/mybatis/controller/MessageController.class
|
||||
com/geekq/miaosha/dao/UserMapper.class
|
||||
com/geekq/miaosha/service/IUserService.class
|
||||
com/geekq/miaosha/exception/GlobleExceptionHandler.class
|
||||
com/geekq/miaosha/rabbitmq/MiaoshaMessage.class
|
||||
com/geekq/miaosha/access/UserContext.class
|
||||
com/geekq/miaosha/result/Result.class
|
||||
com/geekq/miaosha/controller/DemoController.class
|
||||
com/geekq/miaosha/vo/GoodsDetailVo.class
|
||||
com/geekq/miaosha/service/GoodsService.class
|
||||
com/geekq/miaosha/DemoTask$2.class
|
||||
com/geekq/miaosha/redis/RedisService.class
|
||||
com/geekq/miaosha/dao/DruidConfig.class
|
||||
com/geekq/miaosha/controller/LoginController.class
|
||||
com/geekq/miaosha/redis/OrderKey.class
|
||||
com/geekq/miaosha/domain/Goods.class
|
||||
com/geekq/miaosha/config/UserArgumentResolver.class
|
||||
com/geekq/miaosha/redis/MiaoShaUserKey.class
|
||||
com/geekq/miaosha/controller/MiaoshaController.class
|
||||
com/geekq/miaosha/vo/OrderDetailVo.class
|
||||
com/geekq/miaosha/validator/IsMobileValidator.class
|
||||
com/geekq/miaosha/dao/OrderDao.class
|
||||
com/geekq/miaosha/vo/LoginVo.class
|
||||
com/geekq/miaosha/DemoTask$1.class
|
||||
com/geekq/miaosha/domain/MiaoshaOrder.class
|
||||
com/geekq/miaosha/access/AccessInterceptor.class
|
||||
com/geekq/miaosha/domain/MiaoshaGoods.class
|
||||
com/geekq/miaosha/domain/OrderInfo.class
|
||||
com/geekq/miaosha/validator/IsMobile.class
|
||||
com/geekq/miaosha/rabbitmq/MQSender.class
|
||||
com/geekq/miaosha/dao/GoodsDao.class
|
||||
com/geekq/miaosha/controller/UserController.class
|
||||
com/geekq/miaosha/controller/GoodsController.class
|
||||
com/geekq/miaosha/domain/User.class
|
||||
com/geekq/miaosha/Md5Utils/MD5Utils.class
|
||||
com/geekq/miaosha/redis/Userkey.class
|
||||
com/geekq/miaosha/service/UserService.class
|
||||
com/geekq/miaosha/GeekQMainApplication.class
|
||||
com/geekq/miaosha/utils/ValidatorUtil.class
|
||||
com/geekq/miaosha/result/CodeMsg.class
|
||||
com/geekq/miaosha/redis/RedisPoolFactory.class
|
||||
com/geekq/miaosha/access/AccessKey.class
|
||||
com/geekq/miaosha/vo/GoodsVo.class
|
||||
com/geekq/miaosha/dao/MiaoShaUserDao.class
|
||||
com/geekq/miaosha/redis/KeyPrefix.class
|
||||
com/geekq/miaosha/redis/GoodsKey.class
|
||||
com/geekq/miaosha/access/AccessLimit.class
|
||||
com/geekq/miaosha/service/MiaoshaService.class
|
||||
com/geekq/miaosha/rabbitmq/MQConfig.class
|
||||
com/geekq/miaosha/exception/GlobleException.class
|
||||
com/geekq/miaosha/DemoTask.class
|
||||
com/geekq/miaosha/redis/BasePrefix.class
|
||||
com/geekq/miaosha/service/OrderService.class
|
||||
com/geekq/miaosha/common/ResponseCode.class
|
||||
com/geekq/miaosha/dao/UserDao.class
|
||||
com/geekq/miaosha/Test.class
|
||||
com/geekq/miaosha/redis/RedisConfig.class
|
||||
com/geekq/miaosha/utils/UUIDUtil.class
|
|
@ -1,64 +0,0 @@
|
|||
/home/qiurunze/下载/miaosha_1/src/main/java/com/geekq/miaosha/rabbitmq/MQSender.java
|
||||
/home/qiurunze/下载/miaosha_1/src/main/java/com/geekq/miaosha/validator/IsMobileValidator.java
|
||||
/home/qiurunze/下载/miaosha_1/src/main/java/com/geekq/miaosha/common/ServerResponse.java
|
||||
/home/qiurunze/下载/miaosha_1/src/main/java/com/geekq/miaosha/domain/User.java
|
||||
/home/qiurunze/下载/miaosha_1/src/main/java/com/geekq/miaosha/controller/OrderController.java
|
||||
/home/qiurunze/下载/miaosha_1/src/main/java/com/geekq/miaosha/controller/DemoController.java
|
||||
/home/qiurunze/下载/miaosha_1/src/main/java/com/geekq/miaosha/dao/OrderDao.java
|
||||
/home/qiurunze/下载/miaosha_1/src/main/java/com/geekq/miaosha/service/MiaoShaUserService.java
|
||||
/home/qiurunze/下载/miaosha_1/src/main/java/com/geekq/miaosha/controller/RateLimiterController.java
|
||||
/home/qiurunze/下载/miaosha_1/src/main/java/com/geekq/miaosha/domain/MiaoshaUser.java
|
||||
/home/qiurunze/下载/miaosha_1/src/main/java/com/geekq/miaosha/redis/OrderKey.java
|
||||
/home/qiurunze/下载/miaosha_1/src/main/java/com/geekq/miaosha/vo/GoodsDetailVo.java
|
||||
/home/qiurunze/下载/miaosha_1/src/main/java/com/geekq/miaosha/service/UserService.java
|
||||
/home/qiurunze/下载/miaosha_1/src/main/java/com/geekq/miaosha/dao/GoodsDao.java
|
||||
/home/qiurunze/下载/miaosha_1/src/main/java/com/geekq/miaosha/exception/GlobleExceptionHandler.java
|
||||
/home/qiurunze/下载/miaosha_1/src/main/java/com/geekq/miaosha/exception/GlobleException.java
|
||||
/home/qiurunze/下载/miaosha_1/src/main/java/com/geekq/miaosha/redis/MiaoShaUserKey.java
|
||||
/home/qiurunze/下载/miaosha_1/src/main/java/com/geekq/miaosha/controller/MiaoshaController.java
|
||||
/home/qiurunze/下载/miaosha_1/src/main/java/com/geekq/miaosha/result/Result.java
|
||||
/home/qiurunze/下载/miaosha_1/src/main/java/com/geekq/miaosha/redis/Userkey.java
|
||||
/home/qiurunze/下载/miaosha_1/src/main/java/com/geekq/miaosha/access/UserContext.java
|
||||
/home/qiurunze/下载/miaosha_1/src/main/java/com/geekq/miaosha/redis/RedisPoolFactory.java
|
||||
/home/qiurunze/下载/miaosha_1/src/main/java/com/geekq/miaosha/result/CodeMsg.java
|
||||
/home/qiurunze/下载/miaosha_1/src/main/java/com/geekq/miaosha/Md5Utils/MD5Utils.java
|
||||
/home/qiurunze/下载/miaosha_1/src/main/java/com/geekq/miaosha/domain/MiaoshaGoods.java
|
||||
/home/qiurunze/下载/miaosha_1/src/main/java/com/geekq/miaosha/vo/LoginVo.java
|
||||
/home/qiurunze/下载/miaosha_1/src/main/java/com/geekq/miaosha/access/AccessInterceptor.java
|
||||
/home/qiurunze/下载/miaosha_1/src/main/java/com/geekq/miaosha/GeekQMainApplication.java
|
||||
/home/qiurunze/下载/miaosha_1/src/main/java/com/geekq/miaosha/service/GoodsService.java
|
||||
/home/qiurunze/下载/miaosha_1/src/main/java/com/geekq/miaosha/redis/GoodsKey.java
|
||||
/home/qiurunze/下载/miaosha_1/src/main/java/com/geekq/miaosha/utils/ValidatorUtil.java
|
||||
/home/qiurunze/下载/miaosha_1/src/main/java/com/geekq/miaosha/dao/MiaoShaUserDao.java
|
||||
/home/qiurunze/下载/miaosha_1/src/main/java/com/geekq/miaosha/service/MiaoshaService.java
|
||||
/home/qiurunze/下载/miaosha_1/src/main/java/com/geekq/miaosha/service/OrderService.java
|
||||
/home/qiurunze/下载/miaosha_1/src/main/java/com/geekq/miaosha/access/AccessLimit.java
|
||||
/home/qiurunze/下载/miaosha_1/src/main/java/com/geekq/miaosha/access/AccessKey.java
|
||||
/home/qiurunze/下载/miaosha_1/src/main/java/com/geekq/miaosha/domain/Goods.java
|
||||
/home/qiurunze/下载/miaosha_1/src/main/java/com/geekq/miaosha/config/UserArgumentResolver.java
|
||||
/home/qiurunze/下载/miaosha_1/src/main/java/com/geekq/miaosha/redis/MiaoshaKey.java
|
||||
/home/qiurunze/下载/miaosha_1/src/main/java/com/geekq/miaosha/domain/MiaoshaOrder.java
|
||||
/home/qiurunze/下载/miaosha_1/src/main/java/com/geekq/miaosha/controller/UserController.java
|
||||
/home/qiurunze/下载/miaosha_1/src/main/java/com/geekq/miaosha/controller/LoginController.java
|
||||
/home/qiurunze/下载/miaosha_1/src/main/java/com/geekq/miaosha/dao/DruidConfig.java
|
||||
/home/qiurunze/下载/miaosha_1/src/main/java/com/geekq/miaosha/vo/GoodsVo.java
|
||||
/home/qiurunze/下载/miaosha_1/src/main/java/com/geekq/miaosha/Test.java
|
||||
/home/qiurunze/下载/miaosha_1/src/main/java/com/geekq/miaosha/redis/KeyPrefix.java
|
||||
/home/qiurunze/下载/miaosha_1/src/main/java/com/geekq/miaosha/common/ResponseCode.java
|
||||
/home/qiurunze/下载/miaosha_1/src/main/java/com/geekq/miaosha/redis/RedisService.java
|
||||
/home/qiurunze/下载/miaosha_1/src/main/java/com/geekq/miaosha/mybatis/controller/MessageController.java
|
||||
/home/qiurunze/下载/miaosha_1/src/main/java/com/geekq/miaosha/utils/UUIDUtil.java
|
||||
/home/qiurunze/下载/miaosha_1/src/main/java/com/geekq/miaosha/domain/OrderInfo.java
|
||||
/home/qiurunze/下载/miaosha_1/src/main/java/com/geekq/miaosha/validator/IsMobile.java
|
||||
/home/qiurunze/下载/miaosha_1/src/main/java/com/geekq/miaosha/vo/OrderDetailVo.java
|
||||
/home/qiurunze/下载/miaosha_1/src/main/java/com/geekq/miaosha/rabbitmq/MQConfig.java
|
||||
/home/qiurunze/下载/miaosha_1/src/main/java/com/geekq/miaosha/dao/UserMapper.java
|
||||
/home/qiurunze/下载/miaosha_1/src/main/java/com/geekq/miaosha/redis/BasePrefix.java
|
||||
/home/qiurunze/下载/miaosha_1/src/main/java/com/geekq/miaosha/service/IUserService.java
|
||||
/home/qiurunze/下载/miaosha_1/src/main/java/com/geekq/miaosha/config/WebConfig.java
|
||||
/home/qiurunze/下载/miaosha_1/src/main/java/com/geekq/miaosha/redis/RedisConfig.java
|
||||
/home/qiurunze/下载/miaosha_1/src/main/java/com/geekq/miaosha/rabbitmq/MiaoshaMessage.java
|
||||
/home/qiurunze/下载/miaosha_1/src/main/java/com/geekq/miaosha/rabbitmq/MQReceiver.java
|
||||
/home/qiurunze/下载/miaosha_1/src/main/java/com/geekq/miaosha/controller/GoodsController.java
|
||||
/home/qiurunze/下载/miaosha_1/src/main/java/com/geekq/miaosha/dao/UserDao.java
|
||||
/home/qiurunze/下载/miaosha_1/src/main/java/com/geekq/miaosha/DemoTask.java
|
Binary file not shown.
Binary file not shown.
Loading…
Reference in New Issue
Block a user