这篇要讲的东西,主要是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
命令说明:
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)但这个只对HTTP接口之类好使,但像我那种基于WebSocket,使用自定义协议的情况。
还是需要自己定制。
我目前的做法,客户端测试直接参考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
有疑问加站长微信联系(非本文作者)