黑马点评项目感受

集群共享session问题

一般来说session存储的数据只对当前服务器可见(tomcat可见,虽然服务器可以与服务器之间共享数据,但有一个延迟的时间),当请求被其他服务器接受,将无法判断是否登录(session不共享)。

解决方案 用redis储存共享数据

注意:redis存储对象,最好用hash结构。原因 hash结构方便修改,不像json那样要整个更改。

使用StringRedisTemplate时注意 如果 某个键对应的值为 map 那么map中的所有数据都必须是String类型

该操作把UserDto的数据 转换为键值对 用map存储起来,并且 让所有键的值都为 String

熟记 BeanUtil 是一个 对象可以与对象转换,以及把 map 转换成 bean 或者 bean转换成 map

生成 随机数 6个数

项目中如果有多个拦截器,要控制拦截器的先后顺序,可以按添加拦截器的先后顺序,或者调用order方法

如图

order()方法中值越小,就越先执行

如果拦截器不指定拦截路径,就默认拦截全部路径

缓存

数据交换缓冲区,提高读写性能降低数据库的负载。

查询商户缓存

如果用String存储对象,那么就会是json格式。从json格式中取出一个java对象

指定json 和要转换的 类的字节码,也可以把类转换成JSON

查询商户类型缓存

因为 用stringRedisTemplate存储数据,并且还用 list数据结构,那么就会把从数据库中查询的list中的数据转换成 String(json)

做业务时,一定要注意返回给前端的数据类型

缓存的更新

如果 对数据库修改,并且会经常去查询,那么对数据库修改的操作和更新缓存发操作必须是原子性

对缓存操作时,最好是先操作数据库,再删除缓存(并且这两个操作必须是原子性

缓存穿透

redis 和数据库都没有 数据, 所以每次请求 都会打在数据库上

解决方案 1 缓存空对象(把存活时间设置短) 2 布隆过滤器(判断mysql数据库中是否有数据)

3 可以把查询的参数设置复杂点 4 可以做用户权限校验

布隆过滤器如图

布隆过滤器可能存在误判,如果判断出数据不存在那么数据一定不存在。

缓存雪崩

在同一时刻,redis中 大量的key同时失效 或者 redis直接宕机就会导致数据库压力飙升,从而可能导致数据库宕机

解决方案

1 设置不同的过期时间 ttl 2 搭建redis集群

缓存击穿(热点key访问)

一个高并发 的key失效 ,就会导致大量业务去访问数据库,就会导致数据库压力飙升,注意和缓存雪崩有区别,这里注重一个Key

解决方案 1 互斥锁 2 逻辑过期(永不过期)

两者的区别

项目注意

在防止缓存穿透时,设置空值缓存时 如下图

获取值做判断时 注意下图 注释

解释如图

这里存储的为空白 ,并不是""

如果使用逻辑过期处理互斥锁,在不修改源代码的基础上可以把 想要逻辑过期的类和时间绑定在一起

localdateTime表示当前日期时间

如果是逻辑过期时间处理,前提是缓存中现有数据(该案例就是这么讲的)

项目注意

这里 RedisData封装 了 类Shop,那么注意上图的反序列化操作后得到的redisData中的Shop类是JSONObject类型

所以只能用这种方式数据转换。

注意

在用逻辑过期时间处理缓存击穿时,在重建缓存阶段会开启新的线程重建,那么就要保证重建的这个线程结束后才能释放锁

如图(注意注释

定义泛型(返回值类型在参数中设置)

注意上图,这里dbFallback的apply方法的参数是 Function<ID,R>的 ID类型,R是函数的返回类型。

优惠秒杀劵

全局唯一ID

保证一个信息的安全性

该注解含义 表明表中没有该字段,不会映射

默认当前时间,ON UPDATE 表示自动更新,后续指 更新为当前时间。

MP手动设置sql写法 如图

乐观锁解决超卖

直接自定义sql,注意更新操作也会保证数据库加锁,同一时刻下就只有一个线程会修改该数据

注意 ctrl+alt+m 进行代码封装

实现一人一单(注意事项)

上诉操作只能在单台tomcat服务器下,同时也对应一台jvm,下才可满足,如果在多台服务器下,那么也是对应多台jvm下,那么就不能满足

锁对象实际用的字符串常量池的对象引用

实质用的锁对象是 字符串常量池中的userId对象引用,因为调用了intern() 所以单台服务器下每一次调用用的锁对象是同一个, 而上图的 str3 != str1,所以synchronized只能保证单个服务器下的互斥,不能保证集群下的互斥。

项目注意

关闭nginx

分布式锁

注意在锁过期后,误删的原子性

即便加上没有过期时才能删除的条件依然不能保证原子性

原项目的解决误删的方案

通过uuid加上线程id做为分布式锁的值,因为线程的id 会在单台jvm中呈递增趋势

那么多台jvm,就有可能会使线程id 重复,那么也会造成误删,所以加上uuid可以保证

服务器会根据自己生成的uuid加上线程号删除自己对应的那把锁

自己画的图如下

原方案释放锁

用lua脚本保证释放锁的原子性

lua脚本

redisson分布式锁

对于 setnx分布式锁 缺点 1 不可重入 2不会重试 3主从同步时 , 主节点挂掉,从节点转换成主节点时,在这一阶段会出现锁被多个线程获取(概率极低)

redisson的可重入原理

通过hash结构,对应hash的值就是重入锁的重入次数,同样在服务器集群下,filed只需要线程id 来设置,只有value次数减为0时才会释放锁。不会向setnx那样要区分不同的服务器释放锁还需要用uuid标识不同的服务器

利用发布订阅来解决重试获取锁

利用看门狗机制,在每隔一段时间就重置过期时间

项目注意

在实现秒杀抢劵时,会先查询劵的库存和 订单表是否一人一单,那么在高并发下,对于这种的查询操作完全可以放在redis中去查,减少数据库的压力

把秒杀劵的库存做缓存 如图

而对于订单表判断是否一人一单,就用set数据 结构做缓存 如图

当缓存做好时,用lua脚本保证所有操作的原子性 lua脚本如图

使用阻塞队列存储要保存的订单对象

redis消息队列实现异步秒杀

基于redis的list结构实现

发布订阅

stream流数据格式(消息队列)

创建stream消息队列

读取消息队列

  • 2
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
1.2. 结构化一下 1.3. 图形化一下 1.3.1. 运营商后台 1.3.2. 商家后台 1.3.3. 网页前台 参考京东 2. 技术选型 前端:angularJS + Bootstrap 后台:SSM( springmvc+spring+mybatis) 数据库:mysql,使用mycat读写分离 开发模式:SOA 服务中间件:dubbox,需要和zookeeper配合使用 注册中心:zookeeper 消息中间件:Activemq,使用spring-jms 负载均衡:nginx 搜索:solr集群(solrCloud),配合zookeeper搭建, 使用spring-data-solor 缓存:redis集群,使用spring-data-redis 图片存储:fastDFS集群 网页静态化:freemarker 单点登录:cas 权限管理:SpringSecurity, 跨域:cros 支付:微信扫描 短信验证:阿里大于 密码加密:BCrypt 富文本:KindEditor 事务:声明式事务 任务调度:spring task 所有的技术,都可能涉及到为什么用?怎么用?用的过程中有什么问题? 3. 框架搭建 3.1. 前端 理解baseControler.js、base.js、base_pagination.js,以及每一个xxxController.js里面都公共的做了些什么。 baseControler.js 分页配置 列表刷新 处理checkBox勾选 xxxControler.js 自动生成增删改查 base_pagination.js 带分页 base.js 不带分页 3.2. dao 使用了mybatis逆向工程 4. 模块开发 逐个模块开发就好 4.1. 学会评估模块难不难 一个模块难不难从几方面考虑。 涉及几张表? 1,2张表的操作还是没有什么难度的。 涉及哪些功能? 增删改查,批量删除。 前端展示? 分页列表、树形、面包屑、三级联动、内容格式化。 4.2. 举几个简单模块的例子 4.2.1. 品牌管理 单表 分页、新增、删除、修改 4.2.2. 规格管理 2张表 分页、新增、删除、修改、显示优化(显示列表内容的一部分) 4.2.3. 模板管理 2张表 分页、新增、删除、修改、显示优化(显示列表内容的一部分) 4.2.4. 分类管理 单表 4.2.5. 商家审核 单表 4.3. 举一个复杂模块 4.3.1. 商品新增 需要插入3张表,tb_goods、tb_goods_desc、tb_item 前端:三级联动、富文本、图片上传、动态生成内容 4.3.2. 商品修改 需要从3张表获取数据,然后进行回显。 4.4. 典型模块设计 4.4.1. 管理后台 商品新增、商品修改 4.4.2. 前台页面 搜索模块实现 购物车模块实现 支付模块实现 秒杀模块实现 5. 开发过程中问题&优化 1.1. 登录 单点登录怎么实现 session怎么共享 1.2. 缓存 哪些场景需要用到redis redis存储格式的选择 怎么提高redis缓存利用率 缓存如何同步 1.3. 图片上传 图片怎么存储 图片怎么上传 1.4. 搜索 ​ 怎么实现 数据量大、 并发量高的搜索 怎么分词 1.5. 消息通知 ​ 哪些情况用到activeMq 1.6. 优化 seo怎么优化 怎么加快访问速度 1.7. 秒杀 ​ 怎么处理高并发 ​ 秒杀过程中怎么控制库存

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值