<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??一站式輕松地調用各大LLM模型接口,支持GPT4、智譜、豆包、星火、月之暗面及文生圖、文生視頻 廣告
                ## 14) Reactor框架QPS性能測試 ? 接下來我們寫一個測試用例來測一下我們的Reactor框架的qps。 > qps: (Query Per Second)每秒查詢率QPS是對一個特定的查詢服務器在規定時間內所處理流量多少的衡量標準。 ### 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); } 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; } ``` 接下來我們的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`文件。 ### 14.2 并發測試結果 ? 啟動服務端,再啟動客戶端,(注意問了方便看結果,將之前reactor的一些stdout的調試日志都關閉) 看客戶端運行結果 ```bash $ ./client 1 msg_router init... do_connect EINPROGRESS add msg cb msgid = 1 connect 127.0.0.1:7777 succ! ---> qps = 6875 <---- ---> qps = 8890 <---- ---> qps = 8354 <---- ---> qps = 9078 <---- ---> qps = 8933 <---- ---> qps = 9043 <---- ---> qps = 8743 <---- ---> qps = 9048 <---- ---> qps = 8987 <---- ---> qps = 8742 <---- ---> qps = 8720 <---- ---> qps = 8795 <---- ---> qps = 8889 <---- ---> qps = 9034 <---- ---> qps = 8669 <---- ---> qps = 9001 <---- ---> qps = 8810 <---- ---> qps = 8850 <---- ---> qps = 8802 <---- ---> qps = 9072 <---- ---> qps = 8853 <---- ---> qps = 8804 <---- ---> qps = 8574 <---- ---> qps = 8645 <---- ---> qps = 8085 <---- ---> qps = 8720 <---- ... ``` ? 這里我們客戶端是開啟一個線程進行測試,平均每秒服務端會響應8700次左右。 ? 這里我簡單用兩個主機,分別測試了一些數據 **主機1:** > CPU個數:2個 , 內存: 2GB , 系統:Ubuntu18.04虛擬機 | 線程數 | QPS | | ------ | ------- | | 1 | 0.85w/s | | 2 | 1.96w/s | | 10 | 4.12w/s | | 100 | 4.23w/s | | 500 | 3.65w/s | **主機2:** > CPU個數: 24個 , 內存:128GB, 系統: 云主機 | 線程數 | QPS | | ------ | -------- | | 1 | 10.86w/s | | 3 | 31.06w/s | | 5 | 48.12w/s | | 8 | 59.79w/s | ? 現在我們的Lars-Reactor模塊基本已經開完完成了,后續可能會再添加一些模塊,為了其他模塊方便使用Lars-Reactor的一些接口,我們可以對外提供一個公共的頭文件,方便一次性導入 > lars_reactor/include/lars_reactor.h ```c #pragma once #include "io_buf.h" #include "buf_pool.h" #include "reactor_buf.h" #include "net_connection.h" #include "tcp_conn.h" #include "tcp_server.h" #include "tcp_client.h" #include "udp_server.h" #include "udp_client.h" #include "message.h" #include "task_msg.h" #include "event_loop.h" #include "thread_pool.h" #include "thread_queue.h" #include "config_file.h" ``` --- ### 關于作者: 作者:`Aceld(劉丹冰)` mail: [danbing.at@gmail.com](mailto:danbing.at@gmail.com) github: [https://github.com/aceld](https://github.com/aceld) 原創書籍: [http://www.hmoore.net/@aceld](http://www.hmoore.net/@aceld) ![](https://img.kancloud.cn/b0/d1/b0d11a21ba62e96aef1c11d5bfff2cf8_227x227.jpg) >**原創聲明:未經作者允許請勿轉載, 如果轉載請注明出處**
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看