游戏服务器工程实践一:百万级同时在线的全区全服游戏
我应该有资格写这篇文章,因为亲手设计过可以支撑百万级同时在线的全区全服类型的游戏服务器架构。 但这并不代表我有多牛,实际做过之后就会发现,这类游戏的架构设计很简单,做对几件事情就够了。 若干年前我在某公司任职时,参与研发过一款休闲类型的游戏,由 penguin 厂独代。研发的时候,p 厂要求我们的游戏服务器要能支撑百万以上的同时在线,并且要能在 30 分钟内扩容 100 万在线。 在经...
我应该有资格写这篇文章,因为亲手设计过可以支撑百万级同时在线的全区全服类型的游戏服务器架构。 但这并不代表我有多牛,实际做过之后就会发现,这类游戏的架构设计很简单,做对几件事情就够了。 若干年前我在某公司任职时,参与研发过一款休闲类型的游戏,由 penguin 厂独代。研发的时候,p 厂要求我们的游戏服务器要能支撑百万以上的同时在线,并且要能在 30 分钟内扩容 100 万在线。 在经...
本文打算探讨 ACID 中的 C,因为它的定位有些模糊。 1. 正文 学得比较杂的朋友都知道,数据库事务模型的 ACID 里有个 C,分布式的 CAP 理论里也有个 C,刚好中文又都翻译成 “一致性”,就让人很头大了。 这个在《数据密集型应用系统设计》里有详细的介绍[1],读完后就很清晰了: CAP理论中,一致性一词用来表示线性化。 而在ACID中,一致性主要指数据库处...
前言 在 lua vm 中,upvalue 是一个重要的数据结构。upvalue 以一种高效的方式实现了词法作用域,使得函数能成为 lua 中的第一类值,也因其高效的设计,导致在实现上有点复杂。 函数 (proto) + upvalue 构成了闭包(closure),在 lua 中调用一个函数,实际上是调用一个闭包。upvalue 就相当于函数的上下文。 这种带 “上下文” 的函数,也...
lua 的表达式有一些特殊情况。 1. 被括号包起来的表达式永远被当成一个值[1] (f(x,y,z)),即使 f 返回多个值,这个表达式永远是单个值。 2. 多返回值的调整[1] 函数调用和变长参数表达式都会产生多个值,这些表达式被称为多返回值表达式(multires expressions)。 根据多返回值表达式所处的位置,有两条规则: 规则一:当多返...
lua vm 运行过程中,栈是一个重要的数据结构。 栈是一个很巧妙的设计,它同时能满足 lua、c 函数运行的需要,也能实现 lua 与 c 函数的互相调用。 1. 栈 1.1 栈的数据结构 一个操作系统线程中,可以运行多个 lua vm,lua vm 用 global_State 这个结构体来表示。 一个 lua vm 中,可以运行多条 lua thread,即协程,lu...
本文讲一讲如何查看 lua 的字节码(bytecode),以及如何看懂字节码。 以下分析基于 lua-5.4.6,下载地址:https://lua.org/ftp/ 。 1. 查看字节码 1.1 方法一:使用 luac luac 是 lua 自带的编译程序,用法是:luac -l -p <文件名> ,如果要完整展示,则用 -l -l,比如 luac -l -l -p ...
还没写完 … 本文是一篇总结文章,内容包括:1、现代 c++ 应该怎么合理的使用指针;2、发生内存泄漏如何定位。 都是一些比较 basic 的常识,如有错误,请指出,谢谢。 1. 智能指针 c++11 中共有四种智能指针,std::auto_ptr, std::unique_ptr, std::shared_ptr, std::weak_ptr。 std::auto_ptr...
很多时候,要真正理解 c++ 一些特性的实现原理,最快的方式是自己亲自查看 c++ 代码对应的汇编代码。 本文记录一下 c++ 如何查看生成出来的汇编代码,以及如何看懂代码,部分内容参考自《深入理解计算机系统》[1]。 1. 先不看汇编 汇编的可读性挺差的,如果有得选,还是先用 cpp insights,看一看编译器角度生成的源码。cpp insights 的地址是 https:/...
Manual:cppreference - Value categories 。 移动语义很简单,但它相关联的术语很复杂。本文尝试从历史的角度解释清楚这些乱七八糟的术语及其关联: 表达式 (expression)、类型(type)、值类别 (value categories); 左值 (lvalue)、右值 (rvalue)、广义左值 (glvalue...
可能有多年 c++ 编程经验,但回过头来发现,对一些基础概念却并不怎么熟悉,比如表达式、语句这些。有些概念,可能自以为知道,当要用文字把它表达出来的时候,又发现掌握得似乎不是很牢固。 这是一篇总结性的文章,涉及一些最 basic 的常识,如有错误,请指出,谢谢。 1. 概念 要精确的掌握 c++ 的概念,可以看以下材料: specification,比如 cppr...
所谓现代 c++,指的是从 c++11 开始的 c++,从 c++11 开始,加入一些比较现代的语言特性和改进了的库实现,使得用 c++ 开发少了很多心智负担,程序也更加健壮,“看起来像一门新语言”。 从 c++11 开始,每 3 年发布一个新版本,到今年(2024)已经有 5 个版本了,分别是 c++11、c++14、c++17、c++20、c++23,这 5 个版本引入了上百个新的语言...
本文总结 c++ 中 volatile 相关的一些知识。在多线程领域,它是被误解得最严重的,实际上,它对于多线程编程一点帮助都没有。 1. 被误解的 volatile 先说一下结论: volatile 只能阻止编译器优化,应该只把它用于 Memory Mapped I/O 的场景中,不应该将它用于解决多线程下的诸入原子读写之类的问题。 C++11...
多线程编程的水特别特别深,并且网上充斥着大量陈旧或者错误的文章,于是,我觉得有必要自己收集最新资料,做一次总结,故有【多线程编程】这一系列的文章。 首先我想厘清一下【线程同步】的概念。 1. 线程同步 先说我的结论:线程同步是一种约束(或机制),即一个线程还没访问完一个数据的时候,其他线程不能对这一个数据进行访问。 中文互联网上有很多文章在讲 “同步与互斥的区别”,典型的说法是类...
这是一篇关于 epoll 的文章,包含一个展示 et 模式和 lt 模式的 demo,以及一些注意事项。 1. epoll demo demo 参考自《Linux高性能服务器编程》[1],这个 demo 分别展示了 et 模式以及 lt 模式的用法。 demo 地址: https://github.com/antsmallant/antsmallant_blog_demo/tree...
同步、异步、阻塞、非阻塞,这几个概念挺要命的,容易把人搞糊涂。网上可以找到巨量的解释文章,stackoverflow、知乎、quora 上面都有,但没有一篇让我感到满意。有时候作者想通过白话一点的语言解释清楚这些概念,反而由于啰嗦导致解释不清。 1. 结论 经过一番研究,我得出如下结论: 阻塞和非阻塞,一般只用于 I/O 场景, 区别在于内核还没准备好时(如内核可读...
作为后端开发,特别是网络游戏后端开发,经常需要处理各种现网问题,其中有不少是网络相关的。 下面列举的工具主要是在 linux 下的,诊断线上服务器问题的时候,往往是分秒必争,所以这些工具都要用得很熟练,才能不耽误事。 1. 工具 1.1 netstat netstat 可以说是最常用的网络工具了,它的作用就是查看网络状态,tcp、udp、unix socket 都可以。一般是...
游戏开发是一个快速迭代的过程,代码复杂度也很高,借助于设计模式,可以帮助我们降低复杂度,降低系统间的耦合,从而高效高质的做出交付。 最近读了这本书:《游戏编程模式》[1],很受启发,所以结合书本知识以及自己的理解,写一写游戏中常用的设计模式。 1. 模式 1.1 单例模式 先说要点:这是唯一一个不推荐使用的模式,因为它害处多于好处。 尽管这个模式出现在了 GoF 的书[2]...
这篇文章主要想探讨一下游戏开发中的团队管理问题,本质上讨论的是团队生产力问题。我做过服务端主程,也做过软件部门的技术经理,对于这个主题是有一些心得可以讲一讲的。 本文将首先讲一下技术团队管理的目标是什么,之后展开讲如何实现这一目标,最后再讲一些疑难问题的处理。 1. 目标是什么 技术团队管理的终极目标是什么?是做出牛逼的架构,写出牛逼的、bug很少的代码吗? 都不是,赢才是终极的...
最近两年半真是一言难尽,不说也罢。世道再难,也要呼吸顺畅。借用莫老师的一句话:韧性生长,穿越周期。 1. 个人认知上的成长 这一年,认知得到了很大的提升,一方面是阅读了一些有用的书,另一方面是生活的困境促使我进行了大量的思考。对认知成长有帮助的书包括:周岭的《认知觉醒》,安德斯.艾利克森&罗伯特.普尔的《刻意练习》,瑞.达利欧的《原则》、《原则:应对变化中的世界秩序》,申克....
使用 lua 的时候有时候会遇到这样的报错:”attempt to yield across a C-call boundary”。 1. 网络上的解释 可以在网上找到一些关于这个问题的解释。 1.1 解释一 这个 issue:一个关于 yield across a C-call boundary 的问题,云风的解释是: C (skynet framework)-&g...
1. why 使用印象笔记(evernote 的中国版)已经好多年了,对它的持续可用性一直不放心,所以会定期手动对日志做备份。但最近我厌倦这么做了,于是打算试一下这两位老师提到的 obsidian,阮一峰:《最适合程序员的笔记软件》 [1],老C:《周刊(第18期):网状的思考,线性的写作》 [2]。 2. 关于 obsidian obsidian 的核心功能体验,可以参考这个:《...
本文记录一次对 prometheus pushgateway 做性能优化的过程,推送延迟从 200 秒下降到 0.1 秒。 1. 概况 prometheus 只允许拉取(pull)指标数据,不允许主动推给(push)它,所以要接入 prometheus,通常都需要实现一个 exporter 接口,也就是一个 http 接口,允许 prometheus 主动来拉数据。 但是我们的游戏...
瑞.达利欧的《原则》是今年读过的最好的几本书之一,另外几本是《刻意练习》,《原则:应对变化中的世界秩序》,《认知觉醒》,《中央帝国的财经密码》,《穿越百年中东》。 他很厉害、很有趣,研究生是在哈佛商学院读的,刚毕业就拿着很高的薪水在一家公司做期货交易,两年后创办了自己的公司–桥水,他的个人财富居于世界前100位,很牛很牛。 导言: 原则是根本性的真理,它构成了行动的基础,通...
本文探讨网络同步的几个问题。 1. 王者荣耀使用帧同步明智吗? 这个很难评,成王败寇,它成功了,它就是明智的。但是帧同步带来的心智负担还是很重的,他们的分享里面也提到他们花了很大的功夫去解决不一致问题。 个人更喜欢守望先锋的做法,虽然可能开发量更大,但至少没有埋下不一致这种大深坑。 2. 服务端预测 在 FPS 游戏中,会采用服务端预测的技术,服务端在没有收到输入的情况下,...
本文简单讲一讲 “帧同步” 的实现与优化。 1. 实现 帧同步的确定性,要求各种平台之上的客户端计算都是确定的,这些都可能导致不确定计算:浮点数,随机数,执行顺序,排序的稳定性,物理引擎。在实现上,一般有以下的方法: 浮点数可以使用定点数替代。 随机数可以统一随机数种子。 执行顺序,要保持一致,需要所有的逻辑要有一个统一的入口,每次 tick update 进入一个统...