Java秒杀
java秒杀项目
登录模块:
- 登录密码两次MD5加密:
- 用户端:PASS=MD5(明文+固定Salt)
- 服务端:PASS=MD5(用户输入+随机Salt)
- 用户端MD5加密是为了防止用户密码在网络中明文传输,服务端MD5加密是为了提高密码安全性,双 重保险。
private static final String salt = "1a2b3c4d";
public static String inputPassToFormPass(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);
}
//两次加密 MD5(MDS(pass明文+固定salt)+salt)
public static String inputPassToDbPass(String inputPass, String salt) {
String formPass = inputPassToFormPass(inputPass);
String dbPass = formPassToDBPass(formPass, salt);
return dbPass;
}
2.全局异常处理:
-
我们知道,系统中异常包括:编译时异常和运行时异常 RuntimeException ,前者通过捕获异常从而获取异常信息,后者主要通过规范代码开发、测试通过手段减少运行时异常的发生。在开发中,不管是dao层、service层还是controller层,都有可能抛出异常,在Springmvc中,能将所有类型的异常处理从各处理过程解耦出来,既保证了相关处理过程的功能较单一,也实现了异常信息的统一处理和维护。
-
SpringBoot全局异常处理方式主要两种:
使用 @ControllerAdvice 和 @ExceptionHandler 注解。 使用 ErrorController类 来实现
3.Redis实现分布式Session
-
分布式Session问题 之前的代码在我们之后一台应用系统,所有操作都在一台Tomcat上,没有什么问题。当我们部署多台 系统,配合Nginx的时候会出现用户登录的问题 原因 由于 Nginx 使用默认负载均衡策略(轮询),请求将会按照时间顺序逐一分发到后端应用上。 也就是说刚开始我们在 Tomcat1 登录之后,用户信息放在 Tomcat1 的 Session 里。过了一会,请求 又被 Nginx 分发到了 Tomcat2 上,这时 Tomcat2 上 Session 里还没有用户信息,于是又要登录。
-
将用户信息存入Redis
4.统一获取当前用户登录
- 使用mvc拦截器HandlerInterceptor+方法参数解析器HandlerMethodArgumentResolver,获取统一用户登录, 简化代码量,实现解耦。
5.解决超卖
- 减库存时判断库存是否足够。
- 用户id+商品id的唯一键索引,解决同一用户同时秒杀多件商品。
- 再加上逻辑判断。
6.优化
-
页面缓存:添加redis缓存,将前端页面保存到redis缓存。
-
对象缓存。
-
页面静态化。
-
将秒杀订单信息存入Redis,方便判断是否重复抢购时进行查询。
-
把商品库存加载到Redis中,redis预减库存,没有库存后,添加标记,避免频繁和ridis通信:
Map<Long, Boolean> EmptySocketMap = new HashMap<>();
6.接口优化:
- 思路:减少数据库访问,RabbitMQ topic模式
-
- 系统初始化,把商品库存数量加载到Redis
-
- 收到请求,Redis预减库存。库存不足,直接返回。否则进入第3步
-
- 请求入队,立即返回排队中
-
- 请求出队,生成订单,减少库存
-
- 客户端轮询,是否秒杀成功
- 安全优化:
- 秒杀接口地址隐藏,秒杀开始之前,先去请求接口获取秒杀地址。
- 点击秒杀开始前,先输入验证码,分散用户的请求。
8.接口限流