diff --git a/stress/model/request_model.go b/stress/model/request_model.go index 523461590..67881b292 100644 --- a/stress/model/request_model.go +++ b/stress/model/request_model.go @@ -4,7 +4,6 @@ package model import ( "errors" "fmt" - "io" "net/http" "strings" "sync" @@ -23,13 +22,13 @@ const ( // 支持协议 const ( - // FormTypeHTTP http 协议 - FormTypeHTTP = "http" - // FormTypeWebSocket webSocket 协议 + /// FormTypeHTTP http 协议 + //FormTypeHTTP = "http" + /// FormTypeWebSocket webSocket 协议 FormTypeWebSocket = "webSocket" - // FormTypeGRPC grpc 协议 - FormTypeGRPC = "grpc" - FormTypeRadius = "radius" + /// FormTypeGRPC grpc 协议 + //FormTypeGRPC = "grpc" + //FormTypeRadius = "radius" ) // 校验函数 @@ -44,14 +43,6 @@ var ( verifyMapWebSocketMutex sync.RWMutex ) -// RegisterVerifyHTTP 注册 http 校验函数 -func RegisterVerifyHTTP(verify string, verifyFunc VerifyHTTP) { - verifyMapHTTPMutex.Lock() - defer verifyMapHTTPMutex.Unlock() - key := fmt.Sprintf("%s.%s", FormTypeHTTP, verify) - verifyMapHTTP[key] = verifyFunc -} - // RegisterVerifyWebSocket 注册 webSocket 校验函数 func RegisterVerifyWebSocket(verify string, verifyFunc VerifyWebSocket) { verifyMapWebSocketMutex.Lock() @@ -74,23 +65,17 @@ type VerifyWebSocket func(request *Request, seq string, msg []byte) (code int, i // Request 请求数据 type Request struct { - URL string // URL - Form string // http/webSocket/tcp - Method string // 方法 GET/POST/PUT - Headers map[string]string // Headers - Body string // body - Verify string // 验证的方法 - Timeout time.Duration // 请求超时时间 - Debug bool // 是否开启Debug模式 - MaxCon int // 每个连接的请求数 - HTTP2 bool // 是否使用http2.0 - Keepalive bool // 是否开启长连接 - Code int // 验证的状态码 -} - -// GetBody 获取请求数据 -func (r *Request) GetBody() (body io.Reader) { - return strings.NewReader(r.Body) + URL string // URL + Form string // http/webSocket/tcp + // Method string // 方法 GET/POST/PUT + // Headers map[string]string // Headers + //Body string // body + Verify string // 验证的方法 + Timeout time.Duration // 请求超时时间 + Debug bool // 是否开启Debug模式 + MaxCon int // 每个连接的请求数 + Keepalive bool // 是否开启长连接 + Code int // 验证的状态码 } // getVerifyKey 获取校验 key @@ -122,51 +107,12 @@ func (r *Request) GetVerifyWebSocket() VerifyWebSocket { // timeout 请求超时时间 // debug 是否开启debug // path curl文件路径 http接口压测,自定义参数设置 -func NewRequest(url string, verify string, code int, timeout time.Duration, debug bool, path string, - reqHeaders []string, - reqBody string, maxCon int, http2 bool, keepalive bool) (request *Request, err error) { - var ( - method = "GET" - headers = make(map[string]string) - body string - ) - if path != "" { - var curl *CURL - curl, err = ParseTheFile(path) - if err != nil { - return nil, err - } - if url == "" { - url = curl.GetURL() - } - method = curl.GetMethod() - headers = curl.GetHeaders() - body = curl.GetBody() - } else { - if reqBody != "" { - method = "POST" - body = reqBody - } - for _, v := range reqHeaders { - getHeaderValue(v, headers) - } - if _, ok := headers["Content-Type"]; !ok { - headers["Content-Type"] = "application/x-www-form-urlencoded; charset=utf-8" - } - } +func NewRequest(url string, verify string, code int, timeout time.Duration, debug bool, + maxCon int, keepalive bool) (request *Request, err error) { + form := "" - if strings.HasPrefix(url, "http://") || strings.HasPrefix(url, "https://") { - form = FormTypeHTTP - } else if strings.HasPrefix(url, "ws://") || strings.HasPrefix(url, "wss://") { + if strings.HasPrefix(url, "ws://") || strings.HasPrefix(url, "wss://") { form = FormTypeWebSocket - } else if strings.HasPrefix(url, "grpc://") || strings.HasPrefix(url, "rpc://") { - form = FormTypeGRPC - } else if strings.HasPrefix(url, "radius://") { - form = FormTypeRadius - url = url[9:] - } else { - form = FormTypeHTTP - url = fmt.Sprintf("http://%s", url) } if form == "" { err = fmt.Errorf("url:%s 不合法,必须是完整http、webSocket连接", url) @@ -174,17 +120,6 @@ func NewRequest(url string, verify string, code int, timeout time.Duration, debu } var ok bool switch form { - case FormTypeHTTP: - // verify - if verify == "" { - verify = "statusCode" - } - key := fmt.Sprintf("%s.%s", form, verify) - _, ok = verifyMapHTTP[key] - if !ok { - err = errors.New("验证器不存在:" + key) - return - } case FormTypeWebSocket: // verify if verify == "" { @@ -203,14 +138,10 @@ func NewRequest(url string, verify string, code int, timeout time.Duration, debu request = &Request{ URL: url, Form: form, - Method: strings.ToUpper(method), - Headers: headers, - Body: body, Verify: verify, Timeout: timeout, Debug: debug, MaxCon: maxCon, - HTTP2: http2, Keepalive: keepalive, Code: code, } @@ -239,11 +170,10 @@ func (r *Request) Print() { if r == nil { return } - result := fmt.Sprintf("request:\n form:%s \n url:%s \n method:%s \n headers:%v \n", r.Form, r.URL, r.Method, - r.Headers) - result = fmt.Sprintf("%s data:%v \n", result, r.Body) + result := fmt.Sprintf("request:\n form:%s \n url:%s \n", r.Form, r.URL) + //result = fmt.Sprintf("%s data:%v \n", result, r.Body) result = fmt.Sprintf("%s verify:%s \n timeout:%s \n debug:%v \n", result, r.Verify, r.Timeout, r.Debug) - result = fmt.Sprintf("%s http2.0:%v \n keepalive:%v \n maxCon:%v ", result, r.HTTP2, r.Keepalive, r.MaxCon) + //result = fmt.Sprintf("%s http2.0:%v \n keepalive:%v \n maxCon:%v ", result, r.HTTP2, r.Keepalive, r.MaxCon) fmt.Println(result) return } diff --git a/stress/server/client/http_client.go b/stress/server/client/http_client.go deleted file mode 100644 index 715d1f0a3..000000000 --- a/stress/server/client/http_client.go +++ /dev/null @@ -1,99 +0,0 @@ -// Package client http 客户端 -package client - -import ( - "crypto/tls" - "log" - "net/http" - "os" - "time" - - "go_dreamfactory/stress/model" - httplongclinet "go_dreamfactory/stress/server/client/http_longclinet" - - "golang.org/x/net/http2" - - "go_dreamfactory/stress/helper" -) - -// logErr err -var logErr = log.New(os.Stderr, "", 0) - -// HTTPRequest HTTP 请求 -// method 方法 GET POST -// url 请求的url -// body 请求的body -// headers 请求头信息 -// timeout 请求超时时间 -func HTTPRequest(chanID uint64, request *model.Request) (resp *http.Response, requestTime uint64, err error) { - method := request.Method - url := request.URL - body := request.GetBody() - timeout := request.Timeout - headers := request.Headers - - req, err := http.NewRequest(method, url, body) - if err != nil { - return - } - - // 在req中设置Host,解决在header中设置Host不生效问题 - if _, ok := headers["Host"]; ok { - req.Host = headers["Host"] - } - // 设置默认为utf-8编码 - if _, ok := headers["Content-Type"]; !ok { - if headers == nil { - headers = make(map[string]string) - } - headers["Content-Type"] = "application/x-www-form-urlencoded; charset=utf-8" - } - for key, value := range headers { - req.Header.Set(key, value) - } - var client *http.Client - if request.Keepalive { - client = httplongclinet.NewClient(chanID, request) - startTime := time.Now() - resp, err = client.Do(req) - requestTime = uint64(helper.DiffNano(startTime)) - if err != nil { - logErr.Println("请求失败:", err) - - return - } - return - } else { - req.Close = true - tr := &http.Transport{} - if request.HTTP2 { - // 使用真实证书 验证证书 模拟真实请求 - tr = &http.Transport{ - TLSClientConfig: &tls.Config{InsecureSkipVerify: false}, - } - if err = http2.ConfigureTransport(tr); err != nil { - return - } - } else { - // 跳过证书验证 - tr = &http.Transport{ - TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, - } - } - - client = &http.Client{ - Transport: tr, - Timeout: timeout, - } - } - - startTime := time.Now() - resp, err = client.Do(req) - requestTime = uint64(helper.DiffNano(startTime)) - if err != nil { - logErr.Println("请求失败:", err) - - return - } - return -} diff --git a/stress/server/client/http_longclinet/long_clinet.go b/stress/server/client/http_longclinet/long_clinet.go index ac76d283f..4ea12558a 100644 --- a/stress/server/client/http_longclinet/long_clinet.go +++ b/stress/server/client/http_longclinet/long_clinet.go @@ -8,8 +8,6 @@ import ( "time" "go_dreamfactory/stress/model" - - "golang.org/x/net/http2" ) var ( @@ -43,32 +41,18 @@ func setClient(i uint64, request *model.Request) *http.Client { // createLangHttpClient 初始化长连接客户端参数 func createLangHttpClient(request *model.Request) *http.Client { tr := &http.Transport{} - if request.HTTP2 { - // 使用真实证书 验证证书 模拟真实请求 - tr = &http.Transport{ - DialContext: (&net.Dialer{ - Timeout: 30 * time.Second, - KeepAlive: 30 * time.Second, - }).DialContext, - MaxIdleConns: 0, // 最大连接数,默认0无穷大 - MaxIdleConnsPerHost: request.MaxCon, // 对每个host的最大连接数量(MaxIdleConnsPerHost<=MaxIdleConns) - IdleConnTimeout: 90 * time.Second, // 多长时间未使用自动关闭连接 - TLSClientConfig: &tls.Config{InsecureSkipVerify: false}, - } - _ = http2.ConfigureTransport(tr) - } else { - // 跳过证书验证 - tr = &http.Transport{ - DialContext: (&net.Dialer{ - Timeout: 30 * time.Second, - KeepAlive: 30 * time.Second, - }).DialContext, - MaxIdleConns: 0, // 最大连接数,默认0无穷大 - MaxIdleConnsPerHost: request.MaxCon, // 对每个host的最大连接数量(MaxIdleConnsPerHost<=MaxIdleConns) - IdleConnTimeout: 90 * time.Second, // 多长时间未使用自动关闭连接 - TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, - } + + tr = &http.Transport{ + DialContext: (&net.Dialer{ + Timeout: 30 * time.Second, + KeepAlive: 30 * time.Second, + }).DialContext, + MaxIdleConns: 0, // 最大连接数,默认0无穷大 + MaxIdleConnsPerHost: request.MaxCon, // 对每个host的最大连接数量(MaxIdleConnsPerHost<=MaxIdleConns) + IdleConnTimeout: 90 * time.Second, // 多长时间未使用自动关闭连接 + TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, } + return &http.Client{ Transport: tr, } diff --git a/stress/server/dispose.go b/stress/server/dispose.go index a421b1c7e..97135710a 100644 --- a/stress/server/dispose.go +++ b/stress/server/dispose.go @@ -11,7 +11,6 @@ import ( "sync" "time" - "go_dreamfactory/stress/server/client" "go_dreamfactory/stress/server/golink" "go_dreamfactory/stress/server/statistics" "go_dreamfactory/stress/server/verify" @@ -25,11 +24,11 @@ const ( func init() { // http - model.RegisterVerifyHTTP("statusCode", verify.HTTPStatusCode) - model.RegisterVerifyHTTP("json", verify.HTTPJson) + //model.RegisterVerifyHTTP("statusCode", verify.HTTPStatusCode) + //model.RegisterVerifyHTTP("json", verify.HTTPJson) // webSocket - model.RegisterVerifyWebSocket("json", verify.WebSocketJSON) + //model.RegisterVerifyWebSocket("json", verify.WebSocketJSON) model.RegisterVerifyWebSocket("pb", verify.WebSocketProto) } @@ -47,14 +46,12 @@ func Dispose(ctx context.Context, concurrency, totalNumber uint64, request *mode for i := uint64(0); i < concurrency; i++ { wg.Add(1) switch request.Form { - case model.FormTypeHTTP: - go golink.HTTP(ctx, i, ch, totalNumber, &wg, request) case model.FormTypeWebSocket: switch connectionMode { case 1: // 连接以后再启动协程 r := robot.NewRobot(request.URL) - r.SetAccount("21112" + strconv.Itoa(int(i))) + r.SetAccount("31112" + strconv.Itoa(int(i))) //head := &pb.UserMessage{MainType: "user", SubType: "login"} // 先登录 @@ -66,13 +63,6 @@ func Dispose(ctx context.Context, concurrency, totalNumber uint64, request *mode // 并发建立长链接 go func(i uint64) { // 连接以后再启动协程 - // ws := client.NewWebSocket(request.URL) - // err := ws.GetConn() - // if err != nil { - // fmt.Println("连接失败:", i, err) - // return - // } - // golink.WebSocket(ctx, i, ch, totalNumber, &wg, request, ws) }(i) // 注意:时间间隔太短会出现连接失败的报错 默认连接时长:20毫秒(公网连接) time.Sleep(5 * time.Millisecond) @@ -80,19 +70,6 @@ func Dispose(ctx context.Context, concurrency, totalNumber uint64, request *mode data := fmt.Sprintf("不支持的类型:%d", connectionMode) panic(data) } - case model.FormTypeGRPC: - // 连接以后再启动协程 - ws := client.NewGrpcSocket(request.URL) - err := ws.Link() - if err != nil { - fmt.Println("连接失败:", i, err) - continue - } - go golink.Grpc(ctx, i, ch, totalNumber, &wg, request, ws) - case model.FormTypeRadius: - // Radius use udp, does not a connection - go golink.Radius(ctx, i, ch, totalNumber, &wg, request) - default: // 类型不支持 wg.Done() diff --git a/stress/server/golink/grpc_link.go b/stress/server/golink/grpc_link.go index 50db143b7..539019e28 100644 --- a/stress/server/golink/grpc_link.go +++ b/stress/server/golink/grpc_link.go @@ -46,7 +46,7 @@ func grpcRequest(chanID uint64, ch chan<- *model.RequestResults, i uint64, reque var ( ctx = context.Background() req = &pb.Request{ - UserName: request.Body, + //UserName: request.Body, } ) rsp, err := c.HelloWorld(ctx, req) diff --git a/stress/server/golink/http_link.go b/stress/server/golink/http_link.go deleted file mode 100644 index 98d923e90..000000000 --- a/stress/server/golink/http_link.go +++ /dev/null @@ -1,105 +0,0 @@ -// Package golink 连接 -package golink - -import ( - "compress/gzip" - "context" - "fmt" - "io" - "io/ioutil" - "net/http" - "sync" - - "go_dreamfactory/stress/model" - "go_dreamfactory/stress/server/client" -) - -// HTTP 请求 -func HTTP(ctx context.Context, chanID uint64, ch chan<- *model.RequestResults, totalNumber uint64, wg *sync.WaitGroup, - request *model.Request) { - defer func() { - wg.Done() - }() - // fmt.Printf("启动协程 编号:%05d \n", chanID) - for i := uint64(0); i < totalNumber; i++ { - if ctx.Err() != nil { - fmt.Printf("ctx.Err err: %v \n", ctx.Err()) - break - } - - list := getRequestList(request) - isSucceed, errCode, requestTime, contentLength := sendList(chanID, list) - requestResults := &model.RequestResults{ - Time: requestTime, - IsSucceed: isSucceed, - ErrCode: errCode, - ReceivedBytes: contentLength, - } - requestResults.SetID(chanID, i) - ch <- requestResults - } - - return -} - -// sendList 多个接口分步压测 -func sendList(chanID uint64, requestList []*model.Request) (isSucceed bool, errCode int, requestTime uint64, - contentLength int64) { - errCode = model.HTTPOk - for _, request := range requestList { - succeed, code, u, length := send(chanID, request) - isSucceed = succeed - errCode = code - requestTime = requestTime + u - contentLength = contentLength + length - if succeed == false { - break - } - } - return -} - -// send 发送一次请求 -func send(chanID uint64, request *model.Request) (bool, int, uint64, int64) { - var ( - // startTime = time.Now() - isSucceed = false - errCode = model.HTTPOk - contentLength = int64(0) - err error - resp *http.Response - requestTime uint64 - ) - newRequest := getRequest(request) - - resp, requestTime, err = client.HTTPRequest(chanID, newRequest) - - if err != nil { - errCode = model.RequestErr // 请求错误 - } else { - // 此处原方式获取的数据长度可能是 -1,换成如下方式获取可获取到正确的长度 - contentLength, err = getBodyLength(resp) - if err != nil { - contentLength = resp.ContentLength - } - // 验证请求是否成功 - errCode, isSucceed = newRequest.GetVerifyHTTP()(newRequest, resp) - } - return isSucceed, errCode, requestTime, contentLength -} - -// getBodyLength 获取响应数据长度 -func getBodyLength(response *http.Response) (length int64, err error) { - var reader io.ReadCloser - switch response.Header.Get("Content-Encoding") { - case "gzip": - reader, err = gzip.NewReader(response.Body) - defer func() { - _ = reader.Close() - }() - default: - reader = response.Body - } - body, err := ioutil.ReadAll(reader) - return int64(len(body)), err -} diff --git a/stress/server/golink/http_link_many.go b/stress/server/golink/http_link_many.go deleted file mode 100644 index 92ae0015d..000000000 --- a/stress/server/golink/http_link_many.go +++ /dev/null @@ -1,71 +0,0 @@ -// Package golink 连接 -package golink - -import ( - "time" - - "go_dreamfactory/stress/model" -) - -// ReqListMany 接口分步压测 -type ReqListMany struct { - list []*model.Request -} - -// getCount 获取连接 -func (r *ReqListMany) getCount() int { - return len(r.list) -} - -var ( - clientList *ReqListMany -) - -// init 接口分步压测示例 -func init() { - clientList = &ReqListMany{} - // TODO::接口分步压测示例 - // 需要压测的接口参数 - clients := make([]*model.Request, 0) - - // 压测第一步 - clients = append(clients, &model.Request{ - URL: "https://page.aliyun.com/delivery/plan/list", // 请求url - Form: "http", // 请求方式 示例参数:http/webSocket/tcp - Method: "POST", // 请求方法 示例参数:GET/POST/PUT - Headers: map[string]string{ - "referer": "https://cn.aliyun.com/", - "cookie": "aliyun_choice=CN; JSESSIONID=J8866281-CKCFJ4BUZ7GDO9V89YBW1-KJ3J5V9K-GYUW7; maliyun_temporary_console0=1AbLByOMHeZe3G41KYd5WWZvrM%2BGErkaLcWfBbgveKA9ifboArprPASvFUUfhwHtt44qsDwVqMk8Wkdr1F5LccYk2mPCZJiXb0q%2Bllj5u3SQGQurtyPqnG489y%2FkoA%2FEvOwsXJTvXTFQPK%2BGJD4FJg%3D%3D; cna=L3Q5F8cHDGgCAXL3r8fEZtdU; isg=BFNThsmSCcgX-sUcc5Jo2s2T4tF9COfKYi8g9wVwr3KphHMmjdh3GrHFvPTqJD_C; l=eBaceXLnQGBjstRJBOfwPurza77OSIRAguPzaNbMiT5POw1B5WAlWZbqyNY6C3GVh6lwR37EODnaBeYBc3K-nxvOu9eFfGMmn", - }, // headers 头信息 - Body: "adPlanQueryParam=%7B%22adZone%22%3A%7B%22positionList%22%3A%5B%7B%22positionId%22%3A83%7D%5D%7D%2C%22requestId%22%3A%2217958651-f205-44c7-ad5d-f8af92a6217a%22%7D", // 消息体 - Verify: "statusCode", // 验证的方法 示例参数:statusCode、json - Timeout: 30 * time.Second, // 是否开启Debug模式 - Debug: false, // 是否开启Debug模式 - }) - - // 压测第二步 - clients = append(clients, &model.Request{ - URL: "https://page.aliyun.com/delivery/plan/list", // 请求url - Form: "http", // 请求方式 示例参数:http/webSocket/tcp - Method: "POST", // 请求方法 示例参数:GET/POST/PUT - Headers: map[string]string{ - "referer": "https://cn.aliyun.com/", - "cookie": "aliyun_choice=CN; JSESSIONID=J8866281-CKCFJ4BUZ7GDO9V89YBW1-KJ3J5V9K-GYUW7; maliyun_temporary_console0=1AbLByOMHeZe3G41KYd5WWZvrM%2BGErkaLcWfBbgveKA9ifboArprPASvFUUfhwHtt44qsDwVqMk8Wkdr1F5LccYk2mPCZJiXb0q%2Bllj5u3SQGQurtyPqnG489y%2FkoA%2FEvOwsXJTvXTFQPK%2BGJD4FJg%3D%3D; cna=L3Q5F8cHDGgCAXL3r8fEZtdU; isg=BFNThsmSCcgX-sUcc5Jo2s2T4tF9COfKYi8g9wVwr3KphHMmjdh3GrHFvPTqJD_C; l=eBaceXLnQGBjstRJBOfwPurza77OSIRAguPzaNbMiT5POw1B5WAlWZbqyNY6C3GVh6lwR37EODnaBeYBc3K-nxvOu9eFfGMmn", - }, // headers 头信息 - Body: "adPlanQueryParam=%7B%22adZone%22%3A%7B%22positionList%22%3A%5B%7B%22positionId%22%3A83%7D%5D%7D%2C%22requestId%22%3A%2217958651-f205-44c7-ad5d-f8af92a6217a%22%7D", // 消息体 - Verify: "statusCode", // 验证的方法 示例参数:statusCode、json - Timeout: 30 * time.Second, // 是否开启Debug模式 - Debug: false, // 是否开启Debug模式 - }) - clientList.list = clients - // TODO::分步压测时,注释下面一行代码 - clientList.list = nil -} - -// getRequestList 获取请求列表 -func getRequestList(request *model.Request) []*model.Request { - if len(clientList.list) <= 0 { - return []*model.Request{request} - } - return clientList.list -} diff --git a/stress/server/golink/http_link_weigh.go b/stress/server/golink/http_link_weigh.go deleted file mode 100644 index 840d95472..000000000 --- a/stress/server/golink/http_link_weigh.go +++ /dev/null @@ -1,97 +0,0 @@ -// Package golink 连接 -package golink - -import ( - "math/rand" - "time" - - "go_dreamfactory/stress/model" -) - -// ReqListWeigh 接口加权压测 -type ReqListWeigh struct { - list []Req - weighCount uint32 // 总权重 -} - -// Req req -type Req struct { - req *model.Request // 请求信息 - weights uint32 // 权重,数字越大访问频率越高 -} - -// setWeighCount 设置权重 -func (r *ReqListWeigh) setWeighCount() { - r.weighCount = 0 - for _, value := range r.list { - r.weighCount = r.weighCount + value.weights - } -} - -var ( - clientWeigh *ReqListWeigh - r *rand.Rand -) - -// 多接口压测示例 -func init() { - // TODO::压测多个接口示例 - // 需要压测的接口参数 - clients := make([]Req, 0) - clients = append(clients, Req{req: &model.Request{ - URL: "https://page.aliyun.com/delivery/plan/list", // 请求url - Form: "http", // 请求方式 示例参数:http/webSocket/tcp - Method: "POST", // 请求方法 示例参数:GET/POST/PUT - Headers: map[string]string{ - "referer": "https://cn.aliyun.com/", - "cookie": "aliyun_choice=CN; JSESSIONID=J8866281-CKCFJ4BUZ7GDO9V89YBW1-KJ3J5V9K-GYUW7; maliyun_temporary_console0=1AbLByOMHeZe3G41KYd5WWZvrM%2BGErkaLcWfBbgveKA9ifboArprPASvFUUfhwHtt44qsDwVqMk8Wkdr1F5LccYk2mPCZJiXb0q%2Bllj5u3SQGQurtyPqnG489y%2FkoA%2FEvOwsXJTvXTFQPK%2BGJD4FJg%3D%3D; cna=L3Q5F8cHDGgCAXL3r8fEZtdU; isg=BFNThsmSCcgX-sUcc5Jo2s2T4tF9COfKYi8g9wVwr3KphHMmjdh3GrHFvPTqJD_C; l=eBaceXLnQGBjstRJBOfwPurza77OSIRAguPzaNbMiT5POw1B5WAlWZbqyNY6C3GVh6lwR37EODnaBeYBc3K-nxvOu9eFfGMmn", - }, // headers 头信息 - Body: "adPlanQueryParam=%7B%22adZone%22%3A%7B%22positionList%22%3A%5B%7B%22positionId%22%3A83%7D%5D%7D%2C%22requestId%22%3A%2217958651-f205-44c7-ad5d-f8af92a6217a%22%7D", // 消息体 - Verify: "statusCode", // 验证的方法 示例参数:statusCode、json - Timeout: 30 * time.Second, // 是否开启Debug模式 - Debug: false, // 是否开启Debug模式 - }, weights: 2}) - - clients = append(clients, Req{req: &model.Request{ - URL: "https://page.aliyun.com/delivery/plan/list", // 请求url - Form: "http", // 请求方式 示例参数:http/webSocket/tcp - Method: "POST", // 请求方法 示例参数:GET/POST/PUT - Headers: map[string]string{ - "referer": "https://cn.aliyun.com/", - "cookie": "aliyun_choice=CN; JSESSIONID=J8866281-CKCFJ4BUZ7GDO9V89YBW1-KJ3J5V9K-GYUW7; maliyun_temporary_console0=1AbLByOMHeZe3G41KYd5WWZvrM%2BGErkaLcWfBbgveKA9ifboArprPASvFUUfhwHtt44qsDwVqMk8Wkdr1F5LccYk2mPCZJiXb0q%2Bllj5u3SQGQurtyPqnG489y%2FkoA%2FEvOwsXJTvXTFQPK%2BGJD4FJg%3D%3D; cna=L3Q5F8cHDGgCAXL3r8fEZtdU; isg=BFNThsmSCcgX-sUcc5Jo2s2T4tF9COfKYi8g9wVwr3KphHMmjdh3GrHFvPTqJD_C; l=eBaceXLnQGBjstRJBOfwPurza77OSIRAguPzaNbMiT5POw1B5WAlWZbqyNY6C3GVh6lwR37EODnaBeYBc3K-nxvOu9eFfGMmn", - }, // headers 头信息 - Body: "adPlanQueryParam=%7B%22adZone%22%3A%7B%22positionList%22%3A%5B%7B%22positionId%22%3A83%7D%5D%7D%2C%22requestId%22%3A%2217958651-f205-44c7-ad5d-f8af92a6217a%22%7D", // 消息体 - Verify: "statusCode", // 验证的方法 示例参数:statusCode、json - Timeout: 30 * time.Second, // 是否开启Debug模式 - Debug: false, // 是否开启Debug模式 - }, weights: 1}) - - r = rand.New(rand.NewSource(time.Now().Unix())) - clientWeigh = &ReqListWeigh{ - list: clients, - } - - // TODO::注释下面一行代码 - clientWeigh.list = nil - - clientWeigh.setWeighCount() -} - -// getRequest 获取请求 -func getRequest(request *model.Request) *model.Request { - if clientWeigh == nil || clientWeigh.weighCount <= 0 { - return request - } - n := uint32(r.Int31n(int32(clientWeigh.weighCount))) - var ( - count uint32 - ) - for _, value := range clientWeigh.list { - if count >= n { - // value.req.Print() - return value.req - } - count = count + value.weights - } - panic("getRequest err") -} diff --git a/stress/server/verify/http_verify.go b/stress/server/verify/http_verify.go deleted file mode 100644 index 5cd554542..000000000 --- a/stress/server/verify/http_verify.go +++ /dev/null @@ -1,94 +0,0 @@ -// Package verify 校验 -package verify - -import ( - "bytes" - "compress/gzip" - "encoding/json" - "fmt" - "io" - "io/ioutil" - "net/http" - - "go_dreamfactory/stress/model" -) - -// getZipData 处理gzip压缩 -func getZipData(response *http.Response) (body []byte, err error) { - var reader io.ReadCloser - switch response.Header.Get("Content-Encoding") { - case "gzip": - reader, err = gzip.NewReader(response.Body) - defer func() { - _ = reader.Close() - }() - default: - reader = response.Body - } - body, err = ioutil.ReadAll(reader) - response.Body = ioutil.NopCloser(bytes.NewReader(body)) - return -} - -// HTTPStatusCode 通过 HTTP 状态码判断是否请求成功 -func HTTPStatusCode(request *model.Request, response *http.Response) (code int, isSucceed bool) { - defer func() { - _ = response.Body.Close() - }() - code = response.StatusCode - if code == request.Code { - isSucceed = true - } - // 开启调试模式 - if request.GetDebug() { - body, err := getZipData(response) - fmt.Printf("请求结果 httpCode:%d body:%s err:%v \n", response.StatusCode, string(body), err) - } - io.Copy(ioutil.Discard, response.Body) - return -} - -/*************************** 返回值为json ********************************/ - -// ResponseJSON 返回数据结构体 -type ResponseJSON struct { - Code int `json:"code"` - Msg string `json:"msg"` - Data interface{} `json:"data"` -} - -// HTTPJson 通过返回的Body 判断 -// 返回示例: {"code":200,"msg":"Success","data":{}} -// code 默认将http code作为返回码,http code 为200时 取body中的返回code -func HTTPJson(request *model.Request, response *http.Response) (code int, isSucceed bool) { - defer func() { - _ = response.Body.Close() - }() - code = response.StatusCode - if code == http.StatusOK { - body, err := getZipData(response) - if err != nil { - code = model.ParseError - fmt.Printf("请求结果 ioutil.ReadAll err:%v", err) - } else { - responseJSON := &ResponseJSON{} - err = json.Unmarshal(body, responseJSON) - if err != nil { - code = model.ParseError - fmt.Printf("请求结果 json.Unmarshal err:%v", err) - } else { - code = responseJSON.Code - // body 中code返回200为返回数据成功 - if responseJSON.Code == request.Code { - isSucceed = true - } - } - } - // 开启调试模式 - if request.GetDebug() { - fmt.Printf("请求结果 httpCode:%d body:%s err:%v \n", response.StatusCode, string(body), err) - } - } - io.Copy(ioutil.Discard, response.Body) - return -} diff --git a/stress/stress.go b/stress/stress.go index f31777b12..c3fd941d2 100644 --- a/stress/stress.go +++ b/stress/stress.go @@ -35,12 +35,11 @@ var ( debugStr = "false" // 是否是debug requestURL = "" // 压测的url 目前支持,http/https ws/wss path = "" // curl文件路径 http接口压测,自定义参数设置 - verify = "" // verify 验证方法 在server/verify中 http 支持:statusCode、json webSocket支持:json + verify = "pb" // verify 验证方法 在server/verify中 http 支持:statusCode、json webSocket支持:json headers array // 自定义头信息传递给服务器 body = "" // HTTP POST方式传送数据 maxCon = 1 // 单个连接最大请求数 code = 200 // 成功状态码 - http2 = false // 是否开http2.0 keepalive = false // 是否开启长连接 cpuNumber = 1 // CUP 核数,默认为一核,一般场景下单核已经够用了 timeout int64 = 0 // 超时时间,默认不设置 @@ -57,7 +56,6 @@ func init() { flag.StringVar(&body, "data", body, "HTTP POST方式传送数据") flag.IntVar(&maxCon, "m", maxCon, "单个host最大连接数") flag.IntVar(&code, "code", code, "请求成功的状态码") - flag.BoolVar(&http2, "http2", http2, "是否开http2.0") flag.BoolVar(&keepalive, "k", keepalive, "是否开启长连接") flag.IntVar(&cpuNumber, "cpuNumber", cpuNumber, "CUP 核数,默认为一核") flag.Int64Var(&timeout, "timeout", timeout, "超时时间 单位 秒,默认不设置") @@ -84,7 +82,6 @@ func main() { totalNumber = 1 debugStr = "false" requestURL = "ws://106.54.189.74:7891/gateway" - verify = "pb" if concurrency == 0 || totalNumber == 0 || (requestURL == "" && path == "") { fmt.Printf("示例: go run main.go -c 1 -n 1 -u https://www.baidu.com/ \n") fmt.Printf("压测地址或curl路径必填 \n") @@ -93,7 +90,7 @@ func main() { return } debug := strings.ToLower(debugStr) == "false" - request, err := model.NewRequest(requestURL, verify, code, 0, debug, path, headers, body, maxCon, http2, keepalive) + request, err := model.NewRequest(requestURL, verify, code, 0, debug, maxCon, keepalive) if err != nil { fmt.Printf("参数不合法 %v \n", err) return