1 如何设计一个秒杀系统
2 项目搭建
2.1 逆向工程
通过逆向工程基于 t_user 表生产对应的POJO、Mapper、Service、ServiceImpl、Controller等类,项目中使用了MybatisPlus,所以逆向工程也是用了MybatisPlus提供的AutoGenerator.
2.2 公共返回对象
//公共返回对象枚举@Data@ToStringpublic enum RespBeanEnum {//通用SUCCESS(200, "SUCCESS"),ERROR(500, "服务端异常"),//登录模块5002xxLOGIN_ERROR(500210, "用户名或密码不正确"),MOBILE_ERROR(500211, "手机号码格式不正确"),BIND_ERROR(500212, "参数校验异常"),MOBILE_NOT_EXIST(500213, "手机号码不存在"),PASSWORD_UPDATE_FAIL(500214, "密码更新失败"),SESSION_ERROR(500215, "用户不存在"),//秒杀模块5005xxEMPTY_STOCK(500500, "库存不足"),REPEATE_ERROR(500501, "该商品每人限购一件"),REQUEST_ILLEGAL(500502, "请求非法,请重新尝试"),ERROR_CAPTCHA(500503, "验证码错误,请重新输入"),ACCESS_LIMIT_REAHCED(500504, "访问过于频繁,请稍后再试"),//订单模块5003xxORDER_NOT_EXIST(500300, "订单信息不存在"),;private final Integer code;private final String message;}//公共返回对象@Data@NoArgsConstructor@AllArgsConstructorpublic class RespBean {private long code;private String message;private Object obj;/*** 功能描述: 成功返回结果*/public static RespBean success(){return new RespBean(RespBeanEnum.SUCCESS.getCode(),RespBeanEnum.SUCCESS.getMessage(),null);}/*** 功能描述: 成功返回结果*/public static RespBean success(Object obj){return new RespBean(RespBeanEnum.SUCCESS.getCode(),RespBean.success().getMessage(),obj);}/*** 功能描述: 失败返回结果*/public static RespBean error(RespBeanEnum respBeanEnum){return new RespBean(respBeanEnum.getCode(),respBeanEnum.getMessage(),null);}/*** 功能描述: 失败返回结果*/public static RespBean error(RespBeanEnum respBeanEnum,Object obj){return new RespBean(respBeanEnum.getCode(),respBeanEnum.getMessage(),obj);}}
3 分布式会话
3.1 实现登陆功能
3.1.1 两次MD5加密
- 用户端: PASS=MD5(明文+固定Salt)
- 服务端: PASS=MD5(用户输入+随机Salt)
用户端MD5加密是为了防止用户密码在网络中明文传输,服务端MD5加密是为了提高密码安全性,双重保险,数据库被盗后可能根据加密后的密文和Salt字段反推出明文密码,故存入数据库前再进行一次加密。
引入pom.xml
<!-- md5 依赖 --><dependency><groupId>commons-codec</groupId><artifactId>commons-codec</artifactId></dependency><dependency><groupId>org.apache.commons</groupId><artifactId>commons-lang3</artifactId><version>3.6</version></dependency>
实现代码
public class MD5Util {public static String md5(String src){return DigestUtils.md5Hex(src);}private static final String salt="1a2b3c4d";public static String inputPassToFromPass(String inputPass){String str = "" +salt.charAt(0)+salt.charAt(2)+inputPass+salt.charAt(5)+salt.charAt(4);return md5(str);}public static String formPassToDBPass(String formPass,String salt){String str = "" +salt.charAt(0)+salt.charAt(2)+formPass+salt.charAt(5)+salt.charAt(4);return md5(str);}public static String inputPassToDBPass(String inputPass,String salt){String fromPass = inputPassToFromPass(inputPass);String dbPass = formPassToDBPass(fromPass, salt);return dbPass;}public static void main(String[] args) {// d3b1294a61a07da9b49b6e22b2cbd7f9System.out.println(inputPassToFromPass("123456"));System.out.println(formPassToDBPass("d3b1294a61a07da9b49b6e22b2cbd7f9","1a2b3c4d"));System.out.println(inputPassToDBPass("123456","1a2b3c4d"));}}
