:ambulance:多线程模拟秒杀无法获取 request 的问题

This commit is contained in:
zhipeng.zhang
2019-08-14 13:25:40 +08:00
parent 60d13d1d86
commit a3bf7fef6e
5 changed files with 405 additions and 396 deletions

View File

@@ -1,26 +1,26 @@
package com.itstyle.seckill;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
* 启动类
* 创建者 科帮网
* 创建时间 2018年5月12日
* API接口测试http://localhost:8080/seckill/swagger-ui.html
* 跑之前 一定要看文库https://gitee.com/52itstyle/spring-boot-seckill/wikis
*/
@SpringBootApplication
public class Application {
private final static Logger LOGGER = LoggerFactory.getLogger(Application.class);
/**
* 1. 数据库乐观锁2. 基于Redis的分布式锁3. 基于ZooKeeper的分布式锁
* 4. redis 订阅监听5.kafka消息队列
* 启动前 请配置application.properties中相关redis、zk以及kafka相关地址
*/
public static void main(String[] args) throws InterruptedException {
SpringApplication.run(Application.class, args);
LOGGER.info("项目启动 ");
}
package com.itstyle.seckill;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
* 启动类
* 创建者 科帮网
* 创建时间 2018年5月12日
* API接口测试http://localhost:8080/seckill/swagger-ui.html
* 跑之前 一定要看文库https://gitee.com/52itstyle/spring-boot-seckill/wikis
*/
@SpringBootApplication
public class Application {
private final static Logger LOGGER = LoggerFactory.getLogger(Application.class);
/**
* 1. 数据库乐观锁2. 基于Redis的分布式锁3. 基于ZooKeeper的分布式锁
* 4. redis 订阅监听5.kafka消息队列
* 启动前 请配置application.properties中相关redis、zk以及kafka相关地址
*/
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
LOGGER.info("项目启动");
}
}

View File

@@ -13,7 +13,6 @@ import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.context.annotation.Configuration;
import com.google.common.util.concurrent.RateLimiter;
import java.lang.reflect.Method;
import java.util.concurrent.TimeUnit;

View File

@@ -20,9 +20,9 @@ public class IPUtils {
* 如果使用了多级反向代理的话X-Forwarded-For的值并不止一个而是一串IP地址X-Forwarded-For中第一个非unknown的有效IP字符串则为真实IP地址
*/
public static String getIpAddr() {
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
String ip = null;
try {
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
ip = request.getHeader("x-forwarded-for");
if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("Proxy-Client-IP");

View File

@@ -1,284 +1,294 @@
package com.itstyle.seckill.web;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.itstyle.seckill.common.entity.Result;
import com.itstyle.seckill.common.entity.SuccessKilled;
import com.itstyle.seckill.queue.disruptor.DisruptorUtil;
import com.itstyle.seckill.queue.disruptor.SeckillEvent;
import com.itstyle.seckill.queue.jvm.SeckillQueue;
import com.itstyle.seckill.service.ISeckillService;
@Api(tags ="秒杀")
@RestController
@RequestMapping("/seckill")
public class SeckillController {
private final static Logger LOGGER = LoggerFactory.getLogger(SeckillController.class);
private static int corePoolSize = Runtime.getRuntime().availableProcessors();
//创建线程池 调整队列数 拒绝服务
private static ThreadPoolExecutor executor = new ThreadPoolExecutor(corePoolSize, corePoolSize+1, 10l, TimeUnit.SECONDS,
new LinkedBlockingQueue<Runnable>(1000));
@Autowired
private ISeckillService seckillService;
@ApiOperation(value="秒杀一(最low实现)",nickname="科帮网")
@PostMapping("/start")
public Result start(long seckillId){
int skillNum = 1000;
final CountDownLatch latch = new CountDownLatch(skillNum);//N个购买者
seckillService.deleteSeckill(seckillId);
final long killId = seckillId;
LOGGER.info("开始秒杀一(会出现超卖)");
for(int i=0;i<skillNum;i++){
final long userId = i;
Runnable task = new Runnable() {
@Override
public void run() {
Result result = seckillService.startSeckil(killId, userId);
if(result!=null){
LOGGER.info("用户:{}{}",userId,result.get("msg"));
}else{
LOGGER.info("用户:{}{}",userId,"哎呦喂,人也太多了,请稍后!");
}
latch.countDown();
}
};
executor.execute(task);
}
try {
latch.await();// 等待所有人任务结束
Long seckillCount = seckillService.getSeckillCount(seckillId);
LOGGER.info("一共秒杀出{}件商品",seckillCount);
} catch (InterruptedException e) {
e.printStackTrace();
}
return Result.ok();
}
@ApiOperation(value="秒杀二(程序锁)",nickname="科帮网")
@PostMapping("/startLock")
public Result startLock(long seckillId){
int skillNum = 1000;
final CountDownLatch latch = new CountDownLatch(skillNum);//N个购买者
seckillService.deleteSeckill(seckillId);
final long killId = seckillId;
LOGGER.info("开始秒杀二(正常)");
for(int i=0;i<1000;i++){
final long userId = i;
Runnable task = new Runnable() {
@Override
public void run() {
Result result = seckillService.startSeckilLock(killId, userId);
LOGGER.info("用户:{}{}",userId,result.get("msg"));
latch.countDown();
}
};
executor.execute(task);
}
try {
latch.await();// 等待所有人任务结束
Long seckillCount = seckillService.getSeckillCount(seckillId);
LOGGER.info("一共秒杀出{}件商品",seckillCount);
} catch (InterruptedException e) {
e.printStackTrace();
}
return Result.ok();
}
@ApiOperation(value="秒杀三(AOP程序锁)",nickname="科帮网")
@PostMapping("/startAopLock")
public Result startAopLock(long seckillId){
int skillNum = 1000;
final CountDownLatch latch = new CountDownLatch(skillNum);//N个购买者
seckillService.deleteSeckill(seckillId);
final long killId = seckillId;
LOGGER.info("开始秒杀三(正常)");
for(int i=0;i<1000;i++){
final long userId = i;
Runnable task = new Runnable() {
@Override
public void run() {
Result result = seckillService.startSeckilAopLock(killId, userId);
LOGGER.info("用户:{}{}",userId,result.get("msg"));
latch.countDown();
}
};
executor.execute(task);
}
try {
latch.await();// 等待所有人任务结束
Long seckillCount = seckillService.getSeckillCount(seckillId);
LOGGER.info("一共秒杀出{}件商品",seckillCount);
} catch (InterruptedException e) {
e.printStackTrace();
}
return Result.ok();
}
@ApiOperation(value="秒杀四(数据库悲观锁)",nickname="科帮网")
@PostMapping("/startDBPCC_ONE")
public Result startDBPCC_ONE(long seckillId){
int skillNum = 1000;
final CountDownLatch latch = new CountDownLatch(skillNum);//N个购买者
seckillService.deleteSeckill(seckillId);
final long killId = seckillId;
LOGGER.info("开始秒杀四(正常)");
for(int i=0;i<1000;i++){
final long userId = i;
Runnable task = new Runnable() {
@Override
public void run() {
Result result = seckillService.startSeckilDBPCC_ONE(killId, userId);
LOGGER.info("用户:{}{}",userId,result.get("msg"));
latch.countDown();
}
};
executor.execute(task);
}
try {
latch.await();// 等待所有人任务结束
Long seckillCount = seckillService.getSeckillCount(seckillId);
LOGGER.info("一共秒杀出{}件商品",seckillCount);
} catch (InterruptedException e) {
e.printStackTrace();
}
return Result.ok();
}
@ApiOperation(value="秒杀五(数据库悲观锁)",nickname="科帮网")
@PostMapping("/startDPCC_TWO")
public Result startDPCC_TWO(long seckillId){
int skillNum = 1000;
final CountDownLatch latch = new CountDownLatch(skillNum);//N个购买者
seckillService.deleteSeckill(seckillId);
final long killId = seckillId;
LOGGER.info("开始秒杀五(正常、数据库锁最优实现)");
for(int i=0;i<1000;i++){
final long userId = i;
Runnable task = new Runnable() {
@Override
public void run() {
Result result = seckillService.startSeckilDBPCC_TWO(killId, userId);
LOGGER.info("用户:{}{}",userId,result.get("msg"));
latch.countDown();
}
};
executor.execute(task);
}
try {
latch.await();// 等待所有人任务结束
Long seckillCount = seckillService.getSeckillCount(seckillId);
LOGGER.info("一共秒杀出{}件商品",seckillCount);
} catch (InterruptedException e) {
e.printStackTrace();
}
return Result.ok();
}
@ApiOperation(value="秒杀六(数据库乐观锁)",nickname="科帮网")
@PostMapping("/startDBOCC")
public Result startDBOCC(long seckillId){
int skillNum = 1000;
final CountDownLatch latch = new CountDownLatch(skillNum);//N个购买者
seckillService.deleteSeckill(seckillId);
final long killId = seckillId;
LOGGER.info("开始秒杀六(正常、数据库锁最优实现)");
for(int i=0;i<1000;i++){
final long userId = i;
Runnable task = new Runnable() {
@Override
public void run() {
//这里使用的乐观锁、可以自定义抢购数量、如果配置的抢购人数比较少、比如120:100(人数:商品) 会出现少买的情况
//用户同时进入会出现更新失败的情况
Result result = seckillService.startSeckilDBOCC(killId, userId,1);
LOGGER.info("用户:{}{}",userId,result.get("msg"));
latch.countDown();
}
};
executor.execute(task);
}
try {
latch.await();// 等待所有人任务结束
Long seckillCount = seckillService.getSeckillCount(seckillId);
LOGGER.info("一共秒杀出{}件商品",seckillCount);
} catch (InterruptedException e) {
e.printStackTrace();
}
return Result.ok();
}
@ApiOperation(value="秒杀柒(进程内队列)",nickname="科帮网")
@PostMapping("/startQueue")
public Result startQueue(long seckillId){
seckillService.deleteSeckill(seckillId);
final long killId = seckillId;
LOGGER.info("开始秒杀柒(正常)");
for(int i=0;i<1000;i++){
final long userId = i;
Runnable task = new Runnable() {
@Override
public void run() {
SuccessKilled kill = new SuccessKilled();
kill.setSeckillId(killId);
kill.setUserId(userId);
try {
Boolean flag = SeckillQueue.getMailQueue().produce(kill);
if(flag){
LOGGER.info("用户:{}{}",kill.getUserId(),"秒杀成功");
}else{
LOGGER.info("用户:{}{}",userId,"秒杀失败");
}
} catch (InterruptedException e) {
e.printStackTrace();
LOGGER.info("用户:{}{}",userId,"秒杀失败");
}
}
};
executor.execute(task);
}
try {
Thread.sleep(10000);
Long seckillCount = seckillService.getSeckillCount(seckillId);
LOGGER.info("一共秒杀出{}件商品",seckillCount);
} catch (InterruptedException e) {
e.printStackTrace();
}
return Result.ok();
}
@ApiOperation(value="秒杀柒(Disruptor队列)",nickname="科帮网")
@PostMapping("/startDisruptorQueue")
public Result startDisruptorQueue(long seckillId){
seckillService.deleteSeckill(seckillId);
final long killId = seckillId;
LOGGER.info("开始秒杀八(正常)");
for(int i=0;i<1000;i++){
final long userId = i;
Runnable task = new Runnable() {
@Override
public void run() {
SeckillEvent kill = new SeckillEvent();
kill.setSeckillId(killId);
kill.setUserId(userId);
DisruptorUtil.producer(kill);
}
};
executor.execute(task);
}
try {
Thread.sleep(10000);
Long seckillCount = seckillService.getSeckillCount(seckillId);
LOGGER.info("一共秒杀出{}件商品",seckillCount);
} catch (InterruptedException e) {
e.printStackTrace();
}
return Result.ok();
}
}
package com.itstyle.seckill.web;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.itstyle.seckill.common.entity.Result;
import com.itstyle.seckill.common.entity.SuccessKilled;
import com.itstyle.seckill.queue.disruptor.DisruptorUtil;
import com.itstyle.seckill.queue.disruptor.SeckillEvent;
import com.itstyle.seckill.queue.jvm.SeckillQueue;
import com.itstyle.seckill.service.ISeckillService;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
@Api(tags ="秒杀")
@RestController
@RequestMapping("/seckill")
public class SeckillController {
private final static Logger LOGGER = LoggerFactory.getLogger(SeckillController.class);
private static int corePoolSize = Runtime.getRuntime().availableProcessors();
//创建线程池 调整队列数 拒绝服务
private static ThreadPoolExecutor executor = new ThreadPoolExecutor(corePoolSize, corePoolSize+1, 10l, TimeUnit.SECONDS,
new LinkedBlockingQueue<Runnable>(1000));
@Autowired
private ISeckillService seckillService;
@ApiOperation(value="秒杀一(最low实现)",nickname="科帮网")
@PostMapping("/start")
public Result start(long seckillId){
int skillNum = 10;
final CountDownLatch latch = new CountDownLatch(skillNum);//N个购买者
seckillService.deleteSeckill(seckillId);
final long killId = seckillId;
LOGGER.info("开始秒杀一(会出现超卖)");
/**
* 开启新线程之前将RequestAttributes对象设置为子线程共享
* 这里仅仅是为了测试,否则 IPUtils 中获取不到 request 对象
* 用到限流注解的测试用例,都需要加一下两行代码
*/
ServletRequestAttributes sra = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
RequestContextHolder.setRequestAttributes(sra, true);
for(int i=0;i<skillNum;i++){
final long userId = i;
Runnable task = new Runnable() {
@Override
public void run() {
Result result = seckillService.startSeckil(killId, userId);
if(result!=null){
LOGGER.info("用户:{}{}",userId,result.get("msg"));
}else{
LOGGER.info("用户:{}{}",userId,"哎呦喂,人也太多了,请稍后!");
}
latch.countDown();
}
};
executor.execute(task);
}
try {
latch.await();// 等待所有人任务结束
Long seckillCount = seckillService.getSeckillCount(seckillId);
LOGGER.info("一共秒杀出{}件商品",seckillCount);
} catch (InterruptedException e) {
e.printStackTrace();
}
return Result.ok();
}
@ApiOperation(value="秒杀二(程序锁)",nickname="科帮网")
@PostMapping("/startLock")
public Result startLock(long seckillId){
int skillNum = 1000;
final CountDownLatch latch = new CountDownLatch(skillNum);//N个购买者
seckillService.deleteSeckill(seckillId);
final long killId = seckillId;
LOGGER.info("开始秒杀二(正常)");
for(int i=0;i<1000;i++){
final long userId = i;
Runnable task = new Runnable() {
@Override
public void run() {
Result result = seckillService.startSeckilLock(killId, userId);
LOGGER.info("用户:{}{}",userId,result.get("msg"));
latch.countDown();
}
};
executor.execute(task);
}
try {
latch.await();// 等待所有人任务结束
Long seckillCount = seckillService.getSeckillCount(seckillId);
LOGGER.info("一共秒杀出{}件商品",seckillCount);
} catch (InterruptedException e) {
e.printStackTrace();
}
return Result.ok();
}
@ApiOperation(value="秒杀三(AOP程序锁)",nickname="科帮网")
@PostMapping("/startAopLock")
public Result startAopLock(long seckillId){
int skillNum = 1000;
final CountDownLatch latch = new CountDownLatch(skillNum);//N个购买者
seckillService.deleteSeckill(seckillId);
final long killId = seckillId;
LOGGER.info("开始秒杀三(正常)");
for(int i=0;i<1000;i++){
final long userId = i;
Runnable task = new Runnable() {
@Override
public void run() {
Result result = seckillService.startSeckilAopLock(killId, userId);
LOGGER.info("用户:{}{}",userId,result.get("msg"));
latch.countDown();
}
};
executor.execute(task);
}
try {
latch.await();// 等待所有人任务结束
Long seckillCount = seckillService.getSeckillCount(seckillId);
LOGGER.info("一共秒杀出{}件商品",seckillCount);
} catch (InterruptedException e) {
e.printStackTrace();
}
return Result.ok();
}
@ApiOperation(value="秒杀四(数据库悲观锁)",nickname="科帮网")
@PostMapping("/startDBPCC_ONE")
public Result startDBPCC_ONE(long seckillId){
int skillNum = 1000;
final CountDownLatch latch = new CountDownLatch(skillNum);//N个购买者
seckillService.deleteSeckill(seckillId);
final long killId = seckillId;
LOGGER.info("开始秒杀四(正常)");
for(int i=0;i<1000;i++){
final long userId = i;
Runnable task = new Runnable() {
@Override
public void run() {
Result result = seckillService.startSeckilDBPCC_ONE(killId, userId);
LOGGER.info("用户:{}{}",userId,result.get("msg"));
latch.countDown();
}
};
executor.execute(task);
}
try {
latch.await();// 等待所有人任务结束
Long seckillCount = seckillService.getSeckillCount(seckillId);
LOGGER.info("一共秒杀出{}件商品",seckillCount);
} catch (InterruptedException e) {
e.printStackTrace();
}
return Result.ok();
}
@ApiOperation(value="秒杀五(数据库悲观锁)",nickname="科帮网")
@PostMapping("/startDPCC_TWO")
public Result startDPCC_TWO(long seckillId){
int skillNum = 1000;
final CountDownLatch latch = new CountDownLatch(skillNum);//N个购买者
seckillService.deleteSeckill(seckillId);
final long killId = seckillId;
LOGGER.info("开始秒杀五(正常、数据库锁最优实现)");
for(int i=0;i<1000;i++){
final long userId = i;
Runnable task = new Runnable() {
@Override
public void run() {
Result result = seckillService.startSeckilDBPCC_TWO(killId, userId);
LOGGER.info("用户:{}{}",userId,result.get("msg"));
latch.countDown();
}
};
executor.execute(task);
}
try {
latch.await();// 等待所有人任务结束
Long seckillCount = seckillService.getSeckillCount(seckillId);
LOGGER.info("一共秒杀出{}件商品",seckillCount);
} catch (InterruptedException e) {
e.printStackTrace();
}
return Result.ok();
}
@ApiOperation(value="秒杀六(数据库乐观锁)",nickname="科帮网")
@PostMapping("/startDBOCC")
public Result startDBOCC(long seckillId){
int skillNum = 1000;
final CountDownLatch latch = new CountDownLatch(skillNum);//N个购买者
seckillService.deleteSeckill(seckillId);
final long killId = seckillId;
LOGGER.info("开始秒杀六(正常、数据库锁最优实现)");
for(int i=0;i<1000;i++){
final long userId = i;
Runnable task = new Runnable() {
@Override
public void run() {
//这里使用的乐观锁、可以自定义抢购数量、如果配置的抢购人数比较少、比如120:100(人数:商品) 会出现少买的情况
//用户同时进入会出现更新失败的情况
Result result = seckillService.startSeckilDBOCC(killId, userId,1);
LOGGER.info("用户:{}{}",userId,result.get("msg"));
latch.countDown();
}
};
executor.execute(task);
}
try {
latch.await();// 等待所有人任务结束
Long seckillCount = seckillService.getSeckillCount(seckillId);
LOGGER.info("一共秒杀出{}件商品",seckillCount);
} catch (InterruptedException e) {
e.printStackTrace();
}
return Result.ok();
}
@ApiOperation(value="秒杀柒(进程内队列)",nickname="科帮网")
@PostMapping("/startQueue")
public Result startQueue(long seckillId){
seckillService.deleteSeckill(seckillId);
final long killId = seckillId;
LOGGER.info("开始秒杀柒(正常)");
for(int i=0;i<1000;i++){
final long userId = i;
Runnable task = new Runnable() {
@Override
public void run() {
SuccessKilled kill = new SuccessKilled();
kill.setSeckillId(killId);
kill.setUserId(userId);
try {
Boolean flag = SeckillQueue.getMailQueue().produce(kill);
if(flag){
LOGGER.info("用户:{}{}",kill.getUserId(),"秒杀成功");
}else{
LOGGER.info("用户:{}{}",userId,"秒杀失败");
}
} catch (InterruptedException e) {
e.printStackTrace();
LOGGER.info("用户:{}{}",userId,"秒杀失败");
}
}
};
executor.execute(task);
}
try {
Thread.sleep(10000);
Long seckillCount = seckillService.getSeckillCount(seckillId);
LOGGER.info("一共秒杀出{}件商品",seckillCount);
} catch (InterruptedException e) {
e.printStackTrace();
}
return Result.ok();
}
@ApiOperation(value="秒杀柒(Disruptor队列)",nickname="科帮网")
@PostMapping("/startDisruptorQueue")
public Result startDisruptorQueue(long seckillId){
seckillService.deleteSeckill(seckillId);
final long killId = seckillId;
LOGGER.info("开始秒杀八(正常)");
for(int i=0;i<1000;i++){
final long userId = i;
Runnable task = new Runnable() {
@Override
public void run() {
SeckillEvent kill = new SeckillEvent();
kill.setSeckillId(killId);
kill.setUserId(userId);
DisruptorUtil.producer(kill);
}
};
executor.execute(task);
}
try {
Thread.sleep(10000);
Long seckillCount = seckillService.getSeckillCount(seckillId);
LOGGER.info("一共秒杀出{}件商品",seckillCount);
} catch (InterruptedException e) {
e.printStackTrace();
}
return Result.ok();
}
}

View File

@@ -1,85 +1,85 @@
package com.itstyle.seckill.web;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import java.util.List;
import javax.jms.Destination;
import javax.servlet.http.HttpServletRequest;
import org.apache.activemq.command.ActiveMQQueue;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpMethod;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.alibaba.fastjson.JSONObject;
import com.itstyle.seckill.common.entity.Result;
import com.itstyle.seckill.common.entity.Seckill;
import com.itstyle.seckill.common.utils.HttpClient;
import com.itstyle.seckill.common.utils.IPUtils;
import com.itstyle.seckill.queue.activemq.ActiveMQSender;
import com.itstyle.seckill.service.ISeckillService;
@Api(tags = "秒杀商品")
@RestController
@RequestMapping("/seckillPage")
public class SeckillPageController {
@Autowired
private ISeckillService seckillService;
@Autowired
private ActiveMQSender activeMQSender;
@Autowired
private HttpClient httpClient;
@Value("${qq.captcha.url}")
private String url;
@Value("${qq.captcha.aid}")
private String aid;
@Value("${qq.captcha.AppSecretKey}")
private String appSecretKey;
@ApiOperation(value = "秒杀商品列表", nickname = "小柒2012")
@PostMapping("/list")
public Result list() {
//返回JSON数据、前端VUE迭代即可
List<Seckill> List = seckillService.getSeckillList();
return Result.ok(List);
}
@RequestMapping("/startSeckill")
public Result startSeckill(String ticket,String randstr,HttpServletRequest request) {
HttpMethod method =HttpMethod.POST;
MultiValueMap<String, String> params= new LinkedMultiValueMap<String, String>();
params.add("aid", aid);
params.add("AppSecretKey", appSecretKey);
params.add("Ticket", ticket);
params.add("Randstr", randstr);
params.add("UserIP", IPUtils.getIpAddr(request));
String msg = httpClient.client(url,method,params);
/**
* response: 1:验证成功0:验证失败100:AppSecretKey参数校验错误[required]
* evil_level:[0,100],恶意等级[optional]
* err_msg:验证错误信息[optional]
*/
//{"response":"1","evil_level":"0","err_msg":"OK"}
JSONObject json = JSONObject.parseObject(msg);
String response = (String) json.get("response");
if("1".equals(response)){
//进入队列、假数据而已
Destination destination = new ActiveMQQueue("seckill.queue");
activeMQSender.sendChannelMess(destination,1000+";"+1);
return Result.ok();
}else{
return Result.error("验证失败");
}
}
}
package com.itstyle.seckill.web;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import java.util.List;
import javax.jms.Destination;
import javax.servlet.http.HttpServletRequest;
import org.apache.activemq.command.ActiveMQQueue;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpMethod;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.alibaba.fastjson.JSONObject;
import com.itstyle.seckill.common.entity.Result;
import com.itstyle.seckill.common.entity.Seckill;
import com.itstyle.seckill.common.utils.HttpClient;
import com.itstyle.seckill.common.utils.IPUtils;
import com.itstyle.seckill.queue.activemq.ActiveMQSender;
import com.itstyle.seckill.service.ISeckillService;
@Api(tags = "秒杀商品")
@RestController
@RequestMapping("/seckillPage")
public class SeckillPageController {
@Autowired
private ISeckillService seckillService;
@Autowired
private ActiveMQSender activeMQSender;
@Autowired
private HttpClient httpClient;
@Value("${qq.captcha.url}")
private String url;
@Value("${qq.captcha.aid}")
private String aid;
@Value("${qq.captcha.AppSecretKey}")
private String appSecretKey;
@ApiOperation(value = "秒杀商品列表", nickname = "小柒2012")
@PostMapping("/list")
public Result list() {
//返回JSON数据、前端VUE迭代即可
List<Seckill> List = seckillService.getSeckillList();
return Result.ok(List);
}
@RequestMapping("/startSeckill")
public Result startSeckill(String ticket,String randstr,HttpServletRequest request) {
HttpMethod method =HttpMethod.POST;
MultiValueMap<String, String> params= new LinkedMultiValueMap<String, String>();
params.add("aid", aid);
params.add("AppSecretKey", appSecretKey);
params.add("Ticket", ticket);
params.add("Randstr", randstr);
params.add("UserIP", IPUtils.getIpAddr());
String msg = httpClient.client(url,method,params);
/**
* response: 1:验证成功0:验证失败100:AppSecretKey参数校验错误[required]
* evil_level:[0,100],恶意等级[optional]
* err_msg:验证错误信息[optional]
*/
//{"response":"1","evil_level":"0","err_msg":"OK"}
JSONObject json = JSONObject.parseObject(msg);
String response = (String) json.get("response");
if("1".equals(response)){
//进入队列、假数据而已
Destination destination = new ActiveMQQueue("seckill.queue");
activeMQSender.sendChannelMess(destination,1000+";"+1);
return Result.ok();
}else{
return Result.error("验证失败");
}
}
}