使用ASM慢启动预热功能

更新时间: 2023-04-12 14:08:16

ASM自1.14版本起提供慢启动预热功能,支持在用户配置的时间段内逐步增加请求量,避免出现请求超时、数据丢失等问题。本文介绍如何使用ASM慢启动预热功能。

前提条件

背景信息

在未启用慢启动预热功能时,每当新目标Pod加入时,请求方都会向该Pod发送一定比例的流量,不支持新Pod的渐进式流量增加。这对于需要一些预热时间来提供全部负载的服务可能是不可取的,并且可能会导致请求超时、数据丢失和用户体验恶化。例如在基于JVM的Web应用程序中,这些应用程序使用水平Pod自动缩放。当服务刚启动时,它会被大量请求淹没,这会导致应用程序预热时持续超时。因此,每次扩展服务时,都会丢失数据或者会导致这部分请求的响应时间增加。预热的基本思想就是让刚启动的机器逐步接入流量。

慢启动预热功能介绍

慢启动模式又称渐进式流量增加,用户可以为服务配置一个时间段,每当一个服务实例启动时,请求方会向该实例发送一部分请求负载,并在配置的时间段内逐步增加请求量。当慢启动窗口持续时间到达,就会退出慢启动模式。

在慢启动模式下,添加新的目标服务Pod时,避免新增Pod被大量请求击垮,这些新目标服务可以根据指定的加速期在接受其均衡策略的请求之前进行预热。

慢启动对于依赖缓存并且需要预热期才能以最佳性能响应请求的应用程序非常有用。在ASM下,您只需在服务对应的DestinationRule下的配置trafficPolicy/loadBalancer即可,需要注意的是:

  • loadBalancer:表示负载均衡器信息。类型限定于ROUND_ROBINLEAST_REQUEST负载均衡器。

  • warmupDurationSecs:表示Service的预热持续时间。如果设置,则新创建的服务端点在此窗口期间从其创建时间开始保持预热模式,并且Istio逐渐增加该端点的流量,而不是发送成比例的流量。

DestinationRule的YAML示例如下:

apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: mocka
spec:
  host: mocka
  trafficPolicy:
    loadBalancer:
      simple: ROUND_ROBIN
      warmupDurationSecs: 100s
  subsets:
  - name: v1
    labels:
      version: v1
  - name: v2
    labels:
      version: v2

步骤一:配置路由规则并访问入口网关

为方便演示,本文先将Reviews的v1和v2版本的Deployment副本数调整为0,即在Kubernetes集群中将名为reviews-v1与reviews-v2的Deployment部署的副本数缩容为0。

  1. 定义访问入口。

    1. 使用以下内容,创建bookinfo-gateway.yaml文件。

      apiVersion: networking.istio.io/v1alpha3
      kind: Gateway
      metadata:
        name: bookinfo-gateway
      spec:
        selector:
          istio: ingressgateway
        servers:
        - port:
            number: 80
            name: http
            protocol: HTTP
          hosts:
          - "*"
      ---
      apiVersion: networking.istio.io/v1alpha3
      kind: VirtualService
      metadata:
        name: bookinfo
      spec:
        hosts:
        - "*"
        gateways:
        - bookinfo-gateway
        http:
        - match:
          - uri:
              exact: /productpage
          - uri:
              prefix: /static
          - uri:
              exact: /login
          - uri:
              exact: /logout
          - uri:
              prefix: /api/v1/products
          route:
          - destination:
              host: productpage
              port:
                number: 9080
    2. 执行以下命令,部署bookinfo-gateway。

      kubectl apply -f bookinfo-gateway.yaml
  2. 创建Reviews服务。

    1. 使用以下内容,创建reviews.yaml文件。

      apiVersion: networking.istio.io/v1beta1
      kind: DestinationRule
      metadata:
        name: reviews
      spec:
        host: reviews
        subsets:
          - labels:
              version: v1
            name: v1
          - labels:
              version: v2
            name: v2
        trafficPolicy:
          loadBalancer:
            simple: ROUND_ROBIN
      ---
      apiVersion: networking.istio.io/v1beta1
      kind: VirtualService
      metadata:
        name: reviews
      spec:
        hosts:
          - reviews
        http:
          - route:
              - destination:
                  host: reviews                         
    2. 执行以下命令,部署Reviews。

      kubectl apply -f reviews.yaml
  3. 开启网格拓扑, 持续访问入口网关地址。

    本文以通过hey命令发送压测请求10s为例。关于hey命令的下载和安装,请参见hey;关于开启和查看网格拓扑的具体操作,请参见查看应用的网格拓扑

    hey -z 10s http://${网关地址}/productpage

    调用拓扑示例图如下:网格拓扑示例图

步骤二:通过可观测数据查看Pod启动

  1. 登录ASM控制台
  2. 在左侧导航栏,选择服务网格 > 网格管理
  3. 网格管理页面,找到待配置的实例,单击实例的名称或在操作列中单击管理
  4. 在左侧导航栏单击可观测管理中心 > 监控指标

  5. 监控指标页面,单击监控仪表页签,然后单击网格服务级别监控页签,选择对应的Reviews服务。

  6. 发送压测请求并观察监控数据。

    1. 在未开启预热功能的情况下,在Kubernetes集群中将名为reviews-v2的Deployment部署的副本数从0扩容为1。

    2. 执行以下命令,发送压测请求入口网关。

      本文以发送压测请求120s为例。

      hey -z 120s http://${网关地址}/productpage
    3. 观察Prometheus监控的仪表盘数据。

      大约需要15s左右,reviews-v2 Pod将接收均衡的请求(具体时间会跟实际压测环境有关)。通过可观测数据查看Pod启动

  7. 在Kubernetes集群中将名为reviews-v2的Deployment部署的副本数缩容为0。

步骤三:启用预热功能

  1. 使用以下内容,更新reviews.yaml文件。

    增加warmupDurationSecs字段,配置为120s,即定义预热持续时间为120s。

    apiVersion: networking.istio.io/v1beta1
    kind: DestinationRule
    metadata:
      name: reviews
    spec:
      host: reviews
      subsets:
        - labels:
            version: v1
          name: v1
        - labels:
            version: v2
          name: v2
      trafficPolicy:
        loadBalancer:
          simple: ROUND_ROBIN
          warmupDurationSecs: 120s
  2. 执行以下命令,更新Reviews。

    kubectl apply -f reviews.yaml

步骤四:查看预热效果

方式一:通过可观测数据查看预热效果

  1. 开启预热功能后,在Kubernetes集群中将名为reviews-v2的Deployment部署的副本数从0扩容为1。

  2. 执行以下命令,发送压测请求入口网关。

    本文以发送压测请求150s为例。

    hey -z 150s http://${网关地址}/productpage
  3. 网格服务级别监控页签中,观察Prometheus监控的仪表盘数据。

    大概需要45s左右,reviews-v2 Pod将接收均衡的请求(具体时间会跟实际压测环境有关)。通过可观测数据查看预热效果在启用预热功能的情况下,每当一个服务实例启动时,请求方会向该实例发送一部分请求负载,并在配置的时间段内逐步增加请求量。当慢启动窗口持续时间到达,就会退出慢启动模式。

    启用预热功能之后,需要2分30秒左右,流量将均衡地分布到v1和v2版本。通过可观测数据查看预热效果

方式二:通过代理计数器查看预热效果

  1. 执行以下命令,清空计数器的已有数据。

    清空计数器的已有数据,便于查看新增的计数值。

    ## reviews-v1版本对应Pod中的Sidecar代理计数器。
    kubectl exec reviews-v1-55b668fc65-j****  -c istio-proxy -- curl localhost:15000/reset_counters -X POST
  2. 执行以下命令,查看Sidecar代理中的计数器统计成功处理的次数。

    清空计数器后,计数值应为0。

    kubectl exec reviews-v1-55b668fc65-j****  -c istio-proxy -- curl localhost:15000/stats |grep inbound |grep upstream_rq_200

    预期输出:

    cluster.inbound|8000||.upstream_rq_200: 0
  3. 修改reviews-v2版本的Deployment副本数,发送压测请求入口网关。

    1. 在Kubernetes集群中将名为reviews-v2的Deployment部署的副本数缩容为0,然后扩容为1。

    2. 执行以下命令,发送压测请求20s。

      hey -z 20s http://${网关地址}/productpage

      预期输出:

      Status code distribution:
        [200]    3260 responses

      由预期输出得到,通过hey命令在20s时间内成功发送了3260个请求。

  4. 执行以下命令,查看reviews-v1中Sidecar代理中的计数器统计成功处理的次数。

    kubectl exec reviews-v1-55b668fc65-j****  -c istio-proxy -- curl localhost:15000/stats |grep inbound |grep upstream_rq_200

    预期输出:

      % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                     Dload  Upload   Total   Spent    Left  Speed
    100 20873    0 20873    0     0  19.9M      0 --:--:-- --:--:-- --:--:-- 19.9M
    cluster.inbound|9080||.external.upstream_rq_200: 2927
    cluster.inbound|9080||.upstream_rq_200: 2927
  5. 执行以下命令,查看reviews-v2中Sidecar代理中的计数器统计成功处理的次数。

    kubectl exec reviews-v2-858f99c99-j****   -c istio-proxy -- curl localhost:15000/stats |grep inbound |grep upstream_rq_200

    预期输出:

      % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                     Dload  Upload   Total   Spent    Left  Speed
    100 30149    0 30149    0     0  28.7M      0 --:--:-- --:--:-- --:--:-- 28.7M
    cluster.inbound|9080||.external.upstream_rq_200: 333
    cluster.inbound|9080||.upstream_rq_200: 333

    由预期输出得到,在前20s(在120s的慢启动窗口期内),reviews-v2 Pod只处理了少量请求(10%左右)。

  6. 慢启动窗口期后,进行压测并查看预热效果。

    1. 执行以下命令,清空reviews-v1和reviews-v2的计数器。

      ## reviews-v1版本对应Pod中的Sidecar代理计数器。
      kubectl exec reviews-v1-55b668fc65-j****  -c istio-proxy -- curl localhost:15000/reset_counters -X POST
      ## reviews-v2版本对应Pod中的Sidecar代理计数器。
      kubectl exec reviews-v2-858f99c99-j****  -c istio-proxy -- curl localhost:15000/reset_counters -X POST
    2. 执行以下命令,发送压测请求20s。

      hey -z 20s http://${网关地址}/productpage
    3. 执行以下命令,查看reviews-v1中Sidecar代理中的计数器统计成功处理的次数。

      kubectl exec reviews-v1-55b668fc65-j****  -c istio-proxy -- curl localhost:15000/stats |grep inbound |grep upstream_rq_200

      预期输出:

      cluster.inbound|9080||.external.upstream_rq_200: 1600
      cluster.inbound|9080||.upstream_rq_200: 1600
    4. 执行以下命令,查看reviews-v2中Sidecar代理中的计数器统计成功处理的次数。

      kubectl exec reviews-v2-858f99c99-j****   -c istio-proxy -- curl localhost:15000/stats |grep inbound |grep upstream_rq_200

      预期输出:

      cluster.inbound|9080||.external.upstream_rq_200: 1600
      cluster.inbound|9080||.upstream_rq_200: 1600

      由预期输出得到,在慢启动窗口时间之外,reviews-v1和reviews-v2接受并处理了等量的请求数。

阿里云首页 服务网格 ASM 相关技术圈