golang并发测试http demo

package main

import (
	"bytes"
	"fmt"
	"math/rand"
	"net/http"
	"sync"
	"time"
)

const (
	url           = "http://127.0.0.1:8080"  // 请求的 URL
	ratePerSecond = 10                       // 每秒启动的并发数量
	duration      = 60                       // 持续时间,单位为秒
)

var (
	successCount int
	failCount    int
	totalLatency time.Duration
	mu           sync.Mutex
)

// Demo 测试数据生成
func generateTestData() string {
	// 随机用户ID
	userID := rand.Intn(10000) + 1

	// 随机行为事件
	events := []string{"login", "logout", "purchase", "view", "click", "like", "share", "comment"}
	event := events[rand.Intn(len(events))]

	// 随机设备类型
	devices := []string{"iPhone", "Android", "Windows PC", "MacBook", "iPad", "Smartwatch"}
	device := devices[rand.Intn(len(devices))]

	// 随机地理位置 (城市 + 国家)
	cities := []string{"New York", "London", "Tokyo", "Berlin", "Sydney", "Moscow", "Shanghai"}
	country := []string{"USA", "UK", "Japan", "Germany", "Australia", "Russia", "China"}
	location := fmt.Sprintf("%s, %s", cities[rand.Intn(len(cities))], country[rand.Intn(len(country))])

	// 随机时间戳
	timestamp := time.Now().Add(time.Duration(rand.Intn(100000)) * time.Second).Format(time.RFC3339)

	// 生成最终测试数据字符串
	testData := fmt.Sprintf(`{
		"user_id": %d,
		"event": "%s",
		"device": "%s",
		"location": "%s",
		"timestamp": "%s"
	}`, userID, event, device, location, timestamp)

	return testData
}

// 发送 POST 请求并记录统计数据
func sendPostRequest(client *http.Client, wg *sync.WaitGroup) {
	defer wg.Done()

	// 动态生成测试数据
	data := generateTestData()

	req, err := http.NewRequest("POST", url, bytes.NewBuffer([]byte(data)))
	if err != nil {
		fmt.Printf("Error creating request: %v\n", err)
		return
	}
	req.Header.Set("Content-Type", "application/x-www-form-urlencoded")

	start := time.Now()
	resp, err := client.Do(req)
	latency := time.Since(start)

	mu.Lock()
	defer mu.Unlock()

	if err != nil {
		failCount++
		fmt.Printf("Error sending request: %v\n", err)
		return
	}
	defer resp.Body.Close()

	if resp.StatusCode == http.StatusOK {
		successCount++
		totalLatency += latency
		fmt.Println("Request successful")
	} else {
		failCount++
		fmt.Printf("Request failed with status: %d\n", resp.StatusCode)
	}
}

func main() {
	var wg sync.WaitGroup

	client := &http.Client{
		Timeout: 10 * time.Second,
	}

	ticker := time.NewTicker(time.Second / time.Duration(ratePerSecond))
	defer ticker.Stop()

	endTime := time.Now().Add(time.Duration(duration) * time.Second)

	fmt.Println("Starting load test...")

	// 处理并发请求
	for time.Now().Before(endTime) {
		<-ticker.C
		wg.Add(1)
		go sendPostRequest(client, &wg)
	}

	// 等待所有请求完成
	wg.Wait()

	// 计算平均响应时间
	averageLatency := time.Duration(0)
	if successCount > 0 {
		averageLatency = totalLatency / time.Duration(successCount)
	}

	fmt.Printf("\n--- Test Summary ---\n")
	fmt.Printf("Total requests: %d\n", successCount+failCount)
	fmt.Printf("Successful requests: %d\n", successCount)
	fmt.Printf("Failed requests: %d\n", failCount)
	fmt.Printf("Average latency: %v\n", averageLatency)
	fmt.Println("Test completed.")
}

posted @ 2024-12-24 23:15  dujingning  阅读(45)  评论(0)    收藏  举报