Istio通过设置DestinationRule来指定服务的连接池配置,Istio提供了两类常用协议的连接池配置:TCP连接池和HTTP连接池。与负载均衡策略设置类似,连接池的配置也支持服务默认级别的配置、服务子集的配置以及端口级别的连接池配置。TCP连接池和HTTP连接池可以一同配合使用。
1.TCP连接池
TCP连接池对TCP和HTTP类协议均提供支持,示例如下:
1 apiVersion: networking.istio.io/v1alpha3 2 kind: DestinationRule 3 metadata: 4 name: service-go 5 spec: 6 host: service-go 7 trafficPolicy: 8 connectionPool: 9 tcp: 10 maxConnections: 10 11 connectTimeout: 30ms 12 subsets: 13 - name: v1 14 labels: 15 version: v1 16 - name: v2 17 labels: 18 version: v2
第8~11行设置TCP连接池中的最大连接数为10,连接超时时间为30毫秒,当连接池中连接不够用时,服务调用会返回503响应码。
2.HTTP连接池
HTTP连接池对HTTP类协议和gRPC协议均提供支持,示例如下:
1 apiVersion: networking.istio.io/v1alpha3 2 kind: DestinationRule 3 metadata: 4 name: service-go 5 spec: 6 host: service-go 7 trafficPolicy: 8 connectionPool: 9 http: 10 http2MaxRequests: 10 11 http1MaxPendingRequests: 5 12 maxRequestsPerConnection: 2 13 maxRetries: 3 14 subsets: 15 - name: v1 16 labels: 17 version: v1 18 - name: v2 19 labels: 20 version: v2
第8~13行设置HTTP连接池的后端实例的最大并发请求数为10,每个目标的最大待处理请求数为5,连接池中每个连接最多处理2个请求后就关闭,并根据需要重新创建连接池中的连接,请求在服务后端实例集群中失败后的最大重试次数为3。几个参数说明如下:
·http2MaxRequests表示对后端的最大并发请求数,默认值1024。
·http1MaxPendingRequests表示每个目标的最大待处理请求数,这里的目标指的是VirtualService路由规则中配置的destination,当连接池中连接不够用时请求就处于待处理状态。默认值1024。
·maxRequestsPerConnection表示每个连接最多处理多少个请求后关闭,设置为1时表示关闭keep alive特性,每次请求都创建一个新的请求。
·maxRetries表示请求后端失败后重试其他后端实例的总次数,默认值3。
【实验】
1)启动用于并发测试的Pod:
$ kubectl apply -f kubernetes/fortio.yaml
2)创建service-go服务的路由规则:
$ kubectl apply -f istio/route/virtual-service-go.yaml
3)创建连接池规则:
$ kubectl apply -f istio/resilience/destination-rule-go-pool-http.yaml
4)并发访问服务:
$ kubectl exec fortio -c fortio /usr/local/bin/fortio -- load -curl http://service-go/env HTTP/1.1 200 OK content-type: application/json; charset=utf-8 date: Wed, 16 Jan 2019 10:12:35 GMT content-length: 19 x-envoy-upstream-service-time: 4 server: envoy {"message":"go v2"} # 10 并发 $ kubectl exec fortio -c fortio /usr/local/bin/fortio -- load -c 10 -qps 0 -n 100 -loglevel Error http://service-go/env 09:40:38 I logger.go:97> Log level is now 4 Error (was 2 Info) Fortio 1.0.1 running at 0 queries per second, 2->2 procs, for 100 calls: http://service-go/env Aggregated Function Time : count 100 avg 0.01652562 +/- 0.013 min 0.002576677 max 0.064653438 sum 1.65256199 # target 50% 0.0119375 # target 75% 0.018 # target 90% 0.035 # target 99% 0.06 # target 99.9% 0.0641881 Sockets used: 15 (for perfect keepalive, would be 10) Code 200 : 95 (95.0 %) Code 503 : 5 (5.0 %) All done 100 calls (plus 0 warmup) 16.526 ms avg, 563.4 qps # 20 并发 $ kubectl exec fortio -c fortio /usr/local/bin/fortio -- load -c 20 -qps 0 -n 200 -loglevel Error http://service-go/env 09:41:32 I logger.go:97> Log level is now 4 Error (was 2 Info) Fortio 1.0.1 running at 0 queries per second, 2->2 procs, for 200 calls: http://service-go/env Aggregated Function Time : count 200 avg 0.023987068 +/- 0.01622 min 0.001995258 max 0.067905383 sum 4.79741353 # target 50% 0.0194286 # target 75% 0.0357692 # target 90% 0.05 # target 99% 0.0626351 # target 99.9% 0.0673784 Sockets used: 43 (for perfect keepalive, would be 20) Code 200 : 177 (88.5 %) Code 503 : 23 (11.5 %) All done 200 calls (plus 0 warmup) 23.987 ms avg, 711.9 qps # 30 并发 $ kubectl exec fortio -c fortio /usr/local/bin/fortio -- load -c 30 -qps 0 -n 300 -loglevel Error http://service-go/env 09:42:05 I logger.go:97> Log level is now 4 Error (was 2 Info) Fortio 1.0.1 running at 0 queries per second, 2->2 procs, for 300 calls: http://service-go/env Aggregated Function Time : count 300 avg 0.034233818 +/- 0.02268 min 0.002354402 max 0.114700368 sum 10.2701455 # target 50% 0.0285417 # target 75% 0.0446667 # target 90% 0.0686957 # target 99% 0.1 # target 99.9% 0.11323 Sockets used: 137 (for perfect keepalive, would be 30) Code 200 : 192 (64.0 %) Code 503 : 108 (36.0 %) All done 300 calls (plus 0 warmup) 34.234 ms avg, 702.1 qps
从压测结果可以看出,当并发逐渐增大时,服务不可用的响应码(503)所占比例逐渐升高,说明我们配置的HTTP连接池参数已经生效。
5)清理:
$ kubectl delete -f kubernetes/fortio.yaml $ kubectl delete -f istio/route/virtual-service-go.yaml $ kubectl delete -f istio/resilience/destination-rule-go-pool-http.yaml