Solution 4: Building Web Services
Let’s solve the challenge set in the previous lesson.
We'll cover the following...
Solution
Here’s a simple implementation of ab(1) using goroutines and channels in Go.
To run the server side of the ab(1) utility, open a new terminal window and copy and paste the following command into the terminal:
python3 -m http.server 8082
To run the client side, copy and paste the following command into the other terminal window:
go run ab.go -url http://localhost:8082 -c 5 -n 10
Execute the server and client sides in the following playground:
package main
import (
"flag"
"fmt"
"net/http"
"sync"
"io"
"time"
)
func main() {
// Parse command line flags
var (
concurrency int
requests int
url string
)
flag.IntVar(&concurrency, "c", 1, "Number of multiple requests to make at a time")
flag.IntVar(&requests, "n", 1, "Number of requests to perform")
flag.StringVar(&url, "url", "", "URL to test")
flag.Parse()
if url == "" {
fmt.Println("Error: URL is required")
return
}
// Create a channel to track completed requests
done := make(chan bool)
// Create a wait group to synchronize goroutines
var wg sync.WaitGroup
// Start timing the requests
start := time.Now()
// Launch the requested number of goroutines
for i := 0; i < requests; i++ {
wg.Add(1)
go func() {
defer wg.Done()
// Make the HTTP request
resp, err := http.Get(url)
if err != nil {
fmt.Println("Error making request:", err)
return
}
defer resp.Body.Close()
// Read the response body to completion to simulate a real-world scenario
_, _ = io.ReadAll(resp.Body)
// Notify that the request is done
done <- true
}()
// Limit the concurrency
if i%concurrency == 0 {
time.Sleep(time.Millisecond * 10)
}
}
// Calculate and print the results
duration := time.Since(start)
reqsPerSec := float64(requests) / duration.Seconds()
fmt.Println("Concurrency Level: %d\n", concurrency)
fmt.Printf("Time taken for tests: %v seconds\n", duration.Seconds())
fmt.Printf("Complete requests: %d\n", requests)
fmt.Printf("Requests per second: %.2f [#/sec]\n", reqsPerSec)
}
ab.go
Code explanation
Lines 3–9: These are the package imports. The
flagpackage provides a ...
Ask