132 lines
2.8 KiB
Go
132 lines
2.8 KiB
Go
|
package main
|
||
|
|
||
|
import (
|
||
|
"context"
|
||
|
"encoding/json"
|
||
|
"fmt"
|
||
|
"log"
|
||
|
"math/rand"
|
||
|
"sync/atomic"
|
||
|
"time"
|
||
|
|
||
|
"github.com/go-redis/redis/v8"
|
||
|
)
|
||
|
|
||
|
var (
|
||
|
ctx = context.Background()
|
||
|
qpsCount int64
|
||
|
totalOps int64
|
||
|
)
|
||
|
|
||
|
// 复杂数据结构示例
|
||
|
type User struct {
|
||
|
ID int `json:"id"`
|
||
|
Name string `json:"name"`
|
||
|
Email string `json:"email"`
|
||
|
CreatedAt time.Time `json:"created_at"`
|
||
|
Tags []string `json:"tags"`
|
||
|
Profile Profile `json:"profile"`
|
||
|
}
|
||
|
|
||
|
type Profile struct {
|
||
|
Age int `json:"age"`
|
||
|
Location string `json:"location"`
|
||
|
Bio string `json:"bio"`
|
||
|
}
|
||
|
|
||
|
func randomUser(id int) User {
|
||
|
return User{
|
||
|
ID: id,
|
||
|
Name: fmt.Sprintf("User%d", id),
|
||
|
Email: fmt.Sprintf("user%d@example.com", id),
|
||
|
CreatedAt: time.Now(),
|
||
|
Tags: []string{"tag1", "tag2", "tag3"},
|
||
|
Profile: Profile{
|
||
|
Age: rand.Intn(50) + 20,
|
||
|
Location: "City" + fmt.Sprintf("%d", rand.Intn(100)),
|
||
|
Bio: "This is a sample bio for user.",
|
||
|
},
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func main() {
|
||
|
rdb := redis.NewClient(&redis.Options{
|
||
|
Addr: "60.205.233.184:6379", // 请根据实际情况修改
|
||
|
Password: "yyd00058",
|
||
|
DB: 0,
|
||
|
})
|
||
|
|
||
|
// 测试连接
|
||
|
_, err := rdb.Ping(ctx).Result()
|
||
|
if err != nil {
|
||
|
log.Fatalf("无法连接 Redis: %v", err)
|
||
|
}
|
||
|
fmt.Println("Redis 连接成功,开始压力测试...")
|
||
|
|
||
|
// 启动 QPS 统计协程
|
||
|
go func() {
|
||
|
ticker := time.NewTicker(time.Second)
|
||
|
defer ticker.Stop()
|
||
|
for range ticker.C {
|
||
|
count := atomic.SwapInt64(&qpsCount, 0)
|
||
|
fmt.Printf("当前 QPS: %d\n", count)
|
||
|
}
|
||
|
}()
|
||
|
|
||
|
concurrency := 100 // 并发数
|
||
|
for i := 0; i < concurrency; i++ {
|
||
|
go func(id int) {
|
||
|
for {
|
||
|
user := randomUser(id)
|
||
|
key := fmt.Sprintf("user:%d:%d", id, time.Now().UnixNano())
|
||
|
|
||
|
// 序列化复杂结构为 JSON
|
||
|
data, err := json.Marshal(user)
|
||
|
if err != nil {
|
||
|
log.Printf("序列化失败: %v", err)
|
||
|
continue
|
||
|
}
|
||
|
|
||
|
// 写入
|
||
|
err = rdb.Set(ctx, key, data, 0).Err()
|
||
|
if err != nil {
|
||
|
log.Printf("写入失败: %v", err)
|
||
|
continue
|
||
|
}
|
||
|
atomic.AddInt64(&qpsCount, 1)
|
||
|
atomic.AddInt64(&totalOps, 1)
|
||
|
|
||
|
// 读取
|
||
|
val, err := rdb.Get(ctx, key).Result()
|
||
|
if err != nil {
|
||
|
log.Printf("读取失败: %v", err)
|
||
|
continue
|
||
|
}
|
||
|
|
||
|
// 反序列化
|
||
|
var u User
|
||
|
err = json.Unmarshal([]byte(val), &u)
|
||
|
if err != nil {
|
||
|
log.Printf("反序列化失败: %v", err)
|
||
|
continue
|
||
|
}
|
||
|
atomic.AddInt64(&qpsCount, 1)
|
||
|
atomic.AddInt64(&totalOps, 1)
|
||
|
|
||
|
// 删除
|
||
|
err = rdb.Del(ctx, key).Err()
|
||
|
if err != nil {
|
||
|
log.Printf("删除失败: %v", err)
|
||
|
continue
|
||
|
}
|
||
|
atomic.AddInt64(&qpsCount, 1)
|
||
|
atomic.AddInt64(&totalOps, 1)
|
||
|
}
|
||
|
}(i)
|
||
|
}
|
||
|
|
||
|
runDuration := 30 * time.Second
|
||
|
time.Sleep(runDuration)
|
||
|
fmt.Printf("压力测试结束,总操作数: %d\n", atomic.LoadInt64(&totalOps))
|
||
|
}
|