Article

负载均衡 Kong

更新于:2026-07-15

第1章:Kong 网关基础与 Java 集成概述

1.1 什么是 Kong 网关

概念名称说明注意事项
Kong Gateway开源的云原生 API 网关,基于 Nginx 和 OpenResty 构建,用于管理、保护和扩展 API。适用于微服务、云环境和混合部署架构,支持高并发和低延迟。
核心功能提供路由转发、身份认证、限流、日志记录、监控、插件扩展等网关能力。所有功能通过插件机制实现,核心轻量,扩展性强。
使用场景微服务入口、API 安全控制、多租户 API 管理、服务聚合与协议转换。可作为所有后端服务的统一入口,集中管理流量和安全策略。
开源与生态Apache 2.0 开源协议,拥有丰富的插件生态和社区支持。支持官方和第三方插件,也可自定义开发 Lua 或 Go 插件。

1.2 Kong 核心架构与组件(API Gateway、Admin API、Plugin、Database)

组件名称说明注意事项
API Gateway接收客户端请求,执行路由匹配、插件处理、转发至后端服务。默认监听 8000(HTTP)和 8443(HTTPS)端口,是流量入口。
Admin APIRESTful 接口,用于配置和管理 Kong 的服务、路由、插件、消费者等资源。默认监听 8001 端口,应限制外部访问,仅内部管理使用。
Plugin可插拔的功能模块,如认证、限流、日志等,可在服务、路由或消费者级别启用。插件按执行顺序处理请求和响应,部分插件需依赖其他配置(如 JWT 需 Consumer)。
DatabaseKong 使用 PostgreSQL 或 Cassandra 存储配置元数据(服务、路由、插件等)。可配置为无数据库模式(db-less),使用 declarative config 文件部署。
Kong Proxy基于 Nginx/OpenResty 的高性能反向代理层,处理实际流量。支持负载均衡、健康检查、SSL 终止等高级功能。
Kong Manager可选的图形化管理界面(商业版功能),简化 Admin API 操作。开源版可通过第三方工具(如 Konga)实现可视化管理。

1.3 Java 与 Kong 的交互方式(HTTP 调用 Admin API、SDK 封装)

交互方式说明注意事项
直接 HTTP 调用Java 应用通过 HTTP 客户端(如 OkHttp)调用 Kong Admin API 进行资源配置。需手动处理 JSON 序列化、错误码、重试逻辑,适合轻量级集成。
封装 SDK将 Admin API 封装为 Java SDK,提供面向对象的接口(如 KongClient.createService)。提高代码可读性和复用性,建议在复杂项目中使用。
声明式配置(Declarative Config)使用 YAML/JSON 文件定义 Kong 配置,通过 kong reload 加载,Java 可生成配置文件。适用于 CI/CD 场景,避免运行时依赖 Admin API。
事件驱动集成Java 服务通过消息队列或 webhook 响应 Kong 插件事件(如日志、认证失败)。需配合日志插件或自定义插件实现,适合监控和审计场景。

1.4 开发环境准备(Kong 安装、Docker 部署、Java 项目搭建)

准备步骤说明注意事项
Kong 安装方式支持包管理器(如 yum、brew)、Docker、Kubernetes、源码编译等。推荐使用 Docker 快速启动,避免环境依赖问题。
Docker 部署 Kong使用 docker run 启动 Kong 容器,需挂载配置文件并连接数据库。确保容器网络互通,数据库(PostgreSQL)需先启动。
数据库准备安装 PostgreSQL 并创建 Kong 使用的数据库和用户。初始化时运行 kong migrations bootstrap 创建表结构。
Java 项目搭建创建 Maven/Gradle 项目,引入 HTTP 客户端和 JSON 处理库依赖。推荐使用 Spring Boot 快速构建 REST 服务与 Kong 集成。
依赖库示例okhttp3、jackson-databind、spring-web、gson 等。注意版本兼容性,避免冲突。
环境验证启动 Kong 后访问 :8001 检查 Admin API 是否正常。可通过 curl http://localhost:8001 返回 JSON 表示启动成功。

第2章:Kong Admin API 的 Java 封装基础

2.1 HTTP 客户端选择(OkHttp、Apache HttpClient、Spring RestTemplate)

客户端名称语法示例(Java 片段)用途代码示例注意事项
OkHttpOkHttpClient, Request, Call高性能、简洁的 HTTP 客户端OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url("http://localhost:8001/services")
.build();
Response response = client.newCall(request).execute();
支持同步/异步调用,自动处理连接池,推荐用于高并发场景。
Apache HttpClientCloseableHttpClient, HttpGet, HttpPost功能丰富、稳定的企业级 HTTP 客户端CloseableHttpClient client = HttpClients.createDefault();
HttpGet request = new HttpGet("http://localhost:8001/services");
CloseableHttpResponse response = client.execute(request);
配置灵活,支持复杂认证和路由,但 API 较冗长。
Spring RestTemplateRestTemplate, getForObject, postForEntitySpring 生态集成的 REST 调用模板RestTemplate template = new RestTemplate();
String result = template.getForObject("http://localhost:8001/services", String.class);
已标记为过时(自 Spring 5.0),建议使用 WebClient 替代,但存量项目仍广泛使用。

2.2 JSON 序列化与反序列化(Jackson、Gson)

库名称语法示例(Java 片段)用途代码示例注意事项
JacksonObjectMapper, writeValueAsString, readValueJava 最流行的 JSON 处理库ObjectMapper mapper = new ObjectMapper();
String json = mapper.writeValueAsString(serviceObj);
Service svc = mapper.readValue(json, Service.class);
默认支持 POJO 映射,性能高,配置丰富,Spring 默认集成。
GsonGson, toJson, fromJsonGoogle 开发,简单易用的 JSON 库Gson gson = new Gson();
String json = gson.toJson(serviceObj);
Service svc = gson.fromJson(json, Service.class);
无需注解即可序列化,适合简单场景,但对泛型和复杂类型支持略弱于 Jackson。

2.3 RESTful API 调用封装模式

模式名称说明代码示例注意事项
基础封装类创建 KongClient 类,封装通用 HTTP 请求逻辑public class KongClient {
private OkHttpClient client;
private String adminUrl;
public JsonObject get(String path) { ... }
}
统一处理 URL 拼接、头信息、异常转换,提高复用性。
方法链式调用返回 this 支持链式调用,提升 API 可读性client.path("/services").param("name", "svc1").get();适合构建复杂请求参数,但需注意线程安全性。
泛型响应处理使用泛型解析 JSON 响应,避免重复类型转换public <T> T get(String path, Class<T> clazz) {
String json = executeGet(path);
return mapper.readValue(json, clazz);
}
提高类型安全,减少 ClassCastException 风险。
异步调用支持提供异步方法(如 CompletableFuture),避免阻塞主线程public CompletableFuture<JsonObject> getAsync(String path) { ... }适用于高并发管理场景,需合理管理线程池。

2.4 错误处理与重试机制

处理机制说明代码示例注意事项
HTTP 状态码判断根据 Kong Admin API 返回的状态码(400、404、500 等)进行异常分类if (response.code() == 404) {
throw new ResourceNotFoundException();
}
Kong 返回详细错误信息在响应体中,需解析 message 字段。
自定义异常类定义 KongClientExceptionResourceNotFoundException 等细化异常类型public class KongClientException extends RuntimeException { ... }便于上层业务捕获和处理特定错误。
重试机制对网络抖动或 5xx 错误进行自动重试使用循环或库(如 Spring Retry)实现指数退避重试避免对 4xx 错误重试,设置最大重试次数和超时时间。
日志记录记录请求 URL、参数、响应码、错误信息,便于排查问题logger.error("Kong API call failed: {} {}", request.url(), response.code());建议使用 SLF4J + Logback,避免敏感信息(如密钥)被记录。

第3章:服务(Service)管理

3.1 创建服务(createService)

方法名语法用途代码示例注意事项
createServiceJsonObject createService(String name, String url)通过名称和 URL 创建 Kong 服务JsonObject service = client.createService("user-service", "http://localhost:8081");url 可拆分为 protocol、host、port、path;若使用拆分方式,需调用带多个参数的方法。
createServiceJsonObject createService(String name, String protocol, String host, int port, String path)分项指定服务地址参数创建服务JsonObject service = client.createService("order-svc", "http", "192.168.1.100", 8082, "/api");host 不能包含协议和端口;port 必须为有效整数(1-65535)。

3.2 查询服务列表(getServices)

方法名语法用途代码示例注意事项
getServicesJsonObject getServices()获取所有服务的列表JsonObject result = client.getServices();
JsonArray data = result.getAsJsonArray("data");
响应为分页结构,包含 data 数组和 next 分页链接;需遍历 data 获取服务。
getServicesJsonObject getServices(int size)指定每页数量获取服务列表JsonObject result = client.getServices(10);size 最大为 1000;适用于服务数量较多时分页查询。

3.3 查询单个服务(getServiceById)

方法名语法用途代码示例注意事项
getServiceByIdJsonObject getServiceById(String id)根据服务 ID 查询单个服务详情JsonObject service = client.getServiceById("a1b2c3d4");id 可为字符串 UUID 或名称;若服务不存在,返回 404 错误。
getServiceByNameJsonObject getServiceByName(String name)根据服务名称查询服务详情JsonObject service = client.getServiceByName("payment-service");名称需唯一;建议使用 ID 作为主查询键,名称用于可读性。

3.4 更新服务配置(updateService)

方法名语法用途代码示例注意事项
updateServiceJsonObject updateService(String id, JsonObject updatedFields)根据 ID 更新服务部分字段JsonObject updates = new JsonObject();
updates.addProperty("retries", 3);
client.updateService("a1b2c3d4", updates);
仅传入需更新的字段;空字段不会覆盖原值;不可更新 idcreated_at
updateServiceJsonObject updateService(String id, String url)快捷方法:更新服务的完整 URLclient.updateService("a1b2c3d4", "https://newhost:9443/api/v2");相当于更新 protocol、host、port、path 四个字段。

3.5 删除服务(deleteService)

方法名语法用途代码示例注意事项
deleteServiceboolean deleteService(String id)根据 ID 删除指定服务boolean success = client.deleteService("a1b2c3d4");删除成功返回 true(HTTP 204);失败返回 false(如服务不存在)。
deleteServiceByNameboolean deleteServiceByName(String name)根据名称删除服务boolean success = client.deleteServiceByName("legacy-svc");若名称不唯一,行为不确定;建议优先使用 ID 删除。

第4章:路由(Route)管理

4.1 创建路由(createRoute)

方法名语法用途代码示例注意事项
createRouteJsonObject createRoute(String serviceName, String[] paths)为服务创建基于路径的路由String[] paths = {"/users", "/profile"};
client.createRoute("user-svc", paths);
paths 为前缀匹配;请求路径以任一 path 开头即匹配。
createRouteJsonObject createRoute(String serviceName, String[] hosts, String[] methods)为服务创建基于域名和方法的路由String[] hosts = {"api.example.com"};
String[] methods = {"GET", "POST"};
client.createRoute("svc1", hosts, methods);
hosts 匹配 Host 请求头;methods 匹配 HTTP 方法;可组合使用多种条件。
createRouteJsonObject createRoute(String serviceId, Map<String, Object> customConfig)自定义配置创建路由(高级用法)Map<String, Object> config = new HashMap<>();
config.put("paths", Arrays.asList("/admin"));
config.put("preserve_host", true);
client.createRoute("s1-id", config);
支持 preserve_hostsnissourcesdestinations 等高级字段。

4.2 查询路由列表(getRoutes)

方法名语法用途代码示例注意事项
getRoutesJsonObject getRoutes()获取所有路由的列表JsonObject result = client.getRoutes();响应结构与服务列表一致,包含 datanext 分页信息。
getRoutesJsonObject getRoutes(int size)指定每页数量获取路由列表JsonObject result = client.getRoutes(20);用于控制响应体积,避免一次性加载过多路由。

4.3 查询路由详情(getRouteById)

方法名语法用途代码示例注意事项
getRouteByIdJsonObject getRouteById(String id)根据 ID 查询单个路由详情JsonObject route = client.getRouteById("r1a2b3c4");返回路由完整配置,包括关联的服务信息(service 对象)。
getRouteByNameJsonObject getRouteByName(String name)根据名称查询路由(若已设置)JsonObject route = client.getRouteByName("admin-route");name 字段需在创建时显式设置,否则无法通过名称查询。

4.4 更新路由(updateRoute)

方法名语法用途代码示例注意事项
updateRouteJsonObject updateRoute(String id, JsonObject updatedFields)更新路由的指定字段JsonObject updates = new JsonObject();
updates.add("methods", gson.toJsonTree(new String[]{"GET"}));
client.updateRoute("r1a2b3c4", updates);
支持 pathshostsmethodsservice 等字段更新;不可更改 id
updateRouteJsonObject updateRoute(String id, String[] newPaths)快捷更新路由路径client.updateRoute("r1a2b3c4", new String[]{"/api/v2/users"});相当于设置 paths 字段;会覆盖原有 paths

4.5 删除路由(deleteRoute)

方法名语法用途代码示例注意事项
deleteRouteboolean deleteRoute(String id)根据 ID 删除指定路由boolean success = client.deleteRoute("r1a2b3c4");删除后该路由不再生效;关联的服务不受影响。
deleteRouteByNameboolean deleteRouteByName(String name)根据名称删除路由(若已命名)boolean success = client.deleteRouteByName("temp-route");仅当路由设置了 name 字段时有效;建议优先使用 ID 删除。

第5章:消费者(Consumer)管理

5.1 创建消费者(createConsumer)

方法名语法用途代码示例注意事项
createConsumerJsonObject createConsumer(String username)创建带用户名的消费者JsonObject consumer = client.createConsumer("alice");username 必须唯一;可用于认证插件(如 Key Auth、JWT)绑定凭证。
createConsumerJsonObject createConsumer(String username, String customId)创建带用户名和外部 ID 的消费者JsonObject consumer = client.createConsumer("bob", "usr-12345");customId 用于关联外部系统用户 ID,便于跨系统身份映射。

5.2 查询消费者列表(getConsumers)

方法名语法用途代码示例注意事项
getConsumersJsonObject getConsumers()获取所有消费者的列表JsonObject result = client.getConsumers();
JsonArray data = result.getAsJsonArray("data");
响应为分页结构,data 包含消费者数组;可遍历获取每个消费者信息。
getConsumersJsonObject getConsumers(int size)指定每页数量获取消费者列表JsonObject result = client.getConsumers(15);size 范围为 1-1000;建议分页查询以提升性能。

5.3 更新消费者(updateConsumer)

方法名语法用途代码示例注意事项
updateConsumerJsonObject updateConsumer(String id, JsonObject updatedFields)更新消费者的部分字段JsonObject updates = new JsonObject();
updates.addProperty("custom_id", "usr-67890");
client.updateConsumer("c1d2e3f4", updates);
可更新 username 和 custom_id;id 和 created_at 不可更改。
updateConsumerJsonObject updateConsumer(String id, String newUsername)快捷更新消费者用户名client.updateConsumer("c1d2e3f4", "alice-new");新 username 必须未被其他消费者使用,否则操作失败。

5.4 删除消费者(deleteConsumer)

方法名语法用途代码示例注意事项
deleteConsumerboolean deleteConsumer(String id)根据 ID 删除指定消费者boolean success = client.deleteConsumer("c1d2e3f4");删除成功返回 true;若消费者不存在或有关联凭证,可能失败。
deleteConsumerboolean deleteConsumerByUsername(String username)根据用户名删除消费者boolean success = client.deleteConsumerByUsername("alice");若 username 不唯一(理论上不应发生),行为不确定;建议使用 ID 删除。

第6章:插件(Plugin)管理

6.1 启用插件(enablePlugin)

方法名语法用途代码示例注意事项
enablePluginJsonObject enablePlugin(String name)全局启用指定名称的插件JsonObject plugin = client.enablePlugin("key-auth");插件作用于所有服务和路由;需后续配置凭证或规则。
enablePluginJsonObject enablePlugin(String name, String serviceName)为特定服务启用插件JsonObject plugin = client.enablePlugin("rate-limiting", "user-service");serviceName 可为名称或 ID;插件仅对该服务的请求生效。
enablePluginJsonObject enablePlugin(String name, String routeId, Map<String, Object> config)为路由启用插件并传入配置Map<String, Object> config = new HashMap<>();
config.put("minute", 100);
client.enablePlugin("rate-limiting", "r1a2b3c4", config);
config 为插件特定参数;不同插件支持的参数不同。

6.2 查询插件列表(getPlugins)

方法名语法用途代码示例注意事项
getPluginsJsonObject getPlugins()获取所有已启用插件的列表JsonObject result = client.getPlugins();包含全局插件和绑定到服务/路由的插件;响应为分页结构。
getPluginsJsonObject getPlugins(String serviceName)获取某服务上启用的插件JsonObject result = client.getPlugins("order-service");serviceName 可为名称或 ID;返回该服务专属的插件实例。
getPluginsJsonObject getPluginsByRoute(String routeId)获取某路由上启用的插件JsonObject result = client.getPluginsByRoute("r1a2b3c4");用于检查路由级插件配置,如认证、限流等。

6.3 获取插件实例(getPluginById)

方法名语法用途代码示例注意事项
getPluginByIdJsonObject getPluginById(String id)根据插件实例 ID 查询详情JsonObject plugin = client.getPluginById("p1q2r3s4");返回插件完整配置,包括 config、service、route 等关联信息。

6.4 更新插件配置(updatePlugin)

方法名语法用途代码示例注意事项
updatePluginJsonObject updatePlugin(String id, JsonObject newConfig)更新插件实例的配置参数JsonObject config = new JsonObject();
config.addProperty("hour", 500);
client.updatePlugin("p1q2r3s4", config);
newConfig 会完全替换原有 config;若需保留旧值,应先获取再合并。
updatePluginJsonObject updatePlugin(String id, Map<String, Object> config)使用 Map 更新插件配置Map<String, Object> mapConfig = new HashMap<>();
mapConfig.put("redis_host", "10.0.0.10");
client.updatePlugin("p1q2r3s4", mapConfig);
内部自动序列化为 JSON;推荐使用此方法避免手动构建 JsonObject。

6.5 删除插件(deletePlugin)

方法名语法用途代码示例注意事项
deletePluginboolean deletePlugin(String id)根据插件实例 ID 删除插件boolean success = client.deletePlugin("p1q2r3s4");删除后插件立即失效;需确保不影响业务流量。

第7章:认证插件集成(Key Auth、JWT、OAuth2)

7.1 Key Authentication 插件配置与 Java 调用

配置方式说明代码示例注意事项
启用插件在服务或路由上启用 key-auth 插件client.enablePlugin("key-auth", "service-id");启用后,所有请求必须携带有效 API Key,否则返回 401。
创建凭证为消费者创建 API KeyJsonObject key = new JsonObject();
key.addProperty("key", "secret123");
client.addConsumerCredential("consumer-id", "key-auth", key);
可不指定 key,由 Kong 自动生成;建议由系统统一生成并加密存储。
Java 调用客户端在请求头或参数中携带 API Key// Header 方式
request.header("apikey", "secret123");
// 或 Query 参数
GET /api/users?apikey=secret123
推荐使用 apikey 请求头;可通过 key_names 插件配置项自定义参数名。

7.2 JWT 插件配置与 Token 生成验证

配置方式说明代码示例注意事项
启用插件启用 JWT 插件以验证 JWT Tokenclient.enablePlugin("jwt", "service-id");可配置 secret_is_base64、algorithm(HS256/RSA256)等高级选项。
创建凭证为消费者创建 JWT 密钥对(HS256)或公钥(RSA)JsonObject jwt = new JsonObject();
jwt.addProperty("key", "user1");
jwt.addProperty("secret", "mysecret");
client.addConsumerCredential("c1d2e3f4", "jwt", jwt);
RSA 方式需上传公钥(rsa_public_key 字段)。
Java 生成 Token使用 Java JWT 库生成 Token(以 HS256 为例)// 使用 java-jwt 库
String token = JWT.create()
.withKeyId("user1")
.withIssuer("kong")
.sign(Algorithm.HMAC256("mysecret"));
kid(key id)必须与凭证中 key 字段一致。
Java 调用客户端在 Authorization 头中携带 JWT Tokenrequest.header("Authorization", "Bearer <token>");Kong 自动验证签名、过期时间(exp)和签发者(iss,若配置)。

7.3 OAuth2 插件配置与授权流程集成

配置方式说明代码示例注意事项
启用插件在服务上启用 OAuth2 插件Map<String, Object> config = new HashMap<>();
config.put("mandatory_scope", false);
config.put("token_expiration", 3600);
client.enablePlugin("oauth2", "svc-id", config);
支持配置令牌有效期、是否强制作用域等。
创建应用为消费者创建 OAuth2 应用(客户端)JsonObject app = new JsonObject();
app.addProperty("name", "mobile-app");
app.addProperty("client_id", "cli123");
app.addProperty("client_secret", "sec456");
app.addProperty("redirect_uris", "https://client.com/cb");
client.addConsumerCredential("c1d2e3f4", "oauth2", app);
client_id 和 client_secret 用于授权码和密码模式。
授权流程实现授权码模式(Authorization Code)1. 重定向用户到 /oauth2/authorize
2. 用户登录并授权
3. 获取 code
4. 调用 /oauth2/token 换取 access_token
Kong 内置 OAuth2 端点;需前端和后端协同实现。
Java 调用使用 access_token 调用受保护 APIrequest.header("Authorization", "Bearer <access_token>");令牌需在有效期内;可通过 Kong 的 introspection 端点验证令牌状态。

第8章:高级特性与扩展

8.1 负载均衡与健康检查配置

特性说明配置方式注意事项
负载均衡Kong 支持基于哈希(一致性哈希)或轮询的负载均衡创建上游(Upstream)时指定 hash_on 字段:
client.createUpstream("users-svc", "consistent-hashing");
支持 ip、header、cookie、none(轮询)等多种哈希方式。
健康检查主动/被动健康检查机制,自动剔除故障节点在上游中配置 healthchecks 对象:
JsonObject hc = new JsonObject();
hc.addProperty("active", true);
hc.addProperty("http_path", "/health");
upstream.add("healthchecks", hc);
被动检查基于请求错误率;主动检查周期性探测节点。
目标管理为上游添加多个后端目标(Target)client.addTarget("users-svc", "10.0.0.10:8080", 100); // weight=100可动态更新权重或禁用目标;支持优先级(priority)设置。

8.2 限流(Rate Limiting)插件使用

插件类型说明配置示例注意事项
rate-limiting基于服务/路由的简单限流(内存存储)Map<String, Object> config = new HashMap<>();
config.put("minute", 100);
config.put("policy", "local");
client.enablePlugin("rate-limiting", "svc-id", config);
local 策略基于节点内存,分布式环境不一致;建议使用 redis 策略。
rate-limiting-advanced高级限流,支持 Redis 存储、更灵活的限流键config.put("second", 10);
config.put("redis_host", "192.168.1.200");
client.enablePlugin("rate-limiting-advanced", "route-id", config);
支持按 consumer、credential、ip 等维度限流。
Java 调用超出配额时 Kong 返回 429 Too Many RequestsHttpResponse res = execute(request);
if (res.getStatus() == 429) { /* 限流触发 */ }
可通过响应头 X-RateLimit-LimitX-RateLimit-Remaining 获取配额信息。

8.3 日志插件(HTTP Log、File Log)配置

插件类型说明配置示例注意事项
http-log将请求日志发送到远程 HTTP 服务器Map<String, Object> config = new HashMap<>();
config.put("http_endpoint", "http://logserver:8080/ingest");
config.put("method", "POST");
client.enablePlugin("http-log", "global", config);
可配置日志格式(format 字段);确保目标服务器可接收并处理日志。
file-log将日志写入本地文件JsonObject logConfig = new JsonObject();
logConfig.addProperty("path", "/var/log/kong/access.log");
client.enablePlugin("file-log", logConfig);
需确保 Kong 进程有文件写入权限;建议配合 logrotate 管理日志文件。
日志格式自定义日志内容支持使用 Nginx 变量:
"format": {"ts": "$time_iso8601", "host": "$host", "status": "$status"}
格式为 JSON 字符串;可用于结构化日志分析(如 ELK)。

8.4 自定义插件开发与 Java 服务联动

步骤说明技术要点注意事项
插件开发使用 Lua 开发 Kong 自定义插件创建 kong.plugins.custom-auth 目录,实现 access() 函数插件需注册到 Kong 的插件系统;可通过 pongo 工具测试。
Java 联动插件在运行时调用外部 Java 服务进行复杂逻辑处理(如风控、鉴权)在 Lua 中使用 http_client 调用 Java HTTP API:
local http = require("resty.http")
local hc = http:new()
hc:request_uri("http://java-service:8080/validate", { method = "POST", body = data })
需处理超时、重试、序列化;建议使用异步调用避免阻塞请求。
部署方式将插件打包并挂载到 Kong 容器使用 Dockerfile COPY 插件目录,或通过 volume 挂载插件需在 kong.conf 的 plugins 列表中声明(如 custom-auth)。
配置管理通过 Admin API 为自定义插件配置 Java 服务地址等参数Map<String, Object> config = new HashMap<>();
config.put("backend_url", "http://risk-service:9090");
client.enablePlugin("custom-auth", "svc-id", config);
配置信息通过 self.config 在 Lua 插件中访问。

第9章:Java SDK 封装实践

9.1 KongClient 工具类设计

设计原则说明代码示例注意事项
单例模式确保全局只有一个 Kong 客户端实例,避免资源浪费public class KongClient {
private static volatile KongClient instance;
private KongClient() {}
public static KongClient getInstance() {
if (instance == null) {
synchronized (KongClient.class) {
if (instance == null) {
instance = new KongClient();
}
}
}
return instance;
}
}
使用双重检查锁定(DCL)保证线程安全;也可使用静态内部类实现。
模块化接口按功能拆分服务,如 ConsumerService、PluginServicepublic interface ConsumerService {
JsonObject createConsumer(String username);
boolean deleteConsumer(String id);
}

public class KongClient implements ConsumerService, PluginService { ... }
提高代码可维护性;便于单元测试和 Mock。
连接池管理复用 HTTP 连接,提升性能private CloseableHttpClient httpClient = HttpClients.custom()
.setMaxConnTotal(50)
.setMaxConnPerRoute(20)
.build();
避免频繁创建销毁连接;合理设置连接池大小。

9.2 异常统一处理

异常类型说明处理策略代码示例
HTTP 异常如 404(未找到)、409(冲突)、500(服务器错误)捕获 IOException 或 HttpResponseException,解析状态码并抛出自定义异常if (statusCode == 404) throw new KongResourceNotFoundException();
else if (statusCode >= 500) throw new KongServerException();
JSON 解析异常响应体非 JSON 格式或结构不符使用 try-catch (JsonSyntaxException e) 捕获,并记录原始响应返回默认值或抛出 KongParseException。
自定义异常体系定义分层异常便于上层捕获处理public abstract class KongException extends RuntimeException { ... }
public class KongAPIException extends KongException { ... }
public class KongAuthenticationException extends KongException { ... }
上层业务可根据异常类型执行重试、降级或告警逻辑。

9.3 配置文件管理(application.yml / properties)

配置项说明配置示例加载方式
Admin 地址Kong Admin API 的访问地址kong:
admin-url: http://kong-admin:8001
timeout: 5000
max-retries: 3
使用 @Value("${kong.admin-url}") 注入;或通过 ConfigurationProperties 绑定。
认证信息若 Admin API 启用了 RBAC 认证kong.username=admin
kong.password=secret
敏感信息建议加密存储(如使用 Jasypt)。
插件默认值全局插件配置模板kong:
default-plugins:
- name: prometheus
config: {}
初始化时批量启用常用插件。

9.4 同步与异步调用封装

调用方式说明代码示例适用场景
同步调用阻塞等待结果返回直接使用 httpClient.execute(request)简单操作,如创建消费者、查询列表等。
异步调用非阻塞,通过回调或 Future 获取结果Future<HttpResponse> future = httpClient.execute(request, callback);
// 或使用 CompletableFuture
CompletableFuture.supplyAsync(() -> client.getConsumers());
高并发场景下提升吞吐量;批量操作(如初始化多个服务)。
批量操作封装提供批量创建/删除接口public List<KongResult> batchCreateConsumers(List<String> usernames) {
return usernames.parallelStream()
.map(this::createConsumer)
.collect(Collectors.toList());
}
利用 Java 8 Stream 并行流提高效率。

第10章:实战案例

10.1 微服务网关动态注册

步骤说明技术实现优势
服务发现监听 Eureka/Nacos 中的服务上线事件实现 ApplicationListener<ServiceInstanceRegisteredEvent>实时感知服务变化,无需手动配置。
自动注册服务上线后自动在 Kong 中创建 Service 和 RouteString serviceId = kongClient.createService(name, "http://"+ip+":"+port);
kongClient.createRoute(serviceId, "/api/"+name+"/*");
实现”零配置”接入网关,降低运维成本。
健康检查配置上游健康检查,结合 Nacos 心跳在 Kong Upstream 中启用主动健康检查,路径为 /actuator/health双重保障,确保流量只转发到健康实例。

10.2 基于 Kong 的 API 权限控制平台

功能模块说明实现方案价值
权限模型RBAC 模型:用户 → 角色 → 消费者 → 插件凭证前端分配角色绑定 Kong Consumer;后端生成 JWT Key 或 OAuth2 Client统一权限视图,降低管理复杂度。
自助申请开发者自助申请 API 访问权限提供 Web 表单填写应用信息 → 后台审批 → 自动调用 SDK 创建 OAuth2 应用加速 API 开放流程,支持 DevOps 文化。
审计日志记录所有权限变更操作集成 http-log 插件将操作日志发送到 ELK;平台自身记录审批流水满足合规审计要求。

10.3 Kong + Spring Cloud Gateway 联动方案

架构层级说明协作方式优势
边缘网关Kong 作为外部入口,处理公网流量部署在 DMZ 区,负责 SSL 终止、DDoS 防护、全局限流利用 Kong 成熟的高性能网关能力。
内部网关Spring Cloud Gateway 处理内部微服务路由Kong 将请求转发至 SCG 集群,SCG 再路由到具体服务SCG 深度集成 Spring 生态,支持 Hystrix、Sentinel 等熔断降级策略。
配置同步两层网关的路由/服务配置联动自研同步服务监听 Kong Admin API 变更,转换为 SCG 的 DiscoveryClient 事件实现”一套配置,两级生效”,避免重复维护。
统一监控聚合两层网关的指标Kong 暴露 Prometheus 指标;SCG 集成 Micrometer;统一 Grafana 展示全链路可观测性,快速定位性能瓶颈。