blog's People
blog's Issues
influxDB学习
概述
InfluxDB是一个用于存储和分析时序数据的开源数据库,该数据库使用go开发,小巧灵活,依赖少,主要有以下几点特点:
- 内置http接口,方便使用
- 数据可打标记tag,查询灵活
- 类SQL的查询语句
- 安装简单,无依赖
- 实时查询,读写效率非常高
安装
influxDB默认使用下面的网络端口:
- TCP端口8086用作InfluxDB的客户端和服务端的http api通信
- TCP端口8088给备份和恢复数据的RPC服务使用
yum install influxdb
使用指南
写数据
写数据有两种方式,一种使用CLI,一种使用HTTP restful API方式,重点介绍下HTTP
- create db
curl -i -XPOST http://localhost:8086/query --data-urlencode "q=CREATE DATABASE mydb"
- 写数据点
curl -i -XPOST 'http://localhost:8086/write?db=mydb' --data-binary 'cpu_load_short,host=server01,region=us-west value=0.64 1434055562000000000'
它的组成部分有measurement,tags,fields和timestamp。measurement是InfluxDB必须的,严格地说,tags是可选的,但是对于大部分数据都会包含tags用来区分数据的来源,让查询变得容易和高效。tag的key和value都必须是字符串。fields的key也是必须的,而且是字符串,默认情况下field的value是float类型的。timestamp在这个请求行的最后,是一个从1/1/1970 UTC开始到现在的一个纳秒级的Unix time,它是可选的,如果不传,InfluxDB会使用服务器的本地的纳米级的timestamp来作为数据的时间戳,注意无论哪种方式,在InfluxDB中的timestamp只能是UTC时间
- 一次写多个数据点
要想同时发送多个数据点到多个series(在InfluxDB中measurement加tags组成了一个series),可以用新的行来分开这些数据点。这种批量发送的方式可以获得更高的性能
无模式设计
InfluxDB是一个无模式(schemaless)的数据库,你可以在任意时间添加measurement,tags和fields。注意:如果你试图写入一个和之前的类型不一样的数据(例如,filed字段之前接收的是数字类型,现在写了个字符串进去),那么InfluxDB会拒绝这个数据。+
HTTP返回值概要
- 2xx:如果你写了数据后收到HTTP 204 No Content,说明写入成功了!
- 4xx:表示InfluxDB不知道你发的是什么鬼。
- 5xx:系统过载或是应用受损。
查询数据
http接口查询
curl -G 'http://localhost:8086/query?pretty=true' --data-urlencode "db=mydb" --data-urlencode "q=SELECT \"value\" FROM \"cpu_load_short\" WHERE \"region\"='us-west'"
数据采样和保留
InfluxDB每秒可以处理数十万的数据点。如果要长时间地存储大量的数据,对于存储会是很大的压力。一个很自然的方式就是对数据进行采样,对于高精度的裸数据存储较短的时间,而对于低精度的的数据可以保存得久一些甚至永久保存。
InfluxDB提供了两个特性——连续查询(Continuous Queries简称CQ)和保留策略(Retention Policies简称RP),分别用来处理数据采样和管理老数据的。
定义
- Continuous Query (CQ)是在数据库内部自动周期性跑着的一个InfluxQL的查询,CQs需要在SELECT语句中使用一个函数,并且一定包括一个GROUP BY time()语句。
- Retention Policy (RP)是InfluxDB数据架构的一部分,它描述了InfluxDB保存数据的时间。InfluxDB会比较服务器本地的时间戳和你数据的时间戳,并删除比你在RPs里面用DURATION设置的更老的数据。单个数据库中可以有多个RPs但是每个数据的RPs是唯一的。
查询语法
数据查询语法
select 子句
SELECT <field_key>[,<field_key>,<tag_key>] FROM <measurement_name>[,<measurement_name>]
- 从单个measurement查询所有的field和tag
SELECT * FROM "h2o_feet"
- 从单个measurement中查询特定tag和field
SELECT "level description","location","water_level" FROM "h2o_feet"
- 从单个measurement中选择特定的tag和field,并提供其标识符类型
SELECT "level description"::field,"location"::tag,"water_level"::field FROM "h2o_feet"
- 从单个measurement查询所有field
SELECT *::field FROM "h2o_feet"
- 从measurement中选择一个特定的field并执行基本计算
SELECT ("water_level" * 2) + 4 from "h2o_feet"
- 从多个measurement中查询数据
SELECT * FROM "h2o_feet","h2o_pH"
- 从完全限定的measurement中选择所有数据
SELECT * FROM "NOAA_water_database"."autogen"."h2o_feet"
where 子句
- 查询有特定field的key value的数据
SELECT * FROM "h2o_feet" WHERE "water_level" > 8
- 查询有特定field的key value为字符串的数据
SELECT * FROM "h2o_feet" WHERE "level description" = 'below 3 feet'
- 查询有特定field的key value并且带计算的数据
SELECT * FROM "h2o_feet" WHERE "water_level" + 2 > 11.9
- 查询有特定tag的key value的数据
SELECT "water_level" FROM "h2o_feet" WHERE "location" = 'santa_monica'
- 查询有特定tag的key value以及特定field的key value的数据
SELECT "water_level" FROM "h2o_feet" WHERE "location" <> 'santa_monica' AND (water_level < -0.59 OR water_level > 9.95)
- 根据时间戳来过滤数据
SELECT * FROM "h2o_feet" WHERE time > now() - 7d
group by子句
GROUP BY子句后面可以跟用户指定的tags或者是一个时间间隔。
- 对单个tag作group by
SELECT MEAN("water_level") FROM "h2o_feet" GROUP BY "location"
- 对多个tag作group by
SELECT MEAN("index") FROM "h2o_quality" GROUP BY location,randtag
- GROUP BY时间间隔
SELECT COUNT("water_level") FROM "h2o_feet" WHERE "location"='coyote_creek' AND time >= '2015-08-18T00:00:00Z' AND time <= '2015-08-18T00:30:00Z' GROUP BY time(12m)
SELECT COUNT("water_level") FROM "h2o_feet" WHERE time >= '2015-08-18T00:00:00Z' AND time <= '2015-08-18T00:30:00Z' GROUP BY time(12m),"location"
高级GROUP BY time()语法
SELECT <function>(<field_key>) FROM_clause WHERE <time_range> GROUP BY time(<time_interval>,<offset_interval>),[tag_key] [fill(<fill_option>)]
- 查询结果间隔按18分钟group by,并将预设时间边界向前移动
SELECT "water_level" FROM "h2o_feet" WHERE "location"='coyote_creek' AND time >= '2015-08-18T00:00:00Z' AND time <= '2015-08-18T00:54:00Z'
SELECT MEAN("water_level") FROM "h2o_feet" WHERE "location"='coyote_creek' AND time >= '2015-08-18T00:06:00Z' AND time <= '2015-08-18T00:54:00Z' GROUP BY time(18m,6m)
SELECT MEAN("water_level") FROM "h2o_feet" WHERE "location"='coyote_creek' AND time >= '2015-08-18T00:06:00Z' AND time <= '2015-08-18T00:54:00Z' GROUP BY time(18m)
- 查询结果按12分钟间隔group by,并将预设时间界限向后移动
SELECT MEAN("water_level") FROM "h2o_feet" WHERE "location"='coyote_creek' AND time >= '2015-08-18T00:06:00Z' AND time <= '2015-08-18T00:54:00Z' GROUP BY time(18m,-12m)
- 查询结果按12分钟间隔group by,并将预设时间边界向前移动
SELECT COUNT("water_level") FROM "h2o_feet" WHERE "location"='coyote_creek' AND time >= '2015-08-18T00:06:00Z' AND time < '2015-08-18T00:18:00Z' GROUP BY time(12m,6m)
GROUP BY time()加fill()
默认情况下,没有数据的GROUP BY time()间隔返回为null作为输出列中的值。fill()更改不含数据的时间间隔返回的值。请注意,如果GROUP(ing)BY多个对象(例如,tag和时间间隔),那么fill()必须位于GROUP BY子句的末尾。
fill的参数
- 任一数值:用这个数字返回没有数据点的时间间隔
- linear:返回没有数据的时间间隔的线性插值结果。
- none: 不返回在时间间隔里没有点的数据
- previous:返回时间隔间的前一个间隔的数据
SELECT MEAN("tadpoles") FROM "pond" WHERE time >= '2016-11-11T21:00:00Z' AND time <= '2016-11-11T22:06:00Z' GROUP BY time(12m) fill(linear)
INTO子句
SELECT_clause INTO <measurement_name> FROM_clause [WHERE_clause] [GROUP_BY_clause]
正则表达式
InluxDB支持在以下场景使用正则表达式:
- 在SELECT中的field key和tag key;
- 在FROM中的measurement
- 在WHERE中的tag value和字符串类型的field value
- 在GROUP BY中的tag key
- 在SELECT中使用正则表达式指定field key和tag key
SELECT /l/ FROM "h2o_feet" LIMIT 1
- 在SELECT中使用正则表达式指定函数里面的field key
SELECT DISTINCT(/level/) FROM "h2o_feet" WHERE "location" = 'santa_monica' AND time >= '2015-08-18T00:00:00.000000000Z' AND time <= '2015-08-18T00:12:00Z'
- 在FROM中使用正则表达式指定measurement
SELECT MEAN("degrees") FROM /temperature/
- 在WHERE中使用正则表达式指定tag value
SELECT MEAN(water_level) FROM "h2o_feet" WHERE "location" =~ /[m]/ AND "water_level" > 3
- 在WHERE中使用正则表达式指定无值的tag
SELECT * FROM "h2o_feet" WHERE "location" !~ /./
- 在WHERE中使用正则表达式指定有值的tag
SELECT MEAN("water_level") FROM "h2o_feet" WHERE "location" =~ /./
- 在WHERE中使用正则表达式指定一个field value
SELECT MEAN("water_level") FROM "h2o_feet" WHERE "location" = 'santa_monica' AND "level description" =~ /between/
- 在GROUP BY中使用正则表达式指定tag key
SELECT FIRST("index") FROM "h2o_quality" GROUP BY /l/
schema查询语法
InfluxQL是一种类似SQL的查询语言,用于与InfluxDB中的数据进行交互。下面我们要介绍一些有用的查询schema的语法:
- SHOW DATABASES
- SHOW RETENTION POLICIES
- SHOW SERIES
- SHOW MEASUREMENTS
- SHOW TAG KEYS
- SHOW TAG VALUES
- SHOW FIELD KEYS
函数
- COUNT(): 返回非空字段值得数目
- DISTINCT(): 返回field value的不同值列表
- MEAN(): 返回字段的平均值
- MEDIAN(): 返回排好序的字段的中位数
- MODE():返回字段中出现频率最高的值
- SPREAD(): 返回字段中最大和最小值的差值
- STDDEV(): 返回字段的标准差
- SUM():返回字段值的和
- BOTTOM():返回最小的N个field值
- FIRST(): 返回时间戳最早的值
- LAST():返回时间戳最近的值
- MAX():返回最大的字段值
- MIN():返回最小的字段值
- PERCENTILE():返回较大百分之N的字段值
- SAMPLE():返回N个随机抽样的字段值
- TOP():返回最大的N个field值
prometheus基本使用
下载
从prometheus官网上下载最新的版本,解压
tar -xf prometheus-2.0.0.linux-amd64.tar.gz
cd prometheus-*
配置
prometheus是完整的监控产品,它通过http的方式收集指标,它也可以监控自身的指标数据。
配置job和每个job要收集的目标metric数据,配置文件分两级job、target,在k8sz中监控主要配置api-server和etcd的metric地址;
编辑prometheus.yml配置文件,具体如下:
# my global config
global:
scrape_interval: 15s # Set the scrape interval to every 15 seconds. Default is every 1 minute.
evaluation_interval: 15s # Evaluate rules every 15 seconds. The default is every 1 minute.
# scrape_timeout is set to the global default (10s).
# Alertmanager configuration
alerting:
alertmanagers:
- static_configs:
- targets:
# - alertmanager:9093
# Load rules once and periodically evaluate them according to the global 'evaluation_interval'.
rule_files:
# - "first_rules.yml"
# - "second_rules.yml"
# A scrape configuration containing exactly one endpoint to scrape:
# Here it's Prometheus itself.
scrape_configs:
# The job name is added as a label `job=<job_name>` to any timeseries scraped from this config.
- job_name: 'prometheus'
# metrics_path defaults to '/metrics'
# scheme defaults to 'http'.
static_configs:
- targets: ['192.168.56.3:9090']
- job_name: 'kubernetes'
scrape_interval: 5s
static_configs:
- targets: ['192.168.56.4:8080']
- job_name: 'etcd-server'
scrape_interval: 5s
static_configs:
- targets: ['192.168.56.4:2379','192.168.56.5:2379','192.168.56.6:2379']
启动prometheus
./prometheus --config.file=prometheus.yml
然后就可以通过http://:9090访问
建议通过systemd服务启动prometheus
# /etc/systemd/system/prometheus.service
[Unit]
Description=prometheus
After=network.target
[Service]
Type=simple
#User=prometheus
ExecStart=/root/prometheus-2.0.0.linux-amd64/prometheus --config.file=/root/prometheus-2.0.0.linux-amd64/prometheus.yml --storage.tsdb.path=/var/lib/prometheus
Restart=on-failure
[Install]
WantedBy=multi-user.target
启动prometheus
systemctl start prometheus
监控prometheus服务器
为收集监控服务器上的CPU、内存、磁盘、io等信息,要安装node-exporter,该exporter的作用是收集机器系统数据,充当agent的作用;
- 安装node_exporter
- 配置node_exporter service文件
# /etc/systemd/system/node_exporter.service
[Unit]
Description=node_exporter
After=network.target
[Service]
Type=simple
#User=prometheus
ExecStart=/root/prometheus-2.0.0.linux-amd64/node_exporter-0.15.2.linux-amd64/node_exporter
Restart=on-failure
[Install]
WantedBy=multi-user.target
- 启动node_exporter
systemctl start node_exporter
添加prometheus yaml文件中的监控点
- job_name: 'linux'
scrape_interval: 5s
static_configs:
- targets: ['localhost:9100']
重启prometheus
systemctl restart prometheus
绘图展示
prometheus自带的监控界面比较简单,可以配合go实现的开源grafana,界面功能强大,美观;
docker run -d --name=grafana -p 3000:3000 grafana/grafana
通过http://:3000访问grafana,缺省帐号/密码为admin/admin
简单代码实现词云
#!/usr/bin/env python
# coding: utf-8
__author__ = 'yueyt'
import jieba
import numpy as np
import xlrd
from PIL import Image
from matplotlib import pyplot as plt
from wordcloud import WordCloud, STOPWORDS
def excel2text(excel_file):
data = xlrd.open_workbook(excel_file)
table = data.sheets()[0]
nrows = table.nrows
content = []
for i in range(nrows):
row_values = table.row_values(i)
if len(row_values[-1]) > 0:
content.append(row_values[-1])
# remove null content
return content
def gen_text_file(filename, text):
with open(filename, mode='w', encoding='utf-8') as f:
f.write('{}\n'.format(text))
def text2word(text):
return jieba.lcut(text, cut_all=True)
def get_cloud_word(text):
alice_mask = np.array(Image.open("data/bank.jpg"))
stopwords = set(STOPWORDS)
stopwords.add('该条')
stopwords.add('什么')
wc = WordCloud(font_path='wqy-microhei.ttc', stopwords=stopwords, background_color="white", max_words=300,
mask=alice_mask).generate(text)
plt.imshow(wc, interpolation='bilinear')
plt.axis('off')
plt.show()
def get_most_count(text, n):
from collections import Counter
total_counts = Counter(text)
return total_counts.most_common(n)
if __name__ == '__main__':
excel_file = 'data/评论详情_20170401_20170630.xlsx'
content = excel2text(excel_file)
content = ' '.join(content).replace('\n', ' ')
words = text2word(content)
get_cloud_word(' '.join(words))
Go语言实现json2xml转换器
什么是antlr
antlr(ANother Tool for Language Recognition)是一个强大的语法分析器生成工具,它可用于读取,处理,执行和翻译结构化的文本和二进制文件。目前,该工具广泛应用于学术和工业生产领域,同时也是众多语言,工具和框架的基础。
今天我们就用这个工具实现一个go语言版的json2xml转换器;
antlr的作用
关于一门语言的语法描述叫做grammar, 该工具能够为该语言生成语法解析器,并自动建立语法分析数AST,同时antlr也能自动生成数的遍历器,极大地降低手工coding 语法解析器的成本;
实践开始
言归正传,拿json2xml为例,实现一个工具;
安装
以macOS为例
brew install antlr
编辑json语言解析语法
// Derived from http://json.org
grammar JSON;
json: object
| array
;
object
: '{' pair (',' pair)* '}' # AnObject
| '{' '}' # NullObject
;
array
: '[' value (',' value)* ']' # ArrayOfValues
| '[' ']' # NullArray
;
pair: STRING ':' value ;
value
: STRING # String
| NUMBER # Atom
| object # ObjectValue
| array # ArrayValue
| 'true' # Atom
| 'false' # Atom
| 'null' # Atom
;
LCURLY : '{' ;
LBRACK : '[' ;
STRING : '"' (ESC | ~["\\])* '"' ;
fragment ESC : '\\' (["\\/bfnrt] | UNICODE) ;
fragment UNICODE : 'u' HEX HEX HEX HEX ;
fragment HEX : [0-9a-fA-F] ;
NUMBER
: '-'? INT '.' INT EXP? // 1.35, 1.35E-9, 0.3, -4.5
| '-'? INT EXP // 1e10 -3e4
| '-'? INT // -3, 45
;
fragment INT : '0' | '1'..'9' '0'..'9'* ; // no leading zeros
fragment EXP : [Ee] [+\-]? INT ; // \- since - means "range" inside [...]
WS : [ \t\n\r]+ -> skip ;
上面是依照antlr4的语法格式编辑的文件
- antlr4文件语法也比较简单:
- 以grammar关键字开头,名字与文件名相匹配
- 语法分析器的规则必须以小写的字母开头
- 词法分析器的规则必须用大写开头
- | 管道符号分割同一语言规则的若干备选分支,使用圆括号把一些符号组成子规则。
- 涉及到的几个专有名词:
- 语言: 语言即一个有效语句的集合,语句由词组组成,词组由子词组组成,一次循环类推;
- 语法: 语法定义语言的语意规则, 语法中每条规则定义一种词组结构;
- 语法分析树: 以树状的形式代表的语法的层次结构;根结点对应语法规则的名字,叶子节点代表语句中的符号或者词法符号。
- 词法分析器: 将输入的字符序列分解成一系列的词法符号。一个词法分析器负责分析词法;
- 语法分析器: 检查语句结构是否符合语法规范或者是否合法。分析的过程类似走迷宫,一般都是通过对比匹配完成。
- 自顶向下语法分析器: 是语法分析器的一种实现,每条规则都对应语法分析器中的一个函数;
- 前向预测: 语法分析器使用前向预测来进行决策判断,具体指将输入的符号于每个备选分支的起始字符进行比较;
生成解析基础代码
# antlr4 -Dlanguage=Go -package json2xml JSON.g4
使用antlr生成目标语言为Go, package名为json2xml的基础代码
生成的文件如下:
$ tree
├── JSON.g4
├── JSON.interp # 语法解析中间文件
├── JSON.tokens # 语法分析tokens流文件
├── JSONLexer.interp # 词法分析中间文件
├── JSONLexer.tokens # 词法分析tokens流文件
├── json_base_listener.go # 默认是listener模式文件
├── json_lexer.go # 词法分析器
├── json_listener.go # 抽象listener接口文件
├── json_parser.go # parser解析器文件
实现解析器(listener例子)
package main
import (
"fmt"
"io/ioutil"
"log"
"os"
"strings"
"testing"
"c2j/parser/json2xml"
"github.com/antlr/antlr4/runtime/Go/antlr"
)
func init() {
log.SetFlags(log.LstdFlags | log.Lshortfile)
}
type j2xConvert struct {
*json2xml.BaseJSONListener
xml map[antlr.Tree]string
}
func NewJ2xConvert() *j2xConvert {
return &j2xConvert{
&json2xml.BaseJSONListener{},
make(map[antlr.Tree]string),
}
}
func (j *j2xConvert) setXML(ctx antlr.Tree, s string) {
j.xml[ctx] = s
}
func (j *j2xConvert) getXML(ctx antlr.Tree) string {
return j.xml[ctx]
}
// j2xConvert methods
func (j *j2xConvert) ExitJson(ctx *json2xml.JsonContext) {
j.setXML(ctx, j.getXML(ctx.GetChild(0)));
}
func (j *j2xConvert) stripQuotes(s string) string {
if s == "" || ! strings.Contains(s, "\"") {
return s
}
return s[1 : len(s)-1]
}
func (j *j2xConvert) ExitAnObject(ctx *json2xml.AnObjectContext) {
sb := strings.Builder{}
sb.WriteString("\n")
for _, p := range ctx.AllPair() {
sb.WriteString(j.getXML(p))
}
j.setXML(ctx, sb.String())
}
func (j *j2xConvert) ExitNullObject(ctx *json2xml.NullObjectContext) {
j.setXML(ctx, "")
}
func (j *j2xConvert) ExitArrayOfValues(ctx *json2xml.ArrayOfValuesContext) {
sb := strings.Builder{}
sb.WriteString("\n")
for _, p := range ctx.AllValue() {
sb.WriteString("<element>")
sb.WriteString(j.getXML(p))
sb.WriteString("</element>")
sb.WriteString("\n")
}
j.setXML(ctx, sb.String())
}
func (j *j2xConvert) ExitNullArray(ctx *json2xml.NullArrayContext) {
j.setXML(ctx, "")
}
func (j *j2xConvert) ExitPair(ctx *json2xml.PairContext) {
tag := j.stripQuotes(ctx.STRING().GetText())
v := ctx.Value()
r := fmt.Sprintf("<%s>%s</%s>\n", tag, j.getXML(v), tag)
j.setXML(ctx, r)
}
func (j *j2xConvert) ExitObjectValue(ctx *json2xml.ObjectValueContext) {
j.setXML(ctx, j.getXML(ctx.Object()))
}
func (j *j2xConvert) ExitArrayValue(ctx *json2xml.ArrayValueContext) {
j.setXML(ctx, j.getXML(ctx.Array()))
}
func (j *j2xConvert) ExitAtom(ctx *json2xml.AtomContext) {
j.setXML(ctx, ctx.GetText())
}
func (j *j2xConvert) ExitString(ctx *json2xml.StringContext) {
j.setXML(ctx, j.stripQuotes(ctx.GetText()))
}
func TestJSON2XMLVisitor(t *testing.T) {
f, err := os.Open("testdata/json2xml/t.json")
if err != nil {
panic(err)
}
defer f.Close()
content, err := ioutil.ReadAll(f)
if err != nil {
panic(err)
}
// Setup the input
is := antlr.NewInputStream(string(content))
// Create lexter
lexer := json2xml.NewJSONLexer(is)
stream := antlr.NewCommonTokenStream(lexer, antlr.LexerDefaultTokenChannel)
// Create parser and tree
p := json2xml.NewJSONParser(stream)
p.BuildParseTrees = true
tree := p.Json()
// Finally AST tree
j2x := NewJ2xConvert()
antlr.ParseTreeWalkerDefault.Walk(j2x, tree)
log.Println(j2x.getXML(tree))
}
上面代码比较简单,看注释就好;
一般流程如下:
- 新建输入流
- 新建词法分析器
- 生成token流,存储词法分析器生成的词法符号tokens
- 新建语法分析器parser,处理tokens
- 然后针对语法规则,开始语法分析
- 最后通过默认提供的Walker,进行AST的遍历
其中针对中间生成的参数和结果如何存放?好办,直接定义个map,map键以Tree存放;
xml map[antlr.Tree]string
Listener和Visitor
antlr生成的代码有两种默认,默认是listener实现,要生成visitor,需要另加参数-visitor。
这两种机制的区别在于,监听器的方法会被antlr提供的遍历器对象自动调用,而visitor模式的方法中,必须显示调用visit方法来访问子节点。如果忘记调用的话,对应的子树就不会被访问。
总结
antlr是一个强大的工具,能让常见的语法解析工作事半功倍,效率极高。同时,该工具使语法分析过程和程序本身高度分离,提供足够的灵活性和可操控性。
wrk http benchmark tool 使用
简介
wrk是一种现代的HTTP基准测试工具,可在单个多核CPU上运行时产生显着的负载。它将多线程设计与可扩展的事件通知系统(如epoll和kqueue)相结合.同时,该工具可以hook LUA脚本,定制化一些报告等特殊化请求, 是现代http 压测的首选;
如何使用
help
wrk --help
Usage: wrk <options> <url>
Options:
-c, --connections <N> Connections to keep open 连接数
-d, --duration <T> Duration of test 测试持续时间
-t, --threads <N> Number of threads to use 开启线程数目
-s, --script <S> Load Lua script file 加载的lua脚本
-H, --header <H> Add header to request
--latency Print latency statistics
--timeout <T> Socket/request timeout 请求超时时间
-v, --version Print version details
Numeric arguments may include a SI unit (1k, 1M, 1G)
Time arguments may include a time unit (2s, 2m, 2h)
cmd
wrk -t12 -c400 -d30s http://127.0.0.1:8000
结果分析
先列举下结果的字段说明
项目 | 名称 | 说明 |
---|---|---|
Avg | 平均值 | 每次测试的平均值 |
Stdev | 标准偏差 | 结果的离散程度,越高说明越不稳定 |
Max | 最大值 | 最大的一次结果 |
+/- Stdev | 正负一个标准差占比 | 结果的离散程度,越大越不稳定 |
Latency: 可以理解为响应时间
Req/Sec: 每个线程每秒钟的完成的请求数
一般我们来说我们主要关注平均值和最大值.
标准差标志着样本本身离散程度. 如果比较大,说明系统性能波动大
Running 30s test @ http://127.0.0.1:9000
12 threads and 400 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 186.42ms 153.84ms 1.78s 90.69%
Req/Sec 76.16 76.79 333.00 80.96%
16545 requests in 30.10s, 2.60MB read
Socket errors: connect 0, read 52, write 0, timeout 190
Requests/sec: 549.71
Transfer/sec: 88.58KB
定制脚本
具体参见LUA for wrk
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.