设置请求超时

本任务用于示范如何使用 Istio 在 Envoy 中设置请求超时。

Istio 支持 Kubernetes Gateway API, 并计划将其作为未来流量管理的默认 API。 以下说明指导您在网格中配置流量管理时如何选择使用 Gateway API 或 Istio 配置 API。 请按照您的首选项遵循 Gateway APIIstio APIs 页签中的指示说明。

请注意,Kubernetes Gateway API CRD 不会默认安装在大多数 Kubernetes 集群上, 因此请确保在使用 Gateway API 之前已安装好这些 CRD:

  1. $ kubectl get crd gateways.gateway.networking.k8s.io &> /dev/null || \
  2. { kubectl apply -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.1.0/standard-install.yaml; }

开始之前

请求超时

HTTP 请求的超时可以通过路由规则中的 timeout 字段来指定。 默认情况下,超时是禁用的,本任务中,会把 reviews 服务的超时设置为半秒。 为了观察效果,还需要在对 ratings 服务的调用上人为引入 2 秒的延迟。

  1. 将请求路由到 reviews 服务的 v2 版本,它会发起对 ratings 服务的调用:
  1. $ kubectl apply -f - <<EOF
  2. apiVersion: networking.istio.io/v1
  3. kind: VirtualService
  4. metadata:
  5. name: reviews
  6. spec:
  7. hosts:
  8. - reviews
  9. http:
  10. - route:
  11. - destination:
  12. host: reviews
  13. subset: v2
  14. EOF
  1. $ kubectl apply -f - <<EOF
  2. apiVersion: gateway.networking.k8s.io/v1
  3. kind: HTTPRoute
  4. metadata:
  5. name: reviews
  6. spec:
  7. parentRefs:
  8. - group: ""
  9. kind: Service
  10. name: reviews
  11. port: 9080
  12. rules:
  13. - backendRefs:
  14. - name: reviews-v2
  15. port: 9080
  16. EOF
  1. 给对 ratings 服务的调用添加 2 秒的延迟:
  1. $ kubectl apply -f - <<EOF
  2. apiVersion: networking.istio.io/v1
  3. kind: VirtualService
  4. metadata:
  5. name: ratings
  6. spec:
  7. hosts:
  8. - ratings
  9. http:
  10. - fault:
  11. delay:
  12. percentage:
  13. value: 100
  14. fixedDelay: 2s
  15. route:
  16. - destination:
  17. host: ratings
  18. subset: v1
  19. EOF

Gateway API 尚不支持故障注入,因此我们现在需要使用 Istio VirtualService 来添加延迟:

  1. $ kubectl apply -f - <<EOF
  2. apiVersion: networking.istio.io/v1
  3. kind: VirtualService
  4. metadata:
  5. name: ratings
  6. spec:
  7. hosts:
  8. - ratings
  9. http:
  10. - fault:
  11. delay:
  12. percentage:
  13. value: 100
  14. fixedDelay: 2s
  15. route:
  16. - destination:
  17. host: ratings
  18. EOF
  1. 在浏览器中打开 Bookinfo 的网址 http://$GATEWAY_URL/productpage, 其中 $GATEWAY_URL 是入口的外部 IP 地址,如 Bookinfo 文档中所述。

    这时可以看到 Bookinfo 应用运行正常(显示了评级的星型符号),但是每次刷新页面, 都会有 2 秒的延迟。

  2. 现在给对 reviews 服务的调用增加一个半秒的请求超时:

  1. $ kubectl apply -f - <<EOF
  2. apiVersion: networking.istio.io/v1
  3. kind: VirtualService
  4. metadata:
  5. name: reviews
  6. spec:
  7. hosts:
  8. - reviews
  9. http:
  10. - route:
  11. - destination:
  12. host: reviews
  13. subset: v2
  14. timeout: 0.5s
  15. EOF
  1. $ kubectl apply -f - <<EOF
  2. apiVersion: gateway.networking.k8s.io/v1
  3. kind: HTTPRoute
  4. metadata:
  5. name: reviews
  6. spec:
  7. parentRefs:
  8. - group: ""
  9. kind: Service
  10. name: reviews
  11. port: 9080
  12. rules:
  13. - backendRefs:
  14. - name: reviews-v2
  15. port: 9080
  16. timeouts:
  17. request: 500ms
  18. EOF
  1. 刷新 Bookinfo 页面。

    这时候应该看到 1 秒钟就会返回,而不是之前的 2 秒钟,但 reviews 是不可用的。

    即使超时配置为半秒,响应仍需要 1 秒,是因为 productpage 服务中存在硬编码重试, 因此它在返回之前调用 reviews 服务超时两次。

理解原理

本任务中,使用 Istio 为对 reviews 微服务的调用配置了半秒的请求超时。默认情况下请求超时是禁用的。 reviews 服务在处理请求时会接着调用 ratings 服务,用 Istio 在对 ratings 的调用中注入了两秒钟的延迟,这样就让 reviews 服务要花费超过半秒的时间来完成调用, 因此可以观察到超时。

可以观察到,Bookinfo 的页面(调用 reviews 服务来生成页面)没显示评论,而是显示了消息: Sorry, product reviews are currently unavailable for this book. 这就是它收到了来自 reviews 服务的超时错误信息。

如果看过故障注入任务,就会发现 productpage 微服务在调用 reviews 微服务时,还有它自己的应用级的超时(3 秒)设置。 注意在本任务中使用 Istio 路由规则设置了半秒的超时。如果将超时设置为大于 3 秒(比如 4 秒), 则超时将不会有任何影响,因为这两个超时的限制性更强。更多细节可以参考这里

还有一点关于 Istio 中超时控制方面的补充说明,除了像本文一样在路由规则中进行超时设置之外, 还可以进行请求一级的设置,只需在应用的对外请求中加入 x-envoy-upstream-rq-timeout-ms 请求头即可。在这个请求头中的超时设置单位是毫秒而不是秒。

清理

  • 删除应用程序的路由规则:

Zip

  1. $ kubectl delete -f @samples/bookinfo/networking/virtual-service-all-v1.yaml@
  1. $ kubectl delete httproute reviews
  2. $ kubectl delete virtualservice ratings
  • 如果您不打算探索任何后续任务,请参阅 Bookinfo 清理的说明关闭应用程序。