故障注入(Fault Injection)
这个示例向您展示了如何注入故障
以测试应用程序的弹性
。
在你开始之前
- 按照安装指南中的说明安装 Istio。
- 部署Bookinfo示例应用程序,包括默认的目标规则。
- 回顾交通管理概念文档中的故障注入讨论。
- 通过执行请求路由示例或运行以下命令来应用程序的版本路由:
$ kubectl apply -f samples/bookinfo/networking/virtual-service-all-v1.yaml $ kubectl apply -f samples/bookinfo/networking/virtual-service-reviews-test-v2.yaml
- 通过以上配置,请求是这样流转的。
productpage
→reviews:v2
→ratings
(只有jason
用户)productpage
→reviews:v1
(其他用户)
注入HTTP延迟故障
为了测试Bookinfo应用微服务的弹性,在用户jason
的review:v2
和ratings(评级)
微服务之间注入7s延迟。这个测试将会发现一个故意引入 Bookinfo 应用程序中的 bug。
请注意,reviews:v2
对 ratings(评级)
服务的调用有10秒的硬编码连接超时。即使你引入了7秒的延迟,我们仍然期望端到端的流程是没有任何错误的。
创建故障注入规则以延迟来自测试用户
jason
的流量。$ kubectl apply -f samples/bookinfo/networking/virtual-service-ratings-test-delay.yaml
确认规则已经创建:
$ kubectl get virtualservice ratings -o yaml apiVersion: networking.istio.io/v1beta1 kind: VirtualService ... spec: hosts: - ratings http: - fault: delay: fixedDelay: 7s percentage: value: 100 match: - headers: end-user: exact: jason route: - destination: host: ratings subset: v1 - route: - destination: host: ratings subset: v1
等待几秒钟,新规则才能传播到所有Pod。
测试延迟配置
在浏览器中打开Bookinfo Web应用程序。
在
/productpage
网页上,以jason
用户身份登录。
预计Bookinfo主页在大约7秒内正确加载。但是,存在一个问题:Reviews
部分显示错误信息。Error fetching product reviews! Sorry, product reviews are currently unavailable for this book.
查看网页响应时间:
- 打开网页浏览器中的开发者工具菜单。
- 打开 "网络"选项卡
- 重新加载
/productpage
网页。你会发现,该页面实际加载时间约为6秒。
了解发生了什么
你发现了一个 bug。微服务中有硬编码超时,导致 reviews
服务失败。
按照预期,我们引入的 7 秒延迟不会影响到 reviews
服务,因为 reviews
和 ratings
服务间的超时被硬编码为 10 秒。
但是,在 productpage
和 reviews
服务之间也有一个 3 秒的硬编码的超时,再加 1 次重试,一共 6 秒。
结果,productpage
对 reviews
的调用在 6 秒后提前超时并抛出错误了。
在典型的企业应用中,不同的团队独立开发不同的微服务,这样的错误可能会发生。Istio的故障注入规则可以帮助你识别这样的异常情况,而不会影响到终端用户。
请注意,故障注入测试仅限于登录用户为
jason
时。如果你以任何其他用户登录,你将不会遇到任何延迟。
错误修复
这种问题通常会这么解决:
- 增加
productpage
与reviews
服务之间的超时或降低reviews
与ratings
的超时 - 终止并重启修复后的微服务
- 确认
/productpage
页面正常响应且没有任何错误
但是,reviews
服务的 v3 版本已经修复了这个问题。reviews:v3
服务已将 reviews
与 ratings
的超时时间从 10 秒降低为 2.5 秒,因此它可以兼容(小于)下游的 productpage
的请求。
如果按照流量转移示例中的描述,将所有流量迁移到reviews:v3
,那么可以尝试将延迟规则改为任何小于2.5s的量,比如2s,并确认端到端流量持续无误。
注入HTTP abort故障(中止故障)
测试微服务弹性的另一种方法是引入一个HTTP中止故障。在这个示例中,你将为测试用户jason
的ratings
微服务引入一个HTTP中止。
在这种情况下,我们希望页面能够立即加载,同时显示 Ratings service is currently unavailabl(评分服务目前不可用)
这样的消息。
为用户
jason
创建一个发送 HTTP abort 的故障注入规则:$ kubectl apply -f samples/bookinfo/networking/virtual-service-ratings-test-abort.yaml
确认规则已创建。
$ kubectl get virtualservice ratings -o yaml apiVersion: networking.istio.io/v1beta1 kind: VirtualService ... spec: hosts: - ratings http: - fault: abort: httpStatus: 500 percentage: value: 100 match: - headers: end-user: exact: jason route: - destination: host: ratings subset: v1 - route: - destination: host: ratings subset: v1
测试中止配置
在浏览器中打开Bookinfo Web应用程序。
在
/productpage
上,以用户jason
登录。
如果该规则成功传播到所有Pod,则页面将立即加载,并且出现Ratings service is currently unavailable message(评级服务当前不可用)
消息。- 如果你从用户
jason
那里注销,或者在一个匿名窗口(或在另一个浏览器中)打开Bookinfo应用程序,你会看到/productpage
仍然为除了jason
之外的所有人调用reviews:v1
(根本没有调用ratings
)。因此你不会看到任何错误信息。
清理
删除应用程序的路由规则:
$ kubectl delete -f samples/bookinfo/networking/virtual-service-all-v1.yaml
如果您不打算探索任何后续例子,请参考Bookinfo清理说明来删除应用程序。