1 Star 2 Fork 0

yuyong725 / high-concurrency-practice

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
贡献代码
同步代码
取消
提示: 由于 Git 不支持空文件夾,创建文件夹后会生成空的 .keep 文件
Loading...
README

目标

相关名词:https://ruby-china.org/topics/26221

  • 调优,在有限硬件资源的情况下,提供更大的吞吐率,并最终得到吞吐率与硬件,jvm参数的关系
  • 调试事务,不同级别锁的影响程度,以及TPS
  • 秒杀实践

衍生问题思考

MySQL数据库

  • 两百万数据的 select count 很慢,大约11s,如何优化
    • 通过 explain 查看走的是否是索引,本项目查询后发现走的是索引,因此不是索引的问题
    • 开启 profiling
    • 先执行要分析的sql,如 select count(1) from tbname
    • 执行 show profiles,找到上条查询对应的 Query_ID
    • 执行 SHOW PROFILE FOR QUERY ${上面的Query_ID},查看时间分布
    • 发现时间都在send data上,对此网上有种说法是,大数据字段,如text,很长长度的varchar等,mysql会将部分数据放在溢出页里面, 因此还会走一遍磁盘扫描。但本项目直接查的count(1),没有查询大字段,因此该说法不适合当前情况。继续分析发现,查询时,系统磁盘IO很猛, 按理查的是索引,在内存里面,不会有这么多的磁盘IO,遂想到修改配置文件my.cnf,增大innodb_buffer_pool_size, 增大的原则是Data_length + Index_length 值的总和的110%。修改后重启,查询降低到0.1s,问题解决。(注意第一次就有点慢, 因为刚刚启动,索引数据还没有加载到内存,后续查询很快)
      • 继续验证上面提到的问题,select count(detail),查询大字段确实比查主键慢,当然原因在于索引,没有涉及到溢出页的验证

秒杀实践

压测方式:通过 jmeter 模拟 100 用户同时下单

标题 方式 平均响应时间(去掉启动后的第一次) 数据库数据 结论 补充
秒杀一 * 无事务 (16+15+10) / 3 =14ms * 库存剩余16件,销量79件,且数据库销量有多条相同记录。取的是其中一次测试的数据 * 随着测试次数的增加,库存越来越接近0,超卖越来越少。原因未知,也可能是偶然事件 * 超卖 * 由于销量的创建是懒存储,当有第一笔订单时才添加销量。因此出现了多条记录,原理类似某些错误单例模式在并发情况下出现的多个实例 * 库存销量之和可能大于100,也可能小于100,原因在于库存和销量的新增不是原子操作,更新库存与更新销量可能分别是两笔订单最后处理的数据库
秒杀二 * 方法级别添加事务@Transactional (32+48+29)/ 3 = 36ms 库存剩余53件,销量47件,且数据库销量有多条相同记录。库存销量之和始终为100 * 超卖 * 事务保证了更新库存和更新销量的一致性,因此保证了两者之和为100不变 * 事务增加了消耗,相对而言响应较慢,超卖更多 (也可能是偶然,毕竟差距不大)
秒杀三 * 悲观锁(有事务) (20+12+11) / 3 =14ms 库存剩余0件,销量100件,始终如此,没有超卖 * 成功秒杀 * 响应很快,并没有因为锁响应速度收到影响 一开始没有加事务,发现和方式一效果一样,这是因为悲观锁,或者说排他锁的释放时机是事务结束,没有事务锁不生效
秒杀四 * 乐观锁(无事务) (20+12+11) / 3 =14ms 库存剩余0件,销量100件,始终如此,没有超卖 * 成功秒杀 * 响应很快,并没有因为锁响应速度收到影响 * 虽然最终的库存和销量是正确的,但过程中查询的两者之和不为100,因为两步是在不同的乐观锁逻辑之中,不像悲观锁,可重复度级别的事务保证了和始终100,这对业务逻辑影响较小,可以通过其它方式实现
秒杀五 * 分布式锁+线程池(coreSize,maxSize=1) (23+10+12) / 3 =15ms 库存剩余0件,销量100件,始终如此,没有超卖 * 成功秒杀 * 响应很快,并没有因为锁响应速度收到影响 * 将mysql数据库事务可能的问题转给redis,然后将任务存储到队列串行执行 * 虽然没有测试吞吐量,但考虑到redis相对mysql,具体更高级别的响应能力,因而此种方式可能有更高的吞吐量 * 由于是异步存储到数据库,可能出现订单数据的延迟

空文件

简介

高并发实践,测试高并发场景下的事务问题,与性能调优 展开 收起
取消

发行版

暂无发行版

贡献者

全部

近期动态

加载更多
不能加载更多了
1
https://gitee.com/calm_java/high-concurrency-practice.git
git@gitee.com:calm_java/high-concurrency-practice.git
calm_java
high-concurrency-practice
high-concurrency-practice
master

搜索帮助