惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

博客园_首页
Microsoft Azure Blog
Microsoft Azure Blog
aimingoo的专栏
aimingoo的专栏
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
阮一峰的网络日志
阮一峰的网络日志
Martin Fowler
Martin Fowler
B
Blog
The GitHub Blog
The GitHub Blog
T
Tailwind CSS Blog
Stack Overflow Blog
Stack Overflow Blog
L
LangChain Blog
H
Hackread – Cybersecurity News, Data Breaches, AI and More
D
DataBreaches.Net
月光博客
月光博客
人人都是产品经理
人人都是产品经理
IT之家
IT之家
GbyAI
GbyAI
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
WordPress大学
WordPress大学
博客园 - Franky
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
The Cloudflare Blog
C
Check Point Blog
罗磊的独立博客

I'm OWenT

国产大模型(GLM 5.1、Kimi K2.6)真实场景效果和 Coding Plan 额度测试 新版本libatapp的连接管理——从etcd服务发现到拓扑驱动的自动重连 新版本libatbus的设计变更——从树形路由到拓扑驱动 Protobuf又一坑 - C++标准和ABI兼容性 AI真好用-给Blog主题统一加mermaid,chart.js,excalidraw,draw.io的多种引入方式支持 给内网部署Squid-通用HTTP下载缓存 UE使用CodeChecker和clang-tidy生成静态分析报告 找出UE的循环依赖 C++小协程栈和临时变量及作用域的栈溢出问题分析 游戏服务的可观测性能力建设(C++生态) 指标上报的多线程优化和多拉取源点优化 协程(libcopp)的Channel功能和CPU命中率优化 通用RPC代码生成器 实现strong_rc_ptr(比shared_ptr更快的引用计数智能指针) 手夯一个STL allocator和对象内存分析组件 std::condition_variable 的信号丢失问题 踩坑一处(GCC)STL std::async 实现BUG导致的crash问题 GCC 14的一个warning to error BUG 给xresloader(Excel导表工具)增强UE读表支持(包含蓝图,Blueprint) Opentelemetry社区在gRPC的几个链接问题(静态库和动态库混用,musl工具链,符号裁剪) Excel转表工具(xresloader)的新验证器(验证外部Excel和文本数据,唯一性和自定义规则) protobuf v22和gRPC v1.55版本升级的依赖变化和upb适配 关于protobuf近期版本(v20/v3.20+)和 gRPC v1.54版本在某些编译环境下的一些链接和编译问题 xresloader-Excel导表工具链的近期变更汇总 打通游戏服务端框架的C++20协程改造的最后一环 Opentelemetry-cpp的Logs模块标准更新(涉及近期版本:1.8-1.9的BREAK CHANGES) 给cmake-toolset和工具链(curl等)加HTTP/2和HTTP/3支持 又开新坑之 coredns 插件: nftables和filter 关于opentelemetry-cpp社区对于C++ Head Only组件单例和符号可见性的讨论小记 填个转表工具 xresloader 去年的坑(数组尾部裁剪)
libatbus 的大幅优化
owent · 2020-04-17 · via I'm OWenT

blog-website

最近零碎的事太多了,拖了好久没写blog。一些小的碎片话的东西也不值得写,另一方面是这次大幅优化了 atframework 的一些流程细节,特别是针对我们这两年来业务的需求,对 libatbus 进行了一次大重构。这里记录一下重构的内容吧。

重构工程配置脚本

为了拥抱Modern CMake,我对 atframework 中所有的项目(当然也包含 libatbus )进行了重构,主要是一方面重构整理最近几个项目编译和交叉编译 openssl , protobuf 等几个构建流程比较恶心的库的自动化构建流程和工具脚本。如果不追求全部功能的话,还可以用 libressl 来代替 openssl 。也合并适应了给客户端用的交叉编译iOS、Android、Unreal Engine等平台使用的构建流程。

另外atframework 中所有的C++项目都用cmake的export功能导出了,这样无论是作为某个工程的子项目,还是prebuilt之后直接可以使用Modern CMake推荐的find_package(MODULE)机制导入。

符号隐藏和DLL导出

之前写的时候没太注意跨平台符号这块,所以都是建议使用静态库。我们前段时间预研了一段时间的Unreal Engine引擎,涉及一个问题就是把服务器通信组件集成到Unreal Engine中,然后使用Unreal Engine的Dedicated Server和我们自己的服务器通信。这时候就碰到了一些问题。首先Unreal Engine官方提供的预编译包是不开RTTI和Exception的。而如果使用静态编译版本的 libatbus 得开启RTTI和Exception,这就导致得完全重编Unreal Engine,这非常慢切很麻烦。所以这次重构也梳理了一遍符号导出问题。

现在Linux和Windows下得符号导出和符号隐藏规则统一了,并且这样以后,对PE这种独立堆的ABI,也可以编译成dll使用了。这样也就可以编译成外部模块给Unreal Engine使用。

移除msgpack

之前使用msgpack是因为它宣称效率是protobuf的4倍。但是自从protobuf 3.0以后,可以使用Arena来减少碎片,我预估这个对性能的影响还挺明显的。反倒是我之前对msgpack的时候也是暴力new/delete的。所以综合来说我觉得protobuf 3.0+更好一些。另外protobuf生成的接口和反射支持比msgpack方便太多了。

第二个原因也是和上面一条一样,想要支持关闭RTTI和异常。而msgpack代码里写死的异常处理,而protobuf只要开一个编译宏就能完全关闭异常。

新的替代品是 protobuf ,我用protobuf完全替换掉了原来msgpack提供的功能。在切到protobuf之前,我还考虑过使用flatbuffer,写了个简单的对比,有兴趣的童鞋可以看看 《protobuf、flatbuffer、msgpack 针对小数据包的简单对比》cap’n protoflatbuffer 的原理一样我就没特意去再写一个测试了。简单的说就是我觉得flatbuffer对小包太不友好了,对向后兼容也不太友好,感觉可能还是只适合配置和数据转储。

支持使用字符串路径的共享内存通道

现在支持字符串路径的共享内存(使用: shm_open/ftruncate/mmap/munmap/shm_unlink/close/fstat 来管理),支持字符串命名的共享内存(长度限定为NAME_MAX(255))。但是posix标准里这个路径是不能有子目录的,所以新版本版本的glibc里也不允许(一些老版本的glibc允许)。另外linux下英文功能内存会放 tmpfs 的目录 /dev/shm 里,可以建立子目录。但是为了统一跨平台兼容性,我还是没有支持多级目录的。另外这个长度也受glibc库的限制,所以我设置了按NAME_MAX的长度。

增加协议跨版本向前向后兼容管理,增加简单的验证功能

这主要是考虑到后续如果同时多个业务使用或者多个环境使用的时候可能更新有先后。然后如果又不兼容的版本,集群之间可以互相不主动连接,以防不断地尝试重连然后断开。另外增加共享内存通道的版本号检查和架构校验,也是防止共享内存通道如果版本不兼容,随意attach上去可能会破坏数据。atproxy已经接入了这个特性。

额外增加了一个简单的验证功能,这是为了防止多个项目使用的时候误操作,发送了指令到别的业务(如果互通的话)。并不提供严谨的安全机制。

支持多个自定义子网

这是为了atproxy可以部署再自己的前缀分组里,然后管理其他前缀分组的子网。这是为了方便更灵活的运维层面的部署结构。这个改动也影响了协议层变化。不过反正都换protobuf了也是大换血了。

其他细节优化

还有一些其他细节优化列举如下:

  1. 增加连接层错误计数,超出容忍值直接断开连接
  2. 增加大量错误流程的单元测试,优化Unix Sock的单元测试,以支持WSL2
  3. 规范版本号规则:第一位变化表示有向前不兼容的变更;第二位表示有功能增加,向前兼容,第三位表示BUG修复和优化
  4. 更换数据回包的回调名字。

最早的想法是仅失败的时候回包通知,但是后来为了适应有些需求需要尽快知道是否发送成功,所以加了强制回包功能。所以现在的数据转发回包不仅仅是错误处理了,叫on_fail也不合适。所以改成了on_receive_response

不打算支持 protobuf 2.X 了, protobuf 2.X 的最后一个版本到现在已经快5年了,而且proto3的支持现在也已经很完善了。所以我并没有测试protobuf 2.6的兼容性。

未来计划

  1. endpoint 离线后保留一段时间,如果期间重连成功了自动重发
  2. 增加data sequence,事件去重和切换节点的sequence重置
  3. 共享endpoint的写缓冲区(也许后面可以一句这个支持多路并行发包)
  4. 重发消息的超时机制,增加不确定是否成功的错误码
  5. 兄弟节点离线后自动重连几次
  6. 增加endpoint尝试轮询连接数据通道,减少不必要的数据通道,仅保留最快的方式。