Istio实践(4)- 故障注入、熔断及ServiceEntry

前言:接上一篇istio多服务应用部署及调用,本文介绍通过流量管理(故障注入、请求超时等)以及ServiceEntry外部服务部署应用

1.设置服务延迟

  • 修改springbootapp-vs-v1.yaml文件,设置springbootapp服务应用100延迟,延迟时间为3s,percent指定超时比例100%
    image
  • 通过ingressgateway对外开放端口,访问springbootapp服务,发现响应时间为3s
    image

2.设置服务超时

  • 修改springbootapp-vs-v1.yaml文件,设置netcoreapp服务超时时间为2s
    image
  • 通过netcoreapp服务,调用springbootapp服务,由于springbootapp服务100%有3s延迟,那么netcoreapp服务反馈超时错误
    image

3.故障注入(注入 HTTP abort 故障)

  • 修改springbootapp-vs-v1.yaml文件,设置springbootapp服务abort
    image
  • 通过netcoreapp服务,调用springbootapp服务
    image
    image

4.配置熔断器(DestinationRule)

  • 概念:
    1.熔断的基本逻辑就是隔离故障。在微服务架构盛行的今天,服务之间的调用链路相比单体应用时代变得更长了,服务化拆分带来系统整体能力提升的同时,也增加了服务级联故障出现的概率。例如调用链路“A->B->C->D”,如果服务D出现问题,那么链路上的A、B、C都可能会出现问题,这一点也很好理解,因为出现故障的服务D,必然会在某个时间段内阻塞C->D的调用请求,并最终蔓延至整个链路。而服务连接资源又是有限的,这种增加的调用耗时,会逐步消耗掉整个链路中所有服务的可用线程资源,从而成为压垮整个微服务体系的幕后黑手。
    2.限流。熔断的主要目的是隔离故障,而引起故障的原因除了系统本身的问题外,还有一种可能就是请求量达到了系统处理能力的极限,后续新进入的请求会持续加重服务负载,最终导致资源耗尽,从而引起系统级联故障、导致雪崩。而限流的目的就是拒绝多余流量、保证服务整体负载始终处于合理水平。
    从限流范围上看,微服务体系中的每个服务都可以根据自身情况设置合理的限流规则,例如调用链路“A->B->C->D”,B服务的承受力是1000QPS,如果超过该阀值,那么超出的请求就会被拒绝,但这也容易引起A对B的熔断,所以对于微服务设置限流规则的设置最好还是根据压测结果确定。
  • 修改springbootapp-dr.yaml文件

    image

      说明:
      1.maxConnections(最大连接数为1)、http1MaxPendingRequests(最大等待请求数为1),如果连接和并发请求数超过1个,那么该服务就会触发限流规则
      2.http1MaxPendingRequests: http 请求挂起状态的最大请求数
      3.outlierDetection.consecutiveErrors: 拒绝连接的最大失败次数
      4.outlierDetection.interval: 触发熔断的时间间隔,在 interval 时间间隔内,达到 consecutiveErrors 即触发熔断
      5.outlierDetection.baseEjectionTime: 熔断时长
      6.maxEjectionPercent: 熔断连接最大百分比
    
  • 使用压测工具Fortio负载测试客户端调用服务,我们这里使用apifox工具(JMeter也可),进行压测

    image

    image
    发现25%的请求成功,75%的请求失败,限流成功,重复请求还是可以成功的

  • 加大并发次数和循环次数,触发熔断

    image

    image
    此时重复请求,发现总是失败,没有成功的情形,触发了熔断,由于我们设置熔断时间3分钟,我们等3分钟后,再重试,就有成功的情形,测试成功
    image

5.服务条目(Service Entries)

  • 使用服务条目资源(Service Entries)可以将条目添加到 Istio 内部维护的服务注册表中。添加服务条目后,Envoy 代理可以将流量发送到该服务,就好像该服务条目是网格中的服务一样。通过配置服务条目,可以管理在网格外部运行的服务的流量。
  • 新建服务条目资源service-entry-baidu.yaml,指向百度
      apiVersion: networking.istio.io/v1alpha3
      kind: ServiceEntry
      metadata:
        name: baidu-entry
      spec:
        hosts:
        - "www.baidu.com"
        ports:
        - number: 80
          name: http
          protocol: HTTP
        location: MESH_EXTERNAL
        resolution: DNS
    
  • 执行命令,把服务条目放到netistiodemo的命名空间下
      sudo kubectl apply -f service-entry-baidu.yaml -n netistiodemo
      sudo kubectl get se -n netistiodemo
    
  • 使用busybox,访问baidu

    image

  • 修改serviceentry文件,设置了静态域名解析的方式,并随意给了一个IP来标识 baidu,这样访问baidu就失败了;说明我们的serviceentry生效了

    image

    image

  • service entry 使用场景
    如果你需要调用外部合作方服务,该服务跟你的集群毫无关系。这时通过服务条目,你可以将对方服务纳入到自己的Istio网格之内,就像它本身存在你的集群之内一样,结合虚拟服务(virtual service)、目的地规则(destination rule)做更加精细的流量控制、失败注入、重试等功能。
    个人感觉也可以把以前的老项目,整体暴露给Istio网格;比如spring cloud、dubbo、netcore等等已运行部署的服务,通过service entry的方式,纳入到Istio中管理
    能力有限,如有不妥之处,望见谅
posted @ 2022-04-24 22:07  xjk27400861  阅读(577)  评论(0编辑  收藏  举报