重写Sylar基于协程的服务器(2、配置模块的设计)

重写Sylar基于协程的服务器(2、配置模块的设计)

重写Sylar基于协程的服务器系列:

重写Sylar基于协程的服务器(0、搭建开发环境以及项目框架 || 下载编译简化版Sylar)

重写Sylar基于协程的服务器(1、日志模块的架构)

重写Sylar基于协程的服务器(2、配置模块的设计)

重写Sylar基于协程的服务器(3、协程模块的设计)

配置模块存在的必要性

一个服务器软件可能会运行在不同的机器上,机器的配置、网络环境、实际需求等都是千变万化,在服务器软件中,为了适应这些变化,可能就是调整几个变量的值。开发人员不可能每次外在因素的改变就重新编译软件再发布,这明显是不现实的。于是配置模块就在这时发挥它的关键作用,利用好配置模块就不需要再次编译,让配置模块自己加载参数,动态调节就行了。

配置模块的设计与实现

配置模块序列化和反序列化效果(支持std::各种容器

YAML 的基本语法如下:

  1. 大小写敏感。

  2. 利用缩进表示层级关系,缩进只能使用空格,空格的数量不重要。

  3. '#'表示注释。

  4. 数据类型:对象,键值对的集合,即K-V对。数组,一组按次序排列的值。纯量(scalars),单个的、不可再分的值,包括字符串、布尔值、整数、浮点数、Null、时间、日期。

测试配置文件定义了一个key为space,value也是一个map类型的节点,该map有两个kv对,它们的key分别是vec、num,value分别是数组类型和纯量类型。如下

test_config.yml:

space:vec: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]num: 7

测试代码:

void test_logConfig(){// 创建配置变量lunar::ConfigVar<std::vector<int>>::ptr vec = lunar::ConfigVarMgr::GetInstance()->lookUp("space.vec", std::vector<int>(), "vec test");lunar::ConfigVar<int>::ptr num = lunar::ConfigVarMgr::GetInstance()->lookUp("space.num", int(), "num test");// 解析配置文件lunar::ConfigVarMgr::GetInstance()->loadFromFile("test_config.yml");// 反序列化配置 && 输出到控制台LUNAR_LOG_INFO(g_logger) << vec->toString();LUNAR_LOG_INFO(g_logger) << num->toString();
}

解析结果:

[root@localhost build]# ../bin/test_config 
2024-01-31 21:02:02     2433    unknow  4294967295      [INFO]  [system]        /root/workspace/lunar/tests/test_config.cc:53       - 0
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
2024-01-31 21:02:02     2433    unknow  4294967295      [INFO]  [system]        /root/workspace/lunar/tests/test_config.cc:54       7

配置模块类的设计

在Yaml提供的数据类型的基础上,我们的配置文件还需要支持对象类型,所以我们需要通过模板,以泛型编程的方式实现对复杂数据类型的解析,除此之外,我们还要,对各个配置变量进行集中管理,综上所述,类的设计如下:

  1. LexicalCast,对象转换类模板(仿函数),使用C++的模板二次封装Boost库的boost::lexical_cast模板函数,实现基础类型和字符串类型间相互转换。然后对LexicalCast类模板进行偏特化,让其支持C++标准库的容器的序列化与反序列化。所以,我们实现的LexicalCast类模板默认支持基础类型和C++容器,想要支持自定义类型的序列化和反序列化,用户需要自己实现全特化LexicalCast。

  2. ConfigVarBase,配置变量基类,抽象出配置参数共有属性和方法比如变量名、对变量的描述、互斥锁、toString()、fromString()等,方便ConfigVarManager类使用多态对配置变量进行统一的管理。

  3. ConfigVar,配置变量类模板,继承ConfigVarBase类,含有m_value成员变量,利用LexicalCast类模板,实现toString方法将配置变量序列化成Yaml String,实现fromString方法将Yaml String反序列化成配置变量。此外,还支持变更通知,在set方法中调用变更回调,通知引用配置变量的地方更新变量。

  4. ConfigVarManager,配置变量管理类,利用std::map容器管理所有ConfigVar变量,std::map以配置变量名作为key,以配置变量基类智能指针作为value,支持配置变量的查询,用户在查询一条配置变量时,会提供该变量的变量名、默认值、变量描述,如果配置变量不存在,ConfigVarManager还会自动通过new 运算符利用默认值创建一个类型相同的配置变量,然后将<变量名,自动创建的配置变量>插到std::map中并返回给用户,因此ConfigVarManage还有自学习的能力。此外,提供了loadFromYaml函数支持对Yaml文件的解析,通过递归的方式解析Yaml文件中的每个map node节点,因为Yaml文件的map类型就是<key, value>对,这里key,value在配置文件中的含义和成员变量std::map中元素的含义是一致的,所以,取解析到的每个map node节点的key,去查该key是否存在于std::map成员中,如果存在,就调用相应配置变量基类的fronString函数,将map node的value作为参数,反序列化成一个配置变量。

ConfigVarManager的伪代码如下:

伪代码

yaml配置文件解析的核心代码如下:

    // 递归枚举每一个类型为map的节点。static void __ListAllYamlNode(std::string prefix,const YAML::Node& node,std::vector<std::pair<std::string, YAML::Node>>& output){output.push_back(std::make_pair(prefix, node));if(node.IsMap()){for(auto it = node.begin(); it != node.end(); it++){__ListAllYamlNode((prefix.empty() ? prefix :prefix + ".") + it->first.Scalar(), it->second, output);}}}void ConfigVarManager::loadFromFile(const std::string& val){std::vector<std::pair<std::string, YAML::Node>> nodes;YAML::Node root = YAML::LoadFile(val);__ListAllYamlNode("", root, nodes);for(auto it = nodes.begin(); it != nodes.end(); it++){ConfigVarBase::ptr var = lookUpConfigVarBaseByName(it->first);if(var != nullptr){ // 有配置变量就解析该节点std::stringstream ss("");ss << it->second;var->fromString(ss.str());// for debug//LUNAR_LOG_DEBUG(LUNAR_LOG_NAME("system")) << var->toString();}}}

关于yaml-cpp的使用可以参考官方文档:https://github.com/jbeder/yaml-cpp/wiki/Tutorial。

感兴趣的同学,可以阅读一下本文实现的源码:https://github.com/LunarStore/lunar


本章完结

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

vue3使用is动态切换组件报错Vue received a Component which was made a reactive object.

vue3使用is动态切换组件&#xff0c;activeComponent用ref定义报错 Vue received a Component which was made a reactive object. This can lead to unnecessary performance overhead, and should be avoided by marking the component with markRaw or using shallowRef ins…

cesium 多边形渐变颜色

cesium画一个渐变颜色的多边形 方式一&#xff1a;用一张颜色渐变的图片作为材质&#xff0c;结合color属性&#xff0c;可设置多边形的颜色&#xff0c;达到渐变效果。图片指向正北方向。 viewer.entities.add({polygon: {hierarchy: Cesium.Cartesian3.fromDegreesArray([115…

bs4模块

bs4模块与案例 使用指南 bs4&#xff0c;全称BeautifulSoup 4&#xff0c;是Python中一个强大的网页解析库&#xff0c;它可以帮助我们方便地从网页中提取数据。bs4将复杂HTML文档转换成树形结构&#xff0c;每个节点都是Python对象&#xff0c;所有对象可以归纳为4种&#xf…

【PaddleSpeech】语音合成-男声

环境安装 系统&#xff1a;Ubuntu > 16.04 源码下载 使用apt安装 build-essential sudo apt install build-essential 克隆 PaddleSpeech 仓库 # github下载 git clone https://github.com/PaddlePaddle/PaddleSpeech.git # 也可以从gitee下载 git clone https://gite…

EBC金融英国CEO:高波动性周期下,如何寻找市场的稳定性?

利率主导的市场&#xff0c;将在2024年延续。目前&#xff0c;固收市场对于降息的定价&#xff0c;正通过利率传导至不同资产中。尽管市场迫切利用通胀去佐证降息&#xff0c;但各国央行仍囿于通胀目标的政策桎梏。政策和市场预期的博弈将继续牵动市场脉搏&#xff0c;引发价格…

基于SSM+MySQL的的新闻发布系统设计与实现

目录 项目简介 项目技术栈 项目运行环境 项目截图 代码截取 源码获取 项目简介 新闻发布系统是一款基于Servletjspjdbc的网站应用程序&#xff0c;旨在提供一个全面且高效的新闻发布平台。该系统主要包括后台管理和前台新闻展示两个平台&#xff0c;涵盖了新闻稿件的撰写…

充电桩项目实战:搞定多数据源!

你好&#xff0c;我是田哥 最近&#xff0c;我在对充电桩项目进行微服务升级中&#xff0c;既然是项目升级&#xff0c;难免会遇到各种各样的问题。比如&#xff1a;分布式事务问题、多数据源问题、分布式锁问题等。 项目技术栈&#xff1a; SpringSpring BootSpring Cloud Ali…

JavaScript基础(二)—— 运算符、表达式与语句(if、switch、循环)

学习目标&#xff1a; 掌握常见运算符&#xff0c;为程序“能思考”做准备 掌握分支语句&#xff0c;让程序具备判断能力 掌握循环语句&#xff0c;让程序具备重复执行能力 一、运算符 1. 赋值运算符 对变量进行赋值的运算符&#xff0c;能够使用赋值运算符简化代码。 …

推荐系统|概要03_AB测试

文章目录 A/B测试问题流量不够用解决方案——分层实验 Holdout 机制 A/B测试 其中小流量是指对部分的用户先尝试改进的算法模型&#xff0c;而非全部。若为全部&#xff0c;如果算法模型存在问题&#xff0c;可能会导致用户体验差&#xff0c;导致用户流失&#xff0c;而小流量…

深入探究iframe:网页嵌入的魔法盒子(下)

&#x1f90d; 前端开发工程师、技术日更博主、已过CET6 &#x1f368; 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 &#x1f560; 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 &#x1f35a; 蓝桥云课签约作者、上架课程《Vue.js 和 E…

DATAX改造支持geometry类型数据同步

数据库使用postgresql安装了postgis插件存储了geometry空间数据&#xff0c;想使用datax做数据同步&#xff0c;但datax本身不支持geometry类型数据&#xff0c;如何改造呢&#xff1f; 1.首先下载已改造支持geometry类型的datax引擎&#xff0c;下载地址 https://download.c…

Jmeter性能测试: Jmeter 5.6.3 分布式部署

目录 一、实验 1.环境 2.jmeter 配置 slave 代理压测机 3.jmeter配置master控制器压测机 4.启动slave从节点检查 5.启动master主节点检查 6.运行jmeter 7.观察jmeter-server主从节点变化 二、问题 1.jmeter 中间请求和响应乱码 一、实验 1.环境 &#xff08;1&#…

oracle数仓rac两个节点查询耗时不一致问题处理

问题描述 数据库节点1查询比节点2查询慢。现场操作应用发现发现同一sql语句在节点2上只要2分钟左右&#xff0c;在节点1&#xff0c;该条sql执行要超过30分钟。 处理过程 根据问题&#xff0c;初步判断是由于错误的执行计划&#xff0c;导致性能问题&#xff0c;但实际上对两…

编程流程图

对于复杂流程&#xff0c;我做开发之前一般会 先画一下流程图。特别是多个部门有交叉的情况下&#xff1a; processOn&#xff1a; 这个是我之前 一直的选择&#xff0c;他可以画上面的这些&#xff0c;流程图&#xff0c;网页操作&#xff0c;但是他不是免费的&#xff0c;查过…

JavaScript事件冒泡和捕获

&#x1f9d1;‍&#x1f393; 个人主页&#xff1a;《爱蹦跶的大A阿》 &#x1f525;当前正在更新专栏&#xff1a;《VUE》 、《JavaScript保姆级教程》、《krpano》、《krpano中文文档》 ​ ​ ✨ 前言 事件传播是JavaScript中非常重要的一个概念,它描述了从嵌套元素到祖先…

【C++干货铺】哈希结构在C++中的应用

目录 unordered系列关联式容器 unordered_map unordered_map的接口说明 1.unordered_map的构造 2. unordered_map的容量 3. unordered_map的迭代器 4. unordered_map的元素访问 5. unordered_map的查询 6. unordered_map的修改操作 7. unordered_map的桶操作 底层结构 …

mysql+node.js+html+js完整扫雷项目

一.下载 可以直接下载绑定资源&#xff0c; 也可以访问&#xff1a;克隆仓库&#xff1a;mine_clearance: mysqlnode.jshtmljs完整扫雷项目 (gitee.com) 二.运行sql数据文件 将mysql数据文件导入到本地 先在本地localhost里创建数据库 mine_clearance&#xff0c; 然后如图&…

elementUI实现selecttree自定义下拉框树形组件支持多选和搜索

elementUI实现selecttree自定义下拉框树形组件支持多选和搜索 效果图定义子组件父组件应用 效果图 定义子组件 主要结合el-select和el-tree两个组件改造的。 <template><div class"selectTree"><el-select filterable :filter-method"filterMe…

微软给Windows 11增添了一个由AI支持的‘Voice Clarity’功能

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…

linux搭建jupyter

查看虚拟环境 conda info --envs进入虚拟环境 conda activate my_env pip install jupyter pip install ipykernel1. jupyter notebook启动 1.1 创建临时jupyter notebook任务 jupyter notebook --ip0.0.0.0 --no-browser --allow-root --notebook-dir/home/xxx1.2 jupyter…