压测小工具

最近给某东西压测(由于是私有协议没有通用工具可用),就自己写了个可以给压力的工具,可以支持QPS显示和响应时间的分布显示,有兴趣的可以拿来玩玩

sql压测使用样例:

?


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

import groovy.sql.Sql

 

/**

 ``* @author <a href="mailto:wentong@taobao.com"></a>

 ``* @since 11-11-9 2:00

 ``*

 ``*/

 

def client_num = ``100

 

private List<Sql> connent(``int num) {

  ``def result = []

  ``1``.``upto``(num) {result.add(Sql.newInstance(``"jdbc:[mysql://127.0.0.1:3306/sbtest](3306/sbtest)"``, ``"test"``, ``"test"``, ``"com.mysql.jdbc.Driver"``))}

  ``return result

}

 

def clients = connent(client_num)

 

def getId() {

  ``def total_record_num = ``80000000

 

  ``def hot = ``20

 

  ``def step = ``100 / hot

 

  ``BigDecimal hot_range = total_record_num / ``step

  ``if (RandomTest.nextInt(``100``) < ``95``) {

    ``return RandomTest.getId(hot_range, ``1``).intValue().toString()

  ``} ``else {

    ``return RandomTest.getId(total_record_num, ``1``).intValue().toString()

  ``}

 

}

 

def s = ``new StressTest()

s.add({

  ``Sql client = clients.``get``(it)

  ``client.execute(``"select id ,k,c,pad from sbtest where id =" + getId())

}, client_num)

 

s.run()

 

clients.``each {it.close()}

StressTest 源码:

?


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

184

import java.util.concurrent.ExecutorService

import java.util.concurrent.Executors

import java.util.concurrent.TimeUnit

import java.util.concurrent.atomic.AtomicInteger

import java.util.concurrent.atomic.AtomicLong

 

/**

 ``* @author <a href="mailto:wentong@taobao.com"></a>

 ``* @since 11-11-9 1:12

 ``*

 ``*/

class StressTest {

 

  ``int interval = ``1``;   ``//s

 

  ``int count = ``0``;

 

  ``int time = ``0``;

 

  ``boolean print_rt = true

 

  ``private final AtomicLong MONITOR_STAT_QPS_NUM = ``new AtomicLong();

 

  ``private final AtomicLong MONITOR_RESPNSE_TOTAL = ``new AtomicLong();

 

  ``private final AtomicLong MONITOR_RESPNSE_0MS = ``new AtomicLong();

 

  ``private final AtomicLong MONITOR_RESPNSE_0_1MS = ``new AtomicLong();

 

  ``private final AtomicLong MONITOR_RESPNSE_1_5MS = ``new AtomicLong();

 

  ``private final AtomicLong MONITOR_RESPNSE_5_10MS = ``new AtomicLong();

 

  ``private final AtomicLong MONITOR_RESPNSE_10_50MS = ``new AtomicLong();

 

  ``private final AtomicLong MONITOR_RESPNSE_50_100MS = ``new AtomicLong();

 

  ``private final AtomicLong MONITOR_RESPNSE_100_500MS = ``new AtomicLong();

 

  ``private final AtomicLong MONITOR_RESPNSE_500_1000MS = ``new AtomicLong();

 

  ``private final AtomicLong MONITOR_RESPNSE_1000_MS = ``new AtomicLong();

 

  ``private final ThreadLocal<Long> START_TIME = ``new ThreadLocal<Long>();

 

  ``private Map<Closure, Integer> closures = ``new HashMap<Closure, Integer>();

 

  ``private int thread_num = ``0``;

 

  ``private AtomicInteger stop_thread_num = ``new AtomicInteger();

 

  ``private ExecutorService pool;

 

  ``private boolean is_stop = false

 

  ``/**

   ``* Method start ...

   ``*/

  ``private void start() {

    ``START_TIME.set(System.currentTimeMillis());

  ``}

 

  ``/**

   ``* Method end ...

   ``*/

  ``private void end() {

    ``long start = START_TIME.``get``();

    ``long response = System.currentTimeMillis() - start;

    ``MONITOR_STAT_QPS_NUM.incrementAndGet();

    ``MONITOR_RESPNSE_TOTAL.incrementAndGet();

    ``if (response <= ``0``) {

      ``MONITOR_RESPNSE_0MS.incrementAndGet();

    ``} ``else if (response > ``0 && response <= ``1``) {

      ``MONITOR_RESPNSE_0_1MS.incrementAndGet();

    ``} ``else if (response > ``1 && response <= ``5``) {

      ``MONITOR_RESPNSE_1_5MS.incrementAndGet();

    ``} ``else if (response > ``5 && response <= ``10``) {

      ``MONITOR_RESPNSE_5_10MS.incrementAndGet();

    ``} ``else if (response > ``10 && response <= ``50``) {

      ``MONITOR_RESPNSE_10_50MS.incrementAndGet();

    ``} ``else if (response > ``50 && response <= ``100``) {

      ``MONITOR_RESPNSE_50_100MS.incrementAndGet();

    ``} ``else if (response > ``100 && response <= ``500``) {

      ``MONITOR_RESPNSE_100_500MS.incrementAndGet();

    ``} ``else if (response > ``500 && response <= ``1000``) {

      ``MONITOR_RESPNSE_500_1000MS.incrementAndGet();

    ``} ``else if (response > ``1000``) {

      ``MONITOR_RESPNSE_1000_MS.incrementAndGet();

    ``}

  ``}

 

  ``public void add(Closure closure, ``int threadNum) {

    ``closures.put(closure, threadNum)

    ``this.thread_num += threadNum

  ``}

 

  ``public void run() {

    ``pool = Executors.newFixedThreadPool(thread_num + ``1``)

    ``def defer = { c -> pool.submit(c ``as Runnable) }

    ``closures.``each { c ->

      ``if (c.value > ``0``) {

        ``1``.``upto``(c.value) {  idx ->

          ``defer {runit(c.key, idx - ``1``)}

        ``}

      ``}

    ``}

    ``defer {monitor()}

    ``pool.shutdown()

    ``while (!pool.awaitTermination(``1000``, TimeUnit.SECONDS)) {

    ``}

    ``println "#######################################"

  ``}

 

  ``private void runit(Closure closure, ``int i) {

    ``int c = ``count / thread_num;

    ``try {

      ``while(!is_stop && (``count == ``0 || c > ``0``)) {

        ``try {

          ``start()

          ``closure.call(i)

        ``} ``finally {

          ``end()

          ``if (c > ``0``) {

            ``c--

          ``}

        ``}

      ``}

    ``} ``finally {

      ``stop_thread_num.incrementAndGet()

    ``}

  ``}

 

  ``/**

   ``* Method run ...

   ``*/

  ``private void monitor() {

    ``println``(``"start monitor"``)

    ``long start_time = System.currentTimeMillis()

    ``long end_time = start_time + (time * ``1000``);

    ``while (stop_thread_num.``get``() < thread_num) {

      ``if (time > ``0 && System.currentTimeMillis() >= end_time) {

        ``println "time is over"

        ``is_stop = true

      ``}

      ``Thread.sleep(interval * ``1000``);

 

      ``long num = MONITOR_STAT_QPS_NUM.getAndSet(``0``);

      ``println``(``"QPS:" + (num / interval) + ``" TOTAL:" + MONITOR_RESPNSE_TOTAL.``get``());

 

      ``if (print_rt) {

        ``print_rt();

      ``}

      ``println``(``"----------------------------------"``);

    ``}

 

    ``def total_time = (System.currentTimeMillis() - start_time) / ``1000

 

    ``println "avg QPS:"+ MONITOR_RESPNSE_TOTAL.``get``() / total_time + ``" ,total:" + MONITOR_RESPNSE_TOTAL.``get``()

    ``print_rt()

    ``println``(``"end monitor"``)

  ``}

 

  ``private def print_rt() {

    ``long total = MONITOR_RESPNSE_TOTAL.``get``();

    ``println``(``" RT <= 0:      " + (MONITOR_RESPNSE_0MS.``get``() * ``100 / total) + ``"% " +

            ``MONITOR_RESPNSE_0MS.``get``() + ``"/" + total);

    ``println``(``" RT (0,1]:     " + (MONITOR_RESPNSE_0_1MS.``get``() * ``100 / total) + ``"% "+

            ``MONITOR_RESPNSE_0_1MS.``get``() + ``"/" + total);

    ``println``(``" RT (1,5]:     " + (MONITOR_RESPNSE_1_5MS.``get``() * ``100 / total) + ``"% "+

            ``MONITOR_RESPNSE_1_5MS.``get``() + ``"/" + total);

    ``println``(``" RT (5,10]:    " + (MONITOR_RESPNSE_5_10MS.``get``() * ``100 / total) + ``"% " +

            ``MONITOR_RESPNSE_5_10MS.``get``() + ``"/" + total);

    ``println``(``" RT (10,50]:   " + (MONITOR_RESPNSE_10_50MS.``get``() * ``100 / total) + ``"% " +

            ``MONITOR_RESPNSE_10_50MS.``get``() + ``"/" + total);

    ``println``(``" RT (50,100]:  " + (MONITOR_RESPNSE_50_100MS.``get``() * ``100 / total) + ``"% " +

            ``MONITOR_RESPNSE_50_100MS.``get``() + ``"/" + total);

    ``println``(``" RT (100,500]: " + (MONITOR_RESPNSE_100_500MS.``get``() * ``100 / total) + ``"% " +

            ``MONITOR_RESPNSE_100_500MS.``get``() + ``"/" + total);

    ``println``(``" RT (500,1000]:" + (MONITOR_RESPNSE_500_1000MS.``get``() * ``100 / total) + ``"% " +

            ``MONITOR_RESPNSE_500_1000MS.``get``() + ``"/" + total);

    ``println``(``" RT > 1000:    " + (MONITOR_RESPNSE_1000_MS.``get``() * ``100 / total) + ``"% "+

            ``MONITOR_RESPNSE_1000_MS.``get``() + ``"/" + total)

  ``}

}

本文来源于"阿里中间件团队播客",原文发表时间"2011-11-18  "

时间: 2024-10-26 21:32:41

压测小工具的相关文章

HBase跨地区机房的压测小程序——从开发到打包部署(图文版)

今天做了一个跨地区机房的压测小程序,主要的思路就是基于事先准备好的rowkey文件,利用多线程模拟并发的rowkey查询,可以实现并发数的自由控制.主要是整个流程下来,遇到了点打包的坑,所以特意记录下. 编写代码 rowkey文件的准备就不说了.首先是HbaseClient的查询接口,由于创建连接的代价很重,因此这里采用HBase的ConnectionFactory工厂: static { try { Configuration conf = HBaseConfiguration.create(

ruby利用Zip Gem写一个简单的压缩和解压的小工具

    在UNIX下的我们怎么会沦落到用ruby写压缩和解压工具呢?直接上shell啊!但是请允许本猫这次可耻的用ruby来玩玩吧!其实ruby GEM中有很多压缩解压包,我选的是Zip,也许是因为名字符合KISS原则吧!不过在编写中发现Zip中的某些类没有文档中所说明的实例方法,也许在某个平台上还未实现??     话先说到前头,这个工具如果解压有重名文件的情况会直接覆盖原文件而不会有任何提示!测试时务必注意,如果造成一些文件丢失可别怪本猫啊!     代码也考虑到多文件的情况,如果是压缩多文

MySQL压测工具mysqlslap的介绍与使用_Mysql

一.Mysqlslap介绍 mysqlslap是MySQL5.1之后自带的benchmark基准测试工具,类似Apache Bench负载产生工具,生成schema,装载数据,执行benckmark和查询数据,语法简单,灵活,容易使用.该工具可以模拟多个客户端同时并发的向服务器发出查询更新,给出了性能测试数据而且提供了多种引擎的性能比较.mysqlslap为mysql性能优化前后提供了直观的验证依据,笔者建议系统运维人员应该掌握一些常见的压力测试工具,这样才能较为准确的掌握线上系统能够支撑的用户

Http压测工具wrk使用指南

用过了很多压测工具,却一直没找到中意的那款.最近试了wrk感觉不错,写下这份使用指南给自己备忘用,如果能帮到你,那也很好. 安装 wrk支持大多数类UNIX系统,不支持windows.需要操作系统支持LuaJIT和OpenSSL,不过不用担心,大多数类Unix系统都支持.安装wrk非常简单,只要从github上下载wrk源码,在项目路径下执行make命令即可. git clone https://github.com/wg/wrk make make之后,会在项目路径下生成可执行文件wrk,随后

【工具】MySQL 压测工具之mydbtest

一 前言   本文介绍一款绿色免安装版本的数据库压测利器--mydbtest(mydbtest_linux64.bin,由楼方鑫大牛编写).该压测软件区别于sysbench ,tpcc 等常见压测工具软件,免安装,上手快,而且可以针对业务sql做定制化压测.二 如何使用2.1 随机数据生成器    我们在配置文件中指定随机数据的类型,取值范围 比如a int 10 30000 ,随机生成从10-30000的整数,注意 a 必须是where 条件中使用的值,比如where id=:a:,语法 va

通过压测工具Jmeter来评测函数计算的性能表现

阿里云的函数计算今年4月份推出后,陆续推出了Nodejs6.10.Python2.7和Java8等编译环境,今天我们借助压测工具jmeter来评测一下关于函数计算自动弹性扩容这个特性,在测试之前,我们先梳理一下要进行的内容项: 1. 单线程测试基准响应时间,单线程跑1000次,得出某函数计算处理的平均响应时间. 2. 5线程测试单个请求的响应时间:测试小规模并发下,函数计算响应时间比单线程情况如何 3. 20线程测试函数弹性扩容情况:测试大并发规模下,函数计算响应时间情况,以及是否丢包等. 待续

ECS上自建Redis服务压测报告

背景说明 最近处理的企业大客户问题中,出现好几例都是客户通过购买ECS进行自建Redis服务,并且在使用过程中碰到一些因云环境的内部限制等原因导致客户使用中碰到服务异常或者产品性能上无法满足业务需求的情况.每次处理过程都费时费力,TAM同学一直不辞辛苦的跟进,也拉动了ECS/Redis 研发,网络,存储等同学进去排查,又是抓包又是电话会议,最终可能排查下来都是因为场景使用上的不合理,导致客户在该过程用的不爽,我们支持得也累. 这里根据目前客户通常采用的Redis主备Sentinel架构模式,在E

全链路压测-大促备战核武器

全链路压测被誉为大促备战的"核武器",如果之前有关注过阿里双11相关的技术总结,对"全链路压测"一定不会陌生,这个词的出场率几乎100%,从对双11稳定性的价值来看,用"核武器"来形容全链路压测毫不为过. 1. 背景 时间:2016年10月29日凌晨:地点:阿里西溪园区1号楼7楼"光明顶":事件:200多人聚在一起,精神抖擞,摩拳擦掌.这阵势,是要去约群架吗?别紧张,他们只是在进行一次双11的模拟演习-全链路压测. 历年的双1

压测2.0:云压测 + APM = 端到端压测解决方案

从压力测试说起 压力测试是确立系统稳定性的一种测试方法,通常在系统正常运作范围之外进行,以考察其功能极限和隐患.与功能测试不同,压测是以软件响应速度为测试目标的,尤其是针对在较短时间内大量并发用户的访问时,软件的抗压能力. 至于为什么产品或业务系统在通过功能测试后还需要进行压力测试,原因很简单,因为它重要,为什么重要?众所周知,响应速度是用户体验的核心指标之一. SmartBear 数据表明,如果 Amazon 的加载时间延长1秒,那么一年就会减少16亿美元的营收.用户与网站互动的过程中,如果加