TODO
TODO
TODO
TODO
TODO
skynet的配置文件选项thread,指定启动多少个工作线程;请合理配置该选项,通常将它设置为CPU核心数,但是不要超过CPU核心数,否则性能反而会降低。
TODO
根据skynet的特点,如果CPU运算能力不足,选用更多核心的机器比增加物理机性价比高
skynet服务在收到消息时,会创建一个协程,在协程中会运行消息处理方法(即用skynet.dispatch设置的回调方法);这意味着,如果在消息处理方法中调用阻塞API(如:skynet.call, skynet.sleep, socket.read)时,服务不会被卡住(仅仅是处理消息的协程被卡住),导致程序的执行时序得不到保证。
-
3rd第三方库,包括:
lua语言支持lpegjemalloc内存管理lua-md5md5加密
-
lualib- lua的辅助函数
-
lualib-srclua调C提供C层级的API调用,包括:
- socket模块API
- skynet消息发送,注册回调函数API
-
servicelua层服务,依附于snlua这个c服务,涵盖skynet lua层级的一些基本服务,包括:
- lua层级服务的bootstrap服务
- gate服务
- 供lua层创建新服务的launcher服务
-
service-src依附于skynet核心模块的c服务,包括:
- 日志
- snlua
-
skynet-src包含skynet最核心机制的模块,包括:
- 逻辑入口
- skynet_module模块
- skynet_context模块
- 消息队列
- 定时器
- socket
- 每一个
socket对应一个lua vm和一个per client mq - 有一个
socket thread轮询所有的socket,收到信息后,打包发送到per client mq中 - 将
per client mq挂到global message queue的尾部 worker threads从global message queue头部开始,获取每个client对应的消息队列- 处理获取到的消息队列,用完放回
global message queue
start=>start: 消费开始
sleep=>operation: 线程睡眠2.5ms
wakeup=>operation: 唤醒线程
pop=>operation: 从global_mq中pop一个次级消息队列
bempty=>condition: 次级消息队列是否为空?
pop=>operation: 从次级消息队列pop出n条消息,并将其传递给callback函数
callback=>operation: callback函数回调消息
pushback=>operation: 将用完的次级消息队列push回global_mq
start->sleep->wakeup->bempty
bempty(yes)->sleep
bempty(no)->pop->callback->pushback(right)->sleep
线程从次级消息队列pop出消息时,消息的条数取决于线程的权重w:
-
w<0一个线程一次消费一条消息
-
w==0一个线程一次消费完次级消息队列中的所有消息
-
w>0一个线程一次消费w条消息
skynet使用以下特性保证线程安全:
- 依附于skynet核心模块的c服务;
- global_mq和次级消息队列在push/pop时都有加
spinlock; - 通过handle从handle_storage的slot里获取
skynet_context时,加上了rowlock。
- 每个
OS thread会创建一个lua vm - 每个
lua vm会创建海量的coroutine
注意:
- 不支持任务跨
lua vm迁移,coroutine是lua vm内部的数据结构,两个lua vm之间的coroutine无法通用。
| 包头 | type | 其它 |
|---|---|---|
| 2byte | 1byte | 变长 |
-
进程内消息
消息头 消息内容 空白区 8byte 256byte 256byte 常用的序列化格式:
- C服务的文本协议
- Lua服务的自定义序列化库
- 自定义的内存数据结构
- ...
-
跨进程消息
常用的序列化格式:
- 自定义协议
- sproto
- Google Proto Buffers
- JSON
- ...
master/slave模式下节点的harbor之间通过master来建立网络,master既可以是一个单独的进程也可以依附于某个进程(默认)。
master其实就是一个简单的内存key-value数据库;key表示节点的名字/ID,value存储节点harbor的地址信息。
一个5节点网络示意图:
- master连接所有slave节点
- slave节点的新增/减少/服务变更都是先通知master,再由master转发
cluster模式兼容master/slave模式,cluster模式其实就是用更上层的api来实现一个节点信息查询系统;通过查询注册的节点以及对应的服务信息来远程调用,从而实现消息路由。


