我开发了一个基于 Beancount 的账本托管服务 HostedBeans,欢迎大家来了解纯文本复式记账并试用我的服务。

2018 年度小结(技术方面)

今年我完成的业余项目确实非常少,勉强算下来也就只有 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 特性的任务队列。

游轮之行

就如 2018 年度小结 中说的那样,蛋黄并不喜欢出门旅行,就喜欢宅在家里,那怎么办呢,于是我们想到了一种合适的「佛系旅行项目」—— 游轮。在游轮上不需要做计划、想去哪就去哪,绝大部分项目不需要额外付费,在船上只需要走几步路就可以回到室内、找到卫生间,再多走几步就可以回到房间或者找到餐厅(也不需要额外付费)。

我们去的是「喜悦号」的游轮,往返上海和福冈(船每次出海停靠日本不同的港口)。5 天 4 夜,其实就是四个整天(两天在海上、一天停靠在日本、登船和下船加起来一天)。总体上我是比较满意的,船上设施和房间内都非常新、非常干净(蛋黄非常看重这一点),这艘船只启用了一年半,三月末就会离开中国,所以还是要把握机会的。

整个行程人均 2900 元(2200 房费 + 400 固定支出的「小费」+ 300 额外付费项目),这个性价比我觉得也非常可以了,这个价格是淡季的价格,赶上假期就会贵很多。我们住的是阳台房,基本就是比快捷酒店小一些的房间,卫生间很小但设施设计得很好,所以并不难用,有一个露天阳台可以看海。

关于船上设施网上的介绍很全了,我就只谈个人感受。

我们全部吃的是免费餐厅(因为网上测评说收费餐厅并没有比免费的强多少,然后价格很贵),吃得还是很好的,有两种免费餐厅,一种是自助餐,面积很大,饮料、水果和糕点很全、主菜每天会变化但品种不多、没什么海鲜。

另一种是正餐厅,每天有一套不同的菜单(五、六个菜),中西餐的菜混合,每天都有一道虾(很大),还有牛排和三文鱼,这些食材的品质我觉得都是非常好的。然而中餐做得比较「西式」,不看菜单根本猜不出来是什么菜,经蛋黄点拨发现原来是他们不会炒菜,感觉都是炖出来的 … 西餐的话我还是非常满意的。

刚进黄海的时候风景不怎么样,水很浑浊,到靠近日本的地方海才变得非常蓝、非常绿,天也是蓝的,很美。

然后晚上可以看到满天的星星,已经很多年没见过了(当然这一点比较依赖于天气,只有一天晚上没有云,才能看到星星)。船很稳,前两天根本感觉,后面两天开始有一些浪,但还是非常稳的,稳到蛋黄觉得船震没有什么特别的感觉。

上海到日本这片海域,基本全程都能看到其他的船,甲板上有两个望远镜可以用,但蛋黄觉得自己带一个望远镜会更好,可以看海岸、船和海鸥。

室外的气温和昆山差不多,但顶层的风非常大;室内则是恒温的,空调非常足。

甲板上有露天的温水游泳池,还看到有人在里面游。

船上有很多演出和活动(还有广场舞),都是免费的,我们看了两场歌舞剧和一场杂耍。歌舞剧看不太懂,但舞台效果还是很不错的。船上有几个露天的泳池,里面是温水,看到有几个人在游。还有一些乒乓球台,和蛋黄打了很久的乒乓球。

付费娱乐项目我最感兴趣的还是卡丁车,$10 一次五分钟,和之前在昆山玩的比起来价格差不多,但不够刺激:车不够快、不能漂移、赛道窄不容易超车,碰到不会开的人就会一直堵着路,不过既然是在船上也不能要求太高了,我全程玩了三场还是挺开心的。因为船上以大爷大妈为主,所以这些娱乐项目的人很少,不需要排队。

到日本之后的岸上观光项目很坑,基本相当于是被卖给了旅行社(以每个人 500 的价格,不想跟团的话要交 500),带你去一些一点都不好玩的景点、一点都不好吃的「美食广场」、一点都不便宜的免税店,行程还特别赶。

关于这个船三月末离开中国,主要是觉得中国人额外的消费太少,工作人员说在欧美航线一周可以卖 50000 瓶啤酒,然而船上基本都是中老年人,酒吧根本没有人。我和蛋黄觉得很大原因是这个公司(这个公司只有这一艘游轮在中国)不了解中国的情况,没有开发出适合中国大爷大妈的额外消费项目,比如搞搞中医按摩针灸、卖点保健品,实在不行搞个水池让大家扔硬币也行呀。有钱的大爷大妈还是很多的,有一天吃饭和做旁边的一对上海大爷大妈聊天,家里在上海几套房,经常坐游轮(估计这是他们坐的最低端的游轮了),说今天买包买衣服就花了两万多 …. 还觉得特别值。

据说这艘船是为中国人设计的(比如热水和热水壶),船上大部分的服务人员都是中国人,餐厅和客房的服务员则主要是东南亚人。不过总之绝大部分地方都只需要用到中文,对大爷大妈还是非常友好的。东南亚的服务人员的态度非常好,总会笑着打招呼,虽然不会中文也会积极地沟通;然而部分中国的服务人员态度不是很好。

船上网络是额外付费的,大概 500 元全程,我没有买,因为我已经做好准备把「没有网络」作为这次游轮体验的一部分了。实际上因为每天的活动内容都很丰富,没有网络也不会无聊,就看着船下的海浪都可以看很久。我带了电脑、几本书、iPad 和相机,但实际上并没有用到,就是因为船上的活动太丰富;相机的话,因为我换了 iPhone 8,感觉和相机的拍照效果已经差不多了,所以也没怎么用上。

我们在船上看了泰坦尼克号作为安全教育片,我事前事后也了解了不少游轮的背景知识以及泰坦尼克号的故事,经过那之后,现在海上的安全标准应该已经非常可靠了,但蛋黄还是表示想坐一坐救生船(忘记拍救生船的照片了)。

2018 年度小结

转眼又一年过去了,今年我们又回到了昆山,节奏放慢了很多,更多的时间花在了「生活」本身上面。

就如去年的小结中计划的那样,今年四月我们从北京搬回了昆山,接着搬家的机会添置了很多新物件,比如戴森的吸尘器、洗碗机、全自动咖啡机、米皮新风、扫地机器人、恒温龙头、Mesh 路由器、冰箱、桌子椅子、1.8 米的床和床垫等。昆山的厨房也更大了一点,买了更多的锅具和碗筷,感觉生活质量提高了一大截。

在昆山安顿下来之后,因为家里有了更多的地方,所以又买了一些玩具,包括 乐高的跑车乐高的小火车,甚至现在有一个大桌子专门摆我的玩具。

今年我也花了不少时间在「建造类」游戏上,主要包括 天际线(Cities: Skylines)、缺氧(Oxygen Not Included)和异形工厂(Factorio)。异星工厂是我今年新发现的游戏,主要内容是建造自动化的流水线,非常对我的胃口,记得当时连着玩了几天,花了 50 多个小时第一次通关。

皮蛋豆腐今年也三岁了,和之前比起来它们更加「成熟稳重」了。从搬到昆山开始,豆腐总在猫砂盆旁边的地面上撒尿,经过一番摸索后发现原来是它对每天晚上被关在阳台表示不满。于是从那之后就不再把皮蛋豆腐关在阳台上了,即使我们出门也会把它们留在客厅,在我们睡觉的时候也会让它们进入我们的房间,它们有时候睡在衣柜里、有时候睡在地上、有时候睡在椅子上、还有的时候睡在蛋黄的被子上,但它们要是睡在我的被子上就会被我踢下去。

今年也全面启动移民的进程,我们的主要目标是加拿大,毕竟加拿大是英语国家、是高福利的发达国家,同时也是一个传统的移民国家。对于我来说主要是自考学历和英语这两大块,今年一年都在背单词,但其实三天打渔两天晒网,效果并不是很显著。

关于英语学习,我觉得 我们老板的文章 就挺有道理的,要在实际的日常场景中学习英语,将之前消费的一部分中文内容替换成英文。于是我将手机和电脑的系统语言改为英语、开始在洗澡时改听英文的播客、改去 Youtube 直接看一些英文播主的视频、去读技术类的英文书。在产出的方面则新的开源项目都使用英文来写文档和注释,后续还打算开始在 Medium 上开始写英文的博客。

在九月份的时候,我放弃了之前等自动驾驶汽车的想法,决定考一个驾照,主要是考虑可以创造一种租车前往公共交通不便利的地方的可能,尤其如果以后准备去加拿大的话。于是我和蛋黄一块报名,顺利通过了科目一和科目二,剩下的部分则有待明年继续。

在今年的最后两个月,我和蛋黄陷入了一场长达两个月的争吵,主要是关于原生家庭的观念冲突。虽然我们都从一开始就认为我们作为一个小家庭应该和双方的原生家庭保持独立,但因为成长环境、和家人的相处方式的不同,在具体的做法上面还是有非常大的分歧。我不想在这里描述细节,但这件事对我们的负面影响都很大,并且一直持续到了 2019 年。

今年和蛋黄一起去了沈阳、天津和无锡旅行,不过蛋黄其实并不喜欢出门旅行,在外面一副特别「丧」的样子,有时候还发脾气。

除此之外,我还和公司一起去了菲律宾、自己去了海南。在菲律宾的长滩岛的体验其实并不怎么好 —— 主要是没什么吃的,虽然是一个小岛,但并没有吃到什么海鲜。

在 iPhone SE 服役两年半之后,在双十一我入手了 iPhone 8,相比于全面屏和人脸识别,我还是更喜欢指纹。无线充电也非常方便,尤其后来我在家里的桌面上打了一个孔,安装了宜家的嵌入式充电器。

今年币圈和整个投资市场、全球经济都非常不好,大家都说今年只要不亏就算赚了。在股票上面我今年勉强没有亏,但在币圈可是亏惨了,相比于年初几乎跌掉了八成。

精子生于 1995 年,英文 ID jysperm.

订阅推送

通过 Telegram Channel 订阅我的博客日志、产品和项目的动态:

王子亭的博客 @ Telegram


通过邮件订阅订阅我的博客日志、产品和项目的动态(历史邮件):

该博客使用基于  Hexo  的  simpleblock  主题。博客内容使用  CC BY-NC-ND  授权发布。最后生成于 2024-04-08.