您的位置:首页 > 娱乐 > 八卦 > 深圳手机网站建设服务_项目网络计划图_百度免费网站制作_在线子域名二级域名查询工具

深圳手机网站建设服务_项目网络计划图_百度免费网站制作_在线子域名二级域名查询工具

2025/5/2 2:20:13 来源:https://blog.csdn.net/backlash321/article/details/147561905  浏览:    关键词:深圳手机网站建设服务_项目网络计划图_百度免费网站制作_在线子域名二级域名查询工具
深圳手机网站建设服务_项目网络计划图_百度免费网站制作_在线子域名二级域名查询工具

文章目录

  • 1. session管理
    • 1.1 手机号登录流程
    • 1.2 session的数据结构设计
      • 1.2.1 一些概念
      • 1.2.2 session数据结构例子
    • 1.3 引入redis来实现共享session
      • 1.3.1 流程
        • 发送验证码短信的流程
        • 验证码登录流程
        • 登录检查流程
      • 1.3.2 要考虑的问题
  • 2. 限时抢购代金券
    • 2.1 业务流程
    • 2.2 代金券表设计
    • 2.3 高并发场景面临的问题
      • 2.3.1 问题
      • 2.3.2 工具
      • 2.3.3 解决方案

1. session管理

1.1 手机号登录流程

  • 发送短信验证码流程:输入手机号 --> 验证手机号合法(否则回到”输入手机号“) --> 生成验证码 --> 保存验证码到session --> 发送验证码短信。

  • 验证码登录流程:输入手机号、验证码 --> 校验验证码(session中的有没有用户提交的验证码) --> 校验通过,以手机号找用户 --> 用户存在,下一步;用户不存在,则创建用户,再下一步 --> 保存用户信息到session。

  • 登录检查流程:请求携带cookie ,从cookie中拿session id --> 根据session id拿session对象,判断用户是否在session中(用户登录过则在seesion中有记录) --> 用户不存在终止请求响应,或者重定向到登录页;用户存在,继续响应,注意要缓存用户信息,方便后续使用。

如果采用单体服务-单线程-多协程的方式来处理请求,那么session是线程的数据,协程共享它。如果考虑负载均衡而使用多个server实例,那么session要在这些服务实例之间共享,此时只能使用redis(在内存,kv,server实例之间共享)。即session是多个server实例之间共享的状态。

1.2 session的数据结构设计

1.2.1 一些概念

什么是web应用的状态:客户端与服务器在多次交互过程中产生的上下文信息,例如用户登录凭证、购物车内容、操作历史等。

为什么需要状态:判断请求之间的关联性。如判断两次请求是否来自同一个用户,判断两次请求是否来自同一客户端。

session的作用:HTTP是无状态协议,因此需要使用session(服务端维护)跟踪用户状态,常见的状态化机制还有Cookie(服务端分发,客户端携带),Token(服务端分发,客户端携带)。

1.2.2 session数据结构例子

session_obj1 = {'user_id': 'abc','phone': '13112341234','expire_time': 1745738823
}
session_obj2 = {'user_id': 'ABC','phone': '13112341234','expire_time': 1745738823
}
session = {'001': session_obj1,'002': session_obj2
}

1.3 引入redis来实现共享session

redis中保存两类数据:每个手机号的申请的验证码;登录成功的用户信息

1.3.1 流程

发送验证码短信的流程

输入手机号 --> 验证手机号合法(否则回到”输入手机号“) --> 生成验证码 --> 保存验证码到redis,注意加过期时间 ( eg, key=phone:13212341234, val=31245 ) --> 发送验证码短信。

验证码登录流程

输入手机号、验证码 --> 校验验证码(redis中,verify_code = GET phone:13212341234, if verify_code == in_verify_code) --> 校验通过,以手机号找用户 --> 用户存在,下一步;用户不存在,则创建用户,再下一步 --> 保存用户信息到redis( 方式一:用户信息序列化为string形式保存,方式二:直接使用hash,key的格式:token:uuid )。

登录检查流程

请求携带cookie ,从cookie中拿token --> 根据token从redis拿用户信息 --> 拿到用户信息,继续响应,注意要缓存用户信息,方便后续使用同时刷新token过期时间,保证只要用户有请求,登录状态就一直保持;没拿到用户信息,终止请求响应,或者重定向到登录页。

1.3.2 要考虑的问题

问题:如果用户登录后,相当长的一段时间访问那些不需要登录认证的页面,则token一直不会被刷新而自动掉线,这是不合理的。

解决:所有路径都执行刷新token的动作(根据请求cookie中的token访问redis,获取用户信息,用线程变量缓存用户信息,刷新token过期时间),在需要登录认证的路径做额外的登录状态检查工作(检查缓存中是否有用户信息,如果没有则终止继续响应或者重定向到登录页;如果有则继续响应)。

2. 限时抢购代金券

2.1 业务流程

基本流程:查询代金券券(by id) --> 检查时效 --> 检查库存 --> 扣减库存 --> 创建代金券订单并返回订单id

一人只能购买一个单限制下的流程:查询代金券券(by id) --> 检查时效,在时效内继续 --> 检查库存,库存充足继续 --> 根据用户id和代金券di检查代金券订单,订单不存在继续 --> 扣减库存 --> 创建代金券订单并返回订单id

2.2 代金券表设计

对象:普通代金券,限时抢购代金券,代金券订单

表设计:

voucher(voucher_id, shop_id, title, sub_title, rules, pay_value, actual_value, type, status, create_time, update_time)

time_lmt_voucher(voucher_id, stock, start_time, end_time, create_time, update_time)

voucher_order(id, user_id, voucher_id, pay_type, status, pay_time, use_time, refund_time, create_time, update_time)

说明:其中,voucher和time_lmt_voucher是一对一关系,time_lmt_voucher是voucher的扩展。

2.3 高并发场景面临的问题

2.3.1 问题

  1. 超卖(库存为负数):扣减库存逻包含两个操作:读库存并判断库存是否充足,假设初始情况下库存为1(记为op1);更新库存为0(记为op2)。线程1执行op1后线程2也执行op1,然后线程1执行op2,库存为0,线程2再执行op2,库存为-1。
  2. 一人一单限制失效:业务逻辑包含两个操作:根据用户id和代金券id查询代金券订单是否存在,假设初始情况下用户没有代金券订单(记为op1);创建新订单(记为op2)。线程1执行op1后,线程2也执行op1,然后线程1执行op2,创建一个订单,线程2再执行op2,又创建了一个订单。
  3. 使用数据库的自增id作为订单id存在风险(如根据订单id差值推测出订单量等),且订单数量可能受限。

2.3.2 工具

乐观锁:线程不安全不一定发生,不加锁,只有在更新数据时才检查数据是否被已经被修改。使用版本号控制,先访问数据得到版本好,更新时比较版本号,版本号一致则更新数据同时更新版本号,版本号不一致则拒绝更新。

悲观锁:线程不安全一定发生,在访问数据前加锁。

2.3.3 解决方案

  1. 超卖(库存为负数):使用CAS(Compare And Set)原则,限制库存更新操作条件,用op1查询的库存结果来限制op2的更新操作,set time_lmt_voucher into stock=stock-1 where stock=1;
  2. 一人一单限制失效:使用互斥锁构建临界区,把op1和op2放进去。单体服务用进程锁,线程锁,协程锁。分布式服务使用分布式锁。
  3. 使用redis做一个全局id生成器(唯一性,高可用,高性能,递增,安全),id(64bits): 时间戳(32bist) + 序列号(32bits)。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com