1:demo
--main.lua
local skynet = require "skynet"
skynet.start(function()
print("Sever start")
skynet.newservice("simpledb")
--发消息给simpledb服务
skynet.send("SIMPLEDB","lua","TEST")
local i = 0
while true do
i = i>10000000 and 0 or i+1
if i==0 then
print("working")
end
end
skynet.exit()
end)
-- simpledb.lua
local skynet = require "skynet"
require "skynet.manager" -- import skynet.register
local db = {}
local command = {}
function command.TEST()
print("Simpledb test")
return true
end
skynet.start(function()
print("Simpledb start")
skynet.dispatch("lua", function(session, address, cmd, ...)
local f = command[string.upper(cmd)]
if f then
skynet.ret(skynet.pack(f(...)))
else
error(string.format("Unknown command %s", tostring(cmd)))
end
end)
skynet.register "SIMPLEDB"
end)
--配置文件
root = "./"
thread = 1
logger = nil
logpath = "."
harbor = 1
address = "127.0.0.1:2526"
master = "127.0.0.1:2013"
start = "main"
bootstrap = "snlua bootstrap"
standalone = "0.0.0.0:2013"
luaservice = root.."service/?.lua;"..root.."test/?.lua;"..root.."examples/?.lua"
lualoader = "lualib/loader.lua"
snax = root.."examples/?.lua;"..root.."test/?.lua"
cpath = root.."cservice/?.so"
这里的thread 设置为1 只有一个调度线程
这时 main模块会一直占据cpu 而我们的simpledb 就没有机会去处理 TEST消息
为什么会这样?
这和skynet的调度机制有关。skynet使用全局队列保存了要调度的服务,调度算法是先来先服务。如果某个服务有新消息,就把这个服务加到调度队列中,然后等待调度线程调度。而skynet服务的调度切换依赖于协程的挂起,如果当前调度的服务没有主动挂起或退出,就会一直执行,不调度其他服务了。
2:harbor
skynet 可以启动多个节点,不同节点内部的服务地址是相互唯一的,32bit整数, 同一进程的地址高8bit相同(用于区分一个服务处于哪个节点)
每个节点之中 都有一个特殊的服务叫“港口harbor, 当一个消息的目的地址高位和本地址不同,消息就被投递到barbor服务中, 再通过tcp连接传输到目的节点的barbor服务中去--------不同节点之间通过master这个服务建立网络,此可为单独的进程(每个节点都会根据config中的master项去连接master,master再安排不同额harbor服务建立连接)”
3:创建服务
skynet.start(function()
-- 创建新服务返回服务处理者
local handler = skynet.newservice("new_service")
-- 为服务设置别名
skynet.name(".local_alias", handler) -- 设置本地别名(必须是 .开头)
skynet.name("global_name", handler) -- 设置全局别名
-- 获取本地别名返回别名所对应的服务处理者
handler = skynet.localname(".local_alias")
skynet.error("local alias .local_alias's handler is", skynet.address(handler))
-- 获取本地别名返回别名所对应的服务处理者
handler = skynet.localname("global_alias")
skynet.error("local alias global_alias's handler is", skynet.address(handler))
-- 查询本地别名所对应的服务提供者
handler = harbor.queryname(".local_alias")
skynet.error("query name .local_alias's handler is", skynet.address(handler))
-- 查询全局别名所对应的服务提供者
handler = harbor.queryname("global_alias")
--全局的别名不存在,则queryname 将会阻塞,直到全局别名的服务建立成功,
skynet.error("query name global_alias's handler is", skynet.address(handler))
end)