|
|
一个易用的跨平台框架,业务系统采用ECS设计,丰富的组件,网络模型采用iocp/epoll,协议采用protobuf,支持ipv4/ipv6等
要求要求具备C++11以上基础,以及一些C++20特性(module/c++20无栈协程/concept/requires, 了解c++20协程的一些基本关键字) 不为任何抽象付出不可接受的多余运行时性能损耗 快速构建 简介- 晶石框架是一个简易轻量的服务端框架,基于C++11及以上
- 旨在开发出一套跨平台,代码简洁可读性高,执行高效的框架
- 框架正在持续开发中,接受各种建议吐槽
- Attention:region 注释会尽量使用简洁的英文,CI可能会报错哈QVQ
- 多个重要组件移植于LLBC、 nlohmann/Json、 OpenSSL, 再次感谢开源作者的贡献,开发过程中给予了我很大的帮助
特性采用iocp/epoll网络模型,跨windows/linux平台 支持protobuf 3.21.9, 定制了protobuf协议生成器,自动生成c++/c#的协议代码, 支持基于protobuf的ORM,对protobuf生成的ormdata的数据修改会被自动标脏 支持ipv4/ipv6 支持session级别的packet限速 支持openssl md5/sha1/aes等加解密,签名验签 支持ECS设计,轻松设计大型复杂系统 支持任意对象对象池,内存池,可以很轻松的进行内存管理 支持tinyxml 支持对zip文档解压 支持对xlsx解析 强大的日志系统 丰富的组件支持 支持Mysql 8.0存储, 不需要自行建表建库,支持自动建库建表, 支持标脏持久化, 自动存库,数据类型与大小自适应 支持C++20 协程 集成Lua-5.4.7 静态库 linux下支持so级别的热更(原理是在运行时使用dlopen重新加载so, 见PlugingMgr模块, 并采用数据和逻辑分离,逻辑写在so中, 数据定义在可执行程序中, so例子见TestServicePlugin模块),见热更原理介绍 消息支持无锁队列(SPSC与MPMC), 跨线程消息投递高效 工程默认引入yaml-cpp库(以静态库的形式), 支持yaml配置,见3rd/yaml/
热更原理- 组件构成
ShareLibraryLoader: 动态库加载组件, 作为组件嵌入到PluginMgr中, 用于加载指定的动态库 LibraryHotfixMonitor: 动态库热更监控组件, 作为组件嵌入到Application中,用于监控是否有动态库需要热更, PluginMgr: 用于管理插件集, 作为组件嵌入到MyTestService中
流程图
一个易用的跨平台框架,业务系统采用ECS设计,丰富的组件,网络模型采用iocp/epoll,协议采用protobuf,支 ...
- # **.sh 可执行程序名 可执行程序编译版本 插件集HotfixKey 要热更的插件集so文件名
- sh ./scripts/hotfix/hotfix.sh testsuit debug TestPlugin libTestPlugin2.so
复制代码
性能(见doc/压测/)
- 1. 16C32G机器,ini配置1个service, 网络层2个datatransfer poller, qps:26w/s, 客户端延迟:最大<200ms, 平均:150ms
- 2. 32c64G机器,ini配置6个service,网络层每个service1个datatransfer poller, 总的qps:52w/s, 客户端延迟:最大<200ms, 平均:150ms
复制代码 注意- windows下需要开启开发者模式(设置=>更新与安全=>开发者选项),避免bat相关cmd失败
- 所有静态库都需要添加-fPIC编译, 避免无法识别到符号的编译问题
- 由于协程在初始化的时候会将参数,局部变量保存到协程上下文中, 参数如果是引用的也会以引用的形式保存,所以请务必注意参数和局部变量的生命周期问题, 建议使用智能指针
- 尽量避免提交二进制文件到git上,会导致仓库膨胀,二进制文件不是存储文件差异而是整个文件存下来,每次提交都会整个文件存下来会导致仓库体积膨胀
- windows下kernel不生成dll,而是把代码插入到exe工程中
- 使用ECS时千万警惕循环依赖:A <= B <= A <= ... 循环往复把系统资源耗光
- 注意如果基类的命名空间与派生类的命名空间不同,则不可以使用Comp(), 不可以使用基类类型来获取对象,因为注册的时候是根据派生类全名来推导基类名并注册进去的
- 在模版函数中的lambda表达式中调用inline函数且该函数带有局部的static变量有可能导致变量多次初始化
- linux 内核版本3.9.0以上才有reuseport特性
- windows 下dll, exe拥有各自的堆栈空间,各自的全局变量都会各自初始化,所以注意全局变量以及static变量可能出现的重复初始化以及释放问题,建议为了只使用一个堆栈空间,windows下一个程序只有一个exe不依赖dll或者说依赖dll,但是不依赖dll中的全局变量
- thread_local 关键字 gcc 8.0以下有bug,相关连接:https://gcc.gnu.org/bugzilla/show_bug.cgi?id=60702
- 对于core,请不要使用try catch去处理异常,让系统输出core_dump的因为linux 的core_dump可以输出比较全面的崩溃时的数据,而如果仅仅在try catch去使用backtrace打印堆栈信息,是有缺陷的无法还原崩溃时的信息,导致解决错误的困难
- gcc 需要支持8.3及以上,建议切换到tencent os 3 因为默认支持gcc 8.3
- CXX11 ABI兼容性 请设置编译选项
_GLIBCXX_USE_CXX11_ABI=1 放弃兼容gcc 5.x以下版本 - 由于github单文件100MB 限制的原因,对3rd/kernel 3rd/protobuf/lib 两个目录库超过100MB文件进行了partition拆分,编译时会自动合并
- 框架层不可以抛异常,只能使用错误码或者bool, 需不需要异常要上层决定,一般不建议抛异常即使是上层
- 数据库应该采用参数化查询来放置SQL注入攻击
- 关于关闭基于Application的引用, 可以在应用所在目录放入和应用同名后缀加上 .kill_进程id 的后缀其中进程id是当前允许程序的进程id,当使用工具执行关服时, 会创建这样的一个文件,app会监控到有这个文件就会执行关闭操作,也可以使用Ctrl + C进行常规的关闭,windows下不支持点击关闭窗口来关服,因为会导致数据丢失
- 多使用分支预测,可以提前加载预测为真的代码,提升性能
- DisableTruncateDB 线上的时候必须设置成1, 避免手残更改版本号导致清库
- Mysql windows下是大小写不敏感(表名和数据库名), 所以即使表名在建表时有大小写之分也会在建表后变成小写,为了兼容linux/windows的统一,数据库和表名都使用小写,字段名是区分大小写
- 日志开启控制台打印会比较大的影响到性能, 酌情开启,linux下应该禁止开启控制台打印
- windows下编码等请设置系统编码格式为UTF8, 以便在代码编辑时可以使用utf8对字符串正常编码
- 对模板, 内联需要保持敬畏之心,因为会导致代码膨胀, 编译时间无法容忍, 除非过度到c++20采用module, 否则避免过度设计,应该运用巧妙的方式弥补性能上的担忧, 以及在没必要关心性能的部分代码审慎使用模板与内联, 鼓励使用代码生成工具来替代
- 项目头文件中不可直接include kernel.h等比较大的库头文件,应该在实现文件中include
- 使用协程一定注意对象的生命周期
- 如果需要在so中使用库, 则需要在编译so的时候打开PROG_USE_SO的宏定义, 因为对象池或者内存池需要追踪这些对象以便定位内存泄漏问题
- linux so热更时需要显示的销毁全局变量, 避免内存泄漏

链接: https://pan.baidu.com/s/1q5fsmB7ezDn1Hj3gbsSs2A
提取码下载:
|
|