Go語言HTTP測試及程式效能調優
阿新 • • 發佈:2019-02-05
這篇要講的東西,主要是HTTP,WebSocket的測試及如何調優Go程式的一些方法.
分下面幾個內容:
一.httptest測試包
二.效能測試
三.怎麼利用引數分析和調優程式
除了傳統的AB,有一個Go寫的好工具叫boom.
例子:
boom -n 1000 -c 100 https://google.com
命令說明:
還是需要自己定製。
我目前的做法,客戶端測試直接參考boom的原始碼架構,改成支援WebSocket協議。
並加上指定的自定義協議做業務邏輯模擬,用起來還不錯。不過有個地方要注意,如果一下併發
連線太大,WebSocket的TCP連線建立可能會超時,在定製時可以擴大下等待時長.
程式碼如下:
其實這個,可以參考原始碼下的 net/http/pprof/pprof.go
在程式執行中,在命令列視窗,執行"go tool pprof url... "會也成相應的文件.
以profile為例,會等待30s,然後在 \pprof\ 生成相關文件。 然後可使用pprof相關命令來調優。
參考文件:
https://golang.org/cmd/go/#hdr-Description_of_testing_flags
http://saml.rilspace.org/profiling-and-creating-call-graphs-for-go-programs-with-go-tool-pprof
http://www.cnblogs.com/yjf512/archive/2012/12/27/2835331.html
BLOG: http://blog.csdn.net/xcl168
分下面幾個內容:
一.httptest測試包
二.效能測試
三.怎麼利用引數分析和調優程式
四.在執行中實時監控調優
一.httptest測試包
對於HTTP和WebSocket測試,Go標準庫有一個HTTP測試框架.在"http/httptest"包下.
go1.5.1\go\src\net\http\httptest
怎麼用可以在原始碼目錄看例子,也可以上官網看看這個例子:
https://golang.org/src/net/http/request_test.go
裡面各種用法還是很全的.
如果想親自動手試試. https://golang.org/doc/articles/wiki/ 有個很完整的Go Web的例子。
可以搭建起來,再跑一下測試.
比如Post,大致測試程式是這樣的:
二.效能測試func TestPost(t *testing.T) { req, err := NewRequest("POST", "http://localhost:8080/edit/nn", strings.NewReader("body=xcl")) if err != nil { t.Errorf("%v", err) } defer req.Body.Close() req.Header.Set("Content-Type", "application/x-www-form-urlencoded; param=value") if q := req.FormValue("body"); q != "xcl" { t.Errorf(`req.FormValue("body") = %q, want "xcl"`, q) } }
除了傳統的AB,有一個Go寫的好工具叫boom.
例子:
boom -n 1000 -c 100 https://google.com
命令說明:
但這個只對HTTP介面之類好使,但像我那種基於WebSocket,使用自定義協議的情況。Usage: boom [options...] <url> Options: -n Number of requests to run. -c Number of requests to run concurrently. Total number of requests cannot be smaller than the concurency level. -q Rate limit, in seconds (QPS). -o Output type. If none provided, a summary is printed. "csv" is the only supported alternative. Dumps the response metrics in comma-seperated values format. -m HTTP method, one of GET, POST, PUT, DELETE, HEAD, OPTIONS. -h Custom HTTP headers, name1:value1;name2:value2. -t Timeout in ms. -A HTTP Accept header. -d HTTP request body. -T Content-type, defaults to "text/html". -a Basic authentication, username:password. -x HTTP Proxy address as host:port. -readall Consumes the entire request body. -allow-insecure Allow bad/expired TLS/SSL certificates. -disable-compression Disable compression. -disable-keepalive Disable keep-alive, prevents re-use of TCP connections between different HTTP requests. -cpus Number of used cpu cores. (default for current machine is 1 cores)
還是需要自己定製。
我目前的做法,客戶端測試直接參考boom的原始碼架構,改成支援WebSocket協議。
並加上指定的自定義協議做業務邏輯模擬,用起來還不錯。不過有個地方要注意,如果一下併發
連線太大,WebSocket的TCP連線建立可能會超時,在定製時可以擴大下等待時長.
程式碼如下:
//.......
client, err := net.DialTimeout("tcp", serverIP, waiteDial*time.Second)
if err != nil {
log.Printf("[testConnect] 使用者(%s) net.DialTimeout error:%s", userName, err)
return
}
defer client.Close()
config, _ := websocket.NewConfig(serverAddr, origin)
ws, err := websocket.NewClient(config, client)
if err != nil {
log.Printf("[testConnect] 使用者(%s)連線伺服器失敗! err:%s", userName, err)
return
}
//.......
三.怎麼利用引數分析和調優程式/*
調優程式例子
go build main.go
main.exe -cpuprofile=cpu.pprof
go tool pprof main.exe cpu.pprof
Author:xcl
Date: 2015-11-22
*/
package main
import (
"flag"
"fmt"
"os"
"runtime/pprof"
)
var cpuprofile = flag.String("cpuprofile", "", "write cpu profile to file")
func main() {
flag.Parse()
if *cpuprofile != "" {
f, err := os.Create(*cpuprofile)
if err != nil {
fmt.Println("Error: ", err)
}
pprof.StartCPUProfile(f)
defer pprof.StopCPUProfile()
}
t1()
}
func t1() {
for i := 0; i < 10000; i++ {
fmt.Sprintf("%d", i)
}
}
/*
////////////////////////////////////////////////////
E:\GOtest\testing\testpprof3>go build main.go
E:\GOtest\testing\testpprof3>main.exe -cpuprofile=cpu.pprof
E:\GOtest\testing\testpprof3>dir
驅動器 E 中的卷是 doc
卷的序列號是 0E3D-2A1F
E:\GOtest\testing\testpprof3 的目錄
2015/11/22 18:39 <DIR> .
2015/11/22 18:39 <DIR> ..
2015/11/22 18:39 168 cpu.pprof
2015/11/22 18:38 2,826,752 main.exe
2015/11/22 18:38 1,604 main.go
3 個檔案 2,828,524 位元組
2 個目錄 15,171,936,256 可用位元組
E:\GOtest\testing\testpprof3>go tool pprof main.exe cpu.pprof
Entering interactive mode (type "help" for commands)
(pprof) top10
10ms of 10ms total ( 100%)
Showing top 10 nodes out of 11 (cum >= 10ms)
flat flat% sum% cum cum%
10ms 100% 100% 10ms 100% runtime.memmove
0 0% 100% 10ms 100% fmt.(*fmt).integer
0 0% 100% 10ms 100% fmt.(*fmt).pad
0 0% 100% 10ms 100% fmt.(*pp).doPrintf
0 0% 100% 10ms 100% fmt.(*pp).fmtInt64
0 0% 100% 10ms 100% fmt.(*pp).printArg
0 0% 100% 10ms 100% fmt.Sprintf
0 0% 100% 10ms 100% main.main
0 0% 100% 10ms 100% main.t1
0 0% 100% 10ms 100% runtime.goexit
(pprof)
*/
四.在執行中實時監控調優其實這個,可以參考原始碼下的 net/http/pprof/pprof.go
/*
調優程式例子
go build main.go
在瀏覽器邊上檢視
http://127.0.0.1:7081/debug/pprof/
http://127.0.0.1:7081/debug/pprof/profile
Author:xcl
Date: 2015-11-22
*/
package main
import (
"fmt"
"net/http"
"net/http/pprof"
"os"
"time"
)
func main() {
go func() {
if err := StartAdminHttp("127.0.0.1:7081"); err != nil {
os.Exit(-1)
}
}()
t1()
}
func StartAdminHttp(webaddr string) error {
adminServeMux := http.NewServeMux()
adminServeMux.HandleFunc("/debug/pprof/", pprof.Index)
adminServeMux.HandleFunc("/debug/pprof/cmdline", pprof.Cmdline)
adminServeMux.HandleFunc("/debug/pprof/profile", pprof.Profile)
adminServeMux.HandleFunc("/debug/pprof/symbol", pprof.Symbol)
err := http.ListenAndServe(webaddr, adminServeMux)
if err != nil {
x := fmt.Sprintf("http.ListenAdServe(\"%s\") failed (%s)", webaddr, err.Error())
fmt.Println(x)
return err
}
return nil
}
func t1() {
for i := 0; i < 10000; i++ {
fmt.Sprintf("%d", i)
time.Sleep(1 * time.Second)
}
}
另外一種做法:在程式執行中,在命令列視窗,執行"go tool pprof url... "會也成相應的文件.
以profile為例,會等待30s,然後在 \pprof\ 生成相關文件。 然後可使用pprof相關命令來調優。
C:\Users\XCL>go tool pprof http://127.0.0.1:7081/debug/pprof/profile
Fetching profile from http://127.0.0.1:7081/debug/pprof/profile
Please wait... (30s)
Saved profile in \pprof\pprof.127.0.0.1:7081.samples.cpu.001.pb.gz
Entering interactive mode (type "help" for commands)
(pprof)
(pprof)
(pprof) top10
10ms of 10ms total ( 100%)
flat flat% sum% cum cum%
10ms 100% 100% 10ms 100% runtime.runqput
0 0% 100% 10ms 100% runtime.goready.func1
0 0% 100% 10ms 100% runtime.ready
0 0% 100% 10ms 100% runtime.startTheWorldWithSema
0 0% 100% 10ms 100% runtime.systemstack
(pprof)
參考文件:
https://golang.org/cmd/go/#hdr-Description_of_testing_flags
http://saml.rilspace.org/profiling-and-creating-call-graphs-for-go-programs-with-go-tool-pprof
http://www.cnblogs.com/yjf512/archive/2012/12/27/2835331.html
BLOG: http://blog.csdn.net/xcl168