【APISIX源码探究】AdminAPI

AdminAPI用于控制APISIX,如添加路由等操作。默认情况下AdminAPI将监听 9080端口,可以通过admin_listen配置修改监听端口。

nginx.conf

server {
    # 修改为独立端口
    listen 127.0.0.1:9180;
    set $upstream_scheme             'http';
    set $upstream_host               $http_host;
    set $upstream_uri                '';
    location /apisix/admin {
        allow 0.0.0.0/0;
        deny all;
        content_by_lua_block {
            apisix.http_admin()
        }
    }
}
复制代码

主流程

在接收到请求时会进入主流程进行处理。首先是获取在init_worker阶段加载的路由信息,路由信息及处理函数保存在/apisix/admin目录下,接着就是根据路由派发到对应的处理函数。

local router

function _M.http_admin()
    -- 加载路由信息,路由信息在init_worker赋值
    if not router then
        router = admin_init.get()
    end

    core.response.set_header("Server", ver_header)
    -- add cors rsp header
    cors_admin()

    -- add content type to rsp header
    add_content_type()

    -- core.log.info("uri: ", get_var("uri"), " method: ", get_method())
    local ok = router:dispatch(get_var("uri"), {method = get_method()})
    if not ok then
        ngx_exit(404)
    end
end
复制代码

请求路由

admin_api中,系统定义了以下三个路由,其中/apisix/admin/*用于处理主要业务逻辑,通过各个模块暴露出的接口增删改查相应信息。其余两个路由用于热更新插件。

local uri_route = {
    {
        paths = [[/apisix/admin/*]],
        methods = {"GET", "PUT", "POST", "DELETE", "PATCH"},
        handler = run,
    },
    {
        paths = [[/apisix/admin/plugins/list]],
        methods = {"GET"},
        handler = get_plugins_list,
    },
    {
        paths = "/apisix/admin/plugins/reload",
        methods = {"PUT"},
        handler = post_reload_plugins,
    },
}

复制代码

请求处理

local function run()
    local api_ctx = {}
    core.ctx.set_vars_meta(api_ctx)
    ngx.ctx.api_ctx = api_ctx
    -- 解析url
    local uri_segs = core.utils.split_uri(ngx.var.uri)
    core.log.info("uri: ", core.json.delay_encode(uri_segs))
    -- /apisix/admin/consumers
    local seg_res, seg_id = uri_segs[4], uri_segs[5]

    -- 根据url信息选择相应模块处理
    local resources = {
        routes          = require("apisix.admin.routes"),
        services        = require("apisix.admin.services"),
        upstreams       = require("apisix.admin.upstreams"),
        consumers       = require("apisix.admin.consumers"),
        plugins         = require("apisix.admin.plugins"),
    }
    local resource = resources[seg_res]
    -- 解析请求method
    local method = str_lower(get_method())
    -- 解析请求body参数
    local req_body, err = core.request.get_body(MAX_REQ_BODY)
    local data, err = core.json.decode(req_body)
    req_body = data
    -- 获取请求query参数
    local uri_args = ngx.req.get_uri_args() or {}
    -- 执行模块对应代码
    local code, data = resource[method](seg_id, req_body, seg_sub_path,
                                        uri_args)
    -- 返回响应
    core.response.exit(code, data)
end
复制代码

consumers模块

这里我们看下consumers模块具体的处理方法,Consumer在Apisix中扮演服务的消费者角色,其在admin_api中对外提供了put,get,delete方法。

我们看其中的put,用于新增或修改comsuer配置:

function _M.put(username, conf)
    -- 检查用户请求是否符合格式
    local consumer_name, err = check_conf(username, conf)
    -- 用于存储的key
    local key = "/consumers/" .. consumer_name
    -- 设置到etcd中
    local res, err = core.etcd.set(key, conf)
    -- 返回结果
    return res.status, res.body
end
复制代码
分类:
后端