10-服务的压力测试

128 阅读3分钟

服务的压力测试

服务上线之前,我们需要对服务进行压力测试,以确保服务能够在高并发的情况下正常运行。
本文将介绍如何使用k6对服务进行压力测试。

k6简介

Grafana k6是一个高性能的负载测试工具,使用Go语言编写,内嵌JavaScript运行时,
可以轻松进行测试脚本编写。您可以使用k6来模拟流量,作为混沌实验的一部分,从k6测试中触发它们,
或者在Kubernetes中使用xk6-disruptor注入不同类型的故障。此外,k6还可以自动化和计划频繁触发带有小负载的测试, 以持续验证生产环境的性能和可用性。

1.前期准备

  • 单独部署一个压测服务器,部署需要压测的服务
  • 单独一台/多台发压机器,安装k6
  • 安装graphviz,用于显示pprof的性能数据
  • 你需要在你的golang业务服务中添加pprof来收集性能数据
import (
"net/http"
_ "net/http/pprof"
)

func main() {
go func () {
log.Println(http.ListenAndServe("localhost:6060", nil))
}()
// your application code
}

2. 编写测试脚本

import {Client, StatusOK} from 'k6/net/grpc';
import {check, sleep} from 'k6';


const client = new Client();
// Load the protobuf files, which are assumed to be in the same directory as this script
client.load(['../../api/auth'], 'auth.proto');

const GRPC_ADDR = __ENV.SERVER_HOST || '127.0.0.1:8081';
export default function () {
    client.connect(GRPC_ADDR, {
        plaintext: true
    });
    const data = {
        app_id: 'test',
        id: 'test',
        auth: 1,
        data: 'test'
    };

    let response = client.invoke('auth.pb.AuthService/Authenticate', data);
    check(response, {
        'status is OK': (r) => r && r.status === StatusOK,
    });
    response = client.invoke('auth.pb.AuthService/RefreshToken', {"refresh_token": response["message"]["refreshToken"]});
    check(response, {
        'status is OK': (r) => r && r.status === StatusOK,
    });

    response = client.invoke('auth.pb.AuthService/ValidateToken', {"access_token": response["message"]["accessToken"]});
    check(response, {
        'status is OK': (r) => r && r.status === StatusOK,
    });
    response = client.invoke('auth.pb.AuthService/Login', {
        "app_id": "test",
        "open_id": "test",
        "machine_code": "test",
        "data": "test"
    });
    check(response, {
        'status is OK': (r) => r && r.status === StatusOK,
    });

    response = client.invoke('auth.pb.AuthService/AddBlocked', {
        "uid": "test",
        "is_block": true,
        "duration": 100
    });
    check(response, {
        'status is OK': (r) => r && r.status === StatusOK,
    });
    client.close();
    sleep(1);
}

3. 运行测试

 # 运行测试:1000个用户持续30min
k6 run --vus 1000 --duration 30m test.js

4. 采样性能数据

4.1 使用pprof定位性能问题

 # 查看CPU性能数据,默认采样时间为30s
 go tool pprof http://<your app host>:6060/debug/pprof/profile
# 查看内存性能数据
go tool pprof http://<your app host>:6060/debug/pprof/heap
# 具体使用方法可以参考pprof的文档,你可以根据采样的数据进行优化

4.2 使用top命令查看系统性能

top命令主要可以观察Load averageCPU内存Swap等系统性能数据,

  • Load average三个值分别代表1分钟,5分钟,15分钟的平均负载,除以Cpu核数,可以得到负载率,一般负载率大于1就需要考虑优化了。
  • CPU主要关注ussywaidstus表示用户态使用率,sy表示内核态使用率,wa表示IO等待时间,id 表示空闲时间,st表示虚拟机的时间。
  • 内存主要关注totalusedfreesharedbuff/cacheavailabletotal表示总内存,used表示已使用内存,free 表示空闲内存,shared表示共享内存,buff/cache表示缓存内存,available表示可用内存。
  • Swap主要关注totalusedfreecachedtotal表示总swap,used表示已使用swap,free表示空闲swap,cached 表示缓存swap,注意swap使用过多会导致性能下降。
# 查看系统性能
top