后端技术_Skynet设计原理
最近更新:2024-09-23
|
字数总计:808
|
阅读估时:3分钟
|
阅读量:次
- Skynet框架概述
- 抽象模型
- 用户态抽象actor
- 对等actor
- 使用Skynet框架
- 公平调度原理
- skynet
- workflow
- 问题
Skynet框架概述
抽象模型
- 抽象了actor并发模型
- 在用户层去抽象进程(如一个用户一个进程,一个任务一个进程等)
- actor怎么运行?
- 消息驱动actor运行(因为共享用户态内存,加锁麻烦)
- 网络消息驱动(消息怎么存储?消息队列)
- 定时消息驱动
- 消息队列(每一个抽象的进程都有)
- 都是异步的消息,会涉及回调处理
- 协程消除回调
- sessionid选择协程
用户态抽象actor
- 一个actor对应一个lua虚拟机,一个虚拟机只有几百k的大小,所以可以创建很多个
- 每个actor进程有隔离的运行环境
对等actor
- 所有的actor都是对等的概念
- 公平调度
使用Skynet框架
- skynet/ (skynet源码)
- app/ (自己的代码)
- config
1 2 3 4 5 6 7 8 9
| thread = 8 -- 底层8线程 logger = nil -- 日志打在控制台,如果希望打在文件里,就写文件 harber = 0 -- 集群相关 start = "main" -- 最开始启动的是main服务 lua_path = "./skynet/lualib/?.lua;./skynet/lualib/?/init.lua;" -- lua脚本加载路径 luaservice = "./skynet/service/?.lua;./app/?.lua" -- lua抽象的进程 lualoader = "./skynet/lualib/lualoader.lua" cpath = "./skynet/cservice/?.so" lua_cpath = "./skynet/luaclib/?.so"
|
- app/main.lua
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| local skynet = require "skynet" local skynet = require "skynet.socket"
skynet.start(function() local listenfd = socket.listen("0.0.0.0", 8888) socket.start(listenfd, function(clientfd, addr) print("recive a client: " clientfd, addr) end) skynet.timeout(100, function() print("after 1s, do here") end) print("hello skynet")
local slave = skynet.newservice("slave") local response = skynet.call(slave, "lua", "ping") print(response)
end)
|
- Makefile
1 2 3 4 5
| SKYNET_PATH ?= ./skynet all: cd $(SKYNET_PATH) && $(MAKE) PLAT='linux' clean: cd $(SKYNET_PATH) && $(MAKE) clean
|
- 启动服务
- 添加一个service
- app/slave.lua
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| local skynet = require "skynet"
local CMD = {}
function CMD.ping() skynet.retpack("pang") end
skynet.start(function() skynet.dispatch("lua", function(session, source, cmd, ...) local func = assert(CMD[cmd]) func(...) end) end)
|
公平调度原理
skynet
- 调度实体:actor,一个actor有一个消息队列
- 找活跃的消息队列 有消息的消息队列
- 组织所有的活跃的消息队列
- 以actor为一级组织一个有序链表(队列)
- 从队头的actor消费一个消息,若还有剩余消息,将该actor添加到有序链表的队尾
- 重复1——4
workflow
- 调度实体:某种资源,一个资源有一个任务队列,如计算、通信、文件io、cuda、定时器等
- 公平调度目的:让每个资源的执行是公平的
- 找活跃的任务 有任务的任务队列
- 组织所有的活跃的任务队列
- 以资源为一级组织一个有序链表(队列)
- 从队头的资源执行(消费)一个任务,若还有剩余任务,将该资源添加到队尾
- 重复1——4
问题
- 由于用户的问题,每个actor的消息并不是平均的,有些actor的任务就是比较多,所以应用级别上是不公平的
- 解决:工作线程设置权重
2024-03-14
该篇文章被 Cleofwine
归为分类:
服务端