kong流程学习
kong:
根据Nginx的不同执行阶段,kong先执行初始化master和worker进程。
init_by_lua_block {
require 'resty.core'
kong = require 'kong'
kong.init()
}
安装完之后加载/usr/local/share/lua/5.1/
下面的kong.lua,调用init()方法,加载配置文件,创建事件,建立路由。
singletons.dns = dns(config)
singletons.loaded_plugins = assert(load_plugins(config, dao, events))
singletons.serf = Serf.new(config, dao)
singletons.dao = dao
singletons.events = events
singletons.configuration = config
在数据库中检查所有的可用的插件,然后加载插件,插件必须有两个文件handler.lua和schema.lua。以keyauth插件为例,格式为:kong.plugins.keyauth.handler
和kong.plugins.keyauth.schema
。
如果存在kong.plugins.keyauth.hooks
则注册相应的事件。
不同的插件有不同的优先级,根据插件PRIORITY大小排序。
init_worker_by_lua_block {
kong.init_worker()
}
初始化worker_events(这里我不懂,根据worker的pid,建立路由和注册事件)
kong入口server监听8000端口,还开放一个8001端口提供了restful接口,用于后台查询api的调用,插件等。
处理中间任务,然后init_worker(),调用后台任务:
local function keepalive_handler(premature)
if premature then
return
end
-- all workers need to register a recurring timer, in case one of them
-- crashes. Hence, this must be called before the `get_lock()` call.
create_timer(KEEPALIVE_INTERVAL, keepalive_handler)
if not get_lock(KEEPALIVE_KEY, KEEPALIVE_INTERVAL) then
return
end
log(DEBUG, "sending keepalive event to datastore")
local nodes, err = singletons.dao.nodes:find_all {
name = singletons.serf.node_name
}
if err then
log(ERR, "could not retrieve nodes from datastore: ", err)
elseif #nodes == 1 then
local node = nodes[1]
local _, err = singletons.dao.nodes:update(node, node, {
ttl = singletons.configuration.cluster_ttl_on_failure,
quiet = true
})
if err then
log(ERR, "could not update node in datastore:", err)
end
end
end
在8000端口中:
access_by_lua_block {
kong.access()
}
before()方法相当于api的一个middleware,检测路由和http方法,获取ip端口,域名等。
after()方法返回一些kong的执行时间等。
在access中加载kong.plugins.keyauth.handler.lua
的方法中的access方法,调用前后分别调用before()和after()方法。
for plugin, plugin_conf in plugins_iterator(singletons.loaded_plugins, true) do
plugin.handler:access(plugin_conf)
end
遍历插件列表,存储在ngx.ctx.plugins_for_request中
header_filter_by_lua_block {
kong.header_filter()
}
body_filter_by_lua_block {
kong.body_filter()
}
log_by_lua_block {
kong.log()
}