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`文件。


?

?

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/79151.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/79151.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/79151.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【MySQL數據庫】視圖

1&#xff0c;視圖的基本介紹 視圖是一個虛擬表&#xff0c;其內容由查詢定義。與真實表一樣的是&#xff0c;視圖包含帶有名稱的列和行數據&#xff1b;與真實表不一樣的是&#xff0c;視圖本身并不在數據庫中存儲數據。視圖的數據變化會影響到基表&#xff0c;基表的數據變化…

Linux系統安裝方式+適合初學者的發行版本

Linux系統安裝方式適合初學者發行版—目錄 一、Linux系統的安裝方式1. 物理機直接安裝2. 虛擬機安裝3. 雙系統安裝4. Live USB試用5. 云服務器安裝 二、適合初學者的Linux發行版1. Ubuntu2. Linux Mint3. Zorin OS4. Pop!_OS5. Elementary OS6. Fedora7. Manjaro 三、選擇建議場…

Linux C++ JNI封裝、打包成jar包供Java調用詳細介紹

在前面 Android專欄 中詳細介紹了如何在Android Studio中調用通過jni封裝的c庫。 在Android使用 opencv c代碼&#xff0c;需要準備opencv4android&#xff0c;也就是c的任何代碼&#xff0c;是使用Android NDK編譯的&#xff0c;相當于在windows/mac上使用Android stdido交叉…

4.1 模塊概述

1.Python結構 工程 > 包 > 模塊 Python工程: “Python項目中最大的文件夾(本質就是一個文件夾)” --- 左側的 CODE文件夾 為Python工程 Python包: 本質就是一個文件夾,但是python包中具備具體的標識,如果沒有標識則不能導入 --- 左側的 01.Python基礎 文件夾為python包 P…

AJAX 實例

AJAX 實例 引言 Ajax&#xff08;Asynchronous JavaScript and XML&#xff09;是一種在無需重新加載整個頁面的情況下&#xff0c;與服務器交換數據并更新部分網頁的技術。Ajax通過在后臺與服務器交換數據&#xff0c;實現了頁面的動態更新&#xff0c;從而提高了用戶體驗和…

相機的基礎架構

&#x1f4f7; 相機相關基礎架構學習路徑 一、了解手機相機系統架構 Android Camera HAL&#xff08;如果你是做 Android 平臺&#xff09; 學習 Camera HAL3 架構&#xff08;基于 camera_device_t, camera3_device_ops 接口&#xff09; 熟悉 CameraService → CameraProvid…

MLX Chat - 基于 Streamlit 的 MLX 前端界面

本文翻譯整理自&#xff1a;https://github.com/da-z/mlx-ui 一、關于 MLX Chat 一個基于 Streamlit 的簡單 UI/網頁前端&#xff0c;用于 MLX mlx-lm 項目。 相關鏈接資源 github : https://github.com/da-z/mlx-uiMLX 社區模型庫&#xff1a;https://huggingface.co/mlx-co…

el-table 自定義列、自定義數據

一、對象數組格式自定義拆分為N列 1-1、數據格式&#xff1a; const arrayList ref([{"RACK_NO": "A-1-001"},{"RACK_NO": "A-1-002"},{ "RACK_NO": "A-1-003"},//省略多個{"RACK_NO": "A-1-100…

JVM 如何使用性能分析工具定位代碼中的性能問題?

核心思想&#xff1a; 通過工具觀察程序在特定負載下的運行狀態&#xff0c;識別消耗資源最多的代碼段&#xff08;熱點代碼&#xff09;、異常的內存分配模式或線程阻塞情況&#xff0c;然后針對性的優化代碼。 通用步驟&#xff1a; 確定問題&#xff1a; 首先明確遇到了什…

Python虛假新聞檢測識別

程序示例精選 Python虛假新聞檢測識別 如需安裝運行環境或遠程調試&#xff0c;見文章底部個人QQ名片&#xff0c;由專業技術人員遠程協助&#xff01; 前言 這篇博客針對《Python虛假新聞檢測識別》編寫代碼&#xff0c;代碼整潔&#xff0c;規則&#xff0c;易讀。 學習與應…

網絡原理 - 12(HTTP/HTTPS - 3 - 響應)

目錄 認識“狀態碼”&#xff08;status code&#xff09; 200 OK 404 Not Found 403 Forbidden 405 Method Not Allowed 500 Internal Server Error 504 Gateway Timeout 302 Move temporarily 301 Moved Permanently 418 I am a teaport 狀態碼小結&#xff1a; …

Spring Boot中集成Guava Cache或者Caffeine

一、在Spring Boot(1.x版本)中集成Guava Cache 注意&#xff1a; Spring Boot 2.x用戶&#xff1a;優先使用Caffeine&#xff0c;性能更優且維護活躍。 1. 添加依賴 在pom.xml中添加Guava依賴&#xff1a; <dependency><groupId>com.google.guava</groupId&…

Linux工作臺文件操作命令全流程解析

全文目錄 1 確認當前工作路徑2 導航與目錄管理2.1 關鍵命令2.2 邏輯銜接 3 文件基礎操作3.1 創建 → 備份 → 重命名 → 清理3.2 文件查看和編輯3.3 文件鏈接3.4 文件diff 4 文件權限與所有權管理5 文件打包與歸檔6 參考文獻 寫在前面 shell是一種命令解釋器&#xff0c;它提供…

LeetCode第183題_從不訂購的客戶

LeetCode 第183題&#xff1a;從不訂購的客戶 題目描述 表: Customers ---------------------- | Column Name | Type | ---------------------- | id | int | | name | varchar | ---------------------- id 是該表的主鍵。 該表包含消費者的 id 和…

c語言的常用關鍵字

c語言的常用關鍵字 c語言的關鍵字表示數據類型的關鍵字autocharfloatdoubleintlongshortvoidsignedstruct、enum、unionunsigned 表示分支語句的關鍵字ifelseswitchbreakcasecontinuedefault 表示循環語句的關鍵字whiledoforgoto 用于修飾變量或函數的關鍵字constconst修飾變量…

MCU通用輸入輸出端口(GPIO)設計指南

在嵌入式系統開發中&#xff0c;MCU的GPIO接口是一個基礎但非常實用的功能模塊。GPIO全稱是通用輸入輸出端口&#xff0c;它讓MCU可以靈活地與外部設備進行交互。 GPIO的主要特點包括&#xff1a; 多功能性&#xff1a;每個引腳都可以單獨配置為輸入或輸出 可編程性&#xff…

STM32完整內存地址空間分配詳解

在STM32這類基于ARM Cortex-M的32位微控制器中&#xff0c;整個4GB的地址空間(從0x00000000到0xFFFFFFFF)有著非常系統化的分配方案&#xff0c;每個區域都有其特定的用途。下面我將詳細介紹這些地址區域的分配及其功能&#xff1a; STM32完整內存地址空間分配詳解(0x00000000…

實現水平垂直居中的多種方法

在前端開發中&#xff0c;元素的居中是一個常見但又經常讓人頭疼的問題。本文將全面總結各種CSS居中方法&#xff0c;特別是如何實現一個div的水平垂直居中。 為什么居中這么重要&#xff1f; 居中布局是現代網頁設計中最基礎也最重要的布局方式之一。無論是導航菜單、登錄框…

如何實現服務的自動擴縮容(Auto Scaling)

在云計算和分布式系統的時代,系統的彈性和適應性已成為企業構建高效IT基礎設施的核心需求。自動擴縮容(Auto Scaling)作為一種關鍵技術,旨在根據實時負載變化動態調整計算資源,以確保系統性能穩定,同時優化資源利用效率。簡單來說,自動擴縮容是指系統能夠根據預設規則或…

uniapp+vue3+ts 使用canvas實現安卓端、ios端及微信小程序端二維碼生成及下載

加粗樣式uniapp多端生成帶二維碼海報并保存至相冊的實現 在微信小程序開發中&#xff0c;我們常常會遇到生成帶有二維碼的海報并保存到手機相冊的需求&#xff0c;比如分享活動海報、產品宣傳海報等。今天就來和大家分享一下如何通過代碼實現這一功能。 準備工作 在開始之前&am…