背景:海外用户投诉我们一个边缘功能失效,定位到程序假死。随着各种复盘会,把这件小事无限放大。
难点:探针改造复杂,尽管已经有了基础的http接口检测,但针对服务连接各种中间件等场景无法一一覆盖
在研发根治此问题前,使用“熔断”来降低此类故障的影响
熔断,是创建弹性微服务应用程序的重要模式。熔断能够使您的应用程序具备应对来自故障、潜在峰值和其他未知网络因素影响的能力
中间方案,通过网关日志,假死会有504超时的信息,SLS已支持触发各种钩子,逐个重启故障服务的pod
- 优点:配置相对简单,覆盖面广
- 缺点:按照监控的频率间隔,有几分钟延迟
更优istio方案,使用VirtualService配合DestinationRule对超时或者错误重试,并将故障pod踢出
- 优点:侦测更快,发现故障后立即生效
- 缺点:局部配置,所有服务都要写一遍
环境:
- kubernetes v1.18.20
- istio 1.10.3
- 后端服务flask,代码如下,sleep5秒用于模拟超时
from flask import Flask
import time
app = Flask(__name__)
@app.route("/", methods=["GET"])
def index():
time.sleep(5)
return "Hello World Pyvo 2!"
istio中配置如下
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: backend-gateway
spec:
selector:
istio: ingressgateway
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
- "*"
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: vs-backend-flask
spec:
hosts:
- "*"
gateways:
- backend-gateway
http:
- match:
- uri:
prefix: /flask
rewrite:
uri: /
route:
- destination:
host: backend-flask
port:
number: 80
retries:
attempts: 3
perTryTimeout: 2s
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: dr-backend-flask
spec:
host: backend-flask
trafficPolicy:
outlierDetection:
consecutive5xxErrors: 1
interval: 10s
baseEjectionTime: 30s
效果如图,访问出现上游服务超时错误后,在30秒内不会再调度到故障节点