长连接业务配置ELB Ingress负载均衡最佳实践
当长连接业务容器通过ELB Ingress对外提供访问时,可能会遇到压测业务不均衡的问题,导致部分服务器负载过高,影响业务性能。为了解决这一问题,您可以配置客户端连接空闲超时时间、等待客户端请求超时时间、等待后端服务器响应超时时间等参数进行优化,从而实现业务的均衡分布和高效运行。
- 客户端连接空闲超时时间:该配置决定了在没有数据传输的情况下,连接可以保持多久。对于长连接来说,设置一个合理的空闲超时时间可以避免连接长时间占用资源,同时确保在需要时连接仍然可用。如果设置得太短,可能会导致频繁的连接断开和重新建立,增加服务器的负担;如果设置得太长,则可能导致资源浪费。
- 等待客户端请求超时时间:该配置决定了服务器在接收到客户端请求后,等待客户端发送完整请求的时间。对于长连接,这个设置可以防止服务器无限期等待客户端发送数据,从而避免资源被长时间占用。合理设置这个超时时间,可以提高服务器的响应效率和资源利用率。
- 等待后端服务器响应超时时间:该配置决定了服务器在向后端服务器发送请求后,等待后端服务器响应的时间。对于长连接,合理设置这个超时时间可以避免因后端服务器响应慢而导致的连接阻塞,从而提高系统的整体性能和稳定性。
前提条件
- 创建一个CCE Turbo集群,并安装云原生监控插件。
- 创建一个独享型ELB。
- 创建一台可访问公网的ECS主机,并安装Docker和wrk压测工具。
步骤一:准备测试镜像
- 登录ECS主机,创建一个dockerfile文件夹。
mkdir ./dockerfile cd ./dockerfile
- 准备本文中构建测试镜像所需的三个文件:Dockerfile、go.mod、app.go。
- 创建完成后,查看dockerfile目录下包含以下文件。
app.go Dockerfile go.mod
- 登录SWR镜像仓库,将构建的镜像推送到SWR仓库。详情请参见推送镜像到镜像仓库。
docker tag http-long-conn:v1 {Image repository address}/{Organization}/http-long-conn:v1 docker push {Image repository address}/{Organization}/http-long-conn:v1其中{Image repository address}为SWR镜像仓库地址,{Organization}为SWR组织名称。
步骤二:在集群中部署工作负载
- 使用kubectl连接集群。
- 创建一个名为http-long-conn.yaml的文件。其中,http-long-conn.yaml为自定义名称,您可以随意命名。
vi http-long-conn.yaml
文件示例如下:
kind: Deployment apiVersion: apps/v1 metadata: name: http-long-conn namespace: default labels: app: http-long-conn spec: replicas: 4 selector: matchLabels: app: http-long-conn template: metadata: labels: app: http-long-conn spec: containers: - name: http-long-conn image: {Image repository address}/{Organization}/http-long-conn:v1 #替换为您上传的SWR镜像地址 ports: - containerPort: 8080 protocol: TCP env: - name: PORT value: '8080' resources: limits: cpu: 100m memory: 128Mi requests: cpu: 100m memory: 128Mi livenessProbe: httpGet: path: /health port: 8080 scheme: HTTP initialDelaySeconds: 30 timeoutSeconds: 1 periodSeconds: 10 successThreshold: 1 failureThreshold: 3 readinessProbe: httpGet: path: /health port: 8080 scheme: HTTP initialDelaySeconds: 5 timeoutSeconds: 1 periodSeconds: 5 successThreshold: 1 failureThreshold: 3 terminationMessagePath: /dev/termination-log terminationMessagePolicy: File imagePullPolicy: IfNotPresent restartPolicy: Always terminationGracePeriodSeconds: 30 dnsPolicy: ClusterFirst securityContext: {} schedulerName: default-scheduler imagePullSecrets: - name: default-secret tolerations: null strategy: type: RollingUpdate rollingUpdate: maxUnavailable: 25% maxSurge: 25% revisionHistoryLimit: 10 progressDeadlineSeconds: 600 --- apiVersion: v1 kind: Service metadata: name: http-long-conn labels: app: http-long-conn namespace: default spec: selector: app: http-long-conn ports: - name: http-0 targetPort: 8080 nodePort: 0 port: 8080 protocol: TCP type: ClusterIP - 创建工作负载及服务。
kubectl create -f http-long-conn.yaml
- 查看工作负载状态。
kubectl get pod -l app=http-long-conn

步骤四:创建ELB Ingress
- 创建一个名为elb-ingress.yaml的文件。其中,elb-ingress.yaml为自定义名称,您可以随意命名。
vi elb-ingress.yaml
文件示例如下:
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: http-long-conn namespace: default annotations: kubernetes.io/elb.port: '8080' kubernetes.io/elb.id: 1fce4b38-c72b-4fd4-8430-62d46c0a7998 #ELB ID kubernetes.io/elb.class: performance kubernetes.io/elb.keepalive_timeout: '300' # 客户端连接空闲超时时间 kubernetes.io/elb.client_timeout: '60' # 等待客户端请求超时时间 kubernetes.io/elb.member_timeout: '60' # 等待后端服务器响应超时时间 spec: rules: - host: example.com #自定义域名 http: paths: - path: / backend: service: name: http-long-conn port: number: 8080 property: ingress.beta.kubernetes.io/url-match-mode: STARTS_WITH pathType: ImplementationSpecific ingressClassName: cce - 创建Ingress。
kubectl create -f elb-ingress.yaml
- 测试访问域名。

步骤五:压测
使用wrk工具进行压测:
wrk -t2 -c100 -d300s -H "Connection: keep-alive" http://example.com/long-connection
参数说明:
- -t2:表示启用2个线程
- -c100:设置100个并发连接
- -d300s:定义测试持续时间

本文示例中将并发连接配置100和200分别进行压测,在监控中心查看对应的Pod监控数据,如下所示,基本处于负载均衡的状态。
