接下来创建一个客户端,用来向后端服务发送请求,观察是否会触发熔断策略。这里要使用一个简单的负载测试客户端,名字叫fortio。这个客户端可以控制连接数量、并发数以及发送HTTP请求的延迟。使用这一客户端,能够有效地触发前面在目标规则中设置的熔断策略。执行如下命名,或者切换到代码目录执行kubectl apply-n cb-f fortio-deploy.yaml:
kubectl apply -n cb -f - <<EOF
apiVersion: apps/v1beta1
kind: Deployment
metadata:
name: fortio-deploy
spec:
replicas: 1
template:
metadata:
labels:
app: fortio
spec:
containers:
- name: fortio
image: istio/fortio:latest_release
imagePullPolicy: Always
ports:
- containerPort: 8080
name: http-fortio
- containerPort: 8079
name: grpc-ping
EOF
进入客户端pod并使用fortio工具来调用service1服务。在上面的熔断设置中指定了maxConnections:1以及http1MaxPendingRequests:1。这意味着如果超过了一个连接同时发起请求,Istio就会熔断,阻止后续的请求或连接。
首先,确认Fortio_POD运行正常:
FORTIO_POD=$(kubectl get pod -n cb | grep fortio | awk '{ print $1 }')
然后,尝试一下3个并发连接(-c 3),发送30请求(-n 30):
kubectl exec -n cb -it $FORTIO_POD -c fortio /usr/local/bin/fortio -- load -c 3 -qps 0 -n 30 -loglevel Warning http://service1:5678/hello 12:05:40 I logger.go:97> Log level is now 3 Warning (was 2 Info) Fortio 1.0.1 running at 0 queries per second, 4->4 procs, for 30 calls: http://service1: 5678/hello Starting at max qps with 3 thread(s) [gomax 4] for exactly 30 calls (10 per thread + 0) 12:05:40 W http_client.go:604> Parsed non ok code 503 (HTTP/1.1 503) 12:05:40 W http_client.go:604> Parsed non ok code 503 (HTTP/1.1 503) 12:05:40 W http_client.go:604> Parsed non ok code 503 (HTTP/1.1 503) 12:05:40 W http_client.go:604> Parsed non ok code 503 (HTTP/1.1 503) 12:05:40 W http_client.go:604> Parsed non ok code 503 (HTTP/1.1 503) 12:05:40 W http_client.go:604> Parsed non ok code 503 (HTTP/1.1 503) 12:05:40 W http_client.go:604> Parsed non ok code 503 (HTTP/1.1 503) 12:05:40 W http_client.go:604> Parsed non ok code 503 (HTTP/1.1 503) 12:05:40 W http_client.go:604> Parsed non ok code 503 (HTTP/1.1 503) 12:05:40 W http_client.go:604> Parsed non ok code 503 (HTTP/1.1 503) 12:05:40 W http_client.go:604> Parsed non ok code 503 (HTTP/1.1 503) 12:05:40 W http_client.go:604> Parsed non ok code 503 (HTTP/1.1 503) 12:05:40 W http_client.go:604> Parsed non ok code 503 (HTTP/1.1 503) 12:05:40 W http_client.go:604> Parsed non ok code 503 (HTTP/1.1 503) Ended after 57.002494ms : 30 calls. qps=526.29 Aggregated Function Time : count 30 avg 0.0039758417 +/- 0.003147 min 0.000236787 max 0.010303748 sum 0.119275252 # range, mid point, percentile, count >= 0.000236787 <= 0.001 , 0.000618394 , 36.67, 11 > 0.001 <= 0.002 , 0.0015 , 40.00, 1 > 0.003 <= 0.004 , 0.0035 , 50.00, 3 > 0.004 <= 0.005 , 0.0045 , 53.33, 1 > 0.005 <= 0.006 , 0.0055 , 70.00, 5 > 0.006 <= 0.007 , 0.0065 , 80.00, 3 > 0.007 <= 0.008 , 0.0075 , 86.67, 2 > 0.008 <= 0.009 , 0.0085 , 96.67, 3 > 0.01 <= 0.0103037 , 0.0101519 , 100.00, 1 # target 50% 0.004 # target 75% 0.0065 # target 90% 0.00833333 # target 99% 0.0102126 # target 99.9% 0.0102946 Sockets used: 16 (for perfect keepalive, would be 3) Code 200 : 16 (53.3 %) Code 503 : 14 (46.7 %) Response Header Sizes : count 30 avg 112 +/- 104.8 min 0 max 210 sum 3360 Response Body/Total Sizes : count 30 avg 276.33333 +/- 51.6 min 217 max 324 sum 8290 All done 30 calls (plus 0 warmup) 3.976 ms avg, 526.3 qps
可以看到熔断行为生效,只有53.3%的请求获得通过,剩余请求被熔断器拦截了。运行多次可以看到超过了一个连接同时发起请求,Istio就会熔断,阻止后续的请求或连接。查询istio-proxy的状态,获取更多相关信息:
kubectl exec -it -n cb $FORTIO_POD -c istio-proxy -- sh -c 'curl localhost: 15000/stats' |grep service1 | grep pending cluster.outbound|5678||service1.cb.svc.cluster.local.upstream_rq_pending_active: 0 cluster.outbound|5678||service1.cb.svc.cluster.local.upstream_rq_pending_failure_eject: 0 cluster.outbound|5678||service1.cb.svc.cluster.local.upstream_rq_pending_overflow: 27 cluster.outbound|5678||service1.cb.svc.cluster.local.upstream_rq_pending_total: 85
其中,upstream_rq_pending_overf low的值是27,说明有27次调用被标志为熔断。
调整熔断触发规则,调整最大连接数,具体如下:
kubectl apply -n cb -f - <<EOF
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: service1
spec:
host: service1
trafficPolicy:
connectionPool:
tcp:
maxConnections: 5
http:
http1MaxPendingRequests: 5
maxRequestsPerConnection: 5
outlierDetection:
consecutiveErrors: 1
interval: 1s
baseEjectionTime: 3m
maxEjectionPercent: 100
EOF
再次尝试一下3个并发连接(-c 3),发送30请求(-n 30):
kubectl exec -n cb -it $FORTIO_POD -c fortio /usr/local/bin/fortio -- load -c 3 -qps 0 -n 30 -loglevel Warning http://service1:5678/hello 12:11:43 I logger.go:97> Log level is now 3 Warning (was 2 Info) Fortio 1.0.1 running at 0 queries per second, 4->4 procs, for 30 calls: http://service1:5678/hello Starting at max qps with 3 thread(s) [gomax 4] for exactly 30 calls (10 per thread + 0) Ended after 86.830201ms : 30 calls. qps=345.5 Aggregated Function Time : count 30 avg 0.0082158036 +/- 0.003694 min 0.002951869 max 0.015740718 sum 0.246474108 # range, mid point, percentile, count >= 0.00295187 <= 0.003 , 0.00297593 , 3.33, 1 > 0.003 <= 0.004 , 0.0035 , 16.67, 4 > 0.004 <= 0.005 , 0.0045 , 23.33, 2 > 0.005 <= 0.006 , 0.0055 , 36.67, 4 > 0.006 <= 0.007 , 0.0065 , 40.00, 1 > 0.007 <= 0.008 , 0.0075 , 53.33, 4 > 0.009 <= 0.01 , 0.0095 , 76.67, 7 > 0.01 <= 0.011 , 0.0105 , 80.00, 1 > 0.011 <= 0.012 , 0.0115 , 83.33, 1 > 0.012 <= 0.014 , 0.013 , 90.00, 2 > 0.014 <= 0.0157407 , 0.0148704 , 100.00, 3 # target 50% 0.00775 # target 75% 0.00992857 # target 90% 0.014 # target 99% 0.0155666 # target 99.9% 0.0157233 Sockets used: 3 (for perfect keepalive, would be 3) Code 200 : 30 (100.0 %) Response Header Sizes : count 30 avg 210.2 +/- 0.4 min 210 max 211 sum 6306 Response Body/Total Sizes : count 30 avg 324.2 +/- 0.4 min 324 max 325 sum 9726 All done 30 calls (plus 0 warmup) 8.216 ms avg, 345.5 qps
可以看到所有请求都通过了,当前的并发请求不会引起熔断触发。