(转)开源项目miaosha(下)

石墨文档:https://shimo.im/docs/2XlwliBQAYsKCHbq/

(二期)20、开源秒杀项目miaosha解读(下)

【课程20】jmeter.xmind81.5KB

【课程20】秒杀项目杂谈.xmind0.2MB

 

 

代码片段:

RedisTool.java3.2KB

MiaoshaInterface.java4.7KB

 

 

测试过程中,发现了一个bug。

wang.moshu.cache.MiaoshaSuccessTokenCache#validateTokenByKey()方法。

截取商品的goodsRandomName的开始这里应该加一。

goodsRedisStoreCache.incrStore(key.substring(key.lastIndexOf(":")+1, key.lastIndexOf("_")));
高并发测试,学会使用jmeter

jmeter下载地址:http://jmeter.apache.org/download_jmeter.cgi

汉化步骤:

打开bin/jmeter.properties。搜索language=en。替换成language=zh_CN。去掉注释。

 

百度百科

Apache jmeter 可以用于对静态的和动态的资源(文件,Servlet,Perl脚本,java 对象,数据库和查询, FTP服务器 等等)的性能进行测试。它可以用于对服务器、网络或对象模拟繁重的负载来测试它们的强度或分析不同压力类型下的整体性能。你可以使用它做性能的图形分析或在大并发 负载测试 你的服务器/脚本/对象。

 

(1)压力测试及性能测试;

(2)数据库测试;

(3)Java程序的测试;

(4)HTTP及FTP测试;

(5)Web Service测试;

 

 

线程组:所有的任务都是基于线程组,开通多少个线程就代表有多少个并发用户;

Ramp-Up Period:在这么多时间内完成全部测试,比如开了2个线程,而Ramp-Up Period为3,则每个线程的间隔为1.5秒;

Sampler(取样器):所有的测试任务都是Sampler,即任何测试任务的类别都是Sampler,比如HTTP请求、JDBC请求、FTP请求;

断言:对Sampler的测试进行判断是否正确;

监听器:对Sampler的请求结果进行统计、显示;

 

简单入门

Test Plan (测试计划):用来描述一个性能测试,包含与本次性能测试所有相关的功能。也就说本的性能测试的所有内容是于基于一个计划的。

 

添加一个线程组(用户数)

- 用户数

- 过渡期 (用户组发出请求的间隔时间)

- 循环次数 (这个线程的运行次数)

 

增加一个例程(HTTP 请求)到这个组中

- 服务器名(Server Name) 或 IP

- 路径(Path)

 

 

定义完这个后,测试就准备好了,但我们通常需要一些测试报告。在 JMeter 中,我们称这种组件为监听器。因此,在这个测试计划中,加上一个监听器:

你的全部的请求响应结果都将会显示在这里。按:Ctrl + R 开始运行这个测试。如果打开结果视图窗口(View Results Tree),你可以看到实时的运行状态。运行完后,你可以再按: Ctrl + E 来清除旧的结果,并重新按 Ctrl + R 来重新启动一次新的测试。

 

分析结果

1、查看结果树

如图所示:成功的为绿色,失败则显示为红色。如果测试的结果太多,你只需要看到错误的页面,则勾选【仅日志错误】

 

2、聚合报告(Aggregate Report)

其中:

Label:标签,即我们上面的请求名称

#Samples:本次场景中一共发出了多少个请求

Average:平均响应时间

Median:中位数,也就是50%的用户的响应时间

90%Line:表示90%的用户的响应时间,如果最小值和最大值相差很大的话,我们一般选择这个作为最终测试结果

Min:最小响应时间

Max:最大响应时间

Error%:出错率,本次测试中出现错误的请求的数量/请求的总数

Throughput:吞吐量

KB/sec:每秒从服务器端接受到的数据量

 

3、图形结果:可以图形显示吞吐量、响应时间等

 

分布式锁

 

(java内存模型抽象结构)

 

并发处理手段

1.加synchronized锁单线程处理、缺点: (对象锁和类锁)

  • 1.处理速度也会很慢  
  • 2.只适合单点的情况
  • 3.无法做到细粒度控制

2.redis分布式锁:

  • 1.可以支撑每秒10多万的并发,
  • 2.支持分布式,
  • 3.可以更细粒的控制代码(多台机器上多个线程对一个数据进行操作的互斥)
synchronized的用法
// 这锁住的是
class Foo{
    // 这锁住的是类对象
    static synchronized void bar();
    // 这锁住的是this,即实例对象
    synchronized void bar();
    // 等价于static synchronized
    void bar(){
        synchronized(Foo.class){};
    }
    // 等价于synchronized实例方法
    void bar(){
        synchronized(this){}
    }
}
分布式事务

原子性(Atomicity )、一致性( Consistency )、隔离性或独立性( Isolation)和持久性(Durabilily),简称就是ACID

CAP原则
  • C一致性
  • A可用性
  • P分区容错性

实现一致性:

  • 强一致性--spring JTA
  • 弱一致性
  • 最终一致性
BASE理论

BASE是Basically Available(基本可用)、Soft state(软状态)和Eventually consistent(最终一致性)三个短语的缩写。

 

BASE理论是对CAP中一致性和可用性权衡的结果,其来源于对大规模互联网系统分布式实践的总结, 是基于CAP定理逐步演化而来的。BASE理论的核心思想是:即使无法做到强一致性,但每个应用都可以根据自身业务特点,采用适当的方式来使系统达到最终一致性。

缓存问题

作者:我一定会有猫的

链接:https://juejin.im/post/5b604b9ef265da0f62639001

缓存穿透

缓存穿透是指查询一个一定不存在的数据,因为缓存中也无该数据的信息,则会直接去数据库层进行查询,从系统层面来看像是穿透了缓存层直接达到db,从而称为缓存穿透。

  • 布隆过滤器(guava BloomFilter)

类似于哈希表的一种算法,用所有可能的查询条件生成一个bitmap,在进行数据库查询之前会使用这个bitmap进行过滤,如果不在其中则直接过滤,从而减轻数据库层面的压力。

  • 空值缓存 user108

一种比较简单的解决办法,在第一次查询完不存在的数据后,将该key与对应的空值也放入缓存中,只不过设定为较短的失效时间,例如几分钟,这样则可以应对短时间的大量的该key攻击,设置为较短的失效时间是因为该值可能业务无关,存在意义不大,且该次的查询也未必是攻击者发起,无过久存储的必要,故可以早点失效。

缓存雪崩

在普通的缓存系统中一般例如redis、memcache等中,我们会给缓存设置一个失效时间,但是如果所有的缓存的失效时间相同,那么在同一时间失效时,所有系统的请求都会发送到数据库层,db可能无法承受如此大的压力导致系统崩溃。

  • 线程互斥

只让一个线程构建缓存,其他线程等待构建缓存的线程执行完,重新从缓存获取数据才可以,每个时刻只有一个线程在执行请求,减轻了db的压力,但缺点也很明显,降低了系统的qps。

  • 交错失效时间

这种方法时间比较简单粗暴,既然在同一时间失效会造成请求过多雪崩,那我们错开不同的失效时间即可从一定长度上避免这种问题,在缓存进行失效时间设置的时候,从某个适当的值域中随机一个时间作为失效时间即可。

缓存击穿

缓存击穿实际上是缓存雪崩的一个特例,大家使用过微博的应该都知道,微博有一个热门话题的功能,用户对于热门话题的搜索量往往在一些时刻会大大的高于其他话题,这种我们成为系统的“热点“,由于系统中对这些热点的数据缓存也存在失效时间,在热点的缓存到达失效时间时,此时可能依然会有大量的请求到达系统,没有了缓存层的保护,这些请求同样的会到达db从而可能引起故障。击穿与雪崩的区别即在于击穿是对于特定的热点数据来说,而雪崩是全部数据。

  • 二级缓存

对于热点数据进行二级缓存,并对于不同级别的缓存设定不同的失效时间,则请求不会直接击穿缓存层到达数据库。

  • LRU算法

 

应用限流
计数器法
  • 例如数据库连接池大小,线程池大小,秒杀并发数限制。全局请求数量达到一定阈值进行限流。
滑动窗口
  • 在上图中,整个红色的矩形框表示一个时间窗口,在我们的例子中,一个时间窗口就是一分钟。然后我们将时间窗口进行划分,比如图中,我们就将滑动窗口 划成了6格,所以每格代表的是10秒钟。每过10秒钟,我们的时间窗口就会往右滑动一格。每一个格子都有自己独立的计数器counter,比如当一个请求 在0:35秒的时候到达,那么0:30~0:39对应的counter就会加1。

 

漏桶算法
  • 1)桶容量固定,固定速录流出 
  • 2)桶是空的,不流出 
  • 3)以任意速率流入桶,若超过桶容量,被丢弃

令牌桶算法
  • 1)存放固定令牌的桶100,生产令牌的速率固定 10/s
  • 2)当令牌达到上限时候,产生的令牌被丢弃或拒绝 
  • 3)n个请求过来,拿n个令牌,若令牌不足,则请求被决绝或等待

  • 应用
  • Guava的RateLimiter令牌桶算法

对比:令牌桶算法可一次拿n个令牌,说明允许突发请求。漏桶算法流出速率固定,说明会平滑处理突发请求

 

posted @ 2018-11-07 09:48  free_wings  阅读(162)  评论(0编辑  收藏  举报