为了账号安全,请及时绑定邮箱和手机立即绑定

Java高并发秒杀API之高并发优化

  • 后端缓存流程:先在pom文件中引入相关redis依赖,java一般通过jedis来访问redis,然后创建一个redisDao的类,写入jedispool,从jedispool中获取到jedis对象。主要是在写两个方法,一个是从redis中get对象,另一个是向jedis中存入对象,因为redis并没有实现自动序列化功能,所以实际put对象的时候是将数据库中取到的对象序列化成二级制数组,然后根据对象类的反射得到的scheme序列化对象并存到redis中。同样redis取出对象的时候取到的是一个二进制数组,需要根据scheme和一个空对象将二进制数组转换成相应的对象。
    查看全部
  • insert和update代码调换顺序的原因:insert不涉及到行级锁的竞争,所以可以放在前面执行其实降低了一半的行级锁持有时间,因为行级锁的开始时间是从update语句开始的。同时不用担心insert会先插入大量数据,因为insert和update是控制在一个事务当中的,只有update成功后insert才会真正的插入一条数据。
    查看全部
  • 优化:

    前端: 动静态数据做分离,减少请求与响应时间;按钮防重复,防止用户发送无效的重复请求,因为秒杀活动一般都会有购买数量的限制,敲的次数再多,最后还是要查看是否已购。影响了效率,可有前端代为处理并优化

    后端:使用CDN换存重要的静态资源等;在后端对活动结束时间、商品选购时间、业务的相关逻辑要求都放在后端代码中,并调用缓存来进行暂存,已减少对DB的直接操作,提高效率


        1,前端控制触发次数,比如限制控制按钮的触发

        2,使用CDN和缓存机制达到动静分离

        3,减少行级锁和GC的时间,将食物控制在mysql中进行,比如存储过程


    查看全部
  • CDN特点:CDN是和请求对应的资源是不变化的,比如静态资源和JavaScript(URL对应的结果不变)
    CDN是什么:
         1:CDN是(内容分发网络)加速用户获取数据的系统,例如视频资源
         2:部署在离用户最近的网络节点上 3:命中CDN不需要访问后端服务器
         4:互联网公司自己搭建或租用CDN
    使用CDN的好处:
         01 不用去官网直接下载 02 当我们的服务上线一些稳定可靠的CDN比直接发布到我们的服务器更有效
         03 CDN也是web最重要的一个加速的功能点 怎样让系统抗住很高的并发的时候CDN也是一个点

    高并发出现的点:
    1.获取系统时间(但是不用优化,访问一次内存(Cacheline)大约10ns)
    2.秒杀地址接口分析:
       1.无法使用CDN缓存
       2.但是它适合放在服务器缓存:Redis等->内存的服务器端的缓存可以抗很高的QPS,10^5/sQPS,
         现在Redis可以做集群,做了之后QPS可以达到10^6/s。
       3.为什么要做后端缓存 -> 因为后端缓存可以用我们的业务系统来控制。
         比如先访问数据库拿到秒杀的数据放到Redis缓存里面去,当一次访问的时候直接去缓存里面查找,
         缓存有就直接返回,而不去访问我们数据库了。
       4.一致性维护成本比较低:当我们秒杀的东西或秒杀的对象改变了的时候,
         我们可以修改我们的数据库,同时在改一下我们的缓存,或者干脆不改,等超时之后在改

    秒杀地址接口优化:请求地址 -> Redis[一致性维护(超时穿透到SQL语句/当SQL语句更新时主动更新)] -> SQL语句

    3.秒杀操作优化分析(是最重要的一个秒杀按钮操作):
       1.也是不能使用CDN缓存的,CDN不可能把你最核心的东西给缓存(大部分写操作或最核心的数据请求一般没办法使用CDN)
       2.后端缓存困难:库存的问题,不可能在缓存里面减库存,否则会产生数据不一致问题。所以要通过事务来保证数据的一致性
       3.一行数据竞争:热点商品,会对数据库表中的那一行数据产生大量的update减库存竞争

    1:瓶颈分析:
    update 减库存:客户端会执行update,根据拿到结果是否更新了,当我们的SQL通过网络发送给数据库时本身就有网络延迟,
                  除了网络延迟还有java GC(garbage collection,垃圾回收)操作 -> 不需要手动去回收,
                  GC自动就帮我们回收了,新生代GC会暂停所有的事务代码(Java代码)后,执行GC(一般在几十ms),
                  并且,同一行事务是做串行化的。
    ---->insert 购买明细:也会存在网络延迟和GC
    ---->commit/rollback
    也就是说如果是Java客户端去控制这些事务会有什么问题:update 减库存(网络延迟,可能的GC,GC不一定每次都出现,但一定会出现)
    --> 执行insert 购买明细(在网络延迟等待insert语句的返回,然后也可能会GC) --> 最后commit/rollback。
    当前面的这些操作都执行完之后,第二个等待行锁的线程菜能够有机会拿到这一行的锁在去执行update减库存

    特点:
       根据上面的拆分,所以QPS很好分析了 --->(我们所有的SQL执行时间 + 网络延迟时间 + 可能的GC)
       这一行数据就是当前可以执行的时间.比如时间是2ms,概念是1s之内只能有500次减库存的秒杀操作,但是对于
       秒杀系统,特别是热点系统来说其实是不能满足我们的要求的,特别是排队特别长的时候,性能会呈现指数级别下降
    得到的点是:行级锁是在commit/rollback之后释放的;
    优化方向:怎样减少行级锁持有的时间 ---> (当你update表中一行数据的时候,一定要快速的commit/rollback,
             因为其他还在等待,因为这是一个热点的数据);

    2:延迟分析:
    延迟问题是很关键的;
    优化思路:
    -把客户端逻辑放到MySQL(数据库)服务端,避免网络延迟和GC影响
    -如何放到MySQL服务端:

    --两种解决方案:
    ---定制SQL方案: 早期的阿里巴巴的天猫做了一个MySQL的源码层的修改 --->update/*+[auto_commit]*/,
       但是执行完这句update之后,会自动进行回滚(条件是:当update影响的记录数是1,它就会commit,如果等于0就会rollback)
       也就是说它不给Java客户端和MySQL之间网络延迟,然后在由Java客户端去控制commit还是rollback,而是直接用这条语句直接发过去
       告诉它是commit还是rollback。本质上也是降低了网络延迟和GC的干扰,但是成本很高 --> 需要修改MySQL源码,大公司可以这样的团队

    --使用存储过程: 整个事务在MySQL端完成;存储过程设计出来的本质就是想让我们的一组SQL组成一个事务,然后在服务器端完成,
      而避免客户端去完成事务造成的一个性能的干扰。一般情况下像是spring声明式事务或我们手动控制事务都是客户端控制事务,
      这个事务在行级锁没有那么高的竞争情况下是完全OK的,但秒杀是一个特殊的应用场景,它会在同一行中产生热点,大家都竞争同一行父,
      那么这个时候存储过程就发挥作用了,它把整个这条SQL执行过程完全放在MySQL中完成了,
      MySQL执行的效率非常高,因为我们都是通过主键去执行的,查询或更新

    优化总结:
    1:前端控制:暴露接口,按钮防重复
    2:动静态数据分离:CDN缓存,后端缓存
    3:事务竞争优化:减少事务锁时间 ---> 这是秒杀用MySQL解决秒杀问题的很重要的一个关键点;
       因为用事务有一个很大的优点是:保证原子性、隔离性、一致性、持久性。

    查看全部
  • 秒杀操作的简单优化:更新库存的是热点操作,会出现行级锁,而插入购买记录的行为没有行级锁。可以先插入购买明细,可以避免因重复秒杀带来的不必要的更新库存操作,减少不必要的行级锁的占用。然后再去更新库存。这样,行级锁的占用时间可以节省一半(反正是节省了)

    查看全部
  • 优点CDN
    查看全部
  • https://github.com/geekyijun/seckill
    查看全部
    2 采集 收起 来源:8-课程总结

    2017-11-04

  • insert 与 update 之间的逻辑调整。(调整代码顺序 => insert失败就不用执行下面的update的操作 + 降低了rowLock持有的时间 => 优化的目的) insert ignore 主键冲突了,返回0. 成功返回1
    查看全部
  • -- 存储过程 (只在银行被大量的时候,互联网公司用的很少,但是在秒杀中用) -- 1.存储过程优化: 事务行级锁持有的时间 -- 2.不要过渡依赖存储过程 -- 3.简单的逻辑可以应用存储过程 -- 4.QPS:一个秒杀但6000/qps
    查看全部
  • 完整代码地址:https://github.com/firery/imooc-seckill 代码都有完整的注释,依赖更新为目前的最新版本,数据库采用MySQL 8.0。 另外有少许优化,比如最后的浏览器计时误差等。
    查看全部
    2 采集 收起 来源:8-课程总结

    2016-09-27

  • 自定义序列化工具:goole的protostuff。比java自带的serializable空间要小5~10倍 在把对象存到redis缓存中,效率要高很多。
    查看全部
  • 【转】完整代码地址:https://github.com/firery/imooc-seckill 代码都有完整的注释,依赖更新为目前的最新版本,数据库采用MySQL 8.0。 另外有少许优化,比如最后的浏览器计时误差等。

    查看全部
    1 采集 收起 来源:8-课程总结

    2019-09-08

  • 方法一:成本高,大公司使用

    方法二:放到服务器端完成,MySQL执行sql效率非常高

    查看全部
  • 优化:

    前端: 动静态数据做分离,减少请求与响应时间;按钮防重复,防止用户发送无效的重复请求,因为秒杀活动一般都会有购买数量的限制,敲的次数再多,最后还是要查看是否已购。影响了效率,可有前端代为处理并优化

    后端:使用CDN换存重要的静态资源等;在后端对活动结束时间、商品选购时间、业务的相关逻辑要求都放在后端代码中,并调用缓存来进行暂存,已减少对DB的直接操作,提高效率

    查看全部
  • 如何处理高并发

    1、增加服务器数量,通过nginx转发请求去分担流量

    2、代码中使用radis缓存来获取相对稳定的变量,减少访问数据库的次数以及降低网络延迟

    3、使用事务和数据库行级锁来控制高并发问题

    4、降低代码中事务控制的流程以及增删改查

    5、使用存储过程来操作简单的事务操作,减少数据库网络访问时间,增加访问DPS

    查看全部
首页上一页1234567下一页尾页

举报

0/150
提交
取消
课程须知
《Java高并发秒杀API》是系列课程,共四门课,分别为业务分析和DAO层,Service层,Web层和高并发优化。本门课程是第二门课程,学习前需要了解如下知识: 1、精通JavaWeb基础 2、熟悉SpringMVC、Spring和MyBatis框架 3、了解事务和存储过程的概念
老师告诉你能学到什么?
1、掌握秒杀业务 2、能够进行SpringMVC+Spring+MyBatis的整合开发 3、能够对秒杀业务的瓶颈有所了解 4、能够实现对秒杀业务的优化

微信扫码,参与3人拼团

意见反馈 帮助中心 APP下载
官方微信
友情提示:

您好,此课程属于迁移课程,您已购买该课程,无需重复购买,感谢您对慕课网的支持!