大语言模型的基石:Transformer 入坑笔记(三) - 注意力机制和 Transformer

<h2 id="背景">背景</h2> <p>接上文 <a href="https://owent.net/2026/2609.html">《大语言模型的基石:Transformer 入坑笔记(二) - 基本原理和 Word Embeddings》</a>,继续我们的 <a href="https://arxiv.org/pdf/1706.03762">Attention Is All You Need</a>/<a href="https://github.com/huggingface/transformers">Transformer</a> 学习之旅。</p> <p>首先简单了解下传统的方案。</p> <h2 id="卷积神经网络cnn">卷积神经网络(CNN)</h2> <p>卷积神经网络(CNN)似乎更适合静态数据(比如图片处理、提取特征等)。 所谓静态数据,是指每个数据组都单独和目标矩阵运算,通过卷积层、池化层、全连接层等输出。 每个数据组都单独运算所以可以大规模并发,但是数据组之间也缺乏关联。 我大概看了下原理,和我们要关注的 <a href="https://github.com/huggingface/transformers">Transformer</a> 关系不大,先略过了。</p>

2026/6/28
阅读更多

大预言模型的基石:Transformer 入坑笔记(二) - 基本原理和 Word Embeddings

<h2 id="背景">背景</h2> <p>继续我们的 <a href="https://arxiv.org/pdf/1706.03762">Attention Is All You Need</a> 学习之旅。</p> <p>我不是这个领域的,只是感兴趣想补一下基础,所以这一篇先只看最通用的原理:神经网络训练的大概流程、Embedding 是什么,以及 Word2Vec 里两种常见优化思路。</p> <p><a href="https://arxiv.org/pdf/1706.03762">Attention Is All You Need</a> 最早落在机器翻译任务上,它提出的核心架构就是 Transformer。工程上我们常接触到的 <a href="https://github.com/huggingface/transformers">Transformers</a> 库,则是围绕这类模型提供了更完整的封装。</p>

2026/6/24
阅读更多

大预言模型的基石:Transformer 入坑笔记(一) - 大模型训练链路

<h2 id="前言">前言</h2> <p>这几年 AI 的热度一直很高。日常问答、写代码、整理文档、做工具,它已经开始进入不少人的日常工程流。我最近也开始认真补这块东西,主要是想搞清楚:这些模型到底是怎么一步步训练出来的,以及它有没有机会更深入地帮我们优化游戏研发里的工作流。</p>

2026/4/30
阅读更多

国产大模型编码能力实测(GLM 5.1、Kimi K2.6、Mimo v2.5 Pro 和 DeepSeek V4 Pro)

<h2 id="背景">背景</h2> <p>这两天 DeepSeek V4 Pro 刚上线,小米那边也送了一个月的 Mimo Token plan。我本来就在试着用 AI 做一个完整工具,正好顺手把几个国产大语言模型都拉进来跑了一轮:GLM 5.1、Kimi K2.6、Mimo v2.5 Pro 和 DeepSeek V4 Pro。</p> <p>测试样本是我手头正在做的一个工具项目,后面只保留和模型表现有关的数据,不展开它自己的功能设计。</p>

2026/4/30
阅读更多

国产大模型(GLM 5.1、Kimi K2.6)真实场景效果和 Coding Plan 额度测试

<h2 id="背景">背景</h2> <p>今年国产大模型是真的热闹。新模型一出来,宣传话术一个比一个猛。</p> <p>尤其是最近出来的 GLM 5.1。</p> <p><img src="//owent.net/2026/2606-glm5.1.png" alt="2606-glm5.1.png" loading="lazy" /></p> <p>还有 Kimi K2.6。</p> <p><img src="//owent.net/2026/2606-kimi-k2.6.jpg" alt="2606-kimi-k2.6.jpg" loading="lazy" /></p> <p>海报和宣传图看着都很唬人,但真到自己拿去干活的时候,往往还是会闻到一点“跑分没输过,实战没稳过”的味道。所以我干脆把最近几个真实使用场景里的体验记了下来。</p>

2026/4/22
阅读更多

新版本libatapp的连接管理——从etcd服务发现到拓扑驱动的自动重连

<h2 id="前言">前言</h2> <p>在<a href="../2604">上一篇文章</a>中,介绍了 <a href="https://github.com/atframework/libatbus">libatbus</a> 从静态子网树到动态拓扑注册表的路由设计变更。新的拓扑模型解决了代理层无法弹性伸缩和跨区域隔离的问题,但路由只是底层基座——上层应用框架 <a href="https://github.com/atframework/libatapp">libatapp</a> 才是真正面对业务开发者的接口。</p> <p>这篇文章聚焦于 <a href="https://github.com/atframework/libatapp">libatapp</a> 在新架构下的连接管理层设计,涵盖以下核心问题:</p>

2026/3/27
阅读更多

新版本libatbus的设计变更——从树形路由到拓扑驱动

<h2 id="前言">前言</h2> <p>很久很久以前,我为了解决以前项目中bus通信膨胀的问题设计了 <a href="https://github.com/atframework/libatbus">libatbus</a>, 当时主要解决的核心问题是解决大量服务器节点互通时服务器间两两建立通道时的大量内存浪费问题。也同时使用跨进程的无锁队列避免了多写单读场景下的加锁以提高性能。</p>

2026/3/27
阅读更多

Protobuf又一坑 - C++标准和ABI兼容性

<h2 id="背景">背景</h2> <p>前段时间例行升级我为游戏框架写的构建系统 <a href="https://github.com/atframework/cmake-toolset">cmake-toolset</a> 时,又遇到了 <a href="https://github.com/protocolbuffers/protobuf">protobuf</a> 的一个新 ABI 兼容性问题。</p> <p>这已经不是第一次被 <a href="https://github.com/protocolbuffers/protobuf">protobuf</a> 的 ABI 兼容性问题“教育”了。这篇把问题拆开讲清楚,并给出一套可落地的规避方案,供遇到类似问题的同学参考。</p> <ul> <li>编译环境:Windows + Visual Studio 2026</li> <li>Abseil-Cpp:20250512.1</li> <li>Protobuf:v31.1(看起来目前最新的 v33.1 也有这个问题)</li> </ul> <h2 id="现象与错误定位">现象与错误定位</h2> <p>首先在链接阶段出现错误:</p>

2026/1/11
阅读更多

AI真好用-给Blog主题统一加mermaid,chart.js,excalidraw,draw.io,echarts,plotly的多种引入方式支持

<h2 id="背景">背景</h2> <p>在很久以前,我给我的Blog的主题加了 <a href="https://gohugo.io/">Hugo</a> 的针对 <a href="https://mermaid.js.org/">Mermaid</a> 和 <a href="https://www.chartjs.org/">Chart.js</a> shortcodes 的支持。但是之支持迁入代码的方式。 如果文档很复杂,在Markdown里写大段的代码体验观感也不是很好。 而现在很多Markdown生态里是支持通过代码块的方式嵌入的。 同时现在很多插件可以直接按文件后缀编辑文件,然后直接指向文件的形式引用进来,这样可维护性会好很多。</p>

2026/1/1
阅读更多

给内网部署Squid-通用HTTP下载缓存

<h2 id="背景">背景</h2> <p>近期,公司代理侧的流量负担持续上升;在高峰期访问常见开发资源(包管理器、SDK、依赖镜像、CDN 文件等)会出现明显抖动。为降低重复下载带来的外网带宽开销与峰值波动,决定在内网引入一套“通用下载缓存代理”。</p>

2026/1/1
阅读更多

UE使用CodeChecker和clang-tidy生成静态分析报告

<h2 id="前言">前言</h2> <p>现代化的C++项目可以借助多种静态分析工具来检查和发现潜在问题,包括空指针访问风险、未定义行为(UB)、内存错误等。</p> <p>在我们的项目中,服务器工程基于 CMake 构建系统,可以方便地利用社区支持来集成这些静态分析工具,如 <a href="https://clang.llvm.org/extra/clang-tidy/">clang-tidy</a>、<a href="https://clang-analyzer.llvm.org/">clang-analyzer</a>、<a href="https://codechecker.readthedocs.io/">CodeChecker</a> 等。然而,另一部分 C++ 代码运行在 UE(Unreal Engine)引擎中。由于 UE 在编译流程上做了一些特殊扩展,再加上 UBT(UnrealBuildTool)工具在某些能力上的限制,直接开启静态分析会遇到一些问题:</p>

2025/12/22
阅读更多

找出UE的循环依赖

<h2 id="背景">背景</h2> <p>在大型 UE(Unreal Engine)项目中,&ldquo;模块/插件&quot;是维持工程可维护性的基本手段。但随着工程规模增长,很容易出现循环依赖问题:</p> <ul> <li>模块 A 为了复用工具函数依赖模块 B</li> <li>模块 B 为了注册某些类型或访问某些资源又依赖模块 A</li> <li>在某些平台或配置下(尤其是 Editor 构建或 Link 阶段需要聚合大量 <code>.so/.a</code> 时),最终表现为 <strong>循环依赖</strong></li> </ul> <p>UBT(UnrealBuildTool)能检测到循环依赖,但输出的是 <em>ActionGraph</em> 层面的信息:大量 <code>Action #xxxx</code>,并提示&quot;这些 action 互相成环&rdquo;。对于实际排障来说,主要痛点在于:</p>

2025/12/21
阅读更多

C++小协程栈和临时变量及作用域的栈溢出问题分析

<h2 id="背景">背景</h2> <p>近期在给一个项目换一些底层接口的日志处理部分。把原始的类 <code>printf</code> 的格式化方式换成 <a href="https://fmt.dev/">fmtlib</a> / <a href="https://en.cppreference.com/w/cpp/utility/format.html">C++ 20 Text Formatting</a> 的方案。</p> <p>然后发现,替换完一段未执行的代码后,会发生内存写坏的情况。</p> <h2 id="问题分析">问题分析</h2> <p>通过跟踪生成的汇编和 gdb 的 <code>info frame</code> 位置。发现替换之后,栈帧位置大幅增加了。比如对这类代码:</p>

2025/8/2
阅读更多

游戏服务的可观测性能力建设(C++生态)

<h2 id="前言">前言</h2> <p>近年来可观测性领域越来越成熟,游戏服务的可观测性能力建设日益成为提升产品质量与运维效率的关键环节。随着游戏系统架构的不断复杂化,传统的监控和故障排查方式已难以满足业务高可用和用户体验优化的需求。通过健全的可观测性体系,可以实现对游戏服务全链路的实时监控、异常检测与分析,助力技术团队及时发现和定位问题,推动产品持续优化与稳定迭代,从而为玩家提供更加流畅和可靠的游戏体验。</p>

2025/5/23
阅读更多

指标上报的多线程优化和多拉取源点优化

<h2 id="前言">前言</h2> <p>我给我们的服务器框架深度集成了一些可观测性的能力。使用 <a href="https://github.com/open-telemetry/opentelemetry-cpp">opentelemetry-cpp</a> 作为接入层。 在指标方面,我们允许业务层自由地定制化指标上报和拉取,并以此实现策略控制。上报的时候有Pull模式接口(异步接口),也有Push模式接口(同步接口)。 为了减少 <a href="https://github.com/open-telemetry/opentelemetry-cpp">opentelemetry-cpp</a> 内部的视图合并开销,性能最佳,我们尽量使用异步接口。 但是这种情况下由于 <a href="https://github.com/open-telemetry/opentelemetry-cpp">opentelemetry-cpp</a> 内部存在后台Processor线程、Exporter线程等,指标的采集往往需要跨线程操作。 这就要求我们上报代码逻辑需要保证线程安全。</p>

2025/5/21
阅读更多

协程(libcopp)的Channel功能和CPU命中率优化

<h2 id="背景">背景</h2> <p>设计 <a href="https://owent.net/2022/2206.html">《libcopp对C++20协程的接入和接口设计》</a> 的时候,由于C++20协程的promise和awaitable是链式关联的。所以当时设计promise和awaitable之间通过一个共享的context来通信交互。当时第一版实现直接使用了 <code>std::shared_ptr</code> 来管理共享引用,也预留了个规划是未来可以改成非线程安全的引用来减少不必要的Cache Miss开销。</p>

2025/3/12
阅读更多

通用RPC代码生成器

<h2 id="背景">背景</h2> <p>我们项目组需要接入多种RPC接入和工具转换流程,并且每种接入层有自己的扩展和定制需求。为了提高开发效率,我们需要一个通用的RPC代码生成器,能够支持多种RPC接入层级的代码生成,同时支持自定义插件和模板。并且自由增加自定义插件而不需要变更构建系统流程。以便提供最佳的灵活性且能支持protobuf的所有特性。</p>

2025/2/13
阅读更多

实现strong_rc_ptr(比shared_ptr更快的引用计数智能指针)

<h2 id="背景">背景</h2> <p>我们的新项目有个比较复杂的全区全服交易行系统,其中搜索和推荐是高实时性全区服多维度排序的,并且要支持比较复杂的标签交集查询和属性范围查询的自由组合。 当有订单发生变化时,它不仅仅会影响全服状态下搜索和推荐条件的结果变化,也会同时影响商品维度的聚合,交易行层面的数据聚合。</p>

2024/10/8
阅读更多

手夯一个STL allocator和对象内存分析组件

<h2 id="前言">前言</h2> <p>我们项目组前段时间排查和分析压测环境下的某些业务模块大量索引结构的内存问题。通用的工具比如 <a href="https://github.com/jemalloc/jemalloc">jemalloc+jeperf</a> 或者 <a href="https://github.com/google/tcmalloc">tcmalloc+gperf</a> 的组合过于底层,一方面开启跟踪开销较高,另一方面也是会产生过多噪音数据影响判断。所以我针对我们的智能指针(包含 <code>std::shared_ptr</code> 和我最近写了个非线程安全的版本的 <code>strong_rc_ptr</code> , 这个后面有空再分享)和STL容器实现了allocator来帮助动态的手动插桩来分析问题。 最终的效果是可以通过一键替换类型申明的Allocator来插入动态控制和插桩统计的能力,这里分享一下手夯标准STL allocator的一些实现细节,方便其他小伙伴如果需要做类似的实现来参考。</p>

2024/8/21
阅读更多

std::condition_variable 的信号丢失问题

<h2 id="背景">背景</h2> <p>这篇分享拖更了好久了。问题起源于去年我们项目组接入 <a href="https://github.com/open-telemetry/opentelemetry-cpp">opentelemetry-cpp</a> 的时候,在进程优雅退出的时候偶现超时,虽然可以直接kill进程没啥影响但是退出不“优雅”的话总归会破坏发布流程,增加人工介入的成本。这里记录一下问题可能其他的组件有类似的用法也会有相似的问题。</p>

2024/8/2
阅读更多

踩坑一处(GCC)STL `std::async` 实现BUG导致的crash问题

<h2 id="前言">前言</h2> <p>近期发现项目组使用新版本的 <a href="https://github.com/open-telemetry/opentelemetry-cpp">opentelemetry-cpp</a> 的时候偶现崩溃。崩溃的位置在STL的 <code>std::future</code> 析构的地方,而这个 <code>std::future</code> 由 <code>std::async</code>创建。 比较违反直觉,这里记录分享一下分析和解决过程方面其他碰到的小伙伴们。</p> <h2 id="问题分析">问题分析</h2> <h3 id="相关代码和规范">相关代码和规范</h3> <p>首先我们来看下相关代码:</p>

2024/7/21
阅读更多

GCC 14的一个warning to error BUG

<h2 id="背景">背景</h2> <p>早先社区报过 <a href="https://github.com/open-telemetry/opentelemetry-cpp">opentelemetry-cpp</a> 在GCC 14中编译不通过的问题。最近我也是先升级我们项目组的工具链,主要也是把GCC升级到GCC 14,这时候发现有些第三方工具构建失败。 这里记录一下以防后续其他人碰到参考。</p> <h2 id="分析">分析</h2> <p>我们在使用新版本GCC 14编译zsh的时候,报 <code>boolcodes</code> 和定义冲突。</p>

2024/5/30
阅读更多

给xresloader(Excel导表工具)增强UE读表支持(包含蓝图,Blueprint)

<h2 id="前言">前言</h2> <p><a href="https://xresloader.atframe.work/">xresloader</a> 是一组用于把Excel数据结构化并导出为程序可读的数据文件的导表工具集。它包含了一系列跨平台的工具、协议描述和数据读取代码。</p> <p>主要功能特点:</p> <ul> <li>跨平台(java 11 or upper)</li> <li>Excel =&gt; protobuf/msgpack/lua/javascript/json/xml</li> <li>完整支持协议结构,包括嵌套结构和数组嵌套</li> <li>同时支持protobuf proto v2 和 proto v3</li> <li>支持导出proto枚举值到lua/javascript代码和json/xml数据</li> <li>支持导出proto描述信息值到lua/javascript代码和json/xml数据(支持自定义插件,方便用户根据proto描述自定义反射功能)</li> <li>支持导出 UnrealEngine 支持的json或csv格式,支持自动生成和导出 UnrealEngine 的 <code>DataTable</code> 加载代码</li> <li>支持别名表,用于给数据内容使用一个易读的名字</li> <li>支持验证器,可以在数据里直接填写proto字段名或枚举名,或者验证填入数据的是否有效</li> <li>支持通过protobuf协议插件控制部分输出</li> <li>支持自动合表,把多个Excel数据表合并成一个输出文件</li> <li>支持公式</li> <li>支持oneof,支持plain模式输入字符串转为数组或复杂结构,支持map</li> <li>支持空数据压缩(裁剪)或保留定长数组</li> <li>支持基于正则表达式分词的字段名映射转换规则</li> <li>支持设置数据版本号</li> <li>Lua输出支持全局导出或导出为 <code>require</code> 模块或导出为 <code>module</code> 模块。</li> <li>Javascript输出支持全局导出或导出为 <code>nodejs</code> 模块或导出为 <code>AMD</code> 模块。</li> <li>提供CLI批量转换工具(支持python 2.7/python 3 @ Windows、macOS、Linux)</li> <li>提供GUI批量转换工具(支持Windows、macOS、Linux)</li> <li>CLI/GUI批量转换工具支持include来实现配置复用</li> </ul> <p><a href="https://xresloader.atframe.work/">xresloader</a> 包含了多个组件,其中最主要的部分分别是。</p>

2023/11/13
阅读更多

Opentelemetry社区在gRPC的几个链接问题(静态库和动态库混用,musl工具链,符号裁剪)

<h2 id="前言">前言</h2> <p><a href="https://github.com/open-telemetry/opentelemetry-cpp">opentelemetry-cpp</a> 在标准上报协议OTLP里是支持使用 <a href="https://github.com/grpc/grpc">gRPC</a> 作为传输协议的。但是,当 <a href="https://github.com/grpc/grpc">gRPC</a> 被作为静态库同时链接进多个动态库时,在一些平台上会有一些问题。这是 <a href="https://github.com/grpc/grpc">gRPC</a> 本身的一些实现方式导致的。 一直拖到今天才来比较完整得写这个问题的具体成因和解决方案,实际上也有一些其他库有相似实现的也会有相同的问题,所以分享出来看看有没有其他同学也可能碰到可以参考一下。</p>

2023/10/28
阅读更多

Excel转表工具(xresloader)的新验证器(验证外部Excel和文本数据,唯一性和自定义规则)

<h2 id="前言">前言</h2> <p><a href="https://xresloader.atframe.work/">xresloader</a> 是一组用于把Excel数据结构化并导出为程序可读的数据文件的导表工具集。它包含了一系列跨平台的工具、协议描述和数据读取代码。</p> <p>主要功能特点:</p> <ul> <li>跨平台(java 11 or upper)</li> <li>Excel =&gt; protobuf/msgpack/lua/javascript/json/xml</li> <li>完整支持协议结构,包括嵌套结构和数组嵌套</li> <li>同时支持protobuf proto v2 和 proto v3</li> <li>支持导出proto枚举值到lua/javascript代码和json/xml数据</li> <li>支持导出proto描述信息值到lua/javascript代码和json/xml数据(支持自定义插件,方便用户根据proto描述自定义反射功能)</li> <li>支持导出 UnrealEngine 支持的json或csv格式,支持自动生成和导出 UnrealEngine 的 <code>DataTable</code> 加载代码</li> <li>支持别名表,用于给数据内容使用一个易读的名字</li> <li>支持验证器,可以在数据里直接填写proto字段名或枚举名,或者验证填入数据的是否有效</li> <li>支持通过protobuf协议插件控制部分输出</li> <li>支持自动合表,把多个Excel数据表合并成一个输出文件</li> <li>支持公式</li> <li>支持oneof,支持plain模式输入字符串转为数组或复杂结构,支持map</li> <li>支持空数据压缩(裁剪)或保留定长数组</li> <li>支持基于正则表达式分词的字段名映射转换规则</li> <li>支持设置数据版本号</li> <li>Lua输出支持全局导出或导出为 <code>require</code> 模块或导出为 <code>module</code> 模块。</li> <li>Javascript输出支持全局导出或导出为 <code>nodejs</code> 模块或导出为 <code>AMD</code> 模块。</li> <li>提供CLI批量转换工具(支持python 2.7/python 3 @ Windows、macOS、Linux)</li> <li>提供GUI批量转换工具(支持Windows、macOS、Linux)</li> <li>CLI/GUI批量转换工具支持include来实现配置复用</li> </ul> <p><a href="https://xresloader.atframe.work/">xresloader</a> 包含了多个组件,其中最主要的部分分别是。</p>

2023/8/20
阅读更多

protobuf v22和gRPC v1.55版本升级的依赖变化和upb适配

<h2 id="前言">前言</h2> <p>近期的 <a href="https://github.com/protocolbuffers/protobuf">protobuf</a> v22和 <a href="https://github.com/grpc/grpc">gRPC</a> v1.55 版本在构建流程层面引入了一些比较大的变化。 最初我关注到这个问题是在我参与的一个社区项目 <a href="https://github.com/open-telemetry/opentelemetry-cpp">opentelemetry-cpp</a> 的issue中( <a href="https://github.com/open-telemetry/opentelemetry-cpp/issues/2095">https://github.com/open-telemetry/opentelemetry-cpp/issues/2095</a> )。 直到后来,我们在自己的构建系统 <a href="https://github.com/atframework/cmake-toolset">cmake-toolset</a> 对 <a href="https://github.com/protocolbuffers/protobuf">protobuf</a> 和 <a href="https://github.com/grpc/grpc">gRPC</a> 也进行了升级。所以顺带给社区的项目也提交了一些相关的Patch,在这里分享一下可能其他同学也会碰到。</p>

2023/6/17
阅读更多

关于protobuf近期版本(v20/v3.20+)和 gRPC v1.54版本在某些编译环境下的一些链接和编译问题

<h2 id="前言">前言</h2> <p>年初的时候我们项目组的构建系统( <a href="https://github.com/atframework/cmake-toolset">cmake-toolset</a> )里把 <a href="https://github.com/protocolbuffers/protobuf">protobuf</a> 升级到了 v20/v3.20 版本, <a href="https://github.com/grpc/grpc">gRPC</a> 也升级到了 v1.54 版本。然而这两个版本在Linux的ELF ABI和MacOS的Macho ABI下都出现了一些符号未定义的问题(当然也包含Android和iOS)。 这些问题也不仅限于 <a href="https://github.com/protocolbuffers/protobuf">protobuf</a> v20/v3.20 和 <a href="https://github.com/grpc/grpc">gRPC</a> v1.54,后续的版本有些修复了,有些没有。在官方完全修复之前,我们自己打了一些patch去修复这些问题。</p>

2023/6/16
阅读更多

xresloader-Excel导表工具链的近期变更汇总

<h2 id="前言">前言</h2> <p><a href="https://xresloader.atframe.work/">xresloader</a> 是一组用于把Excel数据结构化并导出为程序可读的数据文件的导表工具集。它包含了一系列跨平台的工具、协议描述和数据读取代码。</p> <p>主要功能特点:</p> <ul> <li>跨平台(java 11 or upper)</li> <li>Excel =&gt; protobuf/msgpack/lua/javascript/json/xml</li> <li>完整支持协议结构,包括嵌套结构和数组嵌套</li> <li>同时支持protobuf proto v2 和 proto v3</li> <li>支持导出proto枚举值到lua/javascript代码和json/xml数据</li> <li>支持导出proto描述信息值到lua/javascript代码和json/xml数据(支持自定义插件,方便用户根据proto描述自定义反射功能)</li> <li>支持导出 UnrealEngine 支持的json或csv格式,支持自动生成和导出 UnrealEngine 的 <code>DataTable</code> 加载代码</li> <li>支持别名表,用于给数据内容使用一个易读的名字</li> <li>支持验证器,可以在数据里直接填写proto字段名或枚举名,或者验证填入数据的是否有效</li> <li>支持通过protobuf协议插件控制部分输出</li> <li>支持自动合表,把多个Excel数据表合并成一个输出文件</li> <li>支持公式</li> <li>支持oneof,支持plain模式输入字符串转为数组或复杂结构,支持map</li> <li>支持空数据压缩(裁剪)或保留定长数组</li> <li>支持基于正则表达式分词的字段名映射转换规则</li> <li>支持设置数据版本号</li> <li>Lua输出支持全局导出或导出为 <code>require</code> 模块或导出为 <code>module</code> 模块。</li> <li>Javascript输出支持全局导出或导出为 <code>nodejs</code> 模块或导出为 <code>AMD</code> 模块。</li> <li>提供CLI批量转换工具(支持python 2.7/python 3 @ Windows、macOS、Linux)</li> <li>提供GUI批量转换工具(支持Windows、macOS、Linux)</li> <li>CLI/GUI批量转换工具支持include来实现配置复用</li> </ul> <p><a href="https://xresloader.atframe.work/">xresloader</a> 包含了多个组件,其中最主要的部分分别是。</p>

2023/4/18
阅读更多

打通游戏服务端框架的C++20协程改造的最后一环

<h2 id="前言">前言</h2> <p>我们终于在年初的时候最后完成了整体服务器框架对C++20协程的支持和接入。虽然之前陆陆续续抽时间改造一些组件,让它支持C++20协程,期间也记录了一些早期的设计思路和踩的坑(包括 <a href="https://owent.net/2020/2004.html">《libcopp接入C++20 Coroutine和一些过渡期的设计》</a>和<a href="https://owent.net/2022/2206.html">《libcopp对C++20协程的接入和接口设计》</a>),其中不乏一些C++20协程使用上可能打破我们常规思路细节和编译器的BUG。而且这些都是各个组件的改造,并没有最后整合到一起。</p>

2023/4/8
阅读更多

Opentelemetry-cpp的Logs模块标准更新(涉及近期版本:1.8-1.9的BREAK CHANGES)

<h2 id="背景">背景</h2> <p><a href="https://github.com/open-telemetry/opentelemetry-cpp">Opentelemetry-cpp</a> 是可观测领域,<a href="https://opentelemetry.io/">opentelemetry</a> (CNCF基金会孵化项目)的<a href="https://github.com/open-telemetry/opentelemetry-cpp">C++ SDK接入层</a>。 <a href="https://opentelemetry.io/">opentelemetry</a> 里面主要是分链路跟踪(Trace)、指标(Metrics)、日志(Logs)三大块。 同时 <a href="https://opentelemetry.io/">opentelemetry</a> 有一个标准规范文档 <a href="https://github.com/open-telemetry/opentelemetry-specification">opentelemetry-specification</a> ,而SDK实现主要就是来对这个标准规范文档的特定语言实现。 由于日志(Logs)这一块一直处于Experimental阶段,所以很长时间以来 <a href="https://github.com/open-telemetry/opentelemetry-cpp">C++ SDK接入层</a> 都没有及时更新跟进规范的变化。</p>

2023/2/25
阅读更多

给cmake-toolset和工具链(curl等)加HTTP/2和HTTP/3支持

<h2 id="前言">前言</h2> <p>前段时间集成一些公司内组件的时候发现它依赖 <a href="https://github.com/nghttp2/nghttp2.git">nghttp2</a> 。正好之前一直有给我的构建工具(<a href="https://github.com/atframework/cmake-toolset">cmake-toolset</a>)里的构建 <a href="https://github.com/curl/curl.git">curl</a> 的流程加 HTTP/2 和 HTTP/3 的计划。 所以这波一次性搞定了。</p> <h2 id="构建工具-cmake-toolset-和-curl">构建工具 <a href="https://github.com/atframework/cmake-toolset">cmake-toolset</a> 和 <a href="https://github.com/curl/curl.git">curl</a></h2> <p>首先,<a href="https://github.com/curl/curl.git">curl</a> 是支持多种第三方库作为 HTTP/2 和 HTTP/3(QUIC)算法库的。比如 <a href="https://github.com/ngtcp2/nghttp3.git">nghttp3</a>+<a href="https://github.com/ngtcp2/ngtcp2.git">ngtcp2</a>,或者微软家 <a href="https://github.com/microsoft/msquic">msquic</a>,或者Google家 <a href="https://github.com/google/quiche">quiche</a>。 其中HTTP/3只能选一个,互相是冲突的。而Google的<a href="https://github.com/google/quiche">quiche</a>官方仅有对bazel构建系统的支持,而我的<a href="https://github.com/atframework/cmake-toolset">cmake-toolset</a>是cmake生态的。 这里选用 <a href="https://github.com/ngtcp2/nghttp3.git">nghttp3</a>+<a href="https://github.com/ngtcp2/ngtcp2.git">ngtcp2</a> 的组合,主要是为了和其他的模块共享依赖。</p>

2023/1/30
阅读更多

又开新坑之 coredns 插件: nftables和filter

<h2 id="背景">背景</h2> <p>传说中的下一代 <a href="https://nftables.org/projects/iptables/index.html">iptables</a> 的 <a href="https://nftables.org/projects/nftables/index.html">nftables</a> 已经出来了好长时间了。现在主流发行版的内核也都已经更新到了对 <a href="https://nftables.org/projects/nftables/index.html">nftables</a> 支持足够好的版本。 在2年多前我也初步体验过了 <a href="https://nftables.org/projects/nftables/index.html">nftables</a> ,当时写了个 <a href="https://owent.net/2020/2002.html">《nftables初体验》</a> 。并且开始使用 <a href="https://nftables.org/projects/nftables/index.html">nftables</a> 来实现对家里软路由的管理。 而去年的时候,我也尝试用 <a href="https://nftables.org/projects/nftables/index.html">nftables</a> 实现了双拨(详见: <a href="https://owent.net/2021/2104.html">《折腾一下nftables下的双拨》</a>)并且可以搭配TPROXY透明代理使用。</p>

2022/10/3
阅读更多

关于opentelemetry-cpp社区对于C++ Head Only组件单例和符号可见性的讨论小记

<h2 id="前言">前言</h2> <p>前段时间有人在 <a href="https://github.com/open-telemetry/opentelemetry-cpp">opentelemetry-cpp</a> 提出了api组件在动态库中单例无法工作的 issue ,( <a href="https://github.com/open-telemetry/opentelemetry-cpp/issues/1520">https://github.com/open-telemetry/opentelemetry-cpp/issues/1520</a> ) 。</p> <blockquote> <p><a href="https://opentelemetry.io/">opentelemetry</a> 是可观测性领域的开源项目,目标是统一链路跟踪、数据指标和日志的服务、上报、协议和接口规范,目前属于 <a href="https://cncf.io/">CNCF基金会</a> 孵化项目。而 <a href="https://github.com/open-telemetry/opentelemetry-cpp">opentelemetry-cpp</a> 则是 <a href="https://opentelemetry.io/">opentelemetry</a> 中对标准规范SDK的C++实现。</p>

2022/10/2
阅读更多

填个转表工具 xresloader 去年的坑(数组尾部裁剪)

<h2 id="前言">前言</h2> <p><a href="https://github.com/xresloader/xresloader">xresloader</a> 是一个功能比较全面并且跨平台的Excel导出protobuf、msgpack、xml、lua、json、javascript、UE-Csv、UE-Json等数据格式的工具。 并且整个工具链还包含了基于模板引起生成读表代码的 <a href="https://github.com/xresloader/xres-code-generator">xres-code-generator</a> ,方便产品/策划使用的 <a href="https://github.com/xresloader/xresconv-gui">GUI批量执行工具 - xresconv-gui</a> 和方便CI集成和程序使用的 <a href="https://github.com/xresloader/xresconv-cli">命令行批量执行工具 - xresconv-cli</a>。</p>

2022/8/27
阅读更多

集成 upb 和 lua binding 的踩坑小记

<h2 id="前言">前言</h2> <p>最近新项目重新评估了一下protobuf的C/C++ -&gt; Lua binding 方案。之前,使用最广泛的 Lua binding 方案应该是 <a href="https://blog.codingnow.com/">云风</a> 的 <a href="https://github.com/cloudwu/pbc">pbc</a> 。但是这个库已经是作者弃坑好多年的状态了。我之前使用 <a href="https://github.com/cloudwu/pbc">pbc</a> 的时候刚碰上 protobuf 3.0 刚出来,当时打了patch来适配 protobuf 3.0 ,还修复了一些其他问题。这个Patch有些推给了上游,有些因为和上游的某些机制冲突没有推。我了解到的很多其他项目也或多或少的打了自己的Patch,大多数也没往上游推。基本上 <a href="https://github.com/cloudwu/pbc">pbc</a> 已经处于一个失维的状态,所以这次新项目就干脆来寻求更好,或者说仍然有良好活跃度的解决方案。于是就看向了 <a href="https://github.com/protocolbuffers/upb">upb</a> 。</p>

2022/8/20
阅读更多

libcopp对C++20协程的接入和接口设计

<h2 id="前言">前言</h2> <p>最近开的坑有点多。有点忙不过来了所以好久没写Blog了。这个C++20的协程接入一直在改造计划中,但是一直没抽出时间来正式实施。 在之前,我写过一个初版的C++20协程接入 <a href="https://owent.net/2020/2004.html">《libcopp接入C++20 Coroutine和一些过渡期的设计》</a> 。当时主要是考虑到 Rust也有和C++类似的历史包袱问题,所以参考了一些Rust协程改造过程中的设计。 但是后来尝试在项目中使用的时候发现还是有一些问题。首先C++20的协程并不是零开销抽象,所以强行用Rust的模式反而带来了一定开销和理解上的难度。其次原先的设计中 generator 是按类型去实现外部接入的。但是实际接入SDK的过程中我们有相当一部分类型相同但是接入流程不同的情况,再加上现在各大编译器也都已经让C++20协程的特性脱离 experimental 阶段了,有一些细节有所变化。所以干脆根据我们实际的使用场景,重新设计了下组织结构。</p>

2022/7/23
阅读更多

再度优化GCC、LLVM、Clang、libc++、libc++abi等套件的构建脚本

<h2 id="前言">前言</h2> <p>一直以来,我都维护了完整的 <a href="https://github.com/owent-utils/bash-shell/tree/main/GCC%20Installer">GCC 工具链构建工具</a> 和 <a href="https://github.com/owent-utils/bash-shell/tree/main/LLVM%26Clang%20Installer">LLVM,Clang,libc++,libc++abi工具链构建工具</a> 。 一方面是为了测试和体验新版本编译器的功能和利用一些更现代化的工具检查代码中的风险,另一方面也是为了给我得很多开源仓库做多版本适配。 其中所有的编译期依赖项(不包括 tar,awk等可执行程序的工具)都是自己构建的,这样也能管理好某些新版本组件需要的新版本依赖项,并且做到跨发行版兼容。同时很多发行版自带的 LLVM+Clang 套件都缺斤少两,有的缺少 <code>clang-analyzer</code> ,有的缺少 <code>clang-format</code> ,也有的缺少 <code>libc++</code> 和 <code>libc++abi</code> 或者缺少sanitizer组件。我也是根据自己的需要编译并输出了大多数开发工具,甚至还有一些开发库以便二次开发(比如用libclang写工具来复用libcang的AST功能)。</p>

2022/4/17
阅读更多

游戏服务的分布式事务优化(二)- 事务管理

<h2 id="前言">前言</h2> <p>接上文 <a href="https://owent.net/2022/2203.html">《游戏服务的分布式事务优化(一)- Write Ahead Log(WAL) 模块》</a></p> <p>在挺久以前我写过一篇分享 <a href="https://owent.net/2020/2005.html">《在游戏服务器中使用分布式事务》</a> 。当时尝试在我们的游戏服务中引入TCC模型的分布式事务机制,以优化好友和公会服务的一致性流程。 最开始的实现并不通用,后来我对这个事务的实现做了进一步的优化和重构,抽离成了较为通用的模块,并对之前没全部完成的功能做了进一步完善。 此篇为重构内容的第二部分,主要聚焦于事务管理。</p>

2022/4/17
阅读更多

游戏服务的分布式事务优化(一)- Write Ahead Log(WAL) 模块

<h2 id="前言">前言</h2> <p>在挺久以前我写过一篇分享 <a href="https://owent.net/2020/2005.html">《在游戏服务器中使用分布式事务》</a> 。当时尝试在我们的游戏服务中引入TCC模型的分布式事务机制,以优化好友和公会服务的一致性流程。 但是时间原因,但是写的第一版是深入我们当时的游戏业务的,第一版仅用在好友服上,既不通用测试也不完善。 后来逐渐把公会服务和聊天的功能也采用或部分采用这里的分布式事务的组件来实现,发现有大量的相似代码。 并且由于分布式事务的流程本身比较复杂,其他人接手的时候看起来就会比较吃力,所以我一直有计划重构这一块代码并且实现为更加通用且灵活的模块。 最近也是基本完成了这部分的工作,通用接口主要分为两部分。第一部分是 <strong>Write Ahead Log(WAL)</strong> 模块,第二部分是事务管理模块。 本此分享主要专注于第一部分 <strong>Write Ahead Log(WAL)</strong> 。</p>

2022/4/10
阅读更多

记录一些bazel适配用编译选项

<p>之前搞 <a href="https://github.com/open-telemetry/opentelemetry-cpp">opentelemetry-cpp</a> 的时候接触了下 <a href="https://bazel.build/">bazel</a> 构建系统。这玩意儿用起来有一点坑,特别是使用自定义编译环境的时候。</p> <p>在使用我自己编译的很新版本的 <a href="https://github.com/owent-utils/bash-shell/tree/main/GCC%20Installer">GCC</a> 和 <a href="https://github.com/owent-utils/bash-shell/tree/main/LLVM%26Clang%20Installer">clang+libc++</a> 的时候,涉及对libssp的检测和 <code>LD_LIBRARY_PATH</code> 环境变量在 <a href="https://bazel.build/">bazel</a> 中各个步骤中的传递,这里记录一下适配脚本。</p>

2022/2/14
阅读更多

测试现代化硬件C++浮点数性能和一致性

<h2 id="前言">前言</h2> <p>很久很久以前,浮点数的性能和跨平台跨硬件架构一致性是无法获得保证的,所以我们一般在需要强一致性和高性能的游戏服务器中会禁用浮点数,转而使用自己实现的定点数。 这么多年过去了,前段时间想看看现代化硬件下是否仍然有性能问题和是否能够保证一致性,做了些简单的测试,这里记录一下。</p>

2022/1/27
阅读更多

适配Boringssl和OpenSSL 3.0

<h2 id="前言">前言</h2> <p><a href="https://www.openssl.org/">openssl</a> 3.0发布好一阵子了,我的 <a href="https://github.com/atframework/atframe_utils">atframe_utils</a> 其实也挺早前就完成了对 <a href="https://www.openssl.org/">openssl</a> 3.0 和 <a href="https://github.com/google/boringssl">boringssl</a> 的适配。但是由于懒,一直没写这篇文章。在升级 [openssl] 3.0 和 <a href="https://github.com/google/boringssl">boringssl</a> 还是碰到了一些问题的,有些是由于接口变化,有些是由于功能支持还有些也和构建系统相关。还是有必要记录一下,至少能方便以后查找。</p>

2021/12/12
阅读更多

近期cmake-toolset的一些适配问题

<h2 id="前言">前言</h2> <p>偷懒了好久没有写分享了,最近的时间也是花费了很多时间大量优化了之前游戏服务器框架和组件的很多细节。其中,相对独立且同时也被其他的项目使用的一个工具则是基于 <a href="https://cmake.org/">cmake</a> 和 <a href="https://git-scm.com/">git</a> 且兼容 <a href="https://vcpkg.io">vcpkg</a> 的构建系统 <a href="https://github.com/atframework/cmake-toolset/">cmake-toolset</a> 。之所以要写这么个构建工具主要是要提供比 <a href="https://vcpkg.io">vcpkg</a> 更宽容的兼容性(没办法我们公司的编译环境比较古老),并且提供更进一步的定制化能力(包含但不限于功能开关和下载源,这些东西 <a href="https://vcpkg.io">vcpkg</a> 也是很后期才有了个初步的支持)。那么先来记录一下构建系统适配过程中的一些问题吧。</p>

2021/12/5
阅读更多

C++20 Text Formatting/fmtlib 适配问题小记

<h2 id="前言">前言</h2> <p>C++20 正式发布已经有一段时间了。其中 <code>Text Formatting</code> 是一个我个人比较感兴趣的新组件。它主要是解决了之前字符串格式化库 ( <code>printf</code> 系 ) 的效率问题和运行时安全的问题。 并且新的格式设置的形式也比较友好。相关规范和用法可以参见:</p> <ul> <li><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p0645r10.html#format.formatter">http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p0645r10.html#format.formatter</a></li> <li><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p2216r3.html">http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p2216r3.html</a></li> <li><a href="https://en.cppreference.com/w/cpp/utility/format">https://en.cppreference.com/w/cpp/utility/format</a></li> </ul> <p>在C++ 20能够普及以前,我们可以用 <a href="https://fmt.dev/">fmtlib</a> 这个库来完成一样的功能。实际上我们项目组已经在这么做了。在使用 <a href="https://fmt.dev/">fmtlib</a> 之前,比如我们按玩家打日志大概是这种形式。</p>

2021/9/5
阅读更多

再次重构LLVM+Clang+libcxx+libc++abi+其他相关工具的构建流程

<h2 id="背景">背景</h2> <p>我们有时候写一些基础性类库或者实验新功能的时候,常常需要使用到最新版本的GCC和Clang。一些Linux发行版的源里和一些工具链(比如MSYS2)里其实自带LLVM套件的包,<a href="https://llvm.org/">LLVM</a> 官网也提供一些常见平台的预编译包下载。 那为什么我们还要自己编译呢?如果有注意到的小伙伴可能会发现,很多平台的源和 <a href="https://llvm.org/">LLVM</a> 官网 里下载的预编译包,其实是缺失很多组件的。有些没有libc++和libc++abi(CentOS 8),有些没有Sanitizer相关的组件,有些缺失其他的组件。而Clang虽然支持GCC的libstdc++,但是一方面我们写基础性类库还是要优先考虑原生STL库的兼容性,另一方面Clang对libstdc++的支持也不是太好,特别是有些第三方库在这个组合下也是没有适配得很好,同时gdb和libc++的搭配有时候也不是很完善。 所以我们就需要一个组件尽可能开完整地包含LLVM,Clang,libc++,libc++abi还有其他周边工具(各类Sanitizer,clang-tiny,clang-analyzer等等)的工具链。</p>

2021/8/29
阅读更多

重构基于CMake的构建工具链

<h2 id="背景">背景</h2> <p>对大型项目来说,必然会有很多的依赖项。特别是现代化的组件都会尝试去复用社区资源。而对于C/C++而言,依赖管理一直是一个比较头大的问题。 很多老式的系统和工具都会尝试去走相对标准化的安装过程,比如说用 <a href="https://linux.die.net/man/1/pkg-config">pkg-config</a> 或者用系统自带的包管理工具装在系统默认路径里。 当然这样很不方便,也不容易定制组件。我使用 <a href="https://cmake.org/">cmake</a> 比较多,所以一直以来在我的 <a href="https://github.com/atframework">atframework</a> 项目集中有一个 utility 项目 <a href="https://github.com/atframework/atframe_utils">atframe_utils</a>,里面包含一些常用的构建脚本。 并且在 <a href="https://github.com/atframework/atsf4g-co">atsf4g-co</a> 中实现了一些简单的包管理和构建流程。</p>

2021/6/5
阅读更多

新版GCC和LLVM+Clang终于Release啦

<p>可能是疫情的原因,GCC好久没发布啦。最近总于又Release了,还是大版本。并且三大编译器对C++20的支持也都七七八八了。所以特意立贴庆祝一下,顺带更新一波构建脚本把这两年的一些改动列举一下。</p> <h2 id="gcc编译">GCC编译</h2> <p>构建脚本的主要变化如下:</p>

2021/5/16
阅读更多

折腾一下nftables下的双拨

<h2 id="背景">背景</h2> <p>我们小区终于有联通线路啦,之前一直用的联通的手机号。它套餐满一定额度以后送一条宽带,本着不用白不用的精神,那必须不能浪费。还好我之前设置软路由得时候就预留了两个网口作wan,所以新增得联通得线路直接插那个口上就行了。(吐槽一下联通给得光猫竟然是8年前生产的老古董)</p>

2021/5/16
阅读更多

[C++20] Module partitions和符号交叉引用(声明和实现分离)

<p>C++20 开始支持 <strong>Module</strong> 了。在以前C++为了解决循环依赖问题,经常会把类或者函数声明写前面,实现写后面。然后中间的代码就可以实现内部模块的内聚而互相引用。比如:</p> <pre><code class="language-cpp">class foo; void bar(foo*); class foo { public: foo(){ bar(this); } };</code></pre> <p>那么在 <strong>Module</strong> 里怎么处理这种需求呢?其实我之前一直只是知道有这么个东西,并没有深入研究过。前段时间看到公司论坛里有同学问,就现学了并且试了一下,以下是一些记录。</p>

2021/3/25
阅读更多

[Rust] 实现一个线程安全且迭代器可以保存的链表

<h2 id="背景">背景</h2> <p>今年有个想法,重新设计 <a href="https://github.com/atframework/libatbus">libatbus</a> 然后用 <a href="https://www.rust-lang.org/">Rust</a> 实现出来,然后可以加入一些云原生的支持。这需要一个定时器模块,我看了下 <a href="https://www.rust-lang.org/">Rust</a> 现有的几种定时器的实现,大多是基于堆或树的结构的,没有找到jiffies定时器的实现,所以想自己实现一个算了。这个定时器的实现又需要类似 C++ 的 <code>std::list::iterator</code> 的 <strong>插入和删除某个迭代器对其他迭代器没有影响</strong> 的特性,但是 <a href="https://www.rust-lang.org/">Rust</a> 的数据结构都不是这种设计模型。所以就决定自己写一个吧。</p>

2021/3/9
阅读更多

基于protobuf的代码生成

<h2 id="前言">前言</h2> <p>前段时间我用 <a href="https://www.python.org/">Python</a> 和 <a href="https://www.makotemplates.org/">Mako</a> 模板引擎重新梳理了我们项目中的一些重复的流程。重构了所有的RPC系统。这个工作其实完成了挺久了,但是迫于懒一直拖着没写完这篇记录,就一直没发。</p> <p>使用代码生成工具实现RPC模块还是比较有成效的事情,有助于统一API接口,也有利于部分组件模块化,修改和重构内部实现也会比较方便。业内已有的代码生成实现也比较多,但是多是针对特定系统和框架实现的,如果要接入其他框架或者说接入多种SDK的流程并不是很方便。我这次的实现一方面是针对我们内部的服务提供类似很多RPC系统也提供的内部接口、实现和注册流程的标准化,另一方面也是尽可能灵活且通用一些,可以用于接入外部的SDK。</p>

2021/2/9
阅读更多

几个使用protobuf中C++接口的Arena的坑

<h2 id="前言">前言</h2> <p><a href="https://github.com/protocolbuffers/protobuf">protobuf</a> 从3.0版本开始对C++增加了Arena接口,可以用于使用连续的内存块分配内部对象,并且可以更容易精确地控制对象地生命周期,最终达到减少内存碎片地目的。最近我给我们项目的部分接口流程进行相关地改造,在大多数使用 <a href="https://github.com/protocolbuffers/protobuf">protobuf</a> 的地方都增加了对Arena的支持,但是在接入过程中也碰到了一些问题和坑。</p>

2020/11/10
阅读更多

Amazon Aurora DB存储引擎论文阅读小记

<h2 id="前言">前言</h2> <p>前段时间接触到腾讯云的一个新数据库产品 <a href="https://cloud.tencent.com/product/cynosdb">CynosDB</a> 是基于 <a href="https://aws.amazon.com/rds/aurora/">Amazon Aurora</a> 数据库的Paper实现的。我比较感兴趣就来看看它和之前看过的 <a href="https://ai.google/research/pubs/pub39966" title="Spanner: Google's Globally-Distributed Database">Spanner</a> 之类有什么不同,也许部分设计也能用在我们游戏业务的服务器中。它的主要的创新点在于重新设计了binlog和存储的部分,所以我也主要就看了两篇Paper: <a href="https://media.amazonwebservices.com/blog/2017/aurora-design-considerations-paper.pdf" title="Amazon Aurora: Design Considerations for High Throughput Cloud-Native Relational Databases">《Amazon Aurora - Design Considerations for High Throughput Cloud-Native Relational Databases》</a> 是一个整体性质的介绍和概述; <a href="https://dl.acm.org/doi/abs/10.1145/3183713.3196937" title="Amazon Aurora: On Avoiding Distributed Consensus for I/Os, Commits, and Membership Changes">《Amazon Aurora: On Avoiding Distributed Consensus for I/Os,Commits, and Membership Changes》</a> 是对其重点部分的存储服务的。</p>

2020/11/7
阅读更多

近期对libatapp的一些优化调整(增加服务发现和连接管理,支持yaml等)

<p>最近给 <a href="https://github.com/atframework/libatapp">libatapp</a> 增加了一系列改造,非常多且琐碎,这里简单记录下吧。</p> <p>首先是重构了配置管理。原来是手写在代码里的,因为原来上层的 <a href="https://github.com/atframework/libatbus">libatbus</a> 是不依赖 <a href="https://github.com/protocolbuffers/protobuf">protobuf</a> 的,现在 既然已经依赖 <a href="https://github.com/protocolbuffers/protobuf">protobuf</a> 了就转为 <a href="https://github.com/protocolbuffers/protobuf">protobuf</a> 管理了。同时现在还支持YAML配置,使用 <a href="https://github.com/jbeder/yaml-cpp">yaml-cpp</a> 来解析YAML文件,这个库也被一些其他知名的大型项目使用了,比如 <a href="https://www.envoyproxy.io/">Envoy proxy</a> 。 原来的conf/ini模式的配置也是支持的,现在加载配置的时候会尝试猜测以下配置文件是yaml还是conf/ini模式。 并且增加了统一的 <em>YAML转<a href="https://github.com/protocolbuffers/protobuf">protobuf</a></em> 、 <em>conf/ini转<a href="https://github.com/protocolbuffers/protobuf">protobuf</a></em> 和 <em>指定层级配置导出到<a href="https://github.com/protocolbuffers/protobuf">protobuf</a></em> 的接口来方便使用。比较特殊的是自定义日志配置后端的接入接口有了一些小变化,问题也不大。</p>

2020/10/4
阅读更多

xresloader转表工具链增加了一些新功能(map,oneof支持,输出矩阵,基于模板引擎的加载代码生成等)

<p><a href="https://github.com/xresloader/xresloader">xresloader</a> 是一组用于把Excel数据结构化并导出为程序可读的数据文件的导表工具集。它包含了一系列跨平台的工具、协议描述和数据读取代码。支持把Excel配置输出成 protobuf二进制、xml、json、lua、javascript、nodejs、msgpack、<a href="https://www.unrealengine.com/">UE</a>的Json格式及支持蓝图的代码、<a href="https://www.unrealengine.com/">UE</a>的Csv格式及支持蓝图的代码。</p>

2020/8/29
阅读更多

在游戏服务器中使用分布式事务

<h2 id="前言">前言</h2> <p>游戏业务通常有个特点是模块相关性非常高,模块之间的联动也非常密集且复杂。要保持各个相关模块的数据一致性,同时又兼顾效率和,没有一个通用的方法。通常的做法是走有损服务(也叫柔性服务)和自动修复的方式。比如支付服务一般的做法是在2PC的基础上增加redo log,对于发放和订单确认这两方,如果失败了会尝试几次补发。又或者好友系统或者公会,因为涉及多个对象的数据相互索引,一些做法是玩家在线的时候定期去检查数据是否正确,如果不正确走修复流程。</p>

2020/6/27
阅读更多

libcopp接入C++20 Coroutine和一些过渡期的设计

<h2 id="前言">前言</h2> <p>最近GCC 10.1.0 发布,三大编译器(MSVC、GCC、Clang)都已经支持了<a href="https://en.cppreference.com/w/cpp/language/coroutines">C++20协程</a>,之前给 <a href="https://github.com/owent/libcopp/">libcopp</a> 接入 <a href="https://en.cppreference.com/w/cpp/language/coroutines">C++20协程</a> 的计划也就提上了日程。<a href="https://en.cppreference.com/w/cpp/language/coroutines">C++20协程</a> 在创建、切换开销和内存分配上和传统有栈协程相比有着无可比拟的优势。但是C++20全面普及还有相当长一段时间,所以我们设计的重要目标之一就是能够让以后的迁移更容易且更平滑地进行,本文则是记录了 <a href="https://github.com/owent/libcopp/">libcopp</a> 接入 <a href="https://en.cppreference.com/w/cpp/language/coroutines">C++20协程</a> 时地一些性能上和平滑接入上的思考和成果。</p>

2020/5/22
阅读更多

libatbus 的大幅优化

<p>最近零碎的事太多了,拖了好久没写blog。一些小的碎片话的东西也不值得写,另一方面是这次大幅优化了 <a href="https://github.com/atframework/">atframework</a> 的一些流程细节,特别是针对我们这两年来业务的需求,对 <a href="https://github.com/atframework/libatbus">libatbus</a> 进行了一次大重构。这里记录一下重构的内容吧。</p> <h2 id="重构工程配置脚本">重构工程配置脚本</h2> <p>为了拥抱Modern CMake,我对 <a href="https://github.com/atframework/">atframework</a> 中所有的项目(当然也包含 <a href="https://github.com/atframework/libatbus">libatbus</a> )进行了重构,主要是一方面重构整理最近几个项目编译和交叉编译 <a href="https://www.openssl.org/">openssl</a> , <a href="https://github.com/protocolbuffers/protobuf">protobuf</a> 等几个构建流程比较恶心的库的自动化构建流程和工具脚本。如果不追求全部功能的话,还可以用 <a href="https://www.libressl.org/">libressl</a> 来代替 <a href="https://www.openssl.org/">openssl</a> 。也合并适应了给客户端用的交叉编译iOS、Android、<a href="https://www.unrealengine.com">Unreal Engine</a>等平台使用的构建流程。</p>

2020/4/16
阅读更多

nftables初体验

<h2 id="前言">前言</h2> <p>之前耳闻 <a href="https://nftables.org/projects/nftables/index.html">nftables</a> 是下一代 <a href="https://nftables.org/projects/iptables/index.html">iptables</a> 。前段时间配了一台主机,折腾成家里的软路由。就一并来尝鲜一系列新东西,其中就包括 <a href="https://nftables.org/projects/nftables/index.html">nftables</a> 。<a href="https://nftables.org/projects/nftables/index.html">nftables</a> 和 <a href="https://nftables.org/projects/iptables/index.html">iptables</a> 、<a href="http://ebtables.netfilter.org/">ebtables</a> 等一样,都是对底层 xtables 的封装,目前看来 <a href="https://nftables.org/projects/nftables/index.html">nftables</a> 比 <a href="https://nftables.org/projects/iptables/index.html">iptables</a> 更简洁易用,更易读,更容易理解,扩展性和也更好。但是目前各个发行版中对 <a href="https://nftables.org/projects/nftables/index.html">nftables</a> 的支持还比较参差不齐,导致 <a href="https://nftables.org/projects/nftables/index.html">nftables</a> 很多功能比 <a href="https://nftables.org/projects/iptables/index.html">iptables</a> 还是有所缺失,所以个人感觉短期内还是替代不了 <a href="https://nftables.org/projects/iptables/index.html">iptables</a> (比如 tproxy 功能需要 linux kernel 4.19+, 而即便是 <a href="https://www.centos.org/">CentOS 8</a> 的内核版本也只是 4.18 ,所以都不支持 )。 <a href="https://nftables.org/projects/nftables/index.html">nftables</a> 所支持的功能列表及所以来的内核版本和内核模块可以在这里找到 <a href="https://wiki.nftables.org/wiki-nftables/index.php/Supported_features_compared_to_xtables">https://wiki.nftables.org/wiki-nftables/index.php/Supported_features_compared_to_xtables</a> 。</p>

2020/2/10
阅读更多

容器配置开发环境小计

<h2 id="前言">前言</h2> <p>这段时间折腾了好久容器搭建开发环境和家里软路由趟的一些坑。这里先记录一下使用容器搭开发环境的一些流程和问题。</p> <p>开发环境一般里面会包含很多的工具和开启一些服务。 我自己的环境测试和搭建了 <a href="https://ubuntu.com/">ubuntu</a> 、 <a href="https://centos.org/">centos</a> 、 <a href="https://www.archlinux.org/">archlinux</a> 。 开启了 <a href="https://en.wikipedia.org/wiki/Systemd">systemd</a> , 支持网络代理+vscode远程开发, 支持 <a href="https://www.docker.com/">docker</a> 和 <a href="https://podman.io/">podman</a> ,支持k8s,开启了 sshd 。 所有的构建脚本及 Dockerfile 都放在 <a href="https://github.com/owent-utils/docker-setup">https://github.com/owent-utils/docker-setup</a> 了,有需要的小伙伴可以自取。</p>

2020/1/19
阅读更多

PALM Tree - 适合多核并发架构的B+树 - 论文阅读小记

<h2 id="介绍">介绍</h2> <p>年初的时候再知乎上看到有人分享 <a href="http://www.vldb.org/pvldb/vol4/p795-sewall.pdf" title="PALM: Parallel Architecture-Friendly Latch-FreeModifications to B+ Trees on Many-Core Processors"><strong>PALM树</strong></a> 树的文章,看简介是专为多核并发而设计的树形结构。比较好奇所以抽时间来看了看它的设计原理和是如合做到高并发的。</p> <p>首先按照论文里介绍的 <a href="http://www.vldb.org/pvldb/vol4/p795-sewall.pdf" title="PALM: Parallel Architecture-Friendly Latch-FreeModifications to B+ Trees on Many-Core Processors"><strong>PALM树</strong></a> 的特性:</p>

2019/11/2
阅读更多

跨平台协程库 - libcopp 简介

<p>前段时间有同事联系我想看看可能推广我之前写的协程库 <a href="https://github.com/owent/libcopp">libcopp</a>,虽然 <a href="https://github.com/owent/libcopp">libcopp</a> 已经用到过好几个项目上,这几年也断断续续地写了一些实现细节的文章,但是也但确实需要系统、概览性地介绍下 <a href="https://github.com/owent/libcopp">libcopp</a> ,所以就有了这篇文章。</p> <p>Github: <a href="https://github.com/owent/libcopp">https://github.com/owent/libcopp</a> Document: <a href="https://libcopp.atframe.work/">https://libcopp.atframe.work/</a></p> <h2 id="libcopp-的由来"><a href="https://github.com/owent/libcopp">libcopp</a> 的由来</h2> <p>协程的概念并不是什么非常新颖的东西,最早有做 <a href="https://github.com/owent/libcopp">libcopp</a> 的想法的时候,是听了微信分享的 <a href="https://github.com/Tencent/libco">libco</a> 。但是我们游戏业务里大部分的实现都还是走的事务和Task/Step的模型,特别是C++上异步调用非常不直观。而这种协程的方法可以比较容易地把接口设计得很简洁,而且后续的功能集成上也很容易不破坏原有的API约定,还有微信这么大的业务背书,我们就想在游戏业务里也使用这种方案。我们先是预研了一些类似的方案,但是都不是特别满意。</p>

2019/10/22
阅读更多

C++20 Coroutine 性能测试 (附带和libcopp/libco/libgo/goroutine/linux ucontext对比)

<h2 id="前言">前言</h2> <p>之前写了 <a href="https://owent.net/2018/1806.html">《协程框架(libcopp)v2优化、自适应栈池和同类库的Benchmark对比》</a> 和 <a href="https://owent.net/2019/1904.html">《C++20 Coroutine》</a> ,但是一直没写 <a href="https://en.cppreference.com/w/cpp/language/coroutines">C++20 Coroutine</a> 的测试报告。</p> <p>现在的草案版本比我当时写 <a href="https://owent.net/2019/1904.html">《C++20 Coroutine》</a> 的时候有了一点点更新,<a href="https://en.cppreference.com/w/cpp/language/coroutines">cppreference</a> 上有文档了(<a href="https://en.cppreference.com/w/cpp/language/coroutines">https://en.cppreference.com/w/cpp/language/coroutines</a>) 。里面列举的标准文档是<a href="https://owent.net/2019/1904.html">P0912R5</a>,这个文档目前还没完工,详情可以看他的来源<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/n4775.pdf">N4775</a>。不过内容上暂时还没有太大的变化,今天我就照着之前的方式来benchmark一波 <a href="https://en.cppreference.com/w/cpp/language/coroutines">C++20 Coroutine</a> 吧。</p> <h2 id="压力测试机环境">压力测试机环境</h2> <p>为了方便比较,我更新了一下之前在 <a href="https://owent.net/2018/1806.html">《协程框架(libcopp)v2优化、自适应栈池和同类库的Benchmark对比》</a> 里的测试项目的版本。Windows环境仅仅是为了测试MSVC下的性能,因为GCC还不支持所以Linux下是使用Clang编译的。</p>

2019/10/5
阅读更多

尝鲜Github Action

<h2 id="前言">前言</h2> <p><a href="https://github.com/features/actions">Github Action</a> 上线有一阵子了,大概两周前我的所有账号也是都陆陆续续开发了beta测试的权限。然后就来研究了下这个新的 CI 系统是怎么回事。看介绍,和之前碰到的一些CI系统不太一样的地方是,<a href="https://github.com">Github</a>是做了一个商店的功能。这样大家就可以自己定义自己的Action,然后方便别人复用。同时也可以统一自己的或者组织在构建过程中的一些公共流程。</p> <p>目前 <a href="https://github.com/features/actions">Github Action</a> 的文档还是不是特别的齐全,有些东西找起来比较费劲,还要参考下别人写的成品来理解。我是先试着用 <a href="https://github.com/features/actions">Github Action</a> 来发布我的blog,然后想给 <a href="https://github.com/xresloader/xresloader">xresloader</a> 的自动发布也改成 <a href="https://github.com/features/actions">Github Action</a> ,但是找了一圈发现没有合适的已有的Action,就自己写了一个。功能类似 <a href="https://travis-ci.org">travis-ci</a> 的 Github Release Deployment,发布到了商店: <a href="https://github.com/marketplace/actions/uploadtogithubrelease">https://github.com/marketplace/actions/uploadtogithubrelease</a></p>

2019/9/21
阅读更多

一些xresloader(转表工具)的改进

<h2 id="前言">前言</h2> <p>最近有几个其他项目组的童鞋给我之前的 <a href="https://xresloader.atframe.work/">转表工具链-xresloader</a> 提了几个需求。然后我也根据我们近期一些需求点对转表工具链一起给这套工具做了点功能增强和细节上的一些改进。 这篇blog差不多是这些东西的 CHANGELOG了吧。</p> <h2 id="插件和协议和ci">插件和协议和CI</h2> <p>对一些复杂的需求,使用protobuf插件机制比配置在excel里描述能力要强的多。所以近期大多的新功能都是由插件配置的。但是以前 <a href="https://github.com/xresloader/xresloader">转表引擎-xresloader</a> 的发布流程里只包含输出的jar,协议得去对应源码包里找。另外一个童鞋报给我说找 <a href="https://github.com/">github</a> 的release里的源码包似乎并不支持git lfs,解出来的git lfs文件只有一个版本号,所以我给CI的发布流程里加了对应版本的protocol文件的打包,当然也包括插件的protocol。</p>

2019/9/11
阅读更多

protobuf、flatbuffer、msgpack 针对小数据包的简单对比

<h2 id="前言">前言</h2> <p>前段时间我尝试给 <a href="https://github.com/atframework/">atframework</a> 的 <a href="https://github.com/atframework/libatapp">libatapp</a> 整合进UnrealEngine做Dedicated Server和逻辑server通信的时候碰到了一些问题。主要在于这些客户端引擎一般来说默认都是关闭exception的甚至会关闭RTTI。而 <a href="https://github.com/atframework/libatapp">libatapp</a> 所依赖的通信组件 <a href="https://github.com/atframework/libatbus">libatbus</a> 里内部协议是<a href="https://msgpack.org/">msgpack</a> , 而 <a href="https://msgpack.org/">msgpack</a> 的官方 C++ 的header only的实现是必须开异常的功能的。所以我近期打算抽空增强一波 <a href="https://github.com/atframework/libatbus">libatbus</a> 的功能,增加一些跨版本向前向后兼容功能,和一些简单的验证功能(仅仅是为了防止误操作导致的问题)。具体的变更等我弄完了再发一篇。</p>

2019/8/3
阅读更多

协程框架(libcopp) 小幅优化

<p>最近抽空继续对 <a href="https://github.com/owent/libcopp">libcopp</a> 进行了更新和小幅优化。 首先的Merge了 <a href="https://www.boost.org/libs/context/">boost.context</a> 1.70.0 。这次<a href="https://www.boost.org/libs/context/">boost.context</a>的更新似乎和它写进 <a href="https://www.boost.org/users/history/version_1_70_0.html">CHANGELOG</a> 里的并不完全一致,匹配的只看到 macho 架构的脏数据操作。 不过另外它增加了新的平台支持 mips64,我目前还是简单导入了,但是平台检测工具还没有写,如果要使用是可以通过编译参数切过去的,不过我感觉没人会这么用吧?我自己用都得看一下之前怎么写的。</p>

2019/6/22
阅读更多

Excel转表工具(xresloader) 增加protobuf插件功能和集成 UnrealEngine 支持

<h1 id="前言">前言</h1> <p>我们项目组最近在学习UE,然后就涉及导表这个东东。之前我已经做过一个功能比较全面并且跨平台的Excel导出protobuf、msgpack、xml、lua、json、javascript等的工具 <a href="http://github.com/xresloader/">xresloader</a> 。并且做了方便服务器集成的CLI工具和方便策划、前端用的GUI工具。那么这次很自然地就让它能够导出UE所支持的内容就行了。然后额外增加了基于protobuf插件形式的多key索引和自动生成一些支持蓝图和非蓝图的常用接口代码。</p>

2019/6/8
阅读更多

Anna(支持任意扩展和超高性能的KV数据库系统)阅读笔记

<h1 id="前言">前言</h1> <p>年前被同事安利了这个分布式最终一致性的存储系统 <a href="http://db.cs.berkeley.edu/jmh/papers/anna_ieee18.pdf">Anna</a> 。初略看了一眼Paper,似乎很是牛X。说是支持任意规模的扩展,并且性能不低于 <a href="https://github.com/fastio/pedis">pedis</a>。于是抽空来看看并了解下这套系统的设计特点和这种夸张的单机性能和扩展性的来源。</p> <h1 id="主流分布式kvs的比较">主流分布式KVS的比较</h1> <table> <thead> <tr> <th>系统名词</th> <th>扩容设计</th> <th>内存模型</th> <th>针对单个Key的一致性策略</th> <th>针对多个Key一致性策略</th> </tr> </thead> <tbody> <tr> <td>Masstree</td> <td>多核</td> <td>共享内存</td> <td><a href="https://en.wikipedia.org/wiki/Linearizability"><strong>线性(Linearizable)</strong></a></td> <td>无</td> </tr> <tr> <td>Bw-tree</td> <td>多核</td> <td>共享内存</td> <td><a href="https://en.wikipedia.org/wiki/Linearizability"><strong>线性(Linearizable)</strong></a></td> <td>无</td> </tr> <tr> <td>PALM</td> <td>多核</td> <td>共享内存</td> <td><a href="https://en.wikipedia.org/wiki/Linearizability"><strong>线性(Linearizable)</strong></a></td> <td>无</td> </tr> <tr> <td>MICA</td> <td>多核</td> <td>共享内存</td> <td><a href="https://en.wikipedia.org/wiki/Linearizability"><strong>线性(Linearizable)</strong></a></td> <td>无</td> </tr> <tr> <td>Redis</td> <td>单核</td> <td>N/A</td> <td><a href="https://en.wikipedia.org/wiki/Linearizability"><strong>线性(Linearizable)</strong></a></td> <td><a href="https://en.wikipedia.org/wiki/Serializability"><strong>串行化(Serializable)</strong></a></td> </tr> <tr> <td>COPS, Bolt-on</td> <td>分布式</td> <td>消息队列</td> <td><a href="https://en.wikipedia.org/wiki/Eventual_consistency"><strong>最终一致性(Eventual)</strong></a></td> <td><a href="https://en.wikipedia.org/wiki/Causal_consistency"><strong>因果一致性(Causal)</strong></a></td> </tr> <tr> <td>Bayou</td> <td>分布式</td> <td>消息队列</td> <td><a href="https://en.wikipedia.org/wiki/Eventual_consistency"><strong>最终一致性(Eventual)</strong></a>, 单调读/写, <a href="http://www.dbms2.com/2010/05/01/ryw-read-your-writes-consistency/"><strong>Read Your Writes</strong></a></td> <td><a href="https://en.wikipedia.org/wiki/Eventual_consistency"><strong>最终一致性(Eventual)</strong></a></td> </tr> <tr> <td>Dynamo</td> <td>分布式</td> <td>消息队列</td> <td><a href="https://en.wikipedia.org/wiki/Linearizability"><strong>线性(Linearizable)</strong></a>, <a href="https://en.wikipedia.org/wiki/Eventual_consistency"><strong>最终一致性(Eventual)</strong></a></td> <td>无</td> </tr> <tr> <td>Cassandra</td> <td>分布式</td> <td>消息队列</td> <td><a href="https://en.wikipedia.org/wiki/Linearizability"><strong>线性(Linearizable)</strong></a>, <a href="https://en.wikipedia.org/wiki/Eventual_consistency"><strong>最终一致性(Eventual)</strong></a></td> <td>无</td> </tr> <tr> <td>PNUTS</td> <td>分布式</td> <td>消息队列</td> <td>线性写, 单调读</td> <td>无</td> </tr> <tr> <td>CouchDB</td> <td>分布式</td> <td>消息队列</td> <td><a href="https://en.wikipedia.org/wiki/Eventual_consistency"><strong>最终一致性(Eventual)</strong></a></td> <td>无</td> </tr> <tr> <td>Voldemort</td> <td>分布式</td> <td>消息队列</td> <td><a href="https://en.wikipedia.org/wiki/Linearizability"><strong>线性(Linearizable)</strong></a>, <a href="https://en.wikipedia.org/wiki/Eventual_consistency"><strong>最终一致性(Eventual)</strong></a></td> <td>无</td> </tr> <tr> <td>HBase</td> <td>分布式</td> <td>消息队列</td> <td><a href="https://en.wikipedia.org/wiki/Linearizability"><strong>线性(Linearizable)</strong></a></td> <td>无</td> </tr> <tr> <td>Riak</td> <td>分布式</td> <td>消息队列</td> <td><a href="https://en.wikipedia.org/wiki/Eventual_consistency"><strong>最终一致性(Eventual)</strong></a></td> <td>无</td> </tr> <tr> <td>DocumentDB</td> <td>分布式</td> <td>消息队列</td> <td><a href="https://en.wikipedia.org/wiki/Eventual_consistency"><strong>最终一致性(Eventual)</strong></a>, <a href="https://www.allthingsdistributed.com/2007/12/eventually_consistent.html"><strong>Session</strong></a>, <a href="http://pbs.cs.berkeley.edu/"><strong>Bounded Staleness</strong></a>, <a href="https://en.wikipedia.org/wiki/Linearizability"><strong>线性(Linearizable)</strong></a></td> <td>无</td> </tr> <tr> <td>Memcached</td> <td>多核&amp;分布式</td> <td>共享内存&amp;消息队列</td> <td><a href="https://en.wikipedia.org/wiki/Linearizability"><strong>线性(Linearizable)</strong></a></td> <td>无</td> </tr> <tr> <td>MongoDB</td> <td>多核&amp;分布式</td> <td>共享内存&amp;消息队列</td> <td><a href="https://en.wikipedia.org/wiki/Linearizability"><strong>线性(Linearizable)</strong></a></td> <td>无</td> </tr> <tr> <td>H-Store</td> <td>多核&amp;分布式</td> <td>消息队列</td> <td><a href="https://en.wikipedia.org/wiki/Linearizability"><strong>线性(Linearizable)</strong></a></td> <td><a href="https://en.wikipedia.org/wiki/Serializability"><strong>串行化(Serializable)</strong></a></td> </tr> <tr> <td>ScyllaDB</td> <td>多核&amp;分布式</td> <td>消息队列</td> <td><a href="https://en.wikipedia.org/wiki/Linearizability"><strong>线性(Linearizable)</strong></a>, <a href="https://en.wikipedia.org/wiki/Eventual_consistency"><strong>最终一致性(Eventual)</strong></a></td> <td>无</td> </tr> <tr> <td>Anna</td> <td>多核&amp;分布式</td> <td>消息队列</td> <td><a href="https://en.wikipedia.org/wiki/Eventual_consistency"><strong>最终一致性(Eventual)</strong></a>, <a href="https://en.wikipedia.org/wiki/Eventual_consistency"><strong>最终一致性(Eventual)</strong></a>, Item Cut, Writes Follow Reads, 单调读/写, <a href="http://www.dbms2.com/2010/05/01/ryw-read-your-writes-consistency/"><strong>Read Your Writes</strong></a>, <a href="https://en.wikipedia.org/wiki/PRAM_consistency"><strong>PRAM</strong></a></td> <td><a href="https://jepsen.io/consistency/models/read-committed"><strong>Read Committed</strong></a>, <a href="https://jepsen.io/consistency/models/read-uncommitted"><strong>Read Uncommitted</strong></a></td> </tr> </tbody> </table> <blockquote> <p>一致性说明:</p>

2019/4/21
阅读更多

C++20 Coroutine

<h1 id="前言">前言</h1> <p>最近的新闻里 C++20 已经确认的内容里已经有了协程组件,之前都是粗略看过这个协程草案。最近抽时间更加系统性的看了下接入和实现细节。</p> <p>我的测试代码都是在MSVC下开启 <code>/await</code> 选项后测试的,在我本地的Linux clang环境中,可以通过 <code>$LLVM_CLANG_PREFIX/bin/clang++ -std=c++2a -O0 -g -ggdb -stdlib=libc++ -fcoroutines-ts -lc++ -lc++abi -Wl,-rpath=$LLVM_CLANG_PREFIX/lib/ test.cpp</code> 编译和运行。</p>

2019/3/4
阅读更多

libcopp merge boost.context 1.69.0

<p>过年啦,最近在看一些非技术性的东西,<a href="http://db.cs.berkeley.edu/jmh/papers/anna_ieee18.pdf">Anna</a> 的Paper也还没看完。随手优化了下Blog的主题,修复和优化了一些小问题。然后来Merge了一下 <a href="https://www.boost.org/libs/context/">boost.context</a> 最新 1.69.0 版本的asm部分到 <a href="https://github.com/owent/libcopp">libcopp</a>。</p> <p>其实我有一直跟进 <a href="https://www.boost.org/libs/context/">boost.context</a> 的版本发布,但是现在的版本已经少有BUG了,最近的几次 <a href="https://www.boost.org/">boost</a> 的 release对于 <a href="https://www.boost.org/libs/context/">boost.context</a> 的变化很少,而且我集成的部分也基本上没涉及到,所以最近的两个版本都没有急着Merge。 1.68.0 版本的变化是修复使用 <code>context-impl=ucontext</code> 时,链接报重定义的问题。但是我在 <a href="https://github.com/owent/libcopp">libcopp</a> 里仅使用了它上下文切换的部分和栈与上下文结构,没有使用它的协程对象的部分(主要是觉得它的实现不好用,而且有一些历史遗留包袱)。所以这个对 <a href="https://github.com/owent/libcopp">libcopp</a> 来说相当于没有变化。而在 1.69.0 里主要也是一些环境的编译问题和 <a href="https://www.boost.org/">boost</a> 构建工具和Jamfile.v2方面的优化。不过有一项是和 <a href="https://github.com/owent/libcopp">libcopp</a> 有一些关系的,那就是为ELF的ABI添加了 <code>.file</code> 段。按照PR提交者的说法是如果不添加这个, 链接器会自动添加一个编译时的绝对地址(详情见: <a href="https://github.com/boostorg/context/issues/91">https://github.com/boostorg/context/issues/91</a> )。这个也是辅助性质的,不属于实际功能的改动。</p>

2019/2/11
阅读更多

Google去中心化分布式系统论文三件套(Percolator、Spanner、F1)读后感

<h1 id="前言">前言</h1> <p>之前看过 <a href="https://read.douban.com/ebook/10179010/">《大规模分布式存储系统:原理解析与架构实战》</a> ,这个系统设计还是挺有意思的,里面提及了Google的一整套系统都有论文,而且现在已经进化到下一代支持分布式跨行事务的关系型数据库系统了。所以一直很想抽时间看看Google的那套去中心化并且可以平行扩容的分布式系统和数据库的论文。之前一些计划中的我自己的项目的优化项都差不多完成了,这段时间就陆陆续续的看完了这三篇Paper,可怜我的渣渣英语,所以看得比较慢。</p>

2019/1/31
阅读更多

Rust玩具-企业微信机器人通用服务

<h2 id="新玩具-企业微信机器人">新玩具-企业微信机器人</h2> <p>这个机器人其实蛮久前就做好了,现在才写了点分享出来。 最近企业微信不断地开放了机器人的接口,所以我想想拿来做一些开发工具集成也是挺不错的,顺便也是为了继续熟悉一下 <a href="https://rust-lang.org/">Rust</a> 的编程习惯。 那么这次就大量使用 <a href="https://crates.io/crates/futures">futures</a> 来实现这个机器人的接口服务,这也是即将到来的无栈协程语法糖 <a href="https://crates.io/crates/futures-await">await</a> 的基石。</p>

2019/1/3
阅读更多

使用ELK辅助监控开发测试环境服务质量和问题定位

<h2 id="什么是elk">什么是ELK?</h2> <p>ELK 是 <a href="https://www.elastic.co/cn/products/elasticsearch">elasticsearch</a> + <a href="https://www.elastic.co/cn/products/logstash">logstash</a> + <a href="https://www.elastic.co/cn/products/kibana">kibana</a>的缩写。这一套是现在比较流行的日志全文索引系统了。我之前的项目也有用它来做过日志分析,这次主要是拿来搭建开发测试环境的监控和分析系统,顺带记录一下部署脚本和流程。</p> <p>其中 <a href="https://www.elastic.co/cn/products/elasticsearch">elasticsearch</a> 是日志索引系统,我按两个master,3个数据和处理节点来部署。 <a href="https://www.elastic.co/cn/products/logstash">logstash</a> 和 <a href="https://www.elastic.co/cn/products/kibana">kibana</a> 因为是开发测试环境使用,量级不大,所以只部署了一个节点。但是在使用过程中发现 <a href="https://www.elastic.co/cn/products/elasticsearch">elasticsearch</a> 在jre的GC的时候还是有较长时间的 <em><strong>Stop The World</strong></em> 的问题,而且这期间的数据会倍丢弃。所以为了缓解这个状况,又引入了 <a href="https://redis.io/">redis</a> 作为消息队列使用。然后使用两组pipeline,一个从 client -&gt; <a href="https://www.elastic.co/cn/products/logstash">logstash</a> -&gt; <a href="https://redis.io/">redis</a> ,另一个从 <a href="https://redis.io/">redis</a> -&gt; <a href="https://www.elastic.co/cn/products/logstash">logstash</a> -&gt; <a href="https://www.elastic.co/cn/products/elasticsearch">elasticsearch</a> 来传输。这样如果在 <a href="https://www.elastic.co/cn/products/elasticsearch">elasticsearch</a> GC的 <em><strong>Stop The World</strong></em> 结束的时候会把数据补回去。 外面更大型的部署也有用 <a href="https://kafka.apache.org/">kafka</a> 或者更进一步优化的 <a href="https://pulsar.apache.org/">pulsar</a>。不过我们目前的应用也不太需要 <a href="https://kafka.apache.org/">kafka</a> 和 <a href="https://pulsar.apache.org/">pulsar</a> 那种数据落地和强一致性,使用 <a href="https://redis.io/">redis</a> 也已经够了。</p>

2018/11/17
阅读更多

2018年的新通用伪随机数算法(xoshiro / xoroshiro)的C++(head only)实现

<p>前段时间看到说<a href="https://github.com/lua/lua/blob/f59e6a93c0ad38a27a420e51abf8f13d962446b5/lmathlib.c#L571">Lua 5.4</a>用了一种新的通用随机数算法,替换掉本来内部使用的CRT的随机数引擎。我看了一下大致的实现,CPU和空间复杂度任然保持了一个较低的水平,并且循环节和说是随机性都还不错。我们游戏项目中原本对大量随机数场景的随机数算法使用的是基于线性同余的TAUS88,但是使用过程中发现这个算法分布上还是有一些不是很理想,所以就想把这个新的科研成果也用进我们项目中试试看效果。</p>

2018/10/18
阅读更多

Webpack+vue+boostrap+ejs构建Web版GM工具

<h2 id="前言">前言</h2> <p>Web前端的组件技术刷新真的是日新月异,前段时间看到很多童鞋分享了<a href="https://webpack.js.org/">webpack</a>的使用,刚好之前做我们游戏里Web版的GM工具的时候正在想怎么用简单的方式,做模块分离并且又不需要引入重量级的第三方库或组件,也不需要太繁琐的流程(毕竟只是个小工具)。</p> <p>我们的Web版GM工具长差不多这个样子,全静态页面。</p> <p><img src="//owent.net/2018/1811-01.png" alt="1811-01.png" loading="lazy" /></p> <p><img src="//owent.net/2018/1811-02.png" alt="1811-02.png" loading="lazy" /></p> <p>因为分成了好几个模块,然后由于用的是bootstrap的。上面的Tab和下面的内容还有处理逻辑的函数都分了三大块,在不同的位置。在内容持续增加以后,全都写在一个html里太不方便了,而如果走ajax加载,调试和本地编辑都挺麻烦。</p>

2018/10/16
阅读更多

Rust的第二次接触-写个小服务器程序

<h2 id="just-practice">JUST PRACTICE</h2> <p>蛮久前入门了一下 <a href="https://rust-lang.org/">Rust</a> 语言。它的设计模型非常地吸引C/C++的开发者。但是学习语言嘛还是要练习一下,之前也用它给我们项目写了个命令行小工具。这回拿来写个小型的服务器程序吧。</p> <p><a href="https://rust-lang.org/">Rust</a> 的生态还处于非常初级的阶段。很多组件和库都处于开发中和设计变更的阶段,比起golang来,很多功能库都没有。 服务器编程本身特别注重高并发能力和,高性能。和原来很多客户端程序的思路是不太一样的。所以本来想等新的Futures和await和2.0版本的宏机制完成再搞。而老的<a href="https://crates.io/crates/futures">Futures</a>库由于即将移入核心库,在<a href="https://crates.io/">crates.io</a>上下架了。现在似乎很多<a href="https://rust-lang.org/">Rust</a>的库都按<a href="https://tokio.rs/">Tokio</a>的的模式来,于是我看了一下基于<a href="https://crates.io/crates/futures">Futures</a>的多路复用IO库<a href="https://tokio.rs/">Tokio</a>的文档来练习一下这个小服务器程序。</p>

2018/9/12
阅读更多

理解和适配AEAD加密套件

<h2 id="什么是aead">什么是AEAD</h2> <p>按照维基百科的说法。AEAD的全称是Authenticated encryption (AE) and authenticated encryption with associated data (AEAD, variant of AE)。也就是带附加数据的加密和验证算法。</p> <p>我们很多涉及IO的系统收发数据的时候一般会加上一些校验码,以便检测IO错误。而对外的socket里,这个校验码还有一个功能是挡掉一些不正常的数据。如果这时候如果我们的数据需要带上加密的话,那就是AE了。然后AEAD就是在AE的基础上,增加一些自定义数据,用于防止猜解。</p>

2018/7/1
阅读更多

atsf4g-co的进化:协程框架v2、对象路由系统和一些其他细节优化

<h1 id="前言">前言</h1> <p>年前就计划把以前项目的一些理念和设计方案融合到sample里来。但是内容比较多,一直也没太多时间去完成它。所幸虽然断断续续但终归是完成了。并且在之前的一些实现上还做了一些细节的优化。内容比较多我感觉我自己写的也比较乱,仅当作一个参照和小计吧。</p>

2018/6/22
阅读更多

协程框架(libcopp)v2优化、自适应栈池和同类库的Benchmark对比

<h1 id="协程系统优化">协程系统优化</h1> <p><a href="https://github.com/owent/libcopp">libcopp</a>很早就实现完成了v2版本,现在迁移进<a href="https://github.com/atframework/atsf4g-co/tree/sample_solution">atsf4g-co/tree/sample_solution</a>以后也把v2分支正式并入了主干。原来的版本切出到v1分支并且停止维护了。</p> <h2 id="libcopp-v2内存布局">libcopp v2内存布局</h2> <p>开发<a href="https://github.com/owent/libcopp">libcopp</a> v2版本的最大目的是优化allocator的接口和内存碎片。</p> <p>原来的allocator虽然是可定制的,但是是内置的。每次创建一个allocator对象,不同allocator之间共享数据只能通过全局数据或者TLS数据。现在则可以传入allocator了。这也是为后续的共享栈池做准备。</p>

2018/5/28
阅读更多

可执行文件压缩

<h1 id="前言">前言</h1> <p>最近看<a href="https://rust-lang.org/">Rust</a>相关东西的时候看到一篇关于压缩可执行文件的文章。压缩可执行文件对嵌入式开发特别有用,但是延伸一下用来减少我们游戏行业里预编译的工具二进制包大小和Android/iOS的库也是蛮有用的。</p> <p>原文见这里: <a href="https://jamesmunns.com/blog/tinyrocket/">https://jamesmunns.com/blog/tinyrocket/</a></p> <h1 id="基本流程">基本流程</h1> <ol> <li>Release编译,移除调试符号文件,开启最小化size优化(-Oz)</li> <li>使用LLVM的全量LTO</li> <li>使用xargo重新编译标准库(std)和核心库(core)(这个C/C++不容易模仿,而且编译选项十分难搞)</li> <li>移除<a href="https://github.com/jemalloc/jemalloc">jemalloc</a>(服务器程序还是留着比较好,内置的malloc实现一般碎片比较厉害。虽然C/C++默认也不是<a href="https://github.com/jemalloc/jemalloc">jemalloc</a>,很多项目为了新能还是会用它)</li> <li>移除panic的详情信息(这个仅适用于<a href="https://rust-lang.org/">Rust</a>)</li> <li>strip(由GNU的<a href="https://www.gnu.org/software/binutils/">binutils</a>提供),参考命令: <code>strip [二进制]</code></li> <li><a href="https://upx.github.io/">UPX</a>进一步压缩加壳</li> </ol> <h1 id="尝试改造优化">尝试改造优化</h1> <p>然后尝试使用上面的流程改造我们的 <strong>gmtools-cli</strong> 。原先我是直接开LTO+Release编译的,编出的文件大小为4.4MB(4520728字节)。</p>

2018/4/24
阅读更多

初识Rust

<h1 id="前言">前言</h1> <p>虽然我主要使用C++,但是最近也想学点现代化的新语言。初步想的是从<a href="https://golang.org/">golang</a>和<a href="https://rust-lang.org/">Rust</a>里先选一个。</p> <p>这两年<a href="https://golang.org/">golang</a>在国内很火,最大的特点莫过于语言层面提供了协程支持,能够极大地简化异步逻辑地理解。我之前也接触过一点,还写了个<a href="https://gist.github.com/owent/2286768f2586521600c9fd1700cbf845">goroutine压力测试</a>对比我的<a href="https://github.com/owent/libcopp">libcopp</a>的性能。但是<a href="https://golang.org/">golang</a>的语法我实在不喜欢,特别是那个不管啥类型声明都是反着来,感觉在复杂的类型下会非常反人类。而且听用过的人说<a href="https://golang.org/">golang</a>的GC还很不稳定。另外之前有新闻说<a href="https://golang.org/">golang</a>正在准备2.0,2.0版本即将加入泛型支持,然后导致很多语法不兼容和语法分析得重写。所以我还是懒得踩这个坑了,至少等2.0出来再说。</p> <p><a href="https://rust-lang.org/">Rust</a>是Mozilla搞出来想拿来重写Firefox的。说实话Mozilla和Google还有点差距,导致<a href="https://rust-lang.org/">Rust</a>的发展还比较慢。对比起来就是感觉<a href="https://golang.org/">golang</a>很快就提供了一些快速可用的原型给大型项目使用,标准库也足够丰富。而<a href="https://rust-lang.org/">Rust</a>还纠结在底层、语言层面的优化和最求极致。很多组件都还不成熟,编程设计模型也还没完全统一。</p> <p>但是接触了一点<a href="https://rust-lang.org/">Rust</a>以后,我发现<a href="https://rust-lang.org/">Rust</a>真的是挠到了C++程序员的痒点,语言层面解决了用C++得费很多脑力和用各种奇技淫巧实现并且还不能完全阻止被绕过的质量控制问题,而且保留了C++很多编译期推断得高级特性。并且和C++一样,提供给你能力,但不限定你方法提供 <strong>零成本抽象(zero-cost abstractions)</strong> 或者说叫 <strong>零开销(zero-overhead)</strong>。</p> <blockquote> <p>In general, C++ implementations obey the zero-overhead principle: What you don’t use, you don’t pay for. And further: What you do use, you couldn’t hand code any better.</p>

2018/4/23
阅读更多

使用restructedtext编写xresloader文档

<p>离上一次写Blog过了好久啦。这次拖这么长时间主要是因为最近学习了一个新的文本标记语言 &ndash; <a href="https://en.wikipedia.org/wiki/ReStructuredText">ReStructuredText</a> 。并且重新整理了<a href="https://github.com/xresloader/">Excel导表工具-xresloader工具集</a>的文档,写文档真是好废好废时间啊。</p> <p>好多项目用<a href="https://en.wikipedia.org/wiki/ReStructuredText">ReStructuredText</a>来写文档来着,比如<a href="https://cmake.org/">cmake</a>,再比如<a href="https://www.python.org/">python</a>。然后现在有比较容易上手的<a href="https://readthedocs.com/">readthedocs</a>来托管文档,和<a href="https://github.com/">github</a>的集成也还不错。所以我打算把一些项目的文档也迁移上去。毕竟 <strong>README.md</strong> 还是弱了些。</p> <p>其实<a href="https://en.wikipedia.org/wiki/ReStructuredText">ReStructuredText</a>也支持 <strong>Markdown</strong> 。但是使用 <strong>Markdown</strong> 写文档还是略麻烦,特别是涉及跨文档引用和多行表格的时候,而且 <strong>Markdown</strong> 各个平台的组件和扩展还都不一样,没有统一标准。在这些方面<a href="https://en.wikipedia.org/wiki/ReStructuredText">ReStructuredText</a>就强大多了。不过这也是有代价的,那就是<a href="https://en.wikipedia.org/wiki/ReStructuredText">ReStructuredText</a>的语法规则比 <strong>Markdown</strong> 复杂得多。</p>

2018/4/3
阅读更多

atframework的etcd模块化重构

<h2 id="前言">前言</h2> <p>最近在抽时间整理之气的游戏服务器框架和解决方案里<a href="https://github.com/atframework/atsf4g-co">atsf4g-co</a>,现在的架构是使用<a href="https://coreos.com/etcd">etcd</a>的是<a href="https://github.com/atframework/atsf4g-co/tree/master/atframework/service/atproxy">atproxy</a>。简单得说就是服务集群是分组的,每个分组有分组代理服务<a href="https://github.com/atframework/atsf4g-co/tree/master/atframework/service/atproxy">atproxy</a>做组间通信。然后<a href="https://github.com/atframework/atsf4g-co/tree/master/atframework/service/atproxy">atproxy</a>之间使用<a href="https://coreos.com/etcd">etcd</a>来做分组服务的服务发现和保活,并且以此来实现平行扩容。</p> <p>之前做服务间通信组件<a href="https://github.com/atframework/libatbus">libatbus</a>的时候也提到了有一个暂时没实现的功能,就是全局路由表的自动通知。但是这个功能的实现主要也是用于后面不同种服务间感知到哪些节点是可用的,哪些是不可用的。而且我的简单实现必然是走心跳的模式,因为心跳的形式肯定不能把心跳设置得太短,同时也要考虑网络异常抖动和断线重连和丢包,所以肯定不是丢一个心跳包就认为丢失。所以故障或者扩缩容期间的感知时间就会比较长一些。另外就是因为可能有网络孤岛问题,所以可能短期内数据不一致(当然肯定会保证最终一致性)。</p> <p>再加上由于<a href="https://github.com/atframework/libatbus">libatbus</a>是支持多级父子节点关系的,所以变化通知和同步包就要考虑自己与父节点、兄弟节点、自己与子节点的不同关系并作不同的同步流向,会比较复杂。比如:子节点下线,既要通知父节点,又要通知兄弟节点。那么这时候给兄弟节点通知就有两个通路,一个是经由父节点中转,另一种是直接发。当然这时候并不一定和兄弟节点有直接通路。所以可能兄弟节点会收到两次通知,一次来自兄弟节点,另一次来自公共父节点。然后又会有其他问题,就是万一又收到一条冲突的消息,来自父节点和来自兄弟节点的顺序是没有保证的,这里又得加入版本机制。总的来说,细节会比较复杂,具体在实现<a href="https://github.com/atframework/libatbus">libatbus</a>的这个功能的时候在谈吧。</p> <p>上面说的<a href="https://github.com/atframework/libatbus">libatbus</a>的功能暂时没实现的最重要原因是<a href="https://coreos.com/etcd">etcd</a>可以比较完美的解决上面的延迟问题和不一致问题。缺点就是请求的消耗会高于使用<a href="https://github.com/atframework/libatbus">libatbus</a>的通信机制。不过这玩意本身不是高频操作,而且故障和容灾本身不是一个频发的事情所以关系不大。而之前<a href="https://coreos.com/etcd">etcd</a>的接入是直接写死在<a href="https://github.com/atframework/atsf4g-co/tree/master/atframework/service/atproxy">atproxy</a>里的,那么这次重构的目的主要就是能够抽象出模块化的工具,以便后面不同的服务可以根据需要取用。</p> <h2 id="统一管理驱动管理器和模块化">统一管理驱动管理器和模块化</h2> <p>按现在的功能划分,<a href="https://coreos.com/etcd">etcd</a>的接入总共被分为3个模块,etcd_cluster、etcd_keepalive和etcd_watcher以及一个通用工具etcd_packer。etcd_packer用于对<a href="https://coreos.com/etcd">etcd</a>的一些通用的打解包操作。</p> <p><img src="//owent.net/2018/1802-01.png" alt="模块关系图" loading="lazy" /></p> <h3 id="etcd_cluster">etcd_cluster</h3> <p><a href="https://coreos.com/etcd">etcd</a> v3版本内部的通信已经使用了grpc。本来我是想等他的grpc接口进入官方文档并且提供出的grpc的proto再接入的,可是它一直没有整理出直接grpc的proto文件列表。另外我看了一下它的proto文件里用到了一些<a href="https://github.com/gogo/protobuf">gogoprotobuf</a>的扩展,其他语言不一定可以无缝接入。考虑到etcd使用了<a href="https://github.com/grpc-ecosystem/grpc-gateway">grpc-gateway</a>提供HTTP+JSON的网关层,所以我还是基于他的HTTP接入层来做。因为这里身频次不高,也没有那么在意性能。而且一组<a href="https://coreos.com/etcd">etcd</a>服务的QPS也就在十万的级别,只要管理好连接,不要老新建立和关闭连接,HTTP的性能还是够的。</p>

2018/2/20
阅读更多

C++的backtrace

<h1 id="开始之前">开始之前</h1> <p>很多语言的log模块都有一个功能,就是在打log的时候能够追溯调用栈,有的时候对查bug能有点帮助。之前我也想过给我们的log模块加上C++的backtrace的功能,迟迟一直没有做主要是两个原因:一是C++的backtrace在各个平台和编译器上都不太一样,比较冗杂;二是C/C++在编译优化之后,调用行之类的信息和甚至一些函数可能就被优化没了。所以能提供的信息就相当有限。前两天刚好有朋友问有没有提供这个,所以就花了点时间整理了下适配方案。</p>

2018/1/8
阅读更多

ECDH椭圆双曲线(比DH快10倍的密钥交换)算法简介和封装

<p>前面有几篇blog就提到我有计划支持使用ECDH密钥交换。近期也是抽空把以前的DH密钥交换跨平台适配从<a href="https://github.com/atframework/atsf4g-co/tree/master/atframework/service/atgateway">atgateway</a>抽离出来,而后接入了<a href="https://en.wikipedia.org/wiki/Elliptic-curve_Diffie%E2%80%93Hellman">ECDH</a>流程。</p> <h2 id="背景">背景</h2> <p>对<a href="https://en.wikipedia.org/wiki/Diffie%E2%80%93Hellman_key_exchange">DH</a>和<a href="https://en.wikipedia.org/wiki/Elliptic-curve_Diffie%E2%80%93Hellman">ECDH</a>算法的具体原理这里不做具体介绍了,可以点击链接看。<a href="https://en.wikipedia.org/wiki/Diffie%E2%80%93Hellman_key_exchange">DH</a>和<a href="https://en.wikipedia.org/wiki/Elliptic-curve_Diffie%E2%80%93Hellman">ECDH</a>的主要的作用就是在通信双方发送一些公有参数,保留私有参数,而后通过一系列计算双方都能够得到一个一致的结果。而这个运算的逆运算复杂度过高,在有限时间内不可解(至少量子计算机问世以前不可解),以保证密钥安全性。除了维基百科外,我还看到篇文章图画的很好看的:http://andrea.corbellini.name/2015/05/30/elliptic-curve-cryptography-ecdh-and-ecdsa/ 。而<a href="https://en.wikipedia.org/wiki/Diffie%E2%80%93Hellman_key_exchange">DH</a>和<a href="https://en.wikipedia.org/wiki/Elliptic-curve_Diffie%E2%80%93Hellman">ECDH</a>得区别简单来说就是,前者使用了一个大素数和两个随机数,而后者使用了<a href="https://en.wikipedia.org/wiki/Elliptic-curve_cryptography">ECC</a>算法和两个随机点。</p> <p>实际应用中,有些加密算法的密钥碰撞计算难度反而比破解<a href="https://en.wikipedia.org/wiki/Diffie%E2%80%93Hellman_key_exchange">DH</a>和<a href="https://en.wikipedia.org/wiki/Elliptic-curve_Diffie%E2%80%93Hellman">ECDH</a>要容易(比如<a href="https://github.com/atframework/atsf4g-co/tree/master/atframework/service/atgateway">atgateway</a>支持的<a href="https://en.wikipedia.org/wiki/XXTEA">XXTEA</a>算法,这个算法很简单所以也非常高效)。所以有些工程实践中会每隔一段时间再走一次密钥交换流程来更换密钥。</p> <h2 id="ecdh和dh">ECDH和DH</h2> <p>使用<a href="https://en.wikipedia.org/wiki/Elliptic-curve_Diffie%E2%80%93Hellman">ECDH</a>做密钥交换得时候你可能也会看到<a href="https://en.wikipedia.org/wiki/Elliptic-curve_Diffie%E2%80%93Hellman">ECDHE</a>这个词,这个多出来的E的意思是指每次公钥都随机生成。因为像HTTPS里那种是可以从证书文件里取静态公钥的。我封装的接口其实也是每次都随机生成公钥。</p> <h3 id="适配和接入">适配和接入</h3> <p>我这里选择了按<a href="https://tools.ietf.org/html/rfc4492">RFC 4492</a>进行接入,因为我主要适配的两个库(<a href="https://www.openssl.org/">openssl</a>和<a href="https://tls.mbed.org/">mbedtls</a>)共同支持的似乎只有<a href="https://tools.ietf.org/html/rfc4492">RFC 4492</a>。<a href="https://www.openssl.org/">openssl</a>自不用说了,<a href="https://tls.mbed.org/">mbedtls</a>主要是为了如果需要用到Android或者iOS上的话,用<a href="https://tls.mbed.org/">mbedtls</a>比较容易一些。接入的过程中主要有三个问题。</p>

2017/11/10
阅读更多

protobuf-net的动态Message实现

<p>这本来是个早就可以写的分享。因为代码几周前就迁移并准备好了。而且这也是之前项目的工具,因为可以抽离出来通用化所以单独整理出来。</p> <p>这个项目起源于我们之前哪个项目,客户端想要在Unity的C#里动态加载配置,而<a href="https://github.com/mgravell/protobuf-net">protobuf-net</a>一方面大量使用反射而性能不太行,另一方面使用的时候得生成C#代码才行。客户端原来的做法是把消息扁平化了,使用<a href="https://github.com/mgravell/protobuf-net">protobuf-net</a>得底层读写接口直接操作基本数据类型。这就失去了结构化带来的一系列好处。再加上后来我引入了跨平台导表工具,使用结构化得数据会非常方便,而手动把这个数据打散到客户端读取接口显然很浪费人力而且容易出错。所以我就干脆也使用<a href="https://github.com/mgravell/protobuf-net">protobuf-net</a>的底层读写接口做了现在的<a href="https://github.com/xresloader/DynamicMessage-net">DynamicMessage</a>的支持,API设计是结合<a href="https://github.com/cloudwu/pbc">pbc</a>和protobuf官方的API流程的。</p>

2017/10/31
阅读更多

pbc的proto3接入

<p><a href="https://github.com/google/protobuf">Protobuf</a> 的 proto3发布也有挺长一段时间了。现在很多新项目慢慢转变用proto3来开发。这篇文章主要记录一下我在给<a href="https://github.com/cloudwu/pbc">pbc</a>写对proto3支持时的一些信息,也许对其他童鞋也有点助益。抛砖引玉一下。</p> <h2 id="简介">简介</h2> <p><a href="https://github.com/cloudwu/pbc">pbc</a>是<a href="https://github.com/cloudwu">云风</a>开发的一个纯C的读写<a href="https://github.com/google/protobuf">protobuf</a>的很小巧的库,配合上它提供的lua-5.1和lua-5.3的binding可以很容易地在lua里完成对pb文件的注册和打解包。应该很多人都知道这个组件。</p> <p>但是后来<a href="https://github.com/cloudwu">云风</a>自己又发明了个<a href="https://github.com/cloudwu/sproto">sproto</a>,然后主推在他的<a href="https://github.com/cloudwu/skynet">skynet</a>框架中使用<a href="https://github.com/cloudwu/sproto">sproto</a>,于是<a href="https://github.com/cloudwu/pbc">pbc</a>就不再有功能维护了。</p> <p>我们之前的也尝试直接使用了proto3,也是因为在迁移期,所以并没有使用全部的特性。但是仍然有一些向前不兼容的细节需要处理一下,所以有了这个改造</p>

2017/9/16
阅读更多

atgateway内置协议流程优化-加密、算法协商和ECDH

<p>之前就有计划优化游戏服务器框架网关层的内部协议了,这次泰国旅游回来,新公司入职前,正海有空来做这件事。</p> <h2 id="加密协商">加密协商</h2> <p>以前提到过,最初决定重构这个流程是因为我觉得之前的方法,如果以后要扩展新的算法的话非常的麻烦。而后我看了一下shadowsocksr对多种加解密算法的实现方法,觉得还不错。就打算用类似的方法重写一下。当然也是因为写第一版的时候没考虑太多关于加解密方面的细节,还是优先实现出工程上可用的东西。这次就先稍微深入看了下像<a href="https://www.openssl.org/">openssl</a>和<a href="https://tls.mbed.org/">mbedtls</a>的一些实现,特别是下面会提到的cipher的实现。并以这个为基础来实现以后可能的增加加密算法的扩展。</p>

2017/9/8
阅读更多

整理一波软件源镜像同步工具+DevOps工具

<p>上个月,同学的公司,格奕,突然间跪了。这个月基本属于休息+四处溜达。同时空闲的时候也想整理下之前做得一些之前的做得一些小工具们。在不泄密的情况下开源出来吧(其实也就是想找github存放一下而已,也没什么特别NB的东西)。</p>

2017/8/17
阅读更多

Blog切换到Hugo

<p>其实很早就想把Blog迁移到静态化的博客系统了。不过一直没花时间来搞,当然主要原因还是懒。</p> <p>这次下决心搞主要是因为,之前VPS迁移到Vultr,然后它的主机默认是没有交换区的。后来老是收到网站崩溃告警,每次去看都是MariaDB挂掉了,然后查了一下是内存不足。 然后,调整了几次参数,发现都不能解决问题。我这么个小站搞个高配机器显然是浪费。这种小网站都能耗尽1GB的内存我也是醉了。所以后来就干脆迁移到静态博客系统算了。</p>

2017/7/17
阅读更多

libcopp v2的第一波优化完成

<p>之前测出来<a href="https://github.com/owent/libcopp">libcopp</a>还有一些列优化点,但是要破坏之前的API,所以整理了一下优化的想法和方案。</p> <h2 id="预留空间和合并分配">预留空间和合并分配</h2> <p>之前有太多的堆内存分配了,导致很多碎片。那么第一个想法就是协程对象可以分配在栈上,runner也可以分配在栈上。然后还可以加一个自定义预留长度。每个对象对齐到sizeof(long),总长度对齐到64 Bytes。</p>

2017/7/1
阅读更多

libcopp(v2) vs goroutine性能测试

<p>本来是没想写这个对比。无奈之前和<a href="https://github.com/yuanzhubi/call_in_stack">call_in_stack</a>的作者聊了一阵,发现了一些<a href="https://github.com/owent/libcopp">libcopp</a>的改进空间。然后顺便看了新的boost.context的cc部分的代码,有所启发。想给<a href="https://github.com/owent/libcopp">libcopp</a>做一些优化,主要集中在减少分配次数从而减少内存碎片;在支持的编译器里有些地方用右值引用来减少不必要的拷贝;减少原子操作和减少L1cache miss几个方面。</p> <p>之后改造了茫茫多流程和接口后出了v2版本,虽然没完全优化完,但是组织结构已经定型了,可以用来做压力测试。为了以后方便顺便还把cppcheck和clang-analyzer的静态分析工具写进了dev脚本。然后万万没想到的是,在大量协程的情况下,benchmark的结果性能居然比原来还下降了大约1/3。</p>

2017/6/10
阅读更多

libcopp的线程安全、栈池和merge boost.context 1.64.0

<!-- toc --> <h2 id="线程安全">线程安全</h2> <p>前段时间看到了一个完成读比较高的协程库-<a href="https://github.com/yyzybb537/libgo">libgo</a>,里面提供了线程安全的协程实现,并且也是使用锁。本来我并没有给<a href="https://github.com/owent/libcopp">libcopp</a>里的功能加锁的打算,因为上层dispatcher还是比较容易做到安全分发的,所以原来并不保证线程安全。而且线程安全这种问题单元测试比较难写,可能还得碰点运气。但是思来想去,还是为线程安全做点什么吧。反正也不是很复杂。</p> <p>由于我并没有给utils加互斥锁的跨平台适配,所以先就直接用了自旋锁,来锁住需要考虑线程安全的地方。其实需要加锁的地方并不多,无非是管理器的增删查和task的next函数需要加锁。这些逻辑都很短,功能也很简单,并不会占用太多时间,所以自旋锁的问题也不大。而且以后真发现有问题,换掉也不是什么难事儿。</p>

2017/5/12
阅读更多

GCC 7和LLVM+Clang+libc++abi 4.0的构建脚本

<p>之前的版本发完,有空来更新一下之前的gcc和llvm+clang工具链的编译脚本了。其实GCC 7是才release没多久但是llvm 4.0发布其实有一段时间了。</p> <h2 id="gcc">GCC</h2> <p>这回是GCC的脚本有一些改动。因为我现在开发机的环境很多组件并没有装,所以顺带发现了之前的构建脚本的一些问题。</p>

2017/5/9
阅读更多

libatbus的几个藏得很深的bug

<!-- toc --> <p>在写这篇文章前,我突然想到以前流行了一段时间的服务器面试题:当一个BUG只有几百万分之一的概率会出现,怎么办?这个问题在这个BUG里只是毛毛雨而已,因为这次的BUG的<strong>出现概率是夸张的三亿分之一</strong>。</p> <p>我在好几年前自己开发了一个用于服务器进程间通信的框架,<a href="https://github.com/atframework/libatbus">libatbus</a>,以前用在了客户端的模块隔离的通信心痛中。并且现在开始正式用于服务器。但是前两天看了一下服务器的日志,发现了比较奇怪的-202错误。</p>

2017/4/23
阅读更多

用cmake交叉编译到iOS和Android

<!-- toc --> <p>最近看了下最新版本的cmake的文档,很惊喜地发现他已经支持直接设置Android和OSX的一些变量了,然后有瞄了一眼NDK,发现里面现在也停工官方的cmake支持。</p> <p>索性干脆试试用cmake做对android和iOS平台的一些库的交叉编译,这样用cmake的环境监测系统就会比原来写Makefile+脚本要简单多了。</p>

2017/4/16
阅读更多

开源项目得一些小维护

<!-- toc --> <p>其实我那几个特别是工具类得开源项目一致都有维护和更新,但是每次更新得量和要点并不怎么突出所以一致也没写点什么。但是偶尔吗也会碰到一些稍微值得记录的东西,但是又不多所以很多都遗漏掉了。</p> <p>虽然漏掉得那些也补不回来,我还是对近期得一些维护稍微记录一下吧。虽然近期维护得内容稍微多一些,但是也只能靠记忆回忆一些了。</p>

2017/3/3
阅读更多

atapp的c binding和c#适配

<!-- toc --> <p>这两天在做服务器框架的C的接口导出和C#的接入。之所以要做这么个东西是因为之前的服务器框架(<a href="https://github.com/atframework/atsf4g-co">atsf4g-co</a>)已经完成了通信层面和基本设计模式的细节部分,而且基本算是最大化性能了吧。但是现在的项目的战斗引擎是从以前Unity游戏上抽象而来的,全部由C#编写。再加上最近再考虑接入实时战斗,这样就不能像之前一样用一个简单的通信方式了,必须使用一个高效并且实时性更高通信机制。需要能够处理好比较高的集中式的组播和容灾的通信方式。于是就有了把之前的C++的框架抽离出API来驱动逻辑的想法。这样也比较容易地兼顾开发成本和性能之间地权衡。</p> <h2 id="c-binding">C Binding</h2> <p>那么抽离出框架地目的是抽象出应用底层,这个刚好是<a href="https://github.com/atframework/libatapp">atapp</a>做的事,而且<a href="https://github.com/atframework/libatapp">atapp</a>的层面对外暴露的接口数量也比较少,使用比较简单,所以索性就直接对它下手了。</p> <p>让后第一步是把<a href="https://github.com/atframework/libatapp">atapp</a>需要使用的基本接口抽离出纯C的导出API。之所以要导出成纯C是因为,不同系统环境和编译器环境在C++层符号规则、入栈出栈顺序、内存布局、对其规则等等都不一样。这种情况要做跨平台就很是困难,然而这些在纯C的ISO里都是有明确规范的。所以最简单的方式就是导出到纯C,然后其他语言导入接口。这里的其他语言目前就只有C#,但是纯C接口的话如果想导出到lua或者其他语言的接口也不困难。</p> <p>这里导出的时候有一点点小细节,那就是在Linux上的c api是默认导出的,但是在Windows里是默认不导出的,然后再加上不同编译器的导出用法不一样,所以第一步当然是统一导出标记。最终就是下面这一段</p>

2017/2/15
阅读更多

对象路由系统设计

<!-- toc --> <h2 id="起源">起源</h2> <p>现在的手游也开始越来越复杂,以前少量交互线上保存的服务器架构越来越不能满足现在越来越偏向PC端MMORPG的需求。比如现在手游也引入了地图服务、公会服务等等。特别是地图服务需要能够动态切换服务节点、并且由于广播量巨大,导致我们得用更多级的缓存和更复杂的负载均衡。这些缓存和负载均衡都会涉及缓存失效、同步、更新、发现延迟等问题,所以越来越需要一个路由系统来解决这些问题。</p>

2017/2/4
阅读更多