Created
December 9, 2020 15:29
-
-
Save nullsimon/258ded650969d4bc9f47d46f901b68c6 to your computer and use it in GitHub Desktop.
Multi-threaded concurrency http client golang version
This file contains hidden or 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 ( | |
"bufio" | |
"bytes" | |
"fmt" | |
"io" | |
"io/ioutil" | |
"net/http" | |
"net/url" | |
"os" | |
"runtime" | |
"time" | |
) | |
var ( | |
httpClient *http.Client | |
content []string | |
fail []string | |
) | |
const ( | |
//MaxIdleConnections 2 | |
MaxIdleConnections int = 200 | |
//RequestTimeout 2 | |
RequestTimeout int = 30 | |
//WORKERNUM concurrent goroutine | |
WORKERNUM int = 200 | |
//CPUNUM max cpu num | |
CPUNUM int = 4 | |
//JOBS all jobs num | |
JOBS int = 10 * 10000 | |
//PROGRESS OLD | |
PROGRESS int = 0 | |
) | |
func createHTTPClient() *http.Client { | |
client := &http.Client{ | |
Transport: &http.Transport{ | |
MaxIdleConnsPerHost: MaxIdleConnections, | |
}, | |
Timeout: time.Duration(RequestTimeout) * time.Second, | |
} | |
return client | |
} | |
func worker(id int, jobs <-chan int, results chan<- int) { | |
for j := range jobs { | |
fmt.Println("worker", id, "started job", j) | |
testCPU(j) | |
fmt.Println("worker", id, "finished job", j) | |
results <- j * 2 | |
} | |
} | |
func init() { | |
runtime.GOMAXPROCS(CPUNUM) | |
httpClient = createHTTPClient() | |
content = readLine("/tmp/hello.txt", PROGRESS) | |
} | |
func main() { | |
jobs := make(chan int, JOBS) | |
results := make(chan int, JOBS) | |
for w := 1; w <= WORKERNUM; w++ { | |
go worker(w, jobs, results) | |
} | |
for j := 1; j <= JOBS; j++ { | |
jobs <- j | |
} | |
close(jobs) | |
for a := 1; a <= JOBS; a++ { | |
<-results | |
} | |
fmt.Println(fail) | |
} | |
func fetch(targetURL string, postData url.Values) (string, error) { | |
var request *http.Request | |
postDataStr := postData.Encode() | |
postDataBytes := []byte(postDataStr) | |
postBytesReader := bytes.NewReader(postDataBytes) | |
request, _ = http.NewRequest("POST", targetURL, postBytesReader) | |
request.Header.Add("Content-Type", "application/x-www-form-urlencoded") | |
response, fetchError := httpClient.Do(request) | |
if fetchError != nil { | |
return "", fetchError | |
} | |
defer response.Body.Close() | |
body, readError := ioutil.ReadAll(response.Body) | |
if readError != nil { | |
return "", readError | |
} | |
return string(body), nil | |
} | |
func testCPU(lineNumber int) { | |
targetURL := "https://example.com/" | |
if lineNumber >= len(content) { | |
return | |
} | |
question := url.Values{"apikey": {"something"}, "text": {content[lineNumber-1]}} | |
if _, err := fetch(targetURL, question); err != nil { | |
fail = append(fail, content[lineNumber-1]) | |
} | |
} | |
func readLine(file string, progress int) []string { | |
fi, err := os.Open(file) | |
if err != nil { | |
fmt.Printf("Error: %s\n", err) | |
return nil | |
} | |
defer fi.Close() | |
br := bufio.NewReader(fi) | |
var slice []string | |
i := 0 | |
for { | |
a, _, c := br.ReadLine() | |
i++ | |
if c == io.EOF { | |
break | |
} | |
fmt.Println(string(a)) | |
if i <= progress { | |
continue | |
} | |
slice = append(slice, string(a)) | |
} | |
return slice | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment