pomelo是网易基于Node.js实现的一套完整的服务器引擎。
官方中文wiki:https://github.com/NetEase/pomelo/wiki/Home-in-Chinese
最近开始使用该引擎,做一个源码阅读的笔记
学习pomelo源码之前还需要学习一下Node.js的基础知识
http://nodejs.cn/api/modules.html 官方文档,可以先学一下Node.js的加载模块机制
一、根据官方wiki安装pomelo
https://github.com/NetEase/pomelo/wiki/%E5%AE%89%E8%A3%85pomelo
二、创建一个pomelo项目
https://github.com/NetEase/pomelo/wiki/pomelo%E7%9A%84HelloWorld
三、开始正式分析pomelo的一些基础模块
game-server中的文件目录如下:
在node_modules中找到pomelo模块
这里先分析一些简单模块:
-
pomelo-loader
源码路径就在lib下,可以看到只有一个文件,非常简单。
这个模块的功能就是加载一个文件夹下(不递归)的所有js文件,并返回以名字做key,模块做value的一个map
记载的时候会清除掉require中相应的模块缓存
-
pomelo-logger
基于log4js的一个日志系统
https://github.com/log4js-node/log4js-node
-
pomelo-protocol
将字串封装为byte数组。两种封装方式Package和Message。数组前几个字节有特定意义,也规定好了消息类型。
详见代码pomelo-protocol/lib/protocol.js
-
pomelo-scheduler
调度器。根据传入的时间开启任务,根据间隔执行任务,可以设置执行次数
pomelo-scheduler/README.md 有详细使用方法
使用方式schedule.scheduleJob 第一个参数支持两种形式
1) 简单模式 simpleTrigger.js // 按毫秒的间隔执行一定次数
入参为 object = {
start: number, // Date.now(); 毫秒
period: number, // 执行粒度 毫秒
count: number, // 执行次数 -1就是无限次数
};
2) 复杂模式 cronTrigger.js // 按所传参数区间最小间隔执行
入参为字符串 支持格式'xx xx xx xx xx xx' // 年月日时分秒用空格隔开
每一个字段中 ,代表包含 -代表范围 /代表间隔 a/b:从a开始间隔b
入参: '2018 12 1/3 20 15,16-20,50 20'
解释: 2018年12月(1,4,7,10,13,16,19,22,25,28,31)日20时(15,16,17,18,19,20,50)分20秒
最终存入cronTrigger中的cronTimes中:
cronTrigger = [
[2018],
[12],
[1,4,7,10,13,16,19,22,25,28,31],
[20],
[15,16,17,18,19,20,50],
[20]
];
schedule.js内部的任务队列priorityQueue是一个最小堆队列
查看schedule.js源码可以发现,只会对任务列表中最靠前的设置一个定时器
在schedule.js中的excuteJob中处理具体任务。当执行一个任务时会做一个判断
默认是10ms,也就是每次执行时会查找当前任务队列中10ms之内要执行的任务并执行
考虑到函数调用开销等,这里无法做到毫秒级的精确。
设置accuracy=0之后,setTimeout参数还可能为负,这里做个简单测试:
setTimeout(() => {
console.log('-10 : ', Date.now());
}, -10);
setTimeout(() => {
console.log('0 : ', Date.now());
}, 0);
setTimeout(() => {
console.log('1 : ', Date.now());
}, 1);
setTimeout(() => {
console.log('2 : ', Date.now());
}, 2);
setTimeout(() => {
console.log('10 : ', Date.now());
}, 10);
setTimeout(() => {
console.log('100 : ', Date.now());
}, 100);
输出结果如下:
可以发现setTImeout本身就有一些毫秒级的损失,所以这里的10ms检测对调度的影响不大,已经实现了秒级的精确,足够应对游戏服务器的日常使用