官方文档:Istio / 故障注入、Istio / 设置请求超时
前提条件:
部署服务(我这里是官方bookinfo程序)
服务注入sidecar
部署在这里提到过,原文地址:istio服务网格入门-灰度发布 - (sreok.cn)
故障注入
将请求转发给reviews v2版本
只有这个版本才会调用ratings服务
kubectl apply -f - << EOF
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: reviews
spec:
hosts:
- reviews
http:
- route:
- destination:
host: reviews
subset: v2
EOF
设置ratings服务注入延迟
如果是jason用户的请求,就注入3秒的延迟,比例是100%请求
kubectl apply -f - << EOF
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: ratings
spec:
hosts:
- ratings
http:
- match:
- headers:
end-user:
exact: jason
fault:
delay:
fixedDelay: 3s
percentage:
value: 100
route:
- destination:
host: ratings
subset: v1
- route:
- destination:
host: ratings
subset: v1
EOF
此时请求bookinfo程序,流量被转移到reviews v2版本,没有任何问题
当登录用户为jason时,延迟被注入,按照预期,我们引入的3秒延迟不会影响到 reviews
服务,但是因为 reviews
和 ratings
服务间的超时被硬编码为 10 秒。 但是,在 productpage
和 reviews
服务之间也有一个 3 秒的硬编码的超时,再加 1 次重试,一共 6 秒。 结果,productpage
对 reviews
的调用在 6 秒后提前超时并抛出错误了。
简单来说,productpage在等待reviews,reviews在等待ratings,productpage最多等待3秒就会重试,每次重试都会让reviews 重新请求ratings,所以reviews 与ratings直接的请求必须在3秒内响应
,否则就会抛出错误
可以再次尝试将注入延迟改为2.9秒(只要不超过3秒就会成功,但存在一定误差,这个误差可能时大量请求导致的,我这里是测试,没有其他人的请求,所有可以设置2.9秒)
kubectl apply -f - << EOF
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: ratings
spec:
hosts:
- ratings
http:
- match:
- headers:
end-user:
exact: jason
fault:
delay:
fixedDelay: 2.9s
percentage:
value: 100
route:
- destination:
host: ratings
subset: v1
- route:
- destination:
host: ratings
subset: v1
EOF
这是实际上是官方提供给我们测试的BUG,reviews v3修复了这BUG,将ratings的超时时间设置为2.5秒
更新reviews
kubectl apply -f - << EOF
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: reviews
spec:
hosts:
- reviews
http:
- route:
- destination:
host: reviews
subset: v3
EOF
此时将流量转发给reviews v3版本,ratings响应时间只要超过2.5秒,reviews就不会继续等待,立即返回给productpage,避免ratings故障影响reviews服务
延迟如果在2.5秒内,响应没问题,超过2.5秒,抛出异常
这个时候ratings服务还是设置3s延迟,模拟ratings故障导致无法响应reviews服务,reviews服务也会在2.5秒后,将响应返回给productpage服务,不会影响reviews服务。
请求超时
保留ratings 服务的延迟注入,我设置了3秒,这时设置reviews超时时间
设置reviews 超时时间
kubectl apply -f - <<EOF
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: reviews
spec:
hosts:
- reviews
http:
- route:
- destination:
host: reviews
subset: v3
timeout: 1s
EOF
过程:
=> productpage v1(硬编码3s超时,1次重试)
=> reviews v3(硬编码2.5s超时,设置超时1s,此时会提前超时)
=> ratings v1(设置延时3s响应,延时只要大于等于超时就会响应失败)
解析:
productpage请求reviews服务,reviews请求ratings服务,ratings服务延时3s响应
1秒后reviews服务超时,因为reviews还在等待reviews响应,而ratings要3s后才会响应
productpage因为硬编码会再次重试,还是以上步骤,1秒后reviews服务再次返回超时
productpage发送两次请求,共等待了2秒后返回给客户端,并且此时reviews是不可用的
注意:
productpage硬编码的3s超时没有触发,是因为reviews返回了超时
reviews硬编码2.5s超时没有触发,是因为设置了超时时间(作用就是这个)
结果:
2秒后抛出错误:Sorry, product reviews are currently unavailable for this book.
原因:
reviews服务1秒内没有收到ratings服务的响应,reviews服务超时
这个能解决什么问题?
在故障注入时,我们发现一个bug,就是调用链的下游超时时间大于上游,此时站在架构层解决的方式就可以使用timeout来拦截流量使下游小于上游的超时时间。避免影响中间层服务。
注意:
超时时间只能设置小于硬编码的超时时间
如遇到上面的bug问题,应及时提交并协助修复,高耦合istio并不是最佳方案