前段时间有同事联系我想看看可能推广我之前写的协程库 libcopp,虽然 libcopp 已经用到过好几个项目上,这几年也断断续续地写了一些实现细节的文章,但是也但确实需要系统、概览性地介绍下 libcopp ,所以就有了这篇文章。

前言

之前写了 《协程框架(libcopp)v2优化、自适应栈池和同类库的Benchmark对比》《C++20 Coroutine》 ,但是一直没写 C++20 Coroutine 的测试报告。

现在的草案版本比我当时写 《C++20 Coroutine》 的时候有了一点点更新,cppreference 上有文档了(https://en.cppreference.com/w/cpp/language/coroutines) 。里面列举的标准文档是P0912R5,这个文档目前还没完工,详情可以看他的来源N4775。不过内容上暂时还没有太大的变化,今天我就照着之前的方式来benchmark一波 C++20 Coroutine 吧。

前言

Github Action 上线有一阵子了,大概两周前我的所有账号也是都陆陆续续开发了beta测试的权限。然后就来研究了下这个新的 CI 系统是怎么回事。看介绍,和之前碰到的一些CI系统不太一样的地方是,Github是做了一个商店的功能。这样大家就可以自己定义自己的Action,然后方便别人复用。同时也可以统一自己的或者组织在构建过程中的一些公共流程。

前言

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

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

前言

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

前言

年前被同事安利了这个分布式最终一致性的存储系统 Anna 。初略看了一眼Paper,似乎很是牛X。说是支持任意规模的扩展,并且性能不低于 pedis。于是抽空来看看并了解下这套系统的设计特点和这种夸张的单机性能和扩展性的来源。

主流分布式KVS的比较

系统名词扩容设计内存模型针对单个Key的一致性策略针对多个Key一致性策略
Masstree多核共享内存线性(Linearizable)
Bw-tree多核共享内存线性(Linearizable)
PALM多核共享内存线性(Linearizable)
MICA多核共享内存线性(Linearizable)
Redis单核N/A线性(Linearizable)串行化(Serializable)
COPS, Bolt-on分布式消息队列最终一致性(Eventual)因果一致性(Causal)
Bayou分布式消息队列最终一致性(Eventual), 单调读/写, Read Your Writes最终一致性(Eventual)
Dynamo分布式消息队列线性(Linearizable), 最终一致性(Eventual)
Cassandra分布式消息队列线性(Linearizable), 最终一致性(Eventual)
PNUTS分布式消息队列线性写, 单调读
CouchDB分布式消息队列最终一致性(Eventual)
Voldemort分布式消息队列线性(Linearizable), 最终一致性(Eventual)
HBase分布式消息队列线性(Linearizable)
Riak分布式消息队列最终一致性(Eventual)
DocumentDB分布式消息队列最终一致性(Eventual), Session, Bounded Staleness, 线性(Linearizable)
Memcached多核&分布式共享内存&消息队列线性(Linearizable)
MongoDB多核&分布式共享内存&消息队列线性(Linearizable)
H-Store多核&分布式消息队列线性(Linearizable)串行化(Serializable)
ScyllaDB多核&分布式消息队列线性(Linearizable), 最终一致性(Eventual)
Anna多核&分布式消息队列最终一致性(Eventual), 最终一致性(Eventual), Item Cut, Writes Follow Reads, 单调读/写, Read Your Writes, PRAMRead Committed, Read Uncommitted

一致性说明:

前言

最近的新闻里 C++20 已经确认的内容里已经有了协程组件,之前都是粗略看过这个协程草案。最近抽时间更加系统性的看了下接入和实现细节。

我的测试代码都是在MSVC下开启 /await 选项后测试的,在我本地的Linux clang环境中,可以通过 $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 编译和运行。

前言

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

新玩具-企业微信机器人

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

什么是ELK?

ELK 是 elasticsearch + logstash + kibana的缩写。这一套是现在比较流行的日志全文索引系统了。我之前的项目也有用它来做过日志分析,这次主要是拿来搭建开发测试环境的监控和分析系统,顺带记录一下部署脚本和流程。

其中 elasticsearch 是日志索引系统,我按两个master,3个数据和处理节点来部署。 logstashkibana 因为是开发测试环境使用,量级不大,所以只部署了一个节点。但是在使用过程中发现 elasticsearch 在jre的GC的时候还是有较长时间的 Stop The World 的问题,而且这期间的数据会倍丢弃。所以为了缓解这个状况,又引入了 redis 作为消息队列使用。然后使用两组pipeline,一个从 client -> logstash -> redis ,另一个从 redis -> logstash -> elasticsearch 来传输。这样如果在 elasticsearch GC的 Stop The World 结束的时候会把数据补回去。 外面更大型的部署也有用 kafka 或者更进一步优化的 pulsar。不过我们目前的应用也不太需要 kafkapulsar 那种数据落地和强一致性,使用 redis 也已经够了。

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

前言

Web前端的组件技术刷新真的是日新月异,前段时间看到很多童鞋分享了webpack的使用,刚好之前做我们游戏里Web版的GM工具的时候正在想怎么用简单的方式,做模块分离并且又不需要引入重量级的第三方库或组件,也不需要太繁琐的流程(毕竟只是个小工具)。

我们的Web版GM工具长差不多这个样子,全静态页面。

1811-01.png

1811-02.png

因为分成了好几个模块,然后由于用的是bootstrap的。上面的Tab和下面的内容还有处理逻辑的函数都分了三大块,在不同的位置。在内容持续增加以后,全都写在一个html里太不方便了,而如果走ajax加载,调试和本地编辑都挺麻烦。

JUST PRACTICE

蛮久前入门了一下 Rust 语言。它的设计模型非常地吸引C/C++的开发者。但是学习语言嘛还是要练习一下,之前也用它给我们项目写了个命令行小工具。这回拿来写个小型的服务器程序吧。

什么是AEAD

按照维基百科的说法。AEAD的全称是Authenticated encryption (AE) and authenticated encryption with associated data (AEAD, variant of AE)。也就是带附加数据的加密和验证算法。

我们很多涉及IO的系统收发数据的时候一般会加上一些校验码,以便检测IO错误。而对外的socket里,这个校验码还有一个功能是挡掉一些不正常的数据。如果这时候如果我们的数据需要带上加密的话,那就是AE了。然后AEAD就是在AE的基础上,增加一些自定义数据,用于防止猜解。

前言

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

协程系统优化

libcopp很早就实现完成了v2版本,现在迁移进atsf4g-co/tree/sample_solution以后也把v2分支正式并入了主干。原来的版本切出到v1分支并且停止维护了。

libcopp v2内存布局

开发libcopp v2版本的最大目的是优化allocator的接口和内存碎片。

原来的allocator虽然是可定制的,但是是内置的。每次创建一个allocator对象,不同allocator之间共享数据只能通过全局数据或者TLS数据。现在则可以传入allocator了。这也是为后续的共享栈池做准备。