apisix 拓展,自定义public api 获取注册中心服务列表

需求:

项目中用到了apisix做网关,apisix 支持配置注册中心,主动发现注册中心的服务。
于是我想到了直接通过 apisix 获取注册的服务列表,就不用自己再写一套这个拉取服务的逻辑了。
查看了apisix 的源码,发现数据并没有存放在 etcd 数据库,而是在内存中。
这里我主要讲一下,如何通过 apisix 开放一个接口,供外部访问内部数据。

前置知识

1.1注册中心配置

apixi 可以在 conf/config.yml 配置注册中心地址,以 nacos 为例:

discovery:
  nacos:
    host:
      - "http://${username}:${password}@${host1}:${port1}"
    prefix: "/nacos/v1/"
    fetch_interval: 30    # default 30 sec
    weight: 100           # default 100
    timeout:
      connect: 2000       # default 2000 ms
      send: 2000          # default 2000 ms
      read: 5000          # default 5000 ms

其它注册中心配置,请参照:官网

1.2 自定义插件

public api 需要和插件在一起才能使用, 如果需要自定义插件,可以参考 apisix 自定义认证插件.

public api

概述

public-api 插件可用于通过创建路由的方式暴露用户自定义的 API,默认情况下,在自定义插件中添加的公共 API 不对外暴露的,你需要手动配置一个路由并启用 public-api 插件。
以 jwt-auth 插件为例,你可以使用 jwt-auth 插件创建一个公共 API 端点 /apisix/plugin/jwt/sign 用于 JWT 认证:

基本步骤:

  1. 创建一个路由,并启用 jwt-auth 插件:
curl -X PUT 'http://127.0.0.1:9180/apisix/admin/routes/r1' \
    -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' \
    -H 'Content-Type: application/json' \
    -d '{
    "uri": "/apisix/plugin/jwt/sign",
    "plugins": {
        "public-api": {}
    }
}'

  1. 之后就可以通过调用它来获取 token 了
curl 'http://127.0.0.1:9080/apisix/plugin/jwt/sign?key=user-key'
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2NTk0Mjg1MzIsImtleSI6InVzZXIta2V5In0.NhrWrO-da4kXezxTLdgFBX2rJA2dF1qESs8IgmwhNd0
  1. 对应的源码
    在这里插入图片描述

服务发现 public api

自定义插件

如果 public api 有自定义插件的需求, 可以参考 apisix 自定义认证插件, 也可以参考我另一个文章,apsix 自定义插件
这里依旧以 jwt-auth 为例.

插件测试接口

先简单写个输出:

local function hello()
	local args = ngx.req.get_uri_args()
	if args["json"] then
		return 200, {msg = "world"}
	else
		return 200, "world\n"
	end
end

function _M.api()
    return {
        {
            methods = {"GET"},
            uri = "/apisix/plugin/jwt/sign",
            handler = hello,
        }
    }
end

插件热加载:
使用此命令无需重启 apisix

curl  http://127.0.0.1:9180/apisix/admin/plugins/reload -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT 

输出:

world

服务发现api实现

-- 列出配置的注册中心的所有数据
local function get_discovery_services()
    local response = {}
    local data
    local discovery = require("apisix.discovery.init").discovery
    local discovery_type = require("apisix.core.config_local").local_conf().discovery
    core.log.error("[discovery_type] is ", core.json.encode(discovery_type))
    for key, _ in pairs(discovery_type) do
        local dis_mod = discovery[key]
        local dump_data = dis_mod.dump_data
        if dump_data then
            data = dump_data();
            core.log.error("get_table_items: [key] is ", core.json.encode(key))
            core.log.error("get_table_items: [dump_data] is ", core.json.encode(data, true))
        end
        -- 将数据保存到t中
        response[key]=data
        data=nil
    end
    core.log.error("get_table_items: [dump_data] is ", core.json.encode(response, true))
    return 200, core.json.encode(response)
end

--对外暴露的api
function _M.api()
    return {
        {
            methods = {"GET"},
            uri = "/apisix/plugin/jwt/sign",
            handler = get_discovery_services,
        }
    }
end

测试

接口测试:

curl  http://127.0.0.1:9080/apisix/plugin/jwt/sign?key=user-key -i

结果:

[root@HOST-10-198-20-140 example]# curl http://127.0.0.1:9080/apisix/plugin/jwt/sign?key=user-key -i
HTTP/1.1 200 OK
Date: Thu, 16 May 2024 03:21:21 GMT
Content-Type: text/plain; charset=utf-8
Transfer-Encoding: chunked
Connection: keep-alive
Server: APISIX/3.7.0

{"nacos":{"services":{"xx":{"xx":{"xx-gateway":[{"host":"10.244.xx.xxx","weight":1,"port":8080}]}}},"config":{"host":["http://nacos:nacos@10.198.xx.xx:8848"],"prefix":"/nacos/v1/","weight":100,"secret_key":"","fetch_interval":30,"access_key":"","timeout":{"connect":2000,"send":2000,"read":5000}}}}

返参如下:
在这里插入图片描述
对于多注册中心的配置,这里也是适用的。

参考:https://apisix.apache.org/zh/docs/apisix/plugins/public-api/

  • 0
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值