Skynet服务构建

本文深入解析Skynet框架的消息处理机制,介绍服务API如初始化、启动、结束服务等关键操作,探讨环境变量设置与服务类型的差异,包括普通服务与全局唯一服务的区别及创建方式。

Skynet框架内部实现了一套消息处理过程,消息数据包在业务上是请求或回应,消息采用队列的方式进行处理,而处理者就是服务。

服务API

local skynet = require("skynet")
  1. 获取注册表中的变量值
skynet.getenv(varname)
  1. 设置注册表
skynet.setenv(name, value)
  1. 错误打印输出
skynet.error(...)
  1. 开启服务,使用回调函数初始化服务并将消息处理函数注册到C层。
skynet.start(func)
  1. 结束当前服务
skynet.exit()
  1. 获取当前服务句柄
skynet.self()
  1. 将服务句柄转换为字符串
skynet.address(handle)
  1. 退出Skynet进程
require "skynet.manager"
skynet.abort()
  1. 强制关闭服务
skynet.kill(address)

入门服务

载入Skynet并开启服务

# 确保当前目录位于skynet根目录下
$ pwd

# 创建目录并配置参数
$ mkdir demo 
$ sudo cp ./example/config ./demo
$ sudo cp ./example/config.path ./demo
$ vim config.path
# 将config.path中的example目录替换或加入为demo目录

# 创建文件并编写服务
$ cd demo
$ vim simple.lua
local skynet = require "skynet"
skynet.start(function()
  skynet.error("Server start")
end)

# 开启服务
$ ./skynet demo/config

环境变量

  • 预先记载的环境变量是在config中配置的,加载完毕后所有的服务service都能去获取已设置的环境变量。
  • 可以设置环境变量但不能修改已经存在的环境变量
  • 环境变量设置完成后当前节点上的所有服务都能访问到
  • 环境变量设置完成后当服务退出时,环境变量依然会存在。
$ vim ./demo/simple.lua
local skynet = require "skynet"

skynet.start(function()
  -- 获取默认配置
  skynet.error(skynet.getenv(skynet.address))
  -- 自定义配置并获取
  skynet.setenv("author", "junchow")
  skynet.error(skynet.getenv("author"))
  -- 退出服务节点
  skynet.exit()
end)

$ ./skynet ./demo/simple.lua

服务初始化

skynet.init用于注册服务之前的初始化,也就是在skynet.start之前运行。

$ vim ./demo/simple.lua
local skynet = require "skynet"

skynet.init(function()
  skynet.error("skynet server initialize")
end)

skynet.start(function()
  skynet.error("skynet server start")
end)

$ ./skynet  ./demo/simple.lua
[:01000009] Server initialize
[:01000009] Server start

服务类型

Skynet中的服务分为普通服务和全局唯一服务:

全局唯一服务

全局唯一的服务等同于单例,也就是说只能生成一个服务实例,不管调用多少次创建接口,最后都只会创建一个此类型的服务实例且全局唯一。

创建全局唯一服务

-- 创建当前节点的全局唯一服务
skynet.uniqueservice(name, ...)

-- 创建所有节点的全局唯一服务
-- 参数true表示此服务在所有节点之间是唯一的
skynet.uniqueservice(true, name, ...)

当调用uniqueservice只传入一个服务名时,表示创建当前Skynet节点的全局唯一服务。当第一个参数传递true,第二个参数传递服务名称时,则表示创建所有节点的全局唯一服务。创建成功后,若是第一次创建则返回服务地址,若是第二次创建则返回第一次创建的服务地址。

# 进入skynet目录
$ cd skynet

# 创建demo目录
$ mkdir demo

# 拷贝example目录下的config配置到demo目录
$ cp ./example/config ./demo

# 拷贝example目录下的路径配置 config.path 到 demo 目录
$ cp ./example/config.path ./

# 进入demo目录
$ cd demo

# 修改路径配置,添加demo目录到luaservice目录下和snax目录下
$ vim config.path
root = "./"
luaservice = root.."service/?.lua;"..root.."demo/?.lua;"
lualoader = root."lualib/loader.lua"
lua_path = root.."lualib/?.lua;"..root.."lualib/?/init.lua"
lua_cpath = root.."luaclib/?.so"
snax = root.."demo/?.lua"

# 创建服务
$ vim serviceunique.lua
local skynet = require "skynet"
skynet.start(function()
  skynet.error("uniqueservice is running");
end)

# 创建测试文件
$ vim serviceunique_test.lua
-- 引入skynet框架
local skynet = require "skynet"
-- 设置默认参数
local args = {...}
if #args==0 then
  table.insert(args, "uniqueservice")
end
-- 启动服务
skynet.start(function()
  skynet.error("uniqueservice is start")
  
  local us
  if #args==2 and args[1]=="true" then
    us = skynet.uniqueservice("true", args[2])
  else
    us = skynet.uniqueservice(args[1])
  end

  skynet.error("uniqueservice hanlder is ", skynet.address(us))
end)

# 修改配置中启动脚本为uniqueservice_test
$ vim config
include "config.path"
thread = 8
logger = nil
logpath = "."
harbor = 1
address = "127.0.0.1:2526"
master = "127.0.0.1:2013"
start = "uniqueservice_test"
bootstrap = "snlua bootstrap"
standalone = "0.0.0.0:2013"
cpath = root.."cservice/?.so"

# 运行服务
$ ./skynet ./demo/config
[:01000009] LAUNCH snlua uniqueservice_test
[:01000009] unqiueservice is start
[:0100000a] LAUNCH snlua uniqueservice
[:0100000a] uniqueservice is running
[:01000009] uniqueservice handler is 0100000a

查询全局唯一服务

若不清楚当前是否创建了全局唯一服务,可通过queryservice接口来查询,若没有创建则会一直等待直到目标服务被创建。当参数带true时则表示在所有节点中查询是否存在唯一的服务。

-- 若没有创建则会一直等待直到目标服务被创建
skynet.queryservice(name,...)
-- `true`表示在所有节点中查询是否存在唯一的服务
skynet.queryservice(true, name, ...)

调用queryservice时可以选择是否传递第一个参数true,表示查询的当前Skynet节点的全局唯一服,还是所有节点的全局唯一服。

这两种全局唯一服作用范围不同,所以可以同时存在同名但作用范围不同的全局唯一服。

普通服务

在每次调用创建接口时都会产生一个与之对应的服务实例。可以同时创建多个服务实例,并使用唯一的ID来区分每个服务实例。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值