1.首先我们新建一个Controller用于秒杀:
package com.imooc.Controller;
import com.imooc.service.impl.SeckillServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* Created by zhongliahi on 2018/6/11.
* 秒杀测试
*/
@RestController
@RequestMapping(value = "/skill")
@Slf4j
public class SeckillController {
@Autowired
private SeckillServiceImpl seckillService;
//@PathVariable 可以将 URL 中占位符参数绑定到控制器处理方法的入参中
// URL 中的 {xxx} 占位符可以通过@PathVariable(“xxx“) 绑定到操作方法的入参中。
@GetMapping(value = "/query/{productId}")
public String query(@PathVariable String productId) throws Exception{
return seckillService.querySeckillProductInfo(productId);
}
@GetMapping("/order/{productId}")
public String skill(@PathVariable String productId) throws Exception{
log.info("秒杀----productId:"+productId);
seckillService.orderProductMockDiffUser(productId);
return seckillService.querySeckillProductInfo(productId);
}
}
2.建立一个Service
package com.imooc.service; /** * Created by zhongliahi on 2018/6/11. */ public interface SeckillService { String queryMap(String productId); String querySeckillProductInfo(String productId); void orderProductMockDiffUser(String productId); }
3.实现Service
package com.imooc.service.impl;
import com.imooc.Exception.SellException;
import com.imooc.enums.ExceptionEnum;
import com.imooc.service.SeckillService;
import com.imooc.util.KeyUtils;
import org.springframework.stereotype.Service;
import java.util.HashMap;
import java.util.Map;
/**
* Created by zhonglihai on 2018/6/11.
* 秒杀Serviceimpl
* 演示
*/
@Service
public class SeckillServiceImpl implements SeckillService {
/**
* 秒杀特价 1000000份
* @param productId
* @return
*/
static Map<String,Integer> products;
static Map<String,Integer> stock;
static Map<String,String> orders;
static{
/**
* ,模拟多个表,商品信息表,库存表,秒杀成功订单表
*/
products =new HashMap<>();
stock=new HashMap<>();
orders=new HashMap<>();
products.put("123",1000000);
stock.put("123",1000000);
}
@Override
public String queryMap(String productId) {
return "活动特价,限量:"+products.get(productId)+",还剩:"+stock.get(productId)
+"份"+",成功下单用户数:"+orders.size()+"人。";
}
@Override
public String querySeckillProductInfo(String productId) {
return this.queryMap(productId);
}
/**
* 主要秒杀的逻辑
* @param productId
*/
@Override
public synchronized void orderProductMockDiffUser(String productId) {
//查询该商品库存,为0则活动结束
int stockNum=stock.get(productId);
if(stockNum==0){
throw new SellException(ExceptionEnum.SECKILL_OVER);
}else{
//2.下单(模拟不同用户opendid不同)
orders.put(KeyUtils.getUniqueKey(),productId);
//3.减库存
stockNum=stockNum-1;
try{
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
stock.put(productId,stockNum);
}
}
}
关于压测:
压力测试是一种基本的质量保证行为,在秒杀活动中更为重要,防止超卖(卖出去的比库存的多)、少卖(有买了但是没卖),目前主流的工具与Jmeter、LoadRunner等,老一点的有apache ab等,正好本人机器装有Apace服务,因此使用apache 做压测。
原文:https://www.cnblogs.com/zhonglihai/p/9167120.html