query = query,
headers = headers,
})
end
local function http_request_chunk(self, http_cli)
local endpoint, err = choose_endpoint(self)
ok, err = http_cli:connect({
scheme = endpoint.scheme,
host = endpoint.host,
port = endpoint.port,
ssl_verify = self.ssl_verify,
ssl_cert_path = self.ssl_cert_path,
ssl_key_path = self.ssl_key_path,
})
return endpoint, err
end
可见,APISIX 在每个 worker 进程中,通过 ngx.timer.at 和 lua-resty-etcd 库反复请求 etcd,以此保证每个 Worker 进程中都含有最新的配置 。
APISIX 配置与插件的远程变更接下来,我们看看怎样远程修改 etcd 中的配置 。
我们当然可以直接通过 gRPC 接口修改 etcd 中相应 key 的内容,再基于上述的 watch 机制使得 Nginx 集群自动更新配置 。然而,这样做的风险很大,因为配置请求没有经过校验,进面导致配置数据与 Nginx 集群不匹配!
通过 Nginx 的/apisix/admin/接口修改配置APISIX 提供了这么一种机制:访问任意 1 个 Nginx 节点,通过其 Worker 进程中的 Lua 代码校验请求成功后,再由/v3/dv/put 接口写入 etcd 中 。下面我们来看看 APISIX 是怎么实现的 。
首先,make run 生成的 nginx.conf 会自动监听 9080 端口(可通过 config.yaml 中 apisix.node_listen 配置修改),当 apisix.enable_admin 设置为 true 时,nginx.conf 就会生成以下配置:
server {
listen 9080 default_server reuseport;
location /apisix/admin {
content_by_lua_block {
apisix.http_admin()
}
}
}
这样,Nginx 接收到的/apisix/admin 请求将被 http_admin 函数处理:
-- /apisix/init.lua文件
function _M.http_admin()
local ok = router:dispatch(get_var("uri"), {method = get_method()})
end
admin 接口能够处理的 API ,其中,当 method 方法与 URI 不同时,dispatch 会执行不同的处理函数,其依据如下:
-- /apisix/admin/init.lua文件
local uri_route = {
{
paths = [[/apisix/admin/*]],
methods = {"GET", "PUT", "POST", "DELETE", "PATCH"},
handler = run,
},
{
paths = [[/apisix/admin/stream_routes/*]],
methods = {"GET", "PUT", "POST", "DELETE", "PATCH"},
handler = run_stream,
},
{
paths = [[/apisix/admin/plugins/list]],
methods = {"GET"},
handler = get_plugins_list,
},
{
paths = reload_event,
methods = {"PUT"},
handler = post_reload_plugins,
},
}
比如,当通过/apisix/admin/upstreams/1 和 PUT 方法创建 1 个 Upstream 上游时:
$ curl "http://127.0.0.1:9080/apisix/admin/upstreams/1" -H "X-API-KEY: edd1c9f034335f136f87ad84b625c8f1" -X PUT -d '
> {
> "type": "roundrobin",
> "nodes": {
> "httpbin.org:80": 1
> }
> }'
{"action":"set","node":{"key":"/apisix/upstreams/1","value":{"hash_on":"vars","nodes":{"httpbin.org:80":1},"create_time":1627982128,"update_time":1627982128,"scheme":"http","type":"roundrobin","pass_host":"pass","id":"1"}}}
你会在 error.log 中会看到如下日志(想看到这行日志,必须将 config.yaml 中的 nginx_config.error_log_level 设为 INFO):
2021/08/03 17:15:28 [info] 16437#16437: *23572 [lua] init.lua:130: handler(): uri: ["","apisix","admin","upstreams","1"], client: 127.0.0.1, server: _, request: "PUT /apisix/admin/upstreams/1 HTTP/1.1", host: "127.0.0.1:9080"
这行日志实际是由/apisix/admin/init.lua 中的 run 函数打印的,它的执行依据是上面的 uri_route 字典 。我们看下 run 函数的内容:
-- /apisix/admin/init.lua文件
local function run()
local uri_segs = core.utils.split_uri(ngx.var.uri)
core.log.info("uri: ", core.json.delay_encode(uri_segs))
local seg_res, seg_id = uri_segs[4], uri_segs[5]
local seg_sub_path = core.table.concat(uri_segs, "/", 6)
local resource = resources[seg_res]
local code, data = https://www.isolves.com/it/cxkf/qd/2022-01-14/resource[method](seg_id, req_body, seg_sub_path,
uri_args)
end
这里 resource[method]函数又被做了 1 次抽象,它是由 resources 字典决定的:
-- /apisix/admin/init.lua文件
local resources = {
routes = require("apisix.admin.routes"),
services = require("apisix.admin.services"),
推荐阅读
- win7开机后无法进入系统的处理
- 如何更改电脑的开机密码
- 孩子多大分房睡比较好
- 怎么查询被开通手机号?
- 电脑系统win10忘记开机密码强制重置教程
- 电脑没声音怎么办?电脑没声音了怎么恢复?
- 5 个网站将您的前端技能提升 100 倍
- 红茶中的生物碱,历史上最早的红茶
- 西安全运会开始和结束时间是多久?
- 客服|南宁一公司全是美女,都开奔驰奥迪,警方一查真相不堪入目