Created
April 9, 2018 23:20
-
-
Save aimof/46274e1bc6c1bbac1c0a43c665a8e144 to your computer and use it in GitHub Desktop.
simple load test.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"encoding/json" | |
"io/ioutil" | |
"log" | |
"net/http" | |
"os" | |
"runtime" | |
"sync" | |
"time" | |
) | |
var ( | |
maxGoroutine int = 10000 | |
tps int64 = 10000 | |
interval time.Duration = time.Second / time.Duration(tps) | |
duration time.Duration = 10 * time.Second | |
cpus int = 3 | |
fileName string = "tmp.txt" | |
client http.Client = http.Client{ | |
Timeout: 100 * interval, | |
} | |
manageCh chan bool = make(chan bool, maxGoroutine) | |
resultCh chan Result = make(chan Result, 100*tps) | |
finishConnectCh chan struct{} = make(chan struct{}) | |
finishResultCh chan struct{} = make(chan struct{}) | |
wgConnect sync.WaitGroup = sync.WaitGroup{} | |
wgResult sync.WaitGroup = sync.WaitGroup{} | |
) | |
type Result struct { | |
Status string `json:"status_code"` | |
Body string `json:"body"` | |
standByTime time.Time | |
FormattedStandByTime string `json:"stand_by_time"` | |
startTime time.Time | |
FormattedStartTime string `json:"start_time"` | |
endTime time.Time | |
FormattedEndTime string `json:"end_time"` | |
Err error `json:"error"` | |
} | |
// initialize Result | |
func newResult() Result { | |
return Result{ | |
Status: "", | |
Body: "", | |
standByTime: time.Date(2000, time.January, 1, 0, 0, 0, 0, time.UTC), | |
FormattedStandByTime: "", | |
startTime: time.Date(2000, time.January, 1, 0, 0, 0, 0, time.UTC), | |
FormattedStartTime: "", | |
endTime: time.Date(2000, time.January, 1, 0, 0, 0, 0, time.UTC), | |
FormattedEndTime: "", | |
Err: nil, | |
} | |
} | |
func (result Result) record(file *os.File) { | |
b, err := json.Marshal(result) | |
if err != nil { | |
b = []byte(`{"error": "json marshal error"}`) | |
} | |
_, err = file.Write(b) | |
file.Write([]byte("\n")) | |
if err != nil { | |
log.Fatalln(err) | |
} | |
} | |
func main() { | |
req, err := http.NewRequest("GET", "http://localhost:8080/", nil) | |
if err != nil { | |
log.Fatalln(err) | |
} | |
runtime.GOMAXPROCS(cpus) | |
for i := 0; i < maxGoroutine; i++ { | |
manageCh <- true | |
} | |
ticker := time.NewTicker(interval) | |
file, err := os.OpenFile(fileName, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) | |
if err != nil { | |
log.Fatalln(err) | |
} | |
// record result | |
wgResult.Add(1) | |
go func(file *os.File) { | |
firstLoop: | |
for { | |
select { | |
case result := <-resultCh: | |
result.record(file) | |
case <-finishResultCh: | |
break firstLoop | |
} | |
} | |
for len(resultCh) != 0 { | |
result := <-resultCh | |
result.record(file) | |
} | |
wgResult.Done() | |
}(file) | |
go func(duration time.Duration) { | |
time.Sleep(duration) | |
close(finishConnectCh) | |
}(duration) | |
connectLoop: | |
for { | |
select { | |
case <-ticker.C: | |
wgConnect.Add(1) | |
go doRequest(req) | |
case <-finishConnectCh: | |
break connectLoop | |
} | |
} | |
wgConnect.Wait() | |
wgResult.Wait() | |
} | |
func doRequest(req *http.Request) { | |
defer wgConnect.Done() | |
result := newResult() | |
result.standByTime = time.Now() | |
_ = <-manageCh | |
result.startTime = time.Now() | |
resp, err := client.Do(req) | |
result.endTime = time.Now() | |
if err != nil { | |
result.Err = err | |
resultCh <- result | |
manageCh <- true | |
return | |
} | |
defer resp.Body.Close() | |
result.Status = resp.Status | |
b, err := ioutil.ReadAll(resp.Body) | |
if err != nil { | |
b = make([]byte, 0) | |
result.Err = err | |
} | |
result.Body = string(b) | |
resultCh <- result | |
manageCh <- true | |
return | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment