Kong插件开发实战:从入门到精通

Kong插件开发实战:从入门到精通

【免费下载链接】kong Kong是一款高性能的开源API网关,支持多种协议和插件,能够实现API路由、认证、限流等功能,助力企业构建灵活、安全且可扩展的API架构。 【免费下载链接】kong 项目地址: https://gitcode.com/GitHub_Trending/ko/kong

本文全面介绍了Kong插件开发的核心技术,从PDK(Plugin Development Kit)核心API详解开始,深入解析了请求处理、响应处理、客户端信息、服务处理等关键API模块的使用方法和最佳实践。接着详细讲解了自定义插件的完整开发流程、项目结构、测试策略和部署方法。然后重点探讨了插件性能优化与内存管理技巧,包括内存监控、共享内存优化、避免内存泄漏的模式和高性能计算方案。最后提供了插件分发与社区贡献的完整指南,涵盖LuaRocks包管理分发、贡献流程规范、代码质量要求和社区互动渠道。

PDK(Plugin Development Kit)核心API详解

Kong的Plugin Development Kit(PDK)是插件开发的核心工具集,提供了一系列强大的API来访问和操作请求、响应、客户端信息等。掌握PDK核心API是开发高质量Kong插件的基础,本文将深入解析PDK的核心模块和关键API。

PDK架构概览

PDK采用模块化设计,每个模块专注于特定的功能领域。以下是PDK的主要模块架构:

mermaid

核心请求处理API

kong.request模块

kong.request模块提供了丰富的API来获取客户端请求信息:

-- 获取请求基本信息
local scheme = kong.request.get_scheme()        -- 协议方案(http/https)
local host = kong.request.get_host()            -- 主机名
local port = kong.request.get_port()            -- 端口号
local method = kong.request.get_method()        -- HTTP方法
local path = kong.request.get_path()            -- 请求路径

-- 获取转发相关信息(考虑X-Forwarded头)
local forwarded_scheme = kong.request.get_forwarded_scheme()
local forwarded_host = kong.request.get_forwarded_host()
local forwarded_port = kong.request.get_forwarded_port()

-- 获取查询参数和请求体
local query_args = kong.request.get_query()     -- 查询参数表
local headers = kong.request.get_headers()      -- 请求头表
local body_args = kong.request.get_body()       -- 请求体参数
请求处理示例
-- 示例:验证API密钥插件
local Plugin = {}

function Plugin:access(conf)
    local api_key = kong.request.get_header("X-API-Key")
    
    if not api_key then
        return kong.response.exit(401, { message = "API key required" })
    end
    
    -- 验证逻辑
    local isValid = validate_api_key(api_key)
    if not isValid then
        return kong.response.exit(403, { message = "Invalid API key" })
    end
    
    kong.log.info("API key validated for request to ", kong.request.get_path())
end

return Plugin

响应处理API详解

kong.response模块

kong.response模块允许插件修改发送给客户端的响应:

-- 设置响应状态码和内容
kong.response.exit(200, "Success")                    -- 简单响应
kong.response.exit(401, { error = "Unauthorized" })   -- JSON响应

-- 操作响应头
kong.response.set_header("X-Custom-Header", "value")
kong.response.add_header("X-Multiple", "value1")
kong.response.add_header("X-Multiple", "value2")
kong.response.clear_header("X-Remove-Header")

-- 获取响应信息
local status = kong.response.get_status()
local headers = kong.response.get_headers()
local body = kong.response.get_raw_body()
响应处理状态机

mermaid

客户端信息API

kong.client模块

kong.client模块提供客户端连接信息:

-- 获取客户端IP信息
local client_ip = kong.client.get_ip()                  -- 真实客户端IP
local forwarded_ip = kong.client.get_forwarded_ip()     -- 转发IP
local client_port = kong.client.get_port()              -- 客户端端口

-- 认证和消费者信息
local credential = kong.client.get_credential()         -- 认证凭据
local consumer = kong.client.get_consumer()             -- 消费者信息

-- IP信任验证
local is_trusted = kong.ip.is_trusted(client_ip)        -- 检查IP是否可信

服务处理API

kong.service模块

kong.service模块用于与上游服务交互:

-- 服务请求修改
kong.service.request.set_header("X-Upstream-Header", "value")
kong.service.request.set_query({ param = "value" })
kong.service.request.set_body("new body content")

-- 服务响应处理
local upstream_status = kong.service.response.get_status()
local upstream_headers = kong.service.response.get_headers()
local upstream_body = kong.service.response.get_raw_body()

实用工具API

日志记录

kong.log模块提供多级别日志记录:

kong.log.alert("Alert level message")      -- 警报级别
kong.log.crit("Critical level message")    -- 严重级别
kong.log.err("Error level message")        -- 错误级别
kong.log.warn("Warning level message")     -- 警告级别
kong.log.notice("Notice level message")    -- 通知级别
kong.log.info("Info level message")        -- 信息级别
kong.log.debug("Debug level message")      -- 调试级别
表格操作

kong.table模块提供安全的表格操作:

local tbl = { a = 1, b = 2 }

-- 深度拷贝
local copy = kong.table.deep_copy(tbl)

-- 合并表格
local merged = kong.table.merge(tbl, { c = 3 })

-- 检查空表
local isEmpty = kong.table.is_empty({})

PDK API执行阶段限制

不同PDK API只能在特定的执行阶段调用,以下是主要限制:

API类别允许阶段主要限制
kong.request所有阶段无特殊限制
kong.responseheader_filter之后不能在access阶段设置响应
kong.service.requestaccess、rewrite只能在代理到服务前修改
kong.service.responseheader_filter之后只能读取服务响应
kong.log所有阶段无限制

高级用法示例

自定义认证插件
local Plugin = {}

function Plugin:access(conf)
    -- 获取请求信息
    local token = kong.request.get_header("Authorization")
    local client_ip = kong.client.get_ip()
    
    if not token then
        kong.log.notice("Missing authorization header from ", client_ip)
        return kong.response.exit(401, { error = "Unauthorized" })
    end
    
    -- 验证token
    local isValid, consumer = validate_token(token)
    if not isValid then
        kong.log.warn("Invalid token from ", client_ip)
        return kong.response.exit(403, { error = "Forbidden" })
    end
    
    -- 设置消费者上下文
    kong.ctx.shared.authenticated_consumer = consumer
    
    kong.log.info("User ", consumer.username, " authenticated from ", client_ip)
end

function Plugin:header_filter(conf)
    -- 添加认证头到上游服务
    local consumer = kong.ctx.shared.authenticated_consumer
    if consumer then
        kong.service.request.set_header("X-User-ID", consumer.id)
        kong.service.request.set_header("X-User-Roles", table.concat(consumer.roles, ","))
    end
end

return Plugin
响应转换插件
local Plugin = {}

function Plugin:body_filter(conf)
    -- 只处理JSON响应
    local content_type = kong.response.get_header("Content-Type") or ""
    if not content_type:find("application/json") then
        return
    end
    
    -- 获取响应体
    local body = kong.response.get_raw_body()
    if not body then
        return
    end
    
    -- 解析和转换JSON
    local ok, data = pcall(cjson.decode, body)
    if not ok then
        kong.log.err("Failed to parse JSON response")
        return
    end
    
    -- 应用转换规则
    if conf.add_timestamp then
        data.timestamp = os.time()
    end
    
    if conf.rename_fields then
        for old_name, new_name in pairs(conf.rename_fields) do
            if data[old_name] then
                data[new_name] = data[old_name]
                data[old_name] = nil
            end
        end
    end
    
    -- 设置转换后的响应体
    local new_body = cjson.encode(data)
    kong.response.set_raw_body(new_body)
    
    -- 更新Content-Length头
    kong.response.set_header("Content-Length", #new_body)
end

return Plugin

性能优化最佳实践

  1. 缓存频繁访问的数据:使用kong.ctx.shared避免重复计算
  2. 延迟加载:只在需要时调用资源密集型API
  3. 批量操作:尽量减少API调用次数
  4. 错误处理:使用pcall安全调用可能失败的API
-- 优化示例:缓存客户端IP
function Plugin:access(conf)
    if not kong.ctx.shared.client_ip then
        kong.ctx.shared.client_ip = kong.client.get_ip()
    end
    
    -- 使用缓存的值
    local client_ip = kong.ctx.shared.client_ip
    -- ... 其他逻辑
end

PDK核心API为Kong插件开发提供了强大的基础设施,熟练掌握这些API可以帮助开发者构建高效、可靠的插件解决方案。通过合理的模块划分和阶段控制,可以确保插件在不同执行环境中都能正常工作。

自定义插件的开发流程与测试方法

在Kong生态系统中,插件是扩展网关功能的核心机制。掌握自定义插件的开发流程和测试方法,能够让你为API网关添加定制化的业务逻辑。本文将深入探讨Kong插件的完整开发生命周期,从项目结构到测试策略。

插件架构与核心组件

每个Kong插件都遵循标准的结构设计,主要包含以下几个核心文件:

文件类型作用描述必需性
handler.lua插件业务逻辑实现必需
schema.lua配置参数验证定义必需
access.lua访问阶段处理逻辑可选
daos.lua数据库操作定义可选
migrations/数据库迁移脚本可选

让我们通过一个实际的插件示例来理解这个架构:

-- handler.lua 示例结构
local CustomPluginHandler = {}

CustomPluginHandler.PRIORITY = 1000
CustomPluginHandler.VERSION = "1.0.0"

function CustomPluginHandler:init_worker()
    -- 初始化工作进程
end

function CustomPluginHandler:access(conf)
    -- 访问阶段处理逻辑
    kong.log.debug("Custom plugin processing request")
end

return CustomPluginHandler

插件开发流程详解

1. 项目初始化与配置定义

首先创建插件目录结构,并定义配置schema:

-- schema.lua
local typedefs = require "kong.db.schema.typedefs"

return {
    name = "custom-plugin",
    fields = {
        { protocols = typedefs.protocols_http },
        { config = {
            type = "record",
            fields = {
                { enabled = { 
                    type = "boolean", 
                    default = true, 
                    description = "是否启用插件" 
                }},
                { header_name = { 
                    type = "string", 
                    default = "X-Custom-Header",
                    description = "自定义头部名称"
                }},
                { timeout = {
                    type = "number",
                    default = 5000,
                    between = { 100, 30000 },
                    description = "超时时间(毫秒)"
                }}
            }
        }}
    }
}
2. 业务逻辑实现

在handler.lua中实现核心业务逻辑:

local CustomPluginHandler = {}
CustomPluginHandler.PRIORITY = 1000
CustomPluginHandler.VERSION = "1.0.0"

function CustomPluginHandler:access(conf)
    if not conf.enabled then
        return
    end
    
    -- 添加自定义请求头
    local custom_value = "processed-at-" .. ngx.now()
    kong.service.request.set_header(conf.header_name, custom_value)
    
    -- 记录日志
    kong.log.info("Custom header added: " .. conf.header_name)
end

function CustomPluginHandler:header_filter(conf)
    if conf.echo_response then
        local request_id = kong.request.get_header(conf.header_name)
        if request_id then
            kong.response.set_header(conf.header_name, request_id)
        end
    end
end

return CustomPluginHandler

测试策略与方法

Kong提供了完善的测试框架,支持单元测试和集成测试。

单元测试结构
-- spec/03-plugins/custom-plugin/01-access_spec.lua
local helpers = require "spec.helpers"

describe("Plugin: custom-plugin", function()
    local proxy_client

    lazy_setup(function()
        local bp = helpers.get_db_utils(strategy, nil, { "custom-plugin" })
        
        local route = bp.routes:insert {
            hosts = { "custom.test" },
        }

        bp.plugins:insert {
            name = "custom-plugin",
            route = { id = route.id },
            config = {
                enabled = true,
                header_name = "X-Custom-Test"
            }
        }

        assert(helpers.start_kong({
            database = strategy,
            nginx_conf = "spec/fixtures/custom_nginx.template",
        }))

        proxy_client = helpers.proxy_client()
    end)

    it("adds custom header to request", function()
        local res = assert(proxy_client:send {
            method = "GET",
            path = "/request",
            headers = { ["Host"] = "custom.test" }
        })
        
        assert.res_status(200, res)
        local json = require("cjson").decode(res)
        assert.is_not_nil(json.headers["x-custom-test"])
    end)
end)
测试用例设计矩阵

为了确保插件质量,应该设计全面的测试用例:

mermaid

插件部署与调试

本地开发环境配置

创建开发目录结构:

custom-plugin/
├── kong
│   └── plugins
│       └── custom-plugin
│           ├── handler.lua
│           ├── schema.lua
│           └── spec
│               └── 01-access_spec.lua
└── Makefile

配置Kong加载自定义插件:

# 在kong.conf中添加
plugins = bundled,custom-plugin

# 或者通过环境变量
export KONG_PLUGINS=bundled,custom-plugin
调试技巧

使用Kong的日志系统进行调试:

-- 在handler中添加调试日志
kong.log.debug("Plugin config: ", conf)
kong.log.info("Processing request from: ", kong.client.get_ip())
kong.log.err("Error occurred: ", err_message)

性能优化建议

在开发过程中需要注意性能优化:

  1. 避免阻塞操作:在access阶段避免长时间阻塞的操作
  2. 缓存机制:合理使用Kong的缓存功能减少重复计算
  3. 内存管理:注意Lua对象的内存使用,避免内存泄漏
  4. 并发处理:确保插件在多worker环境下的线程安全

持续集成与自动化测试

建立自动化测试流水线:

# .github/workflows/test.yml
name: Plugin Tests

on: [push, pull_request]

jobs:
  test:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        strategy: [postgres, cassandra]
    steps:
    - uses: actions/checkout@v2
    - name: Setup Kong
      run: make setup
    - name: Run tests
      run: make test STRATEGY=${{ matrix.strategy }}

通过掌握这些开发流程和测试方法,你将能够构建出高质量、可维护的Kong自定义插件,为API网关生态系统贡献自己的力量。

插件性能优化与内存管理技巧

在Kong插件开发中,性能优化和内存管理是确保API网关高效稳定运行的关键因素。Kong作为高性能API网关,其插件系统需要处理大量并发请求,因此优化内存使用和提高执行效率至关重要。

内存监控与管理

Kong提供了强大的内存监控能力,通过kong.node.get_memory_stats()函数可以获取详细的内存使用统计信息。这个功能对于插件开发者来说非常重要,可以帮助识别内存泄漏和优化内存使用。

-- 获取内存统计信息示例
local memory_stats = kong.node.get_memory_stats()

-- 输出示例结构
{
  lua_shared_dicts = {
    kong = {
      allocated_slabs = 12288,      -- 已分配内存块
      capacity = 24576              -- 总容量
    },
    kong_db_cache = {
      allocated_slabs = 12288,
      capacity = 12288
    }
  },
  workers_lua_vms = {
    {
      http_allocated_gc = 1102,     -- HTTP worker的Lua VM内存使用
      pid = 18004                   -- 进程ID
    }
  }
}

共享内存优化策略

Kong使用Nginx共享内存字典(shared dict)来存储插件数据,合理使用共享内存可以显著提升性能:

mermaid

共享内存使用最佳实践:

local function get_cached_data(conf, key)
    local shm = ngx.shared[conf.shm_name or "kong"]
    local data, err = shm:get(key)
    
    if data then
        return data
    end
    
    -- 计算或获取数据
    local new_data = expensive_operation()
    
    -- 使用safe_set避免内存溢出
    local ok, err = shm:safe_set(key, new_data, conf.ttl or 300)
    if not ok then
        kong.log.err("Failed to set shm: ", err)
    end
    
    return new_data
end

避免内存泄漏的模式

在Lua开发中,常见的内存泄漏源包括:

  1. 全局变量滥用:避免在插件中创建不必要的全局变量
  2. 闭包引用:确保及时释放不再需要的闭包引用
  3. 循环引用:注意table之间的相互引用
-- 不良模式:全局变量累积
global_cache = global_cache or {}
function bad_pattern()
    global_cache[os.time()] = some_data  -- 内存泄漏!
end

-- 良好模式:使用局部变量和适当的作用域
local function good_pattern()
    local local_cache = {}
    -- 处理逻辑
    return result  -- 局部变量自动回收
end

性能优化技巧

1. 减少字符串操作

字符串连接在Lua中代价较高,特别是在高频调用的插件中:

-- 低效方式
local result = ""
for i = 1, 1000 do
    result = result .. tostring(i)  -- 每次连接都创建新字符串
end

-- 高效方式
local parts = {}
for i = 1, 1000 do
    parts[#parts + 1] = tostring(i)
end
local result = table.concat(parts)
2. 表预分配优化

预先分配表的大小可以避免动态扩容的开销:

-- 预分配表大小
local function create_preallocated_table(size)
    local tbl = {}
    for i = 1, size do
        tbl[i] = nil  -- 预分配空间
    end
    return tbl
end

-- 在已知元素数量时使用
local data = create_preallocated_table(100)
for i = 1, 100 do
    data[i] = process_item(i)
end
3. 使用FFI进行高性能计算

对于需要高性能计算的场景,可以使用LuaJIT的FFI功能:

local ffi = require("ffi")

ffi.cdef[[
int memcmp(const void *s1, const void *s2, size_t n);
]]

local function fast_memory_compare(buf1, buf2, len)
    return ffi.C.memcmp(buf1, buf2, len) == 0
end

定时器与异步处理

Kong插件中合理使用定时器可以避免阻塞主线程:

mermaid

local function async_operation(premature, conf, data)
    if premature then
        return
    end
    
    -- 执行耗时操作
    local result = process_data(data)
    
    -- 更新共享内存
    local shm = ngx.shared.kong
    shm:set("cached_result", result, 300)
end

function Plugin:access(conf)
    -- 立即响应客户端,异步处理后台任务
    local ok, err = ngx.timer.at(0, async_operation, conf, request_data)
    if not ok then
        kong.log.err("Failed to create timer: ", err)
    end
    
    return kong.response.exit(200, "Processing started")
end

内存使用监控与告警

实现插件级别的内存监控:

local function monitor_memory_usage()
    local stats = kong.node.get_memory_stats()
    local threshold = 80  -- 80% 使用率阈值
    
    for shm_name, shm_info in pairs(stats.lua_shared_dicts) do
        local usage_percent = (shm_info.allocated_slabs / shm_info.capacity) * 100
        
        if usage_percent > threshold then
            kong.log.warn("Shared memory ", shm_name, 
                         " usage exceeded: ", string.format("%.2f%%", usage_percent))
        end
    end
end

-- 定期执行内存检查
local function check_memory_periodically()
    monitor_memory_usage()
    -- 设置下一次检查
    ngx.timer.at(60, check_memory_periodically)
end

最佳实践总结表

优化领域问题现象解决方案效果评估
内存泄漏内存使用持续增长使用局部变量,及时释放引用内存稳定,无泄漏
字符串操作高频字符串连接性能差使用table.concat预分配性能提升30-50%
共享内存频繁的shm操作冲突合理设置TTL,使用safe_set减少锁竞争,提高并发
异步处理阻塞主线程响应使用ngx.timer.at异步执行响应时间降低80%
表操作动态扩容开销大预分配表大小内存分配效率提升

通过实施这些内存管理和性能优化技巧,Kong插件开发者可以构建出更加高效、稳定的插件,确保在高并发场景下依然能够提供优异的性能表现。关键在于持续监控、及时优化,并遵循Kong的最佳实践模式。

插件分发与社区贡献指南

在Kong生态系统中,插件分发和社区贡献是推动平台发展的核心动力。本节将深入探讨如何将您开发的插件有效分发到社区,以及如何遵循最佳实践为Kong项目做出贡献。

插件分发策略

LuaRocks包管理分发

LuaRocks是Kong插件分发的标准方式,它提供了版本管理、依赖解析和自动化安装的能力。以下是创建LuaRocks包的基本结构:

-- rockspec文件示例
package = "kong-plugin-my-custom"
version = "1.0.0-1"
source = {
  url = "https://github.com/your-org/kong-plugin-my-custom/archive/v1.0.0.tar.gz"
}
description = {
  summary = "Custom Kong plugin for advanced request processing",
  detailed = [[
    This plugin provides advanced request transformation capabilities
    with support for JSONPath expressions and template rendering.
  ]],
  license = "Apache-2.0",
  homepage = "https://github.com/your-org/kong-plugin-my-custom"
}
dependencies = {
  "lua >= 5.1",
  "kong >= 3.0.0"
}
build = {
  type = "builtin",
  modules = {
    ["kong.plugins.my-custom.handler"] = "kong/plugins/my-custom/handler.lua",
    ["kong.plugins.my-custom.schema"] = "kong/plugins/my-custom/schema.lua"
  }
}

分发流程如下:

mermaid

私有仓库分发

对于企业级插件,可以通过私有Git仓库或内部包仓库进行分发:

# 从Git仓库安装
luarocks install https://github.com/your-org/kong-plugin-my-custom.git

# 或使用本地路径
luarocks install /path/to/plugin-1.0.0-1.rockspec

社区贡献流程

贡献类型矩阵
贡献类型描述适用场景提交渠道
Bug修复修复现有功能的问题发现并验证了bugGitHub Issues + PR
功能增强改进现有插件功能有明确改进方案GitHub Discussions + PR
新插件开发全新的插件解决特定业务需求独立仓库 + Kong Hub
文档改进完善使用文档发现文档缺失或错误docs.konghq.com PR
测试用例增加测试覆盖率确保代码质量随代码变更提交
提交规范指南

Kong项目遵循严格的提交消息规范,确保历史记录清晰可读:

feat(plugins): add request validation to custom plugin

- Implement JSON schema validation for incoming requests
- Add comprehensive error handling with custom error messages
- Include unit tests covering validation scenarios

Resolves: #1234

提交消息结构要求:

mermaid

代码质量与测试要求

静态代码检查

所有贡献必须通过Luacheck静态分析:

# 运行代码检查
make lint
# 或直接使用luacheck
luacheck . --codes --ignore 111/114

常见的检查规则包括:

  • 变量命名规范(camelCase或snake_case一致性)
  • 未使用的变量和函数检测
  • 代码复杂度控制
  • 错误处理完整性
测试覆盖率要求
-- 测试示例:响应转换插件测试
describe("Response Transformer Plugin", function()
  it("should transform JSON response body", function()
    local mock_response = {
      get_headers = function() return {["Content-Type"] = "application/json"} end,
      get_raw_body = function() return '{"name": "John", "age": 30}' end,
      set_raw_body = function(body) transformed = body end
    }
    
    -- 执行转换逻辑
    local result = transform_json_body({add = {json = {'$.age', '$.years'}}}, mock_response)
    
    assert.equal('{"name":"John","age":30,"years":30}', transformed)
  end)
end)

测试覆盖率目标:

  • 单元测试:≥80%行覆盖率
  • 集成测试:覆盖主要使用场景
  • 性能测试:确保无性能回归

社区互动与支持

参与渠道矩阵
平台主要用途响应时间适合问题类型
GitHub IssuesBug报告和功能请求1-3天技术问题、代码相关
GitHub Discussions技术讨论和帮助几小时使用问题、最佳实践
Kong Nation论坛社区交流和公告1-2天一般性问题、案例分享
Community Slack实时交流实时紧急问题、快速咨询
贡献者权益

积极参与的贡献者可以享受:

  • 官方贡献者徽章(Contributor Badge)
  • 优先技术支持和咨询
  • 早期功能预览和测试机会
  • 社区认可和职业发展机会

版本管理与兼容性

语义化版本控制

遵循SemVer规范,确保版本号传达正确的兼容性信息:

mermaid

  • 主版本号(MAJOR):不兼容的API修改
  • 次版本号(MINOR):向下兼容的功能性新增
  • 修订号(PATCH):向下兼容的问题修正
向后兼容性保证

所有插件更新必须确保:

  • 配置schema向后兼容
  • API接口不破坏现有集成
  • 数据库迁移脚本提供回滚方案
  • 弃用功能提供过渡期和迁移指南

通过遵循这些分发和贡献指南,您不仅可以确保插件的质量和可用性,还能在Kong社区中建立良好的声誉,推动整个生态系统的发展。记住,优秀的开源贡献不仅仅是代码,还包括文档、测试和社区支持的全方位投入。

总结

通过本系列文章的学习,开发者可以全面掌握Kong插件开发的全栈技能。从基础的PDK API使用到高级的性能优化技巧,从单个插件的开发测试到社区分发和贡献,形成了一个完整的知识体系。关键要点包括:熟练掌握PDK各模块API的正确使用场景和执行阶段限制;遵循插件开发的标准流程和项目结构;实施有效的内存管理和性能优化策略;以及遵循社区规范进行插件分发和贡献。这些知识将帮助开发者构建出高性能、稳定可靠的企业级Kong插件,为API网关生态系统做出有价值的贡献。

【免费下载链接】kong Kong是一款高性能的开源API网关,支持多种协议和插件,能够实现API路由、认证、限流等功能,助力企业构建灵活、安全且可扩展的API架构。 【免费下载链接】kong 项目地址: https://gitcode.com/GitHub_Trending/ko/kong

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值