Gor概述
Gor 是用 Golang 寫的一個 HTTP 實時流量復制工具。只需要在 LB 或者 Varnish 入口服務器上執行一個進程,就可以把生產環境的流量復制到任何地方,比如 Staging 環境、Dev 環境。完美解決了 HTTP 層實時流量復制和壓力測試的問題。
Gor的功能
Gor 支持流量的放大和縮小、頻率限制,這樣不需要搭建和生產環境一致的服務器集群也可以正確測試。Gor 還支持根據正則表達式過濾流量,這意味著可以單獨測試某個 API 服務。還可以修改 HTTP 請求頭,比如替換 User-Agent, 或者增加某些 HTTP Header 。
Gor 還可以把請求記錄到文件,以備回放和分析。Gor 支持和 ElasticSearch 集成,將流量存入 ES 進行實時分析。
Gor的安裝
二進制版本
官方預編譯版本使用比較簡單,開箱即用。
通過以下地址下載最新版本
https://github.com/buger/gor/releases
Linux
$ wget https://github.com/buger/gor/releases/download/v0.12.1/gor_0.12.1_x64.tar.gz
$ tar xzvf gor_0.12.1_x64.tar.gz
$ cp gor /usr/local/bin
Mac
$ wget https://github.com/buger/gor/releases/download/v0.12.1/gor_0.12.1_mac.tar.gz
$ tar xzvf gor_0.12.1_mac.tar.gz
編譯安裝
搭建標準的Go語言環境,可參考http://golang.org/doc/code.html
并設置$GOPATH環境變量
獲取源代碼
$ go get github.com/buger/gor
編譯
$ cd $GOPATH/src/github.com/buger/gor
$ go build
編譯完成會產生一個gor二進制文件。
Gor實踐
性能測試
可以將流量復制到文件,然后再對他們進行回放。回放的時候,流量會維持原始的時間間隔。如果你使用了百分比來進行速率限制,那么回放的速率會相應的增加或減少。有了這種速率限制,gor就可以用來進行壓力測試。
#write to file
gor --input-raw :80 --output-file requests.log
#read from file
gor --input-file requests.gor --output-http"http://staging.com"
- 流量復制到文件
可以使用時間戳命名錄制文件,默認情況下,文件是按“塊”存儲的,即文件大小到達上限后,添加后綴,并新建另一個文件,如下
gor ... --output-file %Y%m%d.log
#append false
20140608_0.log
20140608_1.log
20140609_0.log
20140609_1.log
默認是按“塊”存儲文件的方式,但是可以參數配置,--output-file-append,使用之后如下
gor ... --output-file %Y%m%d.log --output-file-append
#append true
20140608.log
20140609.log
時間格式化文件名的配置說明:
%Y: year including the century (at least 4 digits)
%m: month of the year (01..12)
%d: Day of the month (01..31)
%H: Hour of the day, 24-hour clock (00..23)
%M: Minute of the hour (00..59)
%S: Second of the minute (00..60)
默認格式是%Y%m%d%H
- 流量回放
目前,這種方式只支持"input-file",而且只能用百分比去控制回放速率。請注意,這個回放的速率比例是相對于input的。即按照錄下來的流量的時間戳去進行回放。
# Replay from file on 2x speed
gor --input-file "requests.gor|200%" --output-http "staging.com"
上面的命令例子,是以2倍的速率回放。如果“input-flie”是多個文件,可以用正則去匹配,如“request*.gor|200%”
配合如下配置參數,可以更好的體現壓力測試的效果。
--input-file-loop 重復循環執行input-file
--exit-after 30s 在30s后停止,可以控制壓力測試的時間。分鐘的單位是m
性能測試是gor比較常見的用途,其他常用命令參考“Gor常見命令”
Gor常用命令
簡單的HTTP流量復制
$ gor --input-raw :80 --output-http "http://staging.com"
HTTP流量復制頻率控制(獲取每秒超過10個請求)
$ gor --input-tcp :28020 --output-http "http://staging.com|10"
HTTP流量復制縮小
$ gor --input-raw :80 --output-tcp "replay.local:28020|10%"
HTTP流量記錄到本地文件
$ gor --input-raw :80 --output-file requests.gor
HTTP流量回放和壓測
$ gor --input-file "requests.gor|200%" --output-http "staging.com"
HTTP流量過濾復制
$ gor --input-raw :8080 --output-http staging.com --output-http-url-regexp ^www.
自定義一些流量復制的參數
$ gor --input-raw :80 --output-http 192.168.2.6:8000 --http-allow-method POST --http-set-header 'User-Agent: Gor' -output-http-workers=1 -http-allow-url test.php
將流量復制兩份到不同的測試服務
$ gor --input-tcp :28020 --output-http "http://staging.com" --output-http "http://dev.com"
將流量像負載均衡一樣分配到不同的服務器
$ gor --input-tcp :28020 --output-http "http://staging.com" --output-http "http://dev.com" --split-output true
Gor配置參數
$ gor --help
-cpuprofile string
write cpu profile to file
-debug verbose
打開debug模式,顯示所有接口的流量
-http-allow-header value
用一個正則表達式來匹配http頭部,如果請求的頭部沒有匹配上,則被拒絕
gor --input-raw :8080 --output-http staging.com --http-allow-header api-version:^v1 (default [])
-http-allow-method value
類似于一個白名單機制來允許通過的http請求方法,除此之外的方法都被拒絕.
gor --input-raw :8080 --output-http staging.com --http-allow-method GET --http-allow-method OPTIONS (default [])
-http-allow-url value
一個正則表達式用來匹配url, 用來過濾完全匹配的的url,在此之外的都被過濾掉
gor --input-raw :8080 --output-http staging.com --http-allow-url ^www. (default [])
-http-disallow-header value
用一個正則表達式來匹配http頭部,匹配到的請求會被拒絕掉
gor --input-raw :8080 --output-http staging.com --http-disallow-header "User-Agent: Replayed by Gor" (default [])
-http-disallow-url value
用一個正則表達式來匹配url,如果請求匹配上了,則會被拒絕
gor --input-raw :8080 --output-http staging.com --http-disallow-url ^www. (default [])
-http-header-limiter value
讀取請求,基于FNV32-1A散列來拒絕一定比例的特殊請求
gor --input-raw :8080 --output-http staging.com --http-header-imiter user-id:25% (default [])
-http-original-host
在--output-http的輸出中,通常gor會使用取代請求的http頭,所以應該禁用該選項,保留原始的主機頭
-http-param-limiter value
Takes a fraction of requests, consistently taking or rejecting a request based on the FNV32-1A hash of a specific GET param:
gor --input-raw :8080 --output-http staging.com --http-param-limiter user_id:25% (default [])
-http-rewrite-url value
Rewrite the request url based on a mapping:
gor --input-raw :8080 --output-http staging.com --http-rewrite-url /v1/user/([^\/]+)/ping:/v2/user/$1/ping (default [])
-http-set-header value
Inject additional headers to http reqest:
gor --input-raw :8080 --output-http staging.com --http-set-header 'User-Agent: Gor' (default [])
-http-set-param value
Set request url param, if param already exists it will be overwritten:
gor --input-raw :8080 --output-http staging.com --http-set-param api_key=1 (default [])
-input-dummy value
Used for testing outputs. Emits 'Get /' request every 1s (default [])
-input-file value
從一個文件中讀取請求
gor --input-file ./requests.gor --output-http staging.com (default [])
-input-http value
從一個http接口讀取請求
# Listen for http on 9000
gor --input-http :9000 --output-http staging.com (default [])
-input-raw value
Capture traffic from given port (use RAW sockets and require *sudo* access):
# Capture traffic from 8080 port
gor --input-raw :8080 --output-http staging.com (default [])
-input-tcp value
用來在多個gor之間流轉流量
# Receive requests from other Gor instances on 28020 port, and redirect output to staging
gor --input-tcp :28020 --output-http staging.com (default [])
-memprofile string
write memory profile to this file
-middleware string
Used for modifying traffic using external command
-output-dummy value
用來測試輸入,打印出接收的數據. (default [])
-output-file value
把進入的請求寫入一個文件中
gor --input-raw :80 --output-file ./requests.gor (default [])
-output-http value
轉發進入的請求到一個http地址上
# Redirect all incoming requests to staging.com address
gor --input-raw :80 --output-http http://staging.com (default [])
-output-http-elasticsearch string
把請求和響應狀態發送到ElasticSearch:
gor --input-raw :8080 --output-http staging.com --output-http-elasticsearch 'es_host:api_port/index_name'
-output-http-redirects int
設置多少次重定向被允許
-output-http-stats
每5秒鐘輸出一次輸出隊列的狀態
-output-http-timeout duration
指定http的request/response超時時間,默認是5秒
-output-http-workers int
gor默認是動態的擴展工作者數量,你也可以指定固定數量的工作者
-output-tcp value
用來在多個gor之間流轉流量
# Listen for requests on 80 port and forward them to other Gor instance on 28020 port
gor --input-raw :80 --output-tcp replay.local:28020 (default [])
-output-tcp-stats
每5秒鐘報告一次tcp輸出隊列的狀態
-split-output true
By default each output gets same traffic. If set to true it splits traffic equally among all outputs.
-stats
打開輸出隊列的狀態
-verbose
Turn on more verbose output