负载均衡
负载均衡是一种用于分配网络请求负载的技术。在设计需要处理大量流量的系统时,这是一个关键的考虑因素,可以提高系统性能、可扩展性和可靠性。
Apache APISIX 支持多种 负载均衡算法,其中之一是加权轮询算法。该算法以循环模式在一组服务器上分配传入请求。
在本教程中,你将创建一个具有两个上游服务的路由,并使用轮询负载均衡算法来对请求进行负载均衡。
前置条件
- 完成 安装 APISIX 以在 Docker 或 Kubernetes 中安装 APISIX。
- 了解 APISIX 路由 和 上游。
- 如果使用这些工具,请安装 ADC 或 APISIX-MCP。
启用负载均衡
- Admin API
- ADC
- Ingress Controller
- APISIX-MCP
创建一个包含两个上游服务的路由,httpbin.org 和 mock.api7.ai,以在它们之间分配请求。当在 /headers 接收到请求时,两个服务都会响应请求头:
curl -i "http://127.0.0.1:9180/apisix/admin/routes" -X PUT -d '
{
"id": "getting-started-headers",
"uri": "/headers",
"upstream" : {
// Annotate 1
"type": "roundrobin",
// Annotate 2
"nodes": {
"httpbin.org:443": 1,
"mock.api7.ai:443": 1
},
// Annotate 3
"pass_host": "node",
// Annotate 4
"scheme": "https"
}
}'
❶ type: 使用 roundrobin(轮询)作为负载均衡算法。
❷ nodes: 上游服务。
❸ pass_host: 使用 node 将 host 头传递给上游。
❹ scheme: 使用 https 与上游启用 TLS。
如果路由创建成功,你将收到 HTTP/1.1 201 Created 响应。
创建一个包含指向两个上游服务 httpbin.org 和 mock.api7.ai 的路由的 ADC 配置文件。当在 /headers 接收到请求时,两个服务都会响应请求头。
services:
- name: httpbin Service
routes:
- uris:
- /headers
name: getting-started-headers
upstream:
// Annotate 1
type: roundrobin
// Annotate 2
nodes:
- host: mock.api7.ai
port: 443
weight: 1
- host: httpbin.org
port: 443
weight: 1
// Annotate 3
pass_host: node
// Annotate 4
scheme: https
❶ type: 使用 roundrobin(轮询)作为负载均衡算法。
❷ nodes: 上游服务。
❸ pass_host: 使用 node 将 host 头传递给上游。
❹ scheme: 使用 https 与上游启用 TLS。
将配置同步到 APISIX:
adc sync -f adc.yaml
如果配置同步成功,你将收到类似的响应:
[11:25:49 AM] [ADC] › ✔ success Sync configuration
[11:25:49 AM] [ADC] › ★ star All is well, see you next time!
为了演示目的,你将创建一个指向公开托管的 httpbin 服务和 mock.api7.ai 的路由。如果你想代理请求到 Kubernetes 上的服务,请相应修改。
如果你使用 Gateway API,应首先配置 GatewayClass 和 Gateway 资源:
显示配置
apiVersion: gateway.networking.k8s.io/v1
kind: GatewayClass
metadata:
name: apisix
spec:
controllerName: apisix.apache.org/apisix-ingress-controller
---
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
namespace: ingress-apisix
name: apisix
spec:
gatewayClassName: apisix
listeners:
- name: http
protocol: HTTP
port: 80
infrastructure:
parametersRef:
group: apisix.apache.org
kind: GatewayProxy
name: apisix-config
请注意,Gateway 监听器中的 port 是必需的,但被忽略。这是由于数据平面的限制:它无法动态打开新端口。由于 Ingress Controller 不管理数据平面部署,它无法自动更新配置或重新启动数据平面以应用端口更改。
如果你使用 Ingress 或 APISIX 自定义资源,则无需额外配置即可继续,因为下面的 IngressClass 资源已随安装一起应用:
显示配置
apiVersion: networking.k8s.io/v1
kind: IngressClass
metadata:
name: apisix
spec:
controller: apisix.apache.org/apisix-ingress-controller
parameters:
apiGroup: apisix.apache.org
kind: GatewayProxy
name: apisix-config
namespace: ingress-apisix
scope: Namespace
有关参数的更多信息,请参阅 定义控制器和网关。
创建一个 Kubernetes 清单文件,用于代理请求到两个上游服务进行负载均衡的路由:
- Gateway API
- APISIX CRD
apiVersion: v1
kind: Service
metadata:
namespace: ingress-apisix
name: httpbin-external-domain
spec:
type: ExternalName
externalName: httpbin.org
---
apiVersion: v1
kind: Service
metadata:
namespace: ingress-apisix
name: mockapi7-external-domain
spec:
type: ExternalName
externalName: mock.api7.ai
---
apiVersion: apisix.apache.org/v1alpha1
kind: BackendTrafficPolicy
metadata:
namespace: ingress-apisix
name: passhost-node
spec:
targetRefs:
- name: httpbin-external-domain
kind: Service
group: ""
- name: mockapi7-external-domain
kind: Service
group: ""
passHost: node
scheme: https
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
namespace: ingress-apisix
name: lb-route
spec:
parentRefs:
- name: apisix
rules:
- matches:
- path:
type: Exact
value: /headers
backendRefs:
- name: httpbin-external-domain
port: 443
weight: 1
- name: mockapi7-external-domain
port: 443
weight: 1
apiVersion: apisix.apache.org/v2
kind: ApisixUpstream
metadata:
namespace: ingress-apisix
name: httpbin-external-domain
spec:
ingressClassName: apisix
scheme: https
passHost: node
externalNodes:
- type: Domain
name: httpbin.org
weight: 1
port: 443
---
apiVersion: apisix.apache.org/v2
kind: ApisixUpstream
metadata:
namespace: ingress-apisix
name: mockapi7-external-domain
spec:
ingressClassName: apisix
scheme: https
passHost: node
externalNodes:
- type: Domain
name: mock.api7.ai
weight: 1
port: 443
---
apiVersion: apisix.apache.org/v2
kind: ApisixRoute
metadata:
namespace: ingress-apisix
name: lb-route
spec:
ingressClassName: apisix
http:
- name: lb-route
match:
paths:
- /headers
upstreams:
- name: httpbin-external-domain
- name: mockapi7-external-domain
将配置应用到你的集群:
kubectl apply -f lb-route.yaml
在你的 AI 客户端中输入以下提示:
Create a route with the ID getting-started-headers that matches requests to the URI /headers, and forward them to two upstream nodes — httpbin.org and mock.api7.ai — both on 443. Use roundrobin algorithm for load balancing. The route should use HTTPS scheme and pass the original host of each upstream node in the request.
你应该看到类似的响应:
Successfully created route "getting-started-headers" with:
URI: /headers
Two upstream nodes:
https://httpbin.org:443
https://mock.api7.ai:443
Round-robin load balancing
Original host headers preserved (pass_host: node)
Route ID: getting-started-headers
Status: Active (1)
Created at: 1744189246 (2025-04-09 09:00:46 UTC)
The route is now ready to distribute requests between the two upstream endpoints while maintaining the original host headers.
验证
- Admin API
- ADC
- Ingress Controller
- APISIX-MCP
生成 50 个连续请求到 APISIX /headers 路由,以查看负载均衡效果:
resp=$(seq 50 | xargs -I{} curl "http://127.0.0.1:9080/headers" -sL) && \
count_httpbin=$(echo "$resp" | grep "httpbin.org" | wc -l) && \
count_mockapi7=$(echo "$resp" | grep "mock.api7.ai" | wc -l) && \
echo httpbin.org: $count_httpbin, mock.api7.ai: $count_mockapi7
该命令分别统计了两个服务处理的请求数。输出显示请求已分发到两个服务:
httpbin.org: 23, mock.api7.ai: 27
生成 50 个连续请求到 APISIX /headers 路由,以查看负载均衡效果:
resp=$(seq 50 | xargs -I{} curl "http://127.0.0.1:9080/headers" -sL) && \
count_httpbin=$(echo "$resp" | grep "httpbin.org" | wc -l) && \
count_mockapi7=$(echo "$resp" | grep "mock.api7.ai" | wc -l) && \
echo httpbin.org: $count_httpbin, mock.api7.ai: $count_mockapi7
该命令分别统计了两个服务处理的请求数。输出显示请求已分发到两个服务:
httpbin.org: 23, mock.api7.ai: 27
首先,通过端口转发将服务端口暴露给本地机器:
kubectl port-forward svc/apisix-gateway 9080:80 &
上面的命令在后台运行,并将 apisix-gateway 服务的 80 端口映射到本地机器的 9080 端口。
或者,你可以使用负载均衡器在 kind 集群上公开服务。详情请参阅 kind 负载均衡器文档。
生成 50 个连续请求到路由,以查看负载均衡效果:
resp=$(seq 50 | xargs -I{} curl "http://127.0.0.1:9080/headers" -sL) && \
count_httpbin=$(echo "$resp" | grep "httpbin.org" | wc -l) && \
count_mockapi7=$(echo "$resp" | grep "mock.api7.ai" | wc -l) && \
echo httpbin.org: $count_httpbin, mock.api7.ai: $count_mockapi7
该命令分别统计了两个服务处理的请求数。输出显示请求已分发到两个服务:
httpbin.org: 23, mock.api7.ai: 27
在你的 AI 客户端中输入以下提示:
Generate 50 consecutive requests to the APISIX /headers route to observe the load-balancing behavior, then count how many responses came from httpbin.org and how many came from mock.api7.ai.
你应该看到类似的响应:
Load balancing test results for 50 requests to /headers route:
httpbin.org responses: 23 (46%)
mock.api7.ai responses: 27 (54%)
The round-robin load balancing is working as expected, distributing requests between the two upstream nodes. The slight imbalance (46/54 split) could be due to connection timing or other network factors, but overall demonstrates effective load distribution.
请求在服务之间的分布应接近 1:1,但可能并不总是完全为 1:1。轻微的偏差是由于 APISIX 使用多个 worker 运行所致。
下一步
你已经学 习了如何配置负载均衡。在下一个教程中,你将学习如何配置密钥认证。