对于一个系统,尤其是一个复杂的系统,重要的不是会不会发生故障,而是什么时候会发生故障。故障排除对于开发人员和测试人员来说都特别费时费力:对于开发人员来说,他们在开发代码的时候需要花20%的时间写80%的主要逻辑,然后留出80%的时间去处理有各种问题。异常场景;对于测试人员来说,除了用80%的时间编写20%的异常测试项外,还需要花费80%以上的时间来执行这些异常测试项,构建各种故障场景,尤其是这类只出现在理论上的失败让人苦不堪言。故障注入是评估系统可靠性的有效方法,如异常处理、故障恢复等。只有系统的所有服务都经过故障测试并具有容错能力,整个应用程序才是健壮可靠的。从故障注入的方式来看,有编译时故障注入和运行时故障注入。前者需要修改代码模拟故障,后者在运行阶段触发故障。Istio的故障注入就是将故障注入到网格中特定的应用层协议中,使得基于Istio的故障注入能够模拟应用故障场景。接下来我们将解释如何注入故障并测试应用程序的弹性。延迟故障注入为了测试Bookinfo微服务应用程序的弹性,我们将在reviews:v2和用户jason的评级服务之间注入7秒延迟,该测试将发现故意引入Bookinfo应用程序的错误。首先删除之前创建的VirtualService:?~kubectldeletevirtualservicereviewsvirtualservice.networking.istio.io"reviews"deleted?~kubectlgetvirtualserviceNAMEGATEWAYSHOSTSAGEbookinfo[bookinfo-gateway][*]16d为了让请求稳定,这里我们配置Reviews服务的请求路由,相应的资源清单文件samples/bookinfo/networking/virtual-service-reviews-test-v2.yaml:apiVersion:networking.istio.io/v1alpha3kind:VirtualServicemetadata:name:reviewsspec:hosts:-reviewshttp:-match:-headers:end-user:exact:jasonroute:-destination:host:reviewssubset:v2-route:-destination:host:reviewssubset:v1应用上述配置后,jason用户将被路由到reviews:v2版本服务,其他用户将被路由到reviews:v1版本服务。创建故障注入规则,延迟来自测试用户jason的流量,对应的资源清单为samples/bookinfo/networking/virtual-service-ratings-test-delay.yaml:apiVersion:networking.istio.io/v1alpha3kind:VirtualServicemetadata:name:ratingsspec:hosts:-ratingshttp:-match:-headers:end-user:exact:jasonfault:delay:percentage:value:100.0fixedDelay:7sroute:-destination:host:ratingssubset:v1-route:-destination:host:ratingssubset:v1的VirtualService为jason登录时访问ratings服务定义了100%7s的访问延迟。前面我们知道bookinfo示例productpage服务调用reviews,不同版本的reviews调用ratings的方式不同。其中reviews-v1不调用ratings,reviews-v2和reviews-v3调用ratings和render的方式不同。请注意,reviews:v2服务对评级服务的调用具有10秒的硬编码连接超时。因此,尽管引入了7秒的延迟,我们仍然希望端到端的流程没有错误。知道了这一点,让我们现在创建上面的VirtualService资源对象:?~kubectlapply-fsamples/bookinfo/networking/virtual-service-reviews-test-v2.yaml?~kubectlapply-fsamples/bookinfo/networking/virtual-service-ratings-test-delay.yamlvirtualservice.networking.istio.io/ratingscreated?~kubectlgetvirtualserviceNAMEGATEWAYSHOSTSAGEbookinfo["bookinfo-gateway"]["*"]6d23hratings["ratings"]23mreviews["reviews"]4s通过浏览器打开Bookinfo应用,登录以用户jason的身份访问/productpage页面。我们希望Bookinfo主页能够在大约7秒内加载且没有错误,但评论部分显示一条错误消息:抱歉,目前无法获得这本书的产品评论。评论不可用,我们可以看到页面实际上加载了大约6秒,正如预期的那样,我们引入的7秒延迟不会影响评论服务,因为评论和评级服务之间的超时被硬编码为10秒,但实际上有在productpage和reviews服务超时之间还有一个硬编码的3s,加上1次重试,总共6s,所以productpage对reviews的调用在6s之后提前超时并抛出错误。这种类型的错误在不同团队独立开发不同微服务的企业应用中是有可能发生的,而Istio的故障注入规则可以帮助我们在不影响最终用户的情况下识别此类异常。请注意,此故障注入仅限于影响用户jason,如果您以任何其他用户身份登录,则不会遇到任何延迟。我们可以增加productpage和reviews服务的超时时间或者减少reviews和ratings的超时时间来解决这个问题,这个问题在reviewsservice的v3版本中已经修复,reviews:v3servicehaschangedthetimeoutofreviewsandratingsfrom10s减少到2.5s,因此它与下游产品页面请求兼容(小于)。如果我们把上面的Reviews流量转移到reviews:v3服务,那么我们可以尝试修改延迟规则为任何低于2.5s的值,比如2s,然后就可以确认end-to没有错误了-结束过程。通过这个超时故障注入,可以帮助我们轻松发现服务间相互访问的潜在问题。打破访问故障注入测试微服务弹性的另一种方法是引入HTTP中止故障。接下来,我们将为测试用户jason的评级微服务引入HTTP中止。在这种情况下,我们希望页面立即加载,并显示一条消息,例如Ratingsserviceiscurrentlyunavailable。我们这里需要用到的资源列表文件是samples/bookinfo/networking/virtual-service-ratings-test-abort.yaml:apiVersion:networking.istio.io/v1alpha3kind:VirtualServicemetadata:name:ratingsspec:hosts:-ratingshttp:-match:-headers:end-user:exact:jasonfault:abort:percentage:value:100.0httpStatus:500route:-destination:host:ratingssubset:v1-route:-destination:host:ratingssubset:v1以上VirtualService资源对象配置当jason登录时,评论会在访问评级时100%的时间返回500错误响应。然后创建这个资源对象:?~kubectlapply-fsamples/bookinfo/networking/virtual-service-ratings-test-abort.yamlvirtualservice.networking.istio.io/ratingscreated?~kubectlgetvirtualserviceNAMEGATEWAYSHOSTSAGEbookinfo["bookinfo-gateway"]["*"]7dratings["ratings"]68mreviews["reviews"]44m现在我们回到BookInfo应用,登录jason,刷新页面,有时很快就能看到Rating服务不可用的提示信息:bookinfoerror如果用户jason已注销,我们会看到/productpage为jason以外的用户调用reviews:v1(根本不是评级),因此您不会看到任何错误消息,也不会看到星形图形.
