zoukankan      html  css  js  c++  java
  • 项目中遇到哪些难点,如何解决的

    本文原链接:https://blog.csdn.net/weixin_38035852/article/details/81384733

    Sanno限时秒杀抢票系统
    亮点:在高并发情况下的秒杀优化,我们知道当并发数达到一定量的时候,会对数据库服务器带来很大的压力,那么如何缓解这些压力以及提高并发的QPS就是整个项目的重点。(不断的提高QPS)。

    亮点3个:

    1.利用缓存减少数据库的压力,以及读取缓存的速度远远快于数据库(网络时延+IO)
    2.页面静态化技术加快用户访问速度,提高QPS,异步下单增强用户体验,以及内存标记减少Redis的访问。
    3.安全性优化:双重md5密码校验,秒杀接口地址的隐藏,接口限流防刷,数学公式验证码。
    整个的提升了系统的安全性能,

    在高并发量的前提下,一台服务器都是无法承担如此大的并发访问的。我们知道淘宝双11QPS能达到上千万,所以一台服务器的访问量最少都需要上万,所以需要集群服务器才能实现一项高并发业务。

    缓解数据库压力:

    1.本项目大量的利用了缓存技术,包括用户信息缓存(分布式session),商品信息的缓存,商品库存缓存,订单的缓存,减少了对数据库服务器的访问。 

    用户信息缓存引出:分布式session.

    2.分布式session

    我们知道当服务器集群的时候,若用户第一个请求在第一台服务器上,第二个请求在其他服务器上,会出现session的丢失的情况,丢失用户信息。而且在这种高并发场景下,一定是很多服务器同步工作,所以如何解决session分布式的问题是一个重点。

    本项目采用:利用redis缓存的方法,另外布置一个Redis服务器专门用于存放用户的session信息。这样就不会出现用户session丢失的情况。(每次需要session,从缓存中取即可)

    这种方式的优点:相对其他的分布式方式,

    1.服务器文件同步(不建议使用,这样会造成文件重复,资源浪费)

    2.session存数据库(不建议用,会加大数据库压力)

    3.使用cookie(不建议用,cookie不太安全)

    对于集群中机器数多、网络环境复杂的情况有很好的处理效果。

    大量的缓存引用也出现了一个问题,如何识别不同模块中的缓存(key值重复,如何辨别是不同模块的key)。 引出:通用缓存key封装

    3.通用缓存key封装

    利用一个抽象类,定义BaseKey(前缀),定义了缓存的String prefix(前缀) 以及缓存的过期时间。让不同模块继承它。

    这样每次存入一个模块的缓存的时候,加上这个缓存特定的前缀,以及可以统一制定不同的过期时间。

    4.页面静态化以及前后端分离

    页面静态化的主要目的是为了加快页面的加载速度。做法:将订票的详情页面做成静态HTML,放在CDN(减少了服务端的压力)上做为静态数据发送给用户端,而数据信息通过前端ajax 异步发送请求来获取。只获取动态数据信息部分,加载速度可以达到全部渲染的2倍。

     
    难点:
    1.大量的使用了缓存,那么就存在缓存的过期时间控制以及缓存击穿以及缓存雪崩等问题?

    解决:首先针对不同的缓存设置不同的过期时间,比如session缓存,在userKey这个前缀中,设置是30分钟过期,并且加入一层再登陆增加缓存时间的机制。这样每次取session,都会延长30分钟,相对来说,就减少了缓存过期的几率。

    针对热点数据,比如演唱会票这种票详情信息,热点商品由于考虑到是一般抢票10分钟内几乎抢完,于是就设置为10分钟的缓存。

    针对热点数据的缓存击穿问题,万一一波一波的抢票,(火车票)这种,某个时间点万一大量并发,刚好我的这个票缓存时间过了,去访问数据库。对于这种热点数据,我将过期时间一起存入缓存中,取出来的时候,比对一下过期时间和当前时间,少于1分钟,我就更新一下缓存,防止他过期。

    2.大量的使用缓存,对于缓存服务器,也有很大的压力,有时候Redis 压力比mysql还要大很多,思考如何减少Redis的访问?

    一般抢票,票的数量也少,大概1000张左右,但是并发量可能在几万。

    在Redis预减库存的时候,内存中维护一个isOvermap作为一个标记,当没有库存的时候,将其置为true。每次抢票业务 访问Redis之前,查一下map,true说明没有库存,就直接返回No_stock。

    3.高并发的时候,业务来不及同步处理,Redis压力,数据库有时候会有大量的insert 和update 操作,甚至请求堆积过多的时候,to many connections?

    想到了消息队列,用来异步处理请求。每次请求过来,先不去处理请求,而是放入消息队列,然后在后台布置一个监听器,分别监听不同业务的消息队列,有消息来的时候,在进行秒杀抢票操作。这样防止多个请求同时操作的时候,数据库连接过多的异常。

    4.为了在前端就限制同一时间的高并发,我也想到了一些前端就限制掉一些用户的做法。

    数学公式验证码

  • 相关阅读:
    wex5 实战 框架拓展之2 事件派发与data刷新
    wex5 实战 框架拓展之1 公共data组件(Data)
    wex5 实战 HeidiSQL 导入Excel数据
    wex5 实战 手指触屏插件 hammer的集成与优劣
    wex5 实战 登陆帐号更换与用户id一致性
    wex5 实战 用户点评与提交设计技巧
    wex5 实战 省市县三级联动与地址薄同步
    wex5 实战 wex5与js的组件关系与执行顺序(父子与先后)
    wex5 实战 单页模式下的多页面数据同步
    [BZOJ]4237: 稻草人
  • 原文地址:https://www.cnblogs.com/leftJS/p/11105909.html
Copyright © 2011-2022 走看看