湘潭网站建设 皆来磐石网络,外贸公司怎么开,营销型网站的页面层级,如何利用国外网站开发客户文章目录 1.项目介绍2. 分布式登录功能2.1 讲讲登录的整个流程2.2 集群模式session下存储用户信息会有啥问题#xff1f;2.3 为什么采用redis存储用户信息和验证码2.4 redis的存储格式怎么样的#xff1f;2.5 为什么采用Hash结构存储用户信息2.6 为什么采用双拦截器#xff… 文章目录 1.项目介绍2. 分布式登录功能2.1 讲讲登录的整个流程2.2 集群模式session下存储用户信息会有啥问题2.3 为什么采用redis存储用户信息和验证码2.4 redis的存储格式怎么样的2.5 为什么采用Hash结构存储用户信息2.6 为什么采用双拦截器每个拦截器负责什么功能 3 商品缓存功能3.1 什么是延时双删为什么要删两次缓存 4 优惠券秒杀功能4.1 全局唯一ID是怎么实现的4.2 秒杀下单的流程是怎么样的4.3 如何解决超卖问题4.4 如何实现一人一单4.5 锁在事务内部会存在什么问题4.6 分布式锁的误删情况了解吗?4.7 如何实现调用lua4.8 分布式锁失效问题如何解决 5.秒杀优化5.1 秒杀优化流程解析5.2 你使用Jmemter主要是看什么5.3 你的阻塞队列的东西什么时候提交线程任务呢5.4 为什么采用redis的消息队列而不使用jvm的阻塞队列5.5 聊一下redis有哪些消息队列 6.多用户行为管理6.1 如何设计点赞排行榜时间功能的6.2 如何实现关注和共同关注6.3 如何实现附近商铺功能的6.4 如何实现用户签到功能 1.项目介绍
美食项目主要是一个基于SpringBoot的前后端分离项目集成了redis,tomcat,mysql。类似于大众点评。实现了短信登录商户查询缓存优惠券秒杀附近的商户UV统计用户签到好友关注达人探店
2. 分布式登录功能
分布式登录功能基于Redis双拦截机制解决集群下session共享问题利用ThrealLocal存储用户信息
2.1 讲讲登录的整个流程 1.验证码生成用户提交手机号点击发送验证码后端生成验证码存储phone,code到redis返回验证码到前端 2.登录提交手机号和验证码redis中获取验证码校验校验过了查询用户存在则UUID 生成token,存储(token, user)到redis,不存在就新建用户先再存储到redis。返回token信息给前端 2.2 集群模式session下存储用户信息会有啥问题 tomcat并不共享session内存空间一台tomcat无法获取存储在另一台tomcat的session数据 2.3 为什么采用redis存储用户信息和验证码 redis基于内存速度快可以实现集群共享 可以存储key,value数据结构 2.4 redis的存储格式怎么样的 验证码(key, value) — (手机号随机六位数字) String结构 用户信息key, value– (token, 用户信息) Hash结构 2.5 为什么采用Hash结构存储用户信息 内存占用少存取操作方便。针对某个字段可以做增删改操作。 String类型需要全部删除 2.6 为什么采用双拦截器每个拦截器负责什么功能 第一个拦截器判断token是否存在存在找到用户信息存入threadlocal。并刷新token有效期然后放行 判断threadlocal是否有值有则放行无则拦截 3 商品缓存功能
采用Redis实现商品毫秒级响应采用延时双删策略保证数据的一致性。
3.1 什么是延时双删为什么要删两次缓存 延时双删是为了解决数据库数据和缓存数据不一致的问题。先删除缓存再更新数据库延迟一会再删除缓存。删两次缓存时因为并发环境下可能数据库还没更新成功请求来了读取到了数据库的旧数据回填到redis。所以需要延时一会再删一次缓存。 4 优惠券秒杀功能
基于Redis实现全局唯一订单IDCAS解决库存超卖问题Redission分布式锁解决一人一单并发安全问题
4.1 全局唯一ID是怎么实现的 符号位时间戳计数器应用到了String中的incrby功能 其中key采用每天生成不同的key,方便统计每天的订单数量 4.2 秒杀下单的流程是怎么样的 提交优惠券ID查询优惠券信息判断秒杀是否开始判断库存是否充足查询订单校验一人一单减库存均满足创建订单返回订单ID即可 4.3 如何解决超卖问题 使用CAS乐观锁在扣减库存的时候判断库存是否大于0.但是本质还是用到了数据库中的行锁吧修改数据加了写锁。这里锁的是库存 4.4 如何实现一人一单 在扣减库存之前到订单表查询用户ID和优惠券ID是否存在存在存在就拒绝后续动作。这里要加悲观锁锁用户ID注意这里通过userId.toString.intern()获取字符串常量池的规范表示值相同的地址相同可以锁住因为toString方法都会底层是新new了一个对象 注意这里锁的是用户ID要保证事务提交了锁才能释放
4.5 锁在事务内部会存在什么问题 锁释放了但是事务未提交其他线程进来查询认为数据库数据未更新因此可能出现并发安全问题。一般要保证提交事务之后再释放锁 4.6 分布式锁的误删情况了解吗? 线程1拿到锁但是业务执行时间太久了锁过期自动释放。线程2获得redis锁执行业务此时线程1业务执行完了又执行释放锁动作错误把线程2的锁释放了。 解决方案释放锁的时候判断UUID线程ID是否是自己。因为不同集群下线程ID可能一致 这里还存在什么问题吗 判断锁和释放锁之间执行Full GC 业务代码阻塞锁超时释放。GC结束线程2获取锁成功然后线程1释放锁又把线程2的锁释放了 所以需要lua脚本实现判断锁和释放锁的原子性 4.7 如何实现调用lua 使用redistemplate的execute(lua,key,value) 4.8 分布式锁失效问题如何解决 采用多个redis节点作为主节点称之为联锁。只要所有节点获取锁成功才算成功 5.秒杀优化 使用lua脚本实现库存和用户下单资格判断采用Stream消费者组实现消息队列存放下单信息通过单例线程池实现异步下单入库操作优化接口平均响应时间从 2500ms 降低到 110msQPS 提升显著
5.1 秒杀优化流程解析 把判断秒杀库存和校验一人一单功能放到redis做输出优惠券ID用户ID订单ID到阻塞队列中开启线程异步读取线程信息完成下单。 5.2 你使用Jmemter主要是看什么 1.平均值所有请求响应时间的平均值 2.吞吐量每秒处理成功的请求本机达到1500 5.3 你的阻塞队列的东西什么时候提交线程任务呢 类初始化之后就提交任务使用到了PostConstruct注解和bean的生命周期可以联动 5.4 为什么采用redis的消息队列而不使用jvm的阻塞队列 jvm内存限制内存故障消息丢失 redi实现的消息队列可以实现持久化机制并且不受jvm内存限制 5.5 聊一下redis有哪些消息队列 List,PubSub和Stream 本项目采用Stream消息队列的原因支持消费者组组内竞争消息避免重复消费又消费确认机制保证消息至少被消费一次。吞吐量达到1600 6.多用户行为管理
SortedSet实现笔记点赞排行榜、Set集合管理用户共同关注、Geo实现附近商铺功能BitMap实现用户签到
6.1 如何设计点赞排行榜时间功能的 redis的sortedset实现key为笔记IDvalue为点赞的用户及时间。可以根据时间排序返回 6.2 如何实现关注和共同关注 使用redis的set数据结构每个用户存储他关注的所有人信息。 要求两个用户的话拿出来用SInter求交集就行 6.3 如何实现附近商铺功能的 使用到了GEO功能。GEOADD把商铺根据类型作为key,经纬度作为value存入redis. GEOSearch按照半径返回附近店铺的坐标信息。 6.4 如何实现用户签到功能 使用BitMap,相对于mysql存储记录节省了大量的内存空间 主要是他的每一位对应的0和1只要签到了就记录为1即可 存储的key为用户月份。只要4个字节即可