C++负载均衡远程调用学习之QPS性能测试

目录

1.昨日回顾

2.QPS_TEST_PROTOBUF协议的集成

3.QPS_TEST_SERVER端实现

4.QPS_TEST_QPS简单介绍

5.QPS_TEST_QPS客户端工具编写和性能测试


1.昨日回顾

2.QPS_TEST_PROTOBUF协议的集成

14) Reactor框架QPS性能测试

​ 接下来我们写一个测试用例来测一下我们的Reactor框架的qps。

> qps: (Query Per Second)每秒查询率QPS是对一个特定的查询服务器在规定时间内所处理流量多少的衡量标准。

3.QPS_TEST_SERVER端实现

14.1 测试用例代码编写

​ 我们首先定义一个proto文件,用来承载客户端和服务端通信媒介的。

> example/qps_test/echoMessage.proto

```protobuf

syntax = "proto3";

package qps_test;

message EchoMessage

{

string content = 1;

int32 id = 2;

};

```

​ 然后生成对应的cc文件和h文件

```bash

protoc --cpp_out=. ./*.proto

```

​ 接下来我们来实现服务端,服务端主要就是简单的回显,客户端发什么数据,回显就可以了。

> example/qps_test/server.cpp

```c

#include <string>

#include <string.h>

#include "config_file.h"

#include "tcp_server.h"

#include "echoMessage.pb.h"

//回显业务的回调函数

void callback_busi(const char *data, uint32_t len, int msgid, net_connection *conn, void *user_data)

{

qps_test::EchoMessage request, response;

//解包,确保data[0-len]是一个完整包

request.ParseFromArray(data, len);

//设置新pb包

response.set_id(request.id());

response.set_content(request.content());

//序列化

std::string responseString;

response.SerializeToString(&responseString);

conn->send_message(responseString.c_str(), responseString.size(), msgid);

}

int main()

{

event_loop loop;

//加载配置文件

config_file::setPath("./serv.conf");

std::string ip = config_file::instance()->GetString("reactor", "ip", "0.0.0.0");

short port = config_file::instance()->GetNumber("reactor", "port", 8888);

printf("ip = %s, port = %d\n", ip.c_str(), port);

tcp_server server(&loop, ip.c_str(), port);

//注册消息业务路由

server.add_msg_router(1, callback_busi);

loop.event_process();

return 0;

}

```

​ 接下来是客户端,客户端我们创建一个Qps结构体,来记录每秒,服务端成功回显数据的次数,来做qps统计,客户端我们可以指定开多少个线程去压测服务端。

> example/qps_test/client.cpp

```c

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include <time.h>

#include <string>

#include "tcp_client.h"

#include "echoMessage.pb.h"

struct Qps

{

Qps() {

last_time = time(NULL);

succ_cnt = 0;

}

long last_time;//最后一次发包时间 ms为单位

int succ_cnt; //成功收到服务器回显的次数

};

//客户端业务

void busi(const char *data, uint32_t len, int msgid, net_connection *conn, void *user_data)

{

Qps *qps = (Qps*)user_data; //用户参数

qps_test::EchoMessage request, response;

//解析服务端传来的pb数据

if (response.ParseFromArray(data, len) == false) {

printf("server call back data error\n");

return;

}

//判断数据内容是否回显一致

if (response.content() == "Hello Lars!!!") {

//服务器请求响应成功一次

qps->succ_cnt ++;

}

long current_time = time(NULL);

if (current_time - qps->last_time >= 1) {

//如果当前时间比最后记录时间大于1秒,那么我们进行记录

printf("---> qps = %d <----\n", qps->succ_cnt);

qps->last_time = current_time;//记录最后时间

qps->succ_cnt = 0;//清空成功次数

}

//给服务端发送新的请求

request.set_id(response.id() + 1);

request.set_content(response.content());

std::string requestString;

request.SerializeToString(&requestString);

conn->send_message(requestString.c_str(), requestString.size(), msgid);

}

//创建链接成功之后

void connection_start(net_connection *client, void *args)

{

qps_test::EchoMessage request;

request.set_id(1);

request.set_content("Hello Lars!!!");

std::string requestString;

request.SerializeToString(&requestString);

int msgid = 1;//与server端的消息路由一致

client->send_message(requestString.c_str(), requestString.size(), msgid);

}

4.QPS_TEST_QPS简单介绍

void *thread_main(void *args)

{

//给服务端发包

event_loop loop;

tcp_client client(&loop, "127.0.0.1", 7777, "qps client");

Qps qps;

//设置回调

client.add_msg_router(1, busi, (void*)&qps);

//设置链接创建成功之后Hook

client.set_conn_start(connection_start);

loop.event_process();

return NULL;

}

int main(int argc, char **argv)

{

if (argc == 1) {

printf("Usage: ./client [threadNum]\n");

return 1;

}

//创建N个线程

int thread_num = atoi(argv[1]);

pthread_t *tids;

tids = new pthread_t[thread_num];

for (int i = 0; i < thread_num; i++) {

pthread_create(&tids[i], NULL, thread_main, NULL);

}

for (int i = 0; i < thread_num; i++) {

pthread_join(tids[i], NULL);

}

return 0;

}

```

5.QPS_TEST_QPS客户端工具编写和性能测试

接下来我们的Makefile

```makefile

CXX=g++

CFLAGS=-g -O2 -Wall -fPIC -Wno-deprecated

INC=-I../../include

LIB=-L../../lib -llreactor -lpthread -lprotobuf

OBJS = (addsuffix .o, (basename $(wildcard *.cc)))

all:

(CXX) -o server (CFLAGS) server.cpp echoMessage.pb.cc (INC) (LIB)

(CXX) -o client (CFLAGS) client.cpp echoMessage.pb.cc (INC) (LIB)

clean:

-rm -f *.o server client

```

​ 记住编译加上`-lprotobuf` 编译的文件加上`echoMessage.pb.cc`文件。

相关推荐
YJlio1 小时前
Active Directory 工具学习笔记(10.8):AdInsight——保存与导出(证据留存、共享与二次分析)
数据库·笔记·学习
程序员zgh3 小时前
Linux系统常用命令集合
linux·运维·服务器·c语言·开发语言·c++
獭.獭.3 小时前
C++ -- STL【unordered_set与unordered_map的实现】
开发语言·c++·unordered_map·unordered_set
qq_433554544 小时前
C++数位DP
c++·算法·图论
噗噗夹的TA之旅4 小时前
Unity Shader 学习20:URP LitForwardPass PBR 解析
学习·unity·游戏引擎·图形渲染·技术美术
似水এ᭄往昔4 小时前
【C++】--AVL树的认识和实现
开发语言·数据结构·c++·算法·stl
程序员zgh4 小时前
常用通信协议介绍(CAN、RS232、RS485、IIC、SPI、TCP/IP)
c语言·网络·c++
2401_834517074 小时前
AD学习笔记-36 gerber文件输出
笔记·学习
气π4 小时前
【JavaWeb】——(若依 + AI)-基础学习笔记
java·spring boot·笔记·学习·java-ee·mybatis·ruoyi
深蓝海拓4 小时前
PySide6从0开始学习的笔记(三) 布局管理器与尺寸策略
笔记·python·qt·学习·pyqt