HTTP 调用
这章主要介绍如何使用 Higress 插件 Go SDK 实现 HTTP 调用。
1 Envoy 集群(Cluster)名称和服务发现来源
Higress 插件的 Go SDK 在进行 HTTP 和 Redis 调用时,是通过指定的集群名称来识别并连接到相应的 Envoy 集群。 此外,Higress 利用 McpBridge 支持多种服务发现机制,包括静态配置(static)、DNS、Kubernetes 服务、Eureka、Consul、Nacos、以及 Zookeeper 等。 每种服务发现机制对应的集群名称生成规则都有所不同,这些规则在 cluster_wrapper.go 代码文件中有所体现。 为了包装不同的服务发现机制,Higress 插件 Go SDK 定义了 Cluster 接口,该接口包含两个方法:ClusterName 和 HostName。
1.1 FQDN
- 集群名称规则为:
outbound|<Port>||<FQDN>
。 - HostName 规则为:如果设置 Host,返回 Host,否则返回
<FQDN>
。
FQDN 即在服务列表里看到的服务名称,形如:“my-cluster.static”,“your-cluster.dns”,“foo.default.svc.cluster.local”
Host 字段用于发送实际 HTTP 请求时的缺省配置域名,如果在发送时的 URL 里指定了域名,那么将以指定的为准。下面其他的 cluster 中的 Host 字段含义也是一样的。
1.2 当前路由的服务
集群名称是直接通过 proxywasm.GetProperty([]string{“cluster_name”}) 获取的当前路由的目标集群
1.3 静态配置(static)
- 集群名称规则为:
outbound|<port>||<service_name>.static
。 - HostName 规则为:默认为 <service_name>。
1.4 DNS 配置(dns)
- 集群名称规则为:
outbound|<Port>||<ServiceName>.dns
。 - HostName 规则为:如果设置 Host,返回 Host,否则返回
。
1.5 Kubernetes 服务(kubernetes)
- 集群名称规则为:
outbound|<Port>|<Version>|<ServiceName>.<Namespace>.svc.cluster.local
。 - HostName 规则为:如果设置 Host,返回 Host,否则返回
. .svc.cluster.local。
1.6 Nacos
- 集群名称规则为:
outbound|<Port>|<Version>|<ServiceName>.<Group>.<NamespaceID>.nacos
。 - HostName 规则为:如果设置 Host,返回 Host,否则返回 <service_name>。
1.7 Consul
- 集群名称规则为:
outbound|<Port>||<ServiceName>.<Datacenter>.consul
。 - HostName 规则为:如果设置 Host,返回 Host,否则返回
。
2 HTTP 调用
http_wrapper.go 部分核心代码如下:
ClusterClient Get、Head、Options、Post、PUT、Patch、Delete、Connect、Trace、Call 方法最后调用 HttpCall 方法,其核心代码如下:
3 easy-jwt 插件开发
在实际业务场景中,可能需要独立认证授权服务,来完成每个请求的认证和授权,现在开发一个简单的 easy-jwt 插件来演示如何在 Wasm 插件进行 HTTP 调用。 其插件核心流程如下图:
Token Server 提供 2 个接口:
- /api/token/auth: 认证令牌接口
- /api/token/create: 生成令牌接口
3.1 插件部分核心代码
核心流程如下:
- 初始化插件
- 解析配置
- onHttpRequestHeaders 处理
- 检查请求路径是否在 ignoreUrls 列表中
- 是:添加匿名 UID 到请求头,继续处理请求
- 否:继续
- 从请求头中提取令牌,检查令牌是否存在
- 存在:继续
- 不存在:返回错误,发送响应
- 验证令牌
- 如果令牌是匿名令牌,添加匿名 UID 到请求头,继续处理请求
- 如果令牌不是匿名令牌,调用认证服务 /api/token/auth 接口验证令牌
- 如果验证成功,从响应中提取 UID,添加到请求头中,继续处理请求
- 如果验证失败,返回错误,发送响应
- 检查请求路径是否在 ignoreUrls 列表中
3.2 部署和验证
- 部署 YAML 如下:
- 获取令牌
获取 uid 为 100 的用户的访问令牌,其命令如下,其中 <token-server-pod>
是 token-server pod 名称。
- 请求验证
可以看到请求头中包含了 X-Auth-User
同时值为 100 。
4 ext-auth 插件
Higress 官方提供 ext-auth 插件,其功能更加丰富。 ext-auth 插件实现了向外部授权服务发送鉴权请求,以检查客户端请求是否得到授权。该插件实现时参考了 Envoy 原生的 ext_authz filter,实现了原生 filter 中对接 HTTP 服务的部分能力。
5 Envoy Cluster 不存在问题
在默认情况下,Higress 控制面只下发和路由关联的服务到 Envoy Cluster 中,因此有可能在实际开发过程中,发现对应调用 HTTP 服务在 Envoy Cluster 中不存在。 有 3 种方案去解决:
- helm 参数 global.onlyPushRouteCluster, 默认值为 true, 只推送路由关联的 Cluster 到 Envoy Cluster 中。修改为 false 即可。
- 创建一个新路由关联到对应的调用的 HTTP 服务。
- 通过 McpBridge 配置,添加调用的 HTTP 服务。
上面 easy-jwt 插件中调用 token-server 服务,是通过 McpBridge 配置,添加 dns 类型服务,其配置如下:
6 HTTP 回调链问题
在实际开发过程中,可能会遇到 HTTP 回调链的情况,比如在 onHttpRequestHeader 处理阶段,需要调用两个 HTTP 服务,这个时候在 onHttpRequestHeader 阶段中,要先调用第一个 HTTP 服务,在第一个 HTTP 服务的响应回调函数中,再发起第二个 HTTP 服务的调用。 以此类推。这种情况 Redis 调用也是一样处理。 关于回调链可以参考 Higress 官方提供 ai-agent 插件功能。