赞
踩
参考教程:https://www.bilibili.com/video/BV1sf4y1L7KE
Java 1.8
SpringBoot 2.7.4
RabbitMQ 3.11
Redis 6.2.7
Mybatis-plus 3.5.2
MySQL 5.7
可能会遇到黄牛,大量并发写和并发读。
因此设计系统要保证高可用,保证数据一致性,高性能。
多台 Tomcat 配合 Nginx 出现用户登录的问题。
Nginx 使用默认的负载均衡策略(轮询),请求将会按照时间顺序逐一分发到后端应用上。
比如,首先用户在 Tomcat1 上登陆后,用户信息保存在 Tomcat1 的 Session 中。过了一会请求被 Nginx 分发到了 Tomcat2 上,因为 Tomcat2 上的 Session 没有用户信息,此时又要登录。
优点:
缺点:
优点:
缺点:
优点:
缺点:
优点:
缺点:
docker 安装 Redis 6.2.7
客户端使用 Another Redis Desktop Manager 1.5.8
set key value [ex 10 | px 10000] [nx | xx]
当执行 session.setAttribute() 时会自动导入 Redis
首先实现序列化方法,默认的 JDK 序列方法可读性有点差。采用 Jackson 的序列化。
首次登录先存 Cookie,然后在 Redis 中存储 {“user:cookie”:userObject},下一次访问的时候直接拿着本地的 Cookie 去 Redis 取信息。
如果每个页面都需要判断是否登录太麻烦了。如何解决?
redis 单节点,mysql
设置线程数 5000,每个线程重复请求 10 次。
重复此操作 3 次。
QPS:1498.9
QPS:832.8
设置商品为 10。
设置线程数 1000,每个线程重复请求 10 次。
重复此操作 3 次。
QPS:1111.9
可以看到数据库中超卖了 2 件:
订单表和秒杀订单表中的数据条数各有 338 条:
QPS:812.1
数据中超卖了 18 件:
订单表和秒杀订单表中的数据条数各有 196 条数据:
可以看到在并发环境下会出现超卖问题,以及商品库存小于 1 的时候还会加入订单。接下来将基于此进行优化,解决线程同步以及提高 QPS。
每次获取商品列表或者某件商品的信息的时候,先从 Redis 中取,若 Redis 中没有,再去数据库找,并加入 Redis 缓存中。
// 先从 Redis 中取缓存, 若返回的对象不为空则直接返回对象
ValueOperations valueOperations = redisTemplate.opsForValue();
List<GoodsVo> goodList = (List<GoodsVo>) valueOperations.get("goodsList");
if (!ObjectUtils.isEmpty(goodList)) {
return goodList;
}
// 若 Redis 中没有则从数据库加载
List<GoodsVo> list = goodsService.findGoodVo();
// 设置失效时间 5 min
valueOperations.set("goodsList", list, 5, TimeUnit.MINUTES);
return list;
设置线程数 5000,每个线程重复请求 10 次。
重复此操作 3 次。
QPS:3171.3
QPS:2333.6
设置线程数 1000,每个线程重复请求 10 次。
重复此操作 3 次。
QPS:1421.1
QPS:1064.8
相对于之前没有缓存的情况有明显的提升,并且解决了超卖问题,以及解决了同一个用户只能购买一件同样的商品。
应用程序(可以是不同编程语言开发)使用某种协议或者说规范与 OS 底层进行通信。这种规范就是中间件,中间件具有跨平台,支持通信,高可用,持久性等特点。
利用可靠的消息传递机制进行系统和系统直接的通讯,通过提供消息传递和西澳西的排队机制,它可以在分布式系统环境下,扩展进程间的通信。
同时性能要比普通的服务和技术要高。
加入有 10W 的并发请求下订单,我们可以在这些订单入库之前把订单请求堆积到消息队列中,让它稳健可靠的入库和执行。
AMQP,高级消息队列协议
RabbitMQ 中消息传递模型的核心思想是:生产者永远不会直接向队列发送任何消息。生产者常常根本不知道消息是否会被传递到任何队列。
生产者只能将消息发送到交换器(exchange)。
交换器职责:
以上规则由交换机类型定义,类型有:direct
,topic
,headers
,fanout
RabbitMQ 默认交换机:
类似发布订阅,也有点像广播,多个消费者会受到同一个发布者发送的同一个消息。
有选择地接收信息。
绑定的时候可以采取一个额外的 routingKey
参数。为了避免与 basic_publish 参数相混淆,我们要把它称为绑定键。
Fanout 模式中是将消息传给所有的队列,Direct 模式可以指定不同的路由键的消息发送给指定消费者。
根据一个模式(主题)接收信息。
可以指定 RoutingKey 包含某个关键词的队列进行发送。带来更多的灵活性。
RoutingKey 中可以有任意多的单词,最多不能超过 255 字节的限制。
*
表示匹配一个词#
表示匹配 0 个或者多个词当一个队列用 #
绑定键绑定时–它将收到所有的消息,不管 RoutingKey 是什么,就好像在 Fanout 交换机中一样。
可以指定哪些指定 key 的 value 值进行发送。(用的不多)
false
true
设置线程数 1000,每个线程重复请求 10 次。
重复此操作 3 次。
QPS:2196.5
QPS:1784.7
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。