# 网关 API 策略 DCE 5.0 云原生网关支持支持负载均衡、超时重试、黑白名单等十几项 API 策略。本文借助真实的微服务应用演示如何配置各项策略以及每项策略的具体效果。 !!! note - 有关各项策略的配置步骤、参数说明等细节,可参考[配置 API 策略](../gateway/api/api-policy.md)。 - 本文侧重于展示各项策略的使用效果,会省略一些配置步骤。 ## 前提条件 - 准备一个演示服务,例如 `my-otel-demo-adservice` - 创建[网关](../gateway/index.md)、[域名](../gateway/domain/index.md)、[API](../gateway/api/index.md) - 将演示[服务接入网关](gateway01.md) ## 负载均衡 1. 将演示服务扩展为多副本,便于演示负载均衡 2. 参考[负载均衡](../gateway/api/api-policy.md#_2)配置负载均衡策略 3. 编写脚本记录各个服务副本接收到的流量 ??? note "点击查看脚本内容" ```python import requests def lb_pod_count(): pod1_ip = "10.244.1.135" # 服务副本所在节点的 IP pod2_ip = "10.244.2.207" # 服务副本所在节点的 IP pod3_ip = "10.244.3.193" # 服务副本所在节点的 IP pod1_count = 0 pod2_count = 0 pod3_count =0 host = "http://10.6.222.24:30040/ip" # 服务访问地址 headers = {"Host": "ad.service.virtualhost"} for i in range(300): res_ip = requests.get(host, headers=headers).text[11:] if res_ip == pod1_ip: pod1_count += 1 elif res_ip == pod2_ip: pod2_count += 1 elif res_ip == pod3_ip: pod3_count += 1 print("指向%s的流量为:%d" %(pod1_ip,pod1_count)) print("指向%s的流量为:%d" %(pod2_ip,pod2_count)) print("指向%s的流量为:%d" %(pod3_ip,pod3_count)) if __name__ == '__main__': lb_pod_count() ``` 4. 随机负载均衡的效果如下。每个副本随机接受流量,导致个别副本压力过大。 ![random](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/skoala/images/br-gw11.png) 5. 轮询负载均衡的效果如下。每个副本轮流接受流量,因此各个副本处理的流量总数基本相同。 ![random](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/skoala/images/br-gw12.png) ## 路径改写 1. 初始状态下,访问的是服务根路径,返回内容如图。 ![rewrite](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/skoala/images/br-gw09.png) 2. 配置路径改写策略,原先访问服务根路径,改为访问 `/test2` 接口。 ![rewrite](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/skoala/images/br-gw13.png) 3. 效果如图。从返回内容可以看出,现在访问的接口已经改变了,返回的数据也变了。 ![rewrite](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/skoala/images/br-gw14.png) ## 超时配置 1. 启用超时配置,设置响应超过 3 秒时判断访问失败。 ![rewrite](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/skoala/images/br-gw15.png) 2. 通过测试专用接口 `timeout` 让请求响应 1 秒,预期可以成功访问。 下图说明访问成功,接口返回了所设置的请求时间 ![rewrite](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/skoala/images/br-gw16.png) 3. 通过测试专用接口 `timeout` 让请求响应 4 秒,预期会访问失败 下图说明访问失败,接口返回上游请求超时的信息。 ![rewrite](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/skoala/images/br-gw17.png) ## 重试机制 1. 启用重试配置,访问失败时最多重试 6 次,重试响应时间超过 1 秒时视为重试失败。 ![rewrite](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/skoala/images/br-gw18.png) 2. 通过测试专用接口 `set-retry-count` 使得服务的 `/retry` 接口必须请求 3 次才能访问成功。 ![rewrite](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/skoala/images/br-gw19.png) 访问 `retry` 接口。 在重试次数为 6 的情况下,预期可以访问成功。 ![rewrite](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/skoala/images/br-gw20.png) 3. 通过测试专用接口 `set-retry-count` 使得服务的 `/retry` 接口必须请求 7 次才能访问成功。 ![rewrite](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/skoala/images/br-gw21.png) 访问 `retry` 接口。 在重试次数为 6 的情况下,预期也能访问成功。因为首次正常访问加失败后的 6 次重试,正好达到了所需的 7 次访问。 ![rewrite](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/skoala/images/br-gw22.png) 4. 通过测试专用接口 `set-retry-count` 使得服务的 `/retry` 接口必须请求 8 次才能访问成功。 ![rewrite](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/skoala/images/br-gw23.png) 访问 `retry` 接口。 在重试次数为 6 的情况下,预期第一次会访问失败。因为首次正常访问加失败后的 6 次重试,最多只能访问 7 次,达不到所需的 8 次访问。 但此时手动再次访问该接口,就会显示访问成功,因此此时累计的访问次数已经达到了 8 次。 ![rewrite](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/skoala/images/br-gw24.png) ## 请求头重写 1. 启用请求头重写策略,在请求服务时移除 `user-agent` (不区分大小写,并添加 `demo-req`。 ![rewrite](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/skoala/images/br-gw25.png) 2. 使用 postman 工具查看服务初始状态下带有的请求头。可以看到存在 `user-agent`,但没有 `demo-req`。 ![rewrite](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/skoala/images/br-gw28.png) 3. 通过测试专用接口 `/request-header` 查看请求服务时是否带上了 `user-agent`。 返回 `user-agent` 的值为 null,说明该请求头被移除了,重写策略生效。 ![rewrite](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/skoala/images/br-gw26.png) 4. 通过测试专用接口 `/request-header` 查看请求服务时是否带上了 `user-agent`。 返回了预先设置的值,说明添加了该请求头,重写策略生效。 ![rewrite](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/skoala/images/br-gw27.png) ## 响应头重写 1. 启用响应头重写策略,在服务响应头中移除 `x-envoy-upstream-service-time` (不区分大小写)响应头,并添加 `demo-res`。 ![rewrite](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/skoala/images/br-gw29.png) 2. 使用 postman 工具查看初始状态下的响应头。可以看到存在 `x-envoy-upstream-service-time`,但没有 `demo-res`。 ![rewrite](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/skoala/images/br-gw30.png) 3. 直接访问该服务 响应头中没有 `x-envoy-upstream-service-time`,但出现了 `demo-res` ,说明重写策略生效。 ![rewrite](https://docs.daocloud.io/daocloud-docs-images/docs/zh/docs/skoala/images/br-gw31.png) ## WebSocket 1. 编写测试 WebSocket 的脚本 ??? note "点击查看脚本内容" ```html