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

推荐订阅源

The Cloudflare Blog
D
Darknet – Hacking Tools, Hacker News & Cyber Security
T
The Blog of Author Tim Ferriss
G
Google Developers Blog
小众软件
小众软件
J
Java Code Geeks
V
Visual Studio Blog
The Register - Security
The Register - Security
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
罗磊的独立博客
美团技术团队
阮一峰的网络日志
阮一峰的网络日志
V
V2EX
博客园 - 叶小钗
N
Netflix TechBlog - Medium
月光博客
月光博客
aimingoo的专栏
aimingoo的专栏
大猫的无限游戏
大猫的无限游戏
T
The Exploit Database - CXSecurity.com
The Hacker News
The Hacker News
Cisco Talos Blog
Cisco Talos Blog
Hacker News: Ask HN
Hacker News: Ask HN
Hacker News - Newest:
Hacker News - Newest: "LLM"
AWS News Blog
AWS News Blog
Webroot Blog
Webroot Blog
The Last Watchdog
The Last Watchdog
T
Threatpost
I
Intezer
T
Tenable Blog
L
LINUX DO - 热门话题
T
Tailwind CSS Blog
Scott Helme
Scott Helme
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
C
Cybersecurity and Infrastructure Security Agency CISA
Engineering at Meta
Engineering at Meta
S
Schneier on Security
Recent Announcements
Recent Announcements
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
F
Fortinet All Blogs
腾讯CDC
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
T
Troy Hunt's Blog
量子位
H
Hacker News: Front Page
V2EX - 技术
V2EX - 技术
Google Online Security Blog
Google Online Security Blog
人人都是产品经理
人人都是产品经理
博客园 - 【当耐特】
博客园 - Franky
www.infosecurity-magazine.com
www.infosecurity-magazine.com

王子亭的博客

2023 年度小结 HostedBeans: 基于 Beancount 的协作托管服务 离开 LeanCloud 为什么我选择 Apple 设备 2022 年度小结 如何进行技术面试(面试官视角) 为什么在 Apple Silicon 上装 Docker 这么难 2021 年度小结 我们并不需要 Deno 入手 MacBook Air (Apple Silicon) 2020 年度小结 我的 NAS 选型与搭建过程(基于开源方案) TypeScript:重新发明一次 JavaScript 加湿器选购指南 2019 年度小结(技术方面) 2019 年度小结 23 岁的我在想些什么 塞尔达传说:旷野之息(The Legend of Zelda: Breath of the Wild) 设计基于 Redis 的定时任务系统(ZSET + Scripting) 我和太空探索的故事 流浪地球和大刘的短篇小说 游轮之行 2018 年度小结 22 岁的我在想些什么 Play Cards: 探索通用的游戏后端方案 自由软件和开源许可证 入手 Tenda Nova MW6(Mesh 路由器) 游戏:城市天际线(Cities: Skylines) 2017 年度小结(技术方面)
2018 年度小结(技术方面)
王子亭 · 2019-01-31 · via 王子亭的博客

今年我完成的业余项目确实非常少,勉强算下来也就只有 DeployBeta 的 0.4 版本和 Elecpass 的 v3 版本。

所以我今年得到的一个重要的教训就是 一次要专注于一个项目,同时尽快完成一个阶段性的可用版本,尽快发布。尤其是对于我来说,还有全职工作,业余时间并不多,如果不能尽快发布,获得一些反馈,就失去了继续完善的动力,而且会摊子越铺越大,一直无法发布。

在这一点上,DeployBeta 是一个反面的例子,持续了两年的时间,但也没到可以对外发布的标准。而 Elecpass 是一个正面的例子,在 2017 年 10 月,我花了半个月的时间就发布了两个版本,之后一年多的时间我自己一直在使用,然后在今年十一月集中花了一周的时间发布了 v3 版本(筛选框、布局优化、强化编辑功能、编译 Windows 版),这个项目大部分的时候都是「已发布」状态,而不是还有功能做到一半。


在 DeployBeta v4 版本的前夕我将 DeployBeta 开源了,在 v4 和后续的未发布版本中,我实现了 MySQL、Redis、MongoDB 三种数据库的支持、重写了基于 Etcd 的 ORM。所以今年我也写了一些 Golang,今年我主要的怨念在于 Golang 中缺乏对于接口数组(或者说泛型数组)的支持,只能使用 interface{} 和反射来实现 ORM 中「获取结果数组」的功能。

这个 ORM 其实就是将 JSON 数据存储在 Etcd 中,同时提供关系和事务的简单封装。这其实和 Kubernetes 中的 api-server 做的事情差不多,但因为没有找到比较好的关于 Kubernetes 使用 Etcd 的文档,所以我没有太多地参考它。


为什么容器平台能够简化容器的管理工作呢?我认为一个重要的原因是容器平台提供了一种纯描述式的定义文件,让开发者去描述所期望的最终状态。这一点在 Kubernetes 中实现得最为彻底,我相信这也是 Kubernetes 成功的原因之一。

今年因为工作的原因,我非常深度地接触了 Kubernetes,在其基础上进行封装,来提供容器服务。Kubernetes 不仅仅是一个工具,同时也是一个平台,它以 RESTFul 风格的 API 将所有功能抽象为资源,然后由每种资源的 Controller 去将对象的实际状态同步到预期的状态。这意味着在 Kubernetes 的基础上你可以去添加自定义的资源和相应的 Controller 去拓展它的功能。

在对 Dockerfile 的抽象能力忍无可忍之后,今年我用 Node.js 为 Dockerfile 实现了一个简易的 DSL,主要是将 Dockerfile 分为多个段落,然后在每个段落中结构化地保存指令数据,以便在对 Dockerfile 的整个处理过程中随时向任何段落添加或修改指令,最后等到完成所有的处理之后再将结构化的指令数据生成真正的 Dockerfile。经过这样的过程生成的 Dockerfile 有着更规范的格式,更有利于跨应用甚至跨语言之间的缓存。

其实我们在生产环境使用容器技术已经很多年了,但很多时候只是将已有的程序跑在容器里而已,而没能做到 Container Native。例如我们实际上还有很多容器在依赖本地存储、没有有效的健康检查、不能正确地处理信号来实现平滑关闭。


我司今年发布了一个 游戏后端解决方案,它本质上是一个「消息转发服务」,帮助游戏的客户端之间来转发消息、同步状态。

但出于反作弊的需要,我们还需要提供一种在服务器端运行游戏逻辑的能力。对于暴露这种能力的方式,一开始我们内部有两种方案。我认为比较好的方案是将这种在服务器端运行的游戏逻辑也作为一个客户端去加入到消息服务中,以消息服务为中心与其他客户端进行交互。这样做的好处是:

  • 在服务器和客户端之间复用大部分的游戏逻辑
  • 单机游戏 => 动作同步 => 状态同步 的迁移过程非常平滑
  • 服务器端的游戏逻辑和消息转发服务解耦

为了验证这个方案的可行性,我花了一些时间制作了一个 Demo,实现了一个 简单的回合制卡牌游戏,这种模式后来也被我司发布为了正式的产品:Client Engine

在这个过程中我其实是第一次接触游戏后端的开发,其实我并没有去了解既有的游戏框架,但在不知不觉中也重新发明了一些轮子,例如「动作」和「状态」的概念,感觉去探索游戏的开发过程还是挺有意思的一键事情。


今年年初的时候我尝试为云引擎加上了 任务队列 的功能,因为云引擎本来已经有了基于 HTTP 的云函数功能,所以我想这个任务队列只提供一种调度的能力,而不提供计算资源,依然通过 HTTP 来调用原本的云函数。我认为这样的形式可以减少引入的新概念,降低介入的成本。

但低调公布之后的效果并不是很好,我觉得其中一个原因是是我自己就比较少用任务队列,所以比较难站在用户的角度去考虑他们需要任务队列有怎样的功能、希望超时和并发的控制是怎样的。在新的一年里我还会继续改进这个功能,去参考其他类似的云服务如何设计任何队列的功能。

大概是因为我的服务器端编程经验都在 Node.js 上,Node.js 中异步任务的成本很低,所以不需要出于减少线程开销的考虑去使用任务队列;同时我会通过 Redis 来维护一些关键状态,消除单点、保证因应用重启而中断的任务可以恢复,所以也几乎不需要任务队列去保证任务执行的连续性。

在这个功能的实现上我重度地使用了 Redis:使用 Redis 存储所有的状态、提供一致性保证,用 Node.js 去实现 Worker,调用 Lua Script 去实现原子操作。说起来 Redis 是我用过最好的服务器端软件之一,我认为 Redis 找到了一个非常好的切入点、找准了自己的定位,才使得它的设计看起来那么简单。

应该说任务队列的需求是非常多样化的,每种业务可能都会对任务队列有不同的需求,再加上很大程度上又是语言相关的,所以我觉得在这个方面如果能做一些开源项目也会有比较大的空间,例如我就觉得 Redis 5 中的 Stream 类型就是为任务队列设计的,想去写一个充分利用 Stream 特性的任务队列。