Skynet是由服务组成的,为了解决服务之间调用时,服务地址的调用问题,Skynet为服务提供了别名机制,简单来说就是给服务取一个字符串的名字。服务的名字必须是唯一的且不可重复的。由于服务的地址运行时是唯一的,服务的名字也是唯一的。这样也就能解决集群通信时,如果多台机器中某一台机器宕机了,重启后服务的地址发生了变化,但名字是唯一的,因此其他机器调用不会受到影响。
每个服务启动之后都有一个整数来表示ID,也可以使用字符串ID来表示,例如0100000a,其实也就是把ID转换为字符串。但是当使用数字表示时,会根据服务的启动先后顺序而变化,因为它并不是一个固定的数值。如果想要方便的获取某个服务,可通过给服务设置别名来实现。
在Skynet中,服务别名也分为两种:本地别名、全局别名
- 本地别名:只能在当前Skynet节点上使用,本地别名必须使用
.
点号打头。 - 全局别名:可以在所有Skynet节点上使用,全局别名不能以
.
点号开头。
注意的是,本地别名和全局别名是可以同时存在的。
服务别名API需要通过导入skynet.manager
而附加的API,由于兼容目的或构建框架的目的而存在。
local skynet = require "skynet"
require "skynet.manager"
-
register(name)
为当前服务注册别名,可以是全局也可以是本地。简单来说,就是给当前服务起一个字符串的名字。
skynet.register(alias_name)
-
name(name, address)
为指定的服务处理者设定别名,可以是全局也可以是本地。也就是为address
制定的服务起一个名字。
skynet.name(alias_name, service_handler)
-
localname(alias_name)
查询本地别名为alias_name
的服务,返回service_handler
服务处理者,若不存在则返回nil
。
skynet.localname(alias_name)
- 查询别名为
alias_name
的服务,可以是全局别名也可以是本地别名。
skynet.queryname(alias_name)
当查询本地别名时返回servicehandler
若不存在则返回nil
,当查询全局别名时返回servicehandler
,若不存在则阻塞等待到该服务初始化完毕。
local skynet = require "skynet.harbor"
harbor.queryname(alias_name)
为服务注册别名
为普通服务注册别名
- 创建服务
$ vim ./demo/new_service.lua
local skynet = require "skynet"
skynet.start(function()
skynet.error("new service")
end)
- 创建测试文件
$ vim ./demo/service_alias_test.lua
local skynet = require "skynet"
require "skynet.manager"
local harbor = require "skynet.harbor"
-- 启动服务
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")
skynet.error("query name global_alias's handler is", skynet.address(handler))
end)
- 修改配置文件中的启动脚本
$ vim ./demo/config
start = "service_alias_test"
- 加载配置启动系统
$ ./skynet ./demo/config
[:0100000a] new service
[:01000009] local alias .local_alias's handler is :0100000a
[:01000009] local alias global_alias is nil
[:01000009] query name .local_alias's handler is 0100000a
[:01000009] query name global_alias's handler is :0100000a
全局别名查询阻塞
如果全局别名不存在则调用函数harbor.queryname
将会阻塞,直到全局别名的服务建立成功为止。