C++ Webserver从零开始:代码书写(十六)——配置文件,服务器,启动!

前言

现在是2024年2月28日的晚上20点36分,我完成了博客的所有内容。现在我整个人有一种如释重负的感觉,今天用webbench测试的时候还闹了个笑话,我在使用测试命令时,url多写了一个http://没注意,导致webbench访问服务器一直被拒,我一度以为是我代码有问题。还跑到群里,社区里求助,也给我一个同学发了过去。网上也搜索了很久,甚至我还跑去看webbench的源码。但是显而易见地一无所获。就在我心灰易冷地时候,我发现了我给我同学发的出错照片里面的webbecn调用返回信息有两个http://,但哪怕是这样我也没反应过来是我的url写错了,我还问他有没有什么头绪,是不是webbench的url解析代码有问题?后来等我发现是我打错了的时候,再看聊天记录发现他以及说了答案“重复了”,搞得我哭笑不得。好在发现了问题所在,webbench正常使用,让本专栏得以完结(差点烂尾)

配置文件和main文件

配置文件和main文件就不讲了,直接贴代码,感兴趣的同学自己看看

#ifndef CONFIG_H
#define CONFIG_H#include "webserver.h"using namespace std;class Config
{
public:Config();~Config(){};void parse_arg(int argc, char*argv[]);//端口号int PORT;//日志写入方式int LOGWrite;//触发组合模式int TRIGMode;//listenfd触发模式int LISTENTrigmode;//connfd触发模式int CONNTrigmode;//优雅关闭链接int OPT_LINGER;//数据库连接池数量int sql_num;//线程池内的线程数量int thread_num;//是否关闭日志int close_log;//并发模型选择int actor_model;
};#endif
#include "config.h"Config::Config(){//端口号,默认9006PORT = 9006;//PORT = 9000;//日志写入方式,默认同步LOGWrite = 0;//触发组合模式,默认listenfd LT + connfd LTTRIGMode = 0;//listenfd触发模式,默认LTLISTENTrigmode = 0;//connfd触发模式,默认LTCONNTrigmode = 0;//优雅关闭链接,默认不使用OPT_LINGER = 0;//数据库连接池数量,默认8sql_num = 8;//线程池内的线程数量,默认8thread_num = 8;//关闭日志,默认不关闭close_log = 0;//并发模型,默认是proactoractor_model = 0;
}void Config::parse_arg(int argc, char*argv[]){int opt;const char *str = "p:l:m:o:s:t:c:a:";while ((opt = getopt(argc, argv, str)) != -1){switch (opt){case 'p':{PORT = atoi(optarg);break;}case 'l':{LOGWrite = atoi(optarg);break;}case 'm':{TRIGMode = atoi(optarg);break;}case 'o':{OPT_LINGER = atoi(optarg);break;}case 's':{sql_num = atoi(optarg);break;}case 't':{thread_num = atoi(optarg);break;}case 'c':{close_log = atoi(optarg);break;}case 'a':{actor_model = atoi(optarg);break;}default:break;}}
}
#include "config.h"int main(int argc, char *argv[])
{//需要修改的数据库信息,登录名,密码,库名string user = "root";string passwd = "123";string databasename = "testDB";//命令行解析Config config;config.parse_arg(argc, argv);WebServer server;//初始化server.init(config.PORT, user, passwd, databasename, config.LOGWrite, config.OPT_LINGER, config.TRIGMode,  config.sql_num,  config.thread_num, config.close_log, config.actor_model);//日志server.log_write();//数据库server.sql_pool();//线程池server.thread_pool();//触发模式server.trig_mode();//监听server.eventListen();//运行server.eventLoop();return 0;
}

makefile

CXX ?= g++DEBUG ?= 0
ifeq ($(DEBUG), 1)CXXFLAGS += -g
elseCXXFLAGS += -O2endifserver: main.cpp  ./timer/lst_timer.cpp ./http/http_conn.cpp ./log/log.cpp ./CGImysql/sql_connection_pool.cpp  webserver.cpp config.cpp$(CXX) -o server  $^ $(CXXFLAGS) -lpthread -lmysqlclientclean:rm  -r server

运行

创建数据库

将上述文件全部保存到根目录后,运行make命令,就可以得到server文件了

快速运行:./server

自定义运行:./server [-p port] [-l LOGWrite] [-m TRIGMode] [-o OPT_LINGER] [-s sql_num] [-t thread_num] [-c close_log] [-a actor_model]

  • -p,自定义端口号
    • 默认9006
  • -l,选择日志写入方式,默认同步写入
    • 0,同步写入
    • 1,异步写入
  • -m,listenfd和connfd的模式组合,默认使用LT + LT
    • 0,表示使用LT + LT
    • 1,表示使用LT + ET
    • 2,表示使用ET + LT
    • 3,表示使用ET + ET
  • -o,优雅关闭连接,默认不使用
    • 0,不使用
    • 1,使用
  • -s,数据库连接数量
    • 默认为8
  • -t,线程数量
    • 默认为8
  • -c,关闭日志,默认打开
    • 0,打开日志
    • 1,关闭日志
  • -a,选择反应堆模型,默认Proactor
    • 0,Proactor模型
    • 1,Reactor模型

压力测试

webbench原理

webbench是一个开源的用来测试服务器性能的小软件,其基本原理是创建多个子进程进行服务器访问,子进程将自己得到的数据通过管道发给主进程,主进程将结果统计打印输出在屏幕上

测试结果

压力测试使用的webbench-1.5版本,因为我的云服务器是2核2G,webbench本身也会创建非常多进程,所以并发量只能达到4800,换一个硬件环境应该能达到更高的数据。

可以看到,在跑webbench的时候,我的服务器的内存最高差不多跑到了1800多,基本上是给内存全部跑慢了,对于一个2G的内存来说,这已经是接近极限的数字。而系统盘IO达到了差不多40000KB/s,从这个角度上来看,我的服务器应该没有什么大的性能瓶颈了。

结束语

这个专栏到这里就结束了,完成了所有的东西我还是非常开心的,后面找些时间把github上的README整理一下,我的webserver之旅就彻底完结。


润了~~o(* ̄▽ ̄*)ブ

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://xiahunao.cn/news/2815477.html

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

基于Python3的数据结构与算法 - 05 堆排序

目录 一、堆排序之树的基础知识 1. 树的定义 2. 树的一些概念 二、堆排序二叉树的基本知识 1. 二叉树的定义 2. 二叉树的存储方式(表达方式) 2.1 顺序存储方式 三、堆 1. 堆的定义 2. 堆的向下调整性质 四、堆排序的过程 1. 建造堆 五、时…

SpringCloud认识微服务

文章目录 1.1.单体架构1.2.分布式架构1.3.微服务1.4.SpringCloud1.5.总结 随着互联网行业的发展,对服务的要求也越来越高,服务架构也从单体架构逐渐演变为现在流行的微服务架构。这些架构之间有怎样的差别呢? 微服务架构是一种架构模式&…

软考51-上午题-【数据库】-索引

一、索引的定义 在数据库中,索引使得数据库程序无需对整个表进行扫描,就可以在其中找到所需数据。数据库中的索引是某个表中一列或者若干列,值的集合和相应的指向表中物理标识这些值的数据页逻辑指针清单。 二、索引的创建和删除 2-1、索引…

ThreeJS 几何体顶点position、法向量normal及uv坐标

文章目录 几何体的顶点position、法向量normal及uv坐标UV映射UV坐标系UV坐标与顶点坐标设置UV坐标案例1:使用PlaneGeometry创建平面缓存几何体案例2:使用BufferGeometry创建平面缓存几何体 法向量 - 顶点法向量光照计算案例1:不设置顶点法向量…

Linux shell:补充命令的使用

目录 一.导读 二.正文 三.结语 一.导读 上一篇介绍了脚本的简单概念以及使用,现在补充一些命令。 二.正文 目前处于全局目录,通过mkdir创建名我为day01的文件。 通过cd命令day01 切换至day01文件当中。 使用vim文本编辑器文件名(firstdir&…

【algorithm】算法基础课---排序算法(附笔记 | 建议收藏)

🚀write in front🚀 📝个人主页:认真写博客的夏目浅石. 🎁欢迎各位→点赞👍 收藏⭐️ 留言📝 📣系列专栏:AcWing算法学习笔记 💬总结:希望你看完…

day 45 ● 70. 爬楼梯 (进阶)● 322. 零钱兑换 ● 279.完全平方数

#include<bits/stdc.h> using namespace std; int main(){int n,m;cin>>n>>m;vector<int> dp(33,0);dp[0]1;for(int i0;i<n;i){for(int j1;j<m;j){if(i>j)dp[i]dp[i-j];}}// return dp[n];cout<<dp[n]<<endl;} 当然注意 力扣是 …

2.23作业

1.自己实现单向循环链表的功能 //loop_list.c#include"loop_list.h" //创建单向循环链表 loop_p create_head() {loop_p H(loop_p)malloc(sizeof(loop_list));if(HNULL){printf("空间申请失败\n");return NULL;}H->len0;H->nextH;return H; }//创建…

C语言中如何进行内存管理

主页&#xff1a;17_Kevin-CSDN博客 收录专栏&#xff1a;《C语言》 C语言是一种强大而灵活的编程语言&#xff0c;但与其他高级语言不同&#xff0c;它要求程序员自己负责内存的管理。正确的内存管理对于程序的性能和稳定性至关重要。 一、引言 C 语言是一门广泛使用的编程语…

学习Android的第十八天

目录 Android 可复用 BaseAdapter 为什么使用BaseAdapter&#xff1f; 如何使用BaseAdapter&#xff1f; Android GridView 网格视图 GridView 属性 示例 Android Spinner 下拉选项框 Spinner Spinner 属性 示例 Android AutoCompleteTextView 自动完成文本框 Auto…

饲料加工设备让饲料厂和养殖场生产轻松高效

亲爱的饲料厂和养殖场朋友们&#xff0c;你们是不是正在寻找一款方便高效的饲料加工设备呢&#xff1f;那么我们的产品就是你们选择&#xff01; 郑州永兴专为饲料生产而设计的饲料加工设备&#xff0c;无论是养殖场还是饲料厂&#xff0c;都离不开它的帮助。我们提供大中小型…

51单片机-(定时/计数器)

51单片机-&#xff08;定时/计数器&#xff09; 了解CPU时序、特殊功能寄存器和定时/计数器工作原理&#xff0c;以定时器0实现每次间隔一秒亮灯一秒的实验为例理解定时/计数器的编程实现。 1.CPU时序 1.1.四个周期 振荡周期&#xff1a;为单片机提供定时信号的振荡源的周期…

卡尔曼滤波器的定义,实例和代码实现

卡尔曼滤波器(Kalman filter)是一种高效的递归滤波器, 能够从一系列包含噪音的测量值中估计动态系统的状态. 因为不需要存储历史状态, 没有复杂计算, 非常适合在资源有限的嵌入式系统中使用. 常用于飞行器的导引, 导航及控制, 机械和金融中的时间序列分析, 轨迹最佳化等. 卡尔曼…

LeetCode59. 螺旋矩阵 II(C++)

LeetCode59. 螺旋矩阵 II 题目链接代码 题目链接 https://leetcode.cn/problems/spiral-matrix-ii/ 代码 class Solution { public:vector<vector<int>> generateMatrix(int n) {vector<vector<int>> res(n, vector<int>(n, 0));int startx …

Linux第67步_linux字符设备驱动_注册和注销

1、字符设备注册与注销的函数原型” /*字符设备注册的函数原型*/ static inline int register_chrdev(unsigned int major,\ const char *name, \ const struct file_operations *fops) /* major:主设备号&#xff0c;Limnux下每个设备都有一个设备号&#xff0c;设备号分…

点云检测网络PointPillar

1. 提出PointPillar的目的 在此之前对于不规则的稀疏的点云的做法普遍分为两派: 一是把点云数据量化到一个个Voxel里&#xff0c;常见的有VoxelNet和SECOND , 但是这种做法比较普遍的问题是由于voxel大部分是空集所以会浪费算力(SECOND利用稀疏卷积解决了它) &#xff0c;但是…

MNIST数据集下载(自动下载)

&#x1f4da;**MNIST数据集下载(自动下载)**&#x1f4da; &#x1f308; 个人主页&#xff1a;高斯小哥 &#x1f525; 高质量专栏&#xff1a;Matplotlib之旅&#xff1a;零基础精通数据可视化、Python基础【高质量合集】、PyTorch零基础入门教程 &#x1f448; 希望得到您的…

本地数据库Room——study_1

目录 1.概念 2.组成 3.导入依赖 4.具体实现 4.1 数据表的设置 4.2 方法接口 4.3 数据库类 -》 基石&#xff0c;使用模板 4.4 实现真正的实例Room库 1.概念 Room 持久性库在 SQLite 上提供了一个抽象层&#xff0c;以便在充分利用 SQLite 的强大功能的同时&#xff0c…

Qt程序设计-钟表自定义控件实例

本文讲解Qt钟表自定义控件实例。 效果如下: 创建钟表类 #ifndef TIMEPIECE_H #define TIMEPIECE_H#include <QWidget> #include <QPropertyAnimation> #include <QDebug> #include <QPainter> #include <QtMath>#include <QTimer>#incl…

基于InternLM和LangChain搭建自己的知识库

背景 LLM存在一定的局限性&#xff0c;如&#xff1a; 知识时效性受限&#xff1a;如何让LLM能够获取最新的知识专业能力有限&#xff1a;如何打造垂直领域的大模型定制化成本高&#xff1a;如何打造个人专属的LLM应用 正文 为了突破LLM的局限性&#xff0c;目前有两种范式…