欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 汽车 > 时评 > 黑马点评项目总结

黑马点评项目总结

2025/6/24 10:55:10 来源:https://blog.csdn.net/2301_79652490/article/details/145661297  浏览:    关键词:黑马点评项目总结

1.使用redis来代替session,解决session在分布式服务中的session共享问题。

因为redis中的数据是共享的,所以可以有效的解决这个问题

这里使用redis,相比于session有什么优势?

1. 性能优势

  • 高并发支持:Redis 是基于内存的数据库,具有极高的读写性能,能够轻松应对高并发场景。相比之下,传统的 Session 通常存储在服务器内存或数据库中,性能可能受限于服务器资源或数据库的读写速度。

  • 快速的数据访问:Redis 的读写速度极快,可以快速存储和检索用户会话信息,从而提高系统的响应速度。这对于需要频繁访问用户状态信息的登录功能来说,是一个显著的优势。

2. 灵活性和可扩展性

  • 动态管理用户状态:Redis 允许在服务器端动态管理用户的状态信息,例如可以随时修改、删除或更新用户的会话数据。而 JWT 一旦签发,其内容就固定了,无法在服务器端动态修改,除非重新签发新的 JWT。

  • 支持复杂的数据结构:Redis 支持多种数据结构,如字符串、哈希、列表、集合等,可以方便地存储和管理复杂的用户会话信息。相比之下,JWT 通常只包含简单的键值对数据。

3. 安全性增强

  • 防止 Token 泄露风险:Redis 存储的会话信息可以在服务器端进行安全管理,例如可以设置会话的过期时间、进行加密存储等。而 JWT 一旦被泄露,攻击者可以在有效期内随意使用,因为 JWT 是自包含的,服务器无法在不重新签发的情况下使其失效。

  • 支持会话撤销:如果需要使某个用户的会话失效,例如用户登出或账号被盗,Redis 可以立即删除对应的会话数据,从而实现会话的快速撤销。而 JWT 由于其无状态性,无法在不重新签发的情况下实现会话的快速撤销。

2.双重拦截器,刷新token有效期

3.使用redis缓存商户信息

缓存更新是redis为了节约内存而设计出来的一个东西,主要是因为内存数据宝贵,当我们向redis插入太多数据,此时就可能会导致缓存中的数据过多,所以redis会对部分数据进行更新,或者把他叫为淘汰更合适。

缓存更新策略为超时剔除主动更新。  主动更新采取的是,先更新数据库再删缓存。

4.缓存三兄弟,穿透,击穿,雪崩。

使用缓存空值来解决缓存穿透问题(存在短期数据不一致的问题)。(也可以使用布隆过滤器来解决,可能存在误判的问题)。

使用过期时间加上一个随机值来解决缓存雪崩的问题。

使用逻辑过期时间解决缓存击穿问题。(当发现数据到达过期时间,就新开一个线程去重构缓存,当前线程返回旧数据)

5.使用redis生成全局唯一ID

当用户抢购时,就会生成订单并保存到tb_voucher_order这张表中,而订单表如果使用数据库自增ID就存在一些问题:* id的规律性太明显 * 受单表数据量的限制

场景分析:如果我们的id具有太明显的规则,用户或者说商业对手很容易猜测出来我们的一些敏感信息,比如商城在一天时间内,卖出了多少单,这明显不合适。

场景分析二:随着我们商城规模越来越大,mysql的单表的容量不宜超过500W,数据量过大之后,我们要进行拆库拆表,但拆分表了之后,他们从逻辑上讲他们是同一张表,所以他们的id是不能一样的, 于是乎我们需要保证id的唯一性。

6.乐观锁解决超卖问题

7.分布式锁解决一人一单问题。

刚开始使用的是synchronized锁,锁的力度太大,改为锁住用户对象。

同时后面出现了事物失效的问题,因为事物是通过动态代理实现的,所以我们要获取代理对象。

上述锁在单机下可行,在集群模式下,由于每个服务器有自己的tomcat,所以看似锁的同一个用户,但确不是同一个对象,所以会出现问题。

因此我们决定采用分布式锁来解决一人一单的问题。

分布式锁:满足分布式系统或集群模式下多进程可见并且互斥的锁。

分布式锁的核心思想就是让大家都使用同一把锁,只要大家使用的是同一把锁,那么我们就能锁住线程,不让线程进行,让程序串行执行,这就是分布式锁的核心思路。

那么分布式锁他应该满足一些什么样的条件呢?

可见性:多个线程都能看到相同的结果,注意:这个地方说的可见性并不是并发编程中指的内存可见性,只是说多个进程之间都能感知到变化的意思

互斥:互斥是分布式锁的最基本的条件,使得程序串行执行

高可用:程序不易崩溃,时时刻刻都保证较高的可用性

高性能:由于加锁本身就让性能降低,所有对于分布式锁本身需要他就较高的加锁性能和释放锁性能

安全性:安全也是程序中必不可少的一环

存入当前线程标识解决分布式锁误删问题:

lua脚本解决分布式锁原子性问题:

8.redission分布式锁

这个具体看一下视频吧,理解理解原理背一背

9.秒杀优化-异步秒杀思路

整体思路:当用户下单之后,判断库存是否充足只需要导redis中去根据key找对应的value是否大于0即可,如果不充足,则直接结束,如果充足,继续在redis中判断用户是否可以下单,如果set集合中没有这条数据,说明他可以下单,如果set集合中没有这条记录,则将userId和优惠卷存入到redis中,并且返回0,整个过程需要保证是原子性的,我们可以使用lua来操作

当以上判断逻辑走完之后,我们可以判断当前redis中返回的结果是否是0 ,如果是0,则表示可以下单,则将之前说的信息存入到到queue中去,然后返回,然后再来个线程异步的下单,前端可以通过返回的订单id来判断是否下单成功。

基于redis的stream流消息队列从而实现异步下单的功能

10.点赞功能实现

11.共同关注:

本文采用:

推拉结合模式:也叫做读写混合,兼具推和拉两种模式的优点。

推拉模式是一个折中的方案,站在发件人这一段,如果是个普通的人,那么我们采用写扩散的方式,直接把数据写入到他的粉丝中去,因为普通的人他的粉丝关注量比较小,所以这样做没有压力,如果是大V,那么他是直接将数据先写入到一份到发件箱里边去,然后再直接写一份到活跃粉丝收件箱里边去,现在站在收件人这端来看,如果是活跃粉丝,那么大V和普通的人发的都会直接写入到自己收件箱里边来,而如果是普通的粉丝,由于他们上线不是很频繁,所以等他们上线时,再从发件箱里边去拉信息。

核心的意思:就是我们在保存完探店笔记后,获得到当前笔记的粉丝,然后把数据推送到粉丝的redis中去。

11.附近商户功能

GEO就是Geolocation的简写形式,代表地理坐标。Redis在3.2版本中加入了对GEO的支持,允许存储地理坐标信息,帮助我们根据经纬度来检索数据。

我们要做的事情是:将数据库表中的数据导入到redis中去,redis中的GEO,GEO在redis中就一个menber和一个经纬度,我们把x和y轴传入到redis做的经纬度位置去,但我们不能把所有的数据都放入到menber中去,毕竟作为redis是一个内存级数据库,如果存海量数据,redis还是力不从心,所以我们在这个地方存储他的id即可。

但是这个时候还有一个问题,就是在redis中并没有存储type,所以我们无法根据type来对数据进行筛选,所以我们可以按照商户类型做分组,类型相同的商户作为同一组,以typeId为key存入同一个GEO集合中即可

12.用户签到-BitMap

需求:实现签到接口,将当前用户当天签到信息保存到Redis中

思路:我们可以把年和月作为bitMap的key,然后保存到一个bitMap中,每次签到就到对应的位上把数字从0变成1,只要对应是1,就表明说明这一天已经签到了,反之则没有签到。

我们通过接口文档发现,此接口并没有传递任何的参数,没有参数怎么确实是哪一天签到呢?这个很容易,可以通过后台代码直接获取即可,然后到对应的地址上去修改bitMap。

版权声明:

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

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

热搜词