本文内容基于 配置请求路由。
经过 配置请求路由 的配置,下面是请求的流程:
productpage → reviews:v2 → ratings (针对 jason 用户)
productpage → reviews:v1 (其他用户)
注入 HTTP 延迟故障
为了测试微服务应用程序 Bookinfo 的弹性,为用户 jason 在 reviews:v2
和 ratings
服务之间注入一个 7 秒的延迟。
reviews:v2
服务对 ratings
服务的调用具有 10 秒的硬编码连接超时。因此,尽管引入了 7 秒的延迟,仍然可以期望端到端的流程是没有任何错误的。
创建故障注入规则以延迟来自测试用户 jason 的流量:
cat samples/bookinfo/networking/virtual-service-ratings-test-delay.yaml
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: ratings
spec:
hosts:
- ratings
http:
- match:
- headers:
end-user:
exact: jason
fault:
delay:
percentage:
value: 100.0
fixedDelay: 7s
route:
- destination:
host: ratings
subset: v1
- route:
- destination:
host: ratings
subset: v1
kubectl apply -f samples/bookinfo/networking/virtual-service-ratings-test-delay.yaml
期望 Bookinfo 主页在大约 7 秒钟加载完成并且没有错误。 但是,出现了一个问题:Reviews
部分显示了错误消息:
Error fetching product reviews!
Sorry, product reviews are currently unavailable for this book.
重新加载 productpage
页面,会看到页面加载实际上用了大约 6s。此时发现了一个 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
的请求。
接下来,将来自 jason 用户的流量转移到 reviews:v3
(显示红色星形),可以尝试修改延迟规则为任何低于 2.5 秒的数值,例如 2 秒,然后确认端到端的流程没有任何错误。
cp samples/bookinfo/networking/virtual-service-reviews-test-v2.yaml samples/bookinfo/networking/virtual-service-reviews-test-v3.yaml
vim samples/bookinfo/networking/virtual-service-reviews-test-v3.yaml
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: reviews
spec:
hosts:
- reviews
http:
- match:
- headers:
end-user:
exact: jason
route:
- destination:
host: reviews
subset: v3
- route:
- destination:
host: reviews
subset: v1
kubectl apply -f samples/bookinfo/networking/virtual-service-reviews-test-v3.yaml
cp samples/bookinfo/networking/virtual-service-ratings-test-delay.yaml samples/bookinfo/networking/virtual-service-ratings-test-delay-2.yaml
vim samples/bookinfo/networking/virtual-service-ratings-test-delay-2.yaml
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: ratings
spec:
hosts:
- ratings
http:
- match:
- headers:
end-user:
exact: jason
fault:
delay:
percentage:
value: 100.0
fixedDelay: 2s
route:
- destination:
host: ratings
subset: v1
- route:
- destination:
host: ratings
subset: v1
kubectl apply -f samples/bookinfo/networking/virtual-service-ratings-test-delay-2.yaml
可以看到,页面加载实际上用了大约 2s,来自 jason 用户的流量转移到 reviews:v3
(显示红色星形),端到端的流程是没有任何错误的。
注入 HTTP abort 故障
测试微服务弹性的另一种方法是引入 HTTP abort 故障。给 ratings
微服务为测试用户 jason 引入一个 HTTP abort。
在这种情况下,期望页面能够立即加载,同时显示 Ratings service is currently unavailable
这样的消息。
为用户 jason 创建一个发送 HTTP abort 的故障注入规则:
cat samples/bookinfo/networking/virtual-service-ratings-test-abort.yaml
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: ratings
spec:
hosts:
- ratings
http:
- match:
- headers:
end-user:
exact: jason
fault:
abort:
percentage:
value: 100.0
httpStatus: 500
route:
- destination:
host: ratings
subset: v1
- route:
- destination:
host: ratings
subset: v1
kubectl apply -f samples/bookinfo/networking/virtual-service-ratings-test-abort.yaml
可以看到,此时页面立即加载,并未发生延迟,而是直接提示:Ratings service is currently unavailable
。如果注销用户 jason 或在匿名窗口中打开 Bookinfo 应用程序,可以看到 /productpage
为除 jason 以外的其他用户调用了 reviews:v1
。