AutoArchiveIdleMonitor
AutoArchiveIdleMonitor(简称为 AAI)是一个常驻的监控器协程,它的主要作用是在检测到服务器离线或者服务器在线但人数为 0 时启动一个倒计时,在倒计时结束之后执行实例回收流程。该监控器协程是 go-aliyunmc 自动回收机制的核心,也是低成本理念的主要体现。
主循环
AAI 的主循环在不断检测以下各项之一是否有更新
- 整个协程的上下文是否结束
- 服务器状态的更新
- 倒计时结束信号
- 归档流程结束信号以及结果(未在图中画出,作为归档流程的一部分)
这一检查阻塞到其中任意一个信号到达,然后开始执行相应的流程。
- 如果协程的上下文结束,就终止整个 AAI。这种情况一般认为只发生在程序退出时
- 如果服务状态发生变化,就对这一变化调用 handleSnapshot 进行处理
- 如果倒计时结束,就进入到归档流程中
- 如果归档流程结束,就输出其结果
用流程图来表达如下:
注意流程图由于是线形的,其无法简洁表达“等待”,仅供参考。
handleSnapshot
handleSnapshot 用于对当前获取到的服务器状态快照进行一系列的判断来决定是否启动或取消倒计时。
取消倒计时仅当
- 服务器玩家数量大于 0,此时服务器一定在线,实例一定运行。
- 实例未运行
当以上条件均不满足,可以推知,实例一定在运行,服务器不在线或服务器在线且玩家数量为 0,此时启动倒计时。请注意流程图中没有包含此推导过程,启动倒计时的条件可能不明显。
实例回收流程
实例回收流程专门指 AAI 倒计时到期后触发的流程,包含以下步骤:
- 关闭服务器,这一步与关闭服务器任务效果相同
- 归档服务器,这一步与归档任务效果相同
- 强制删除实例,这一步与 DELETE /instance/active 效果相同
实例回收流程的第三步是强制删除操作,相当于对实例执行断电并强制删除,从而省去了关闭实例的过程。一个刚刚归档过的实例可以认为是可丢弃的(disposable)。
特殊设计
实例回收流程与归档任务有重合的部分,但因为实例回收流程相比归档任务多了两个步骤,因此实例回收流程没有复用归档任务(虽然是可以的)。系统中存在一个全局的标志 global_states.IsArchiving 用来表示是否有与归档相关的任务正在运行。实例回收流程、归档任务都会维护和参考这个标志。
- 任务继承:当 AAI 在尝试开始归档任务的时候发现已经有归档任务在执行,那么它将尝试等待该任务执行完毕并将执行完毕的结果视为等同其触发归档任务的结果。使用这一设计主要是考虑到归档任务耗时较长。
- 任务互斥:虽然 AAI 在实现上没有调用任务系统中的归档任务,但其任务互斥仍然成立。当 AAI 正在执行归档流程时,任务系统中的归档任务无法被触发。