我来斗胆回答一下,麻烦各位大佬指正: 抢课是谁先到先得模式,还是先报名再摇号方式?考虑到学校的硬件性能不会太好,先开启限流,比如 nginx ,就让 1 秒钟只有 500 个请求,避免系统崩溃。抢课过程: 第一种,可以开启事务,开启事务->扣减课程余额->给学生添加课程信息->结束事务; 第二种,先在内存中记录下课程 id 和对应的学生学号。比如限制一天内报名,到期后,随机抽取 n 个学生。然后余额=0 ,给学生添加课程信息。可以使用 redis ,或者本地 cache redis 满了,看是不是某些超大的 key 没有设置过期时间,可以优先把这种忘记设置过期时间的临时 key 删除掉。如果 key 都在使用中,而且数据都有意义,只能加内存。开启内存淘汰机制,LRU 解决高并发的本质是什么? 资源是有限制的,对于远超资源的流量,如何处理。比如抢课,只有 50 个名额,但是有 500 个学生要来抢课;或者说我的服务器硬件不行,无法处理那么多请求,大量流量下如何不宕机。首先要限流,不让系统被大流量打崩溃。到了具体的数据要加锁处理。数据修改完了,后续的其他操作(比如给学生添加课程信息),异步解耦还是跟着同步操作。
1 ,只从 MySQL 看,那用乐观锁或悲观锁,分库分表。。 2 ,如果硬件暂时无法拓展,缩短过期时间,让压力分担到后端,同时考虑其他方案拓展这个 Redis,例如分布式等等 3 ,解决高并发的本质是,解决资源争用。需要对资源管理,对资源的横向纵向扩展,解决队列和熔断,等等
本菜鸡的主观回答: 1. 考察互斥锁吧, 这种抢课的场景加个悲观锁就完全 ok, 再大点规模的并发考虑上消息队列 2. 如果项目本身使用 redis 就比较多那应该在设计初期就构建 redis 集群以保证动态扩容的灵活性; 如果是短期异常增长导致, 排查是否有异常的大规模缓存, 清理废数据; 再就是可能业务规模突然爆发超出预期, 我觉得可以全量备份以后到新服务器恢复数据然后后端暂时切换 redis 的连接 3. 并发问题主要在 io 和锁资源竞争, 优化 io 的基本方式就是异步解耦吧, 锁的话主要是对应业务场景下选择合适的锁
1.方法有很多 说一个上面没提到的 合并请求 把多个扣减课程余额的事务维护在内存或者缓存,合并成一次批量扣减课程余额的事务 2.搞不懂这个问题想问什么 分析大 key? 内存淘汰策略?集群架构打散数据? 3.这个问题大了 不好回答 性能优化:代码优化(异步、并行、各种资源的池化)、缓存(Nginx 静态缓存、CDN 、JVM 缓存、Redishuanc)、数据库优化(索引、大数据量下的分库分表、分布式数据库) 分布式架构:微服务拆分(水平扩展、负载均衡) 并发控制:高并发带来的问题(合理的使用锁、尽量避免事务/长事务、乐观锁) 监控:APM 、压力测试
高并发的本质就是有效的资源下完成更多的请求。如何完成更多的请求? 1. 减少单个请求的处理时间。从缓存、异步的角度考虑。 2. 提升服务承接并发数。以 web 服务为例子,就是提升最大连接数。 另外一方面就是扩展性,如果服务都是无状态的服务,那么直接水平扩展,因此这要求服务尽量做到无状态。