【Kubernetes】K8S下gRPC负载均衡问题

  • Post author:
  • Post category:其他




k8s gRPC负载均衡问题

在 K8S 下部署服务,缺省情况下会被分配一个地址(也就是 ClusterIP),客户端的请求会发送给它,然后再通过负载均衡转发给后端某个 pod:

在这里插入图片描述



grpc http2.0链接复用问题

HTTP/1.1 不是实现了基于 KeepAlive 的连接复用么?为什么 HTTP/1.1 的复用没问题,而 HTTP/2 的复用就有问题?

答案是 HTTP/1.1 的 复用是串行的,当请求到达的时候,如果没有空闲连接那么就新创建一个连接,如果有空闲连接那么就可以复用,同一个时间点,连接里最多只能承载一个请求,结果是 HTTP/1.1 可以连接多个 pod;

而 HTTP/2 的复用是并行的,当请求到达的时候,如果没有连接那么就创建连接,如果有连接,那么不管其是否空闲都可以复用,同一个时间点,连接里可以承载多个请求,结果是 HTTP/2 仅仅连接了一个 pod。


如果默认使用直链方式也就是交给k8s自己去处理负载均衡,在http1.x短连接是没有问题的,grpc是使用http2实现的,它是长链接多路复用,后续发送的请求也都会打到相同pod,造成负载不均衡



问题复现

package main

import (
	"context"
	"fmt"
	"log"
	"sync"
	"time"

	pb "codeup.aliyun.com/rpc/proto/test"
	"google.golang.org/grpc"
)

var (
	client   pb.TestSrvServiceClient
	GrpcAddr = "svc cluster_ip:8351"
)

func init() {
	conn, err := grpc.Dial(GrpcAddr, grpc.WithInsecure(), grpc.WithBlock())
	if err != nil {
		log.Fatalf("did not connect: %v", err)
	}
	client = pb.NewTestSrvServiceClient(conn)
}

func getAliyunServiceClient() pb.TestSrvServiceClient {
	return client
}

func main() {
	c := getAliyunServiceClient()
	wg := &sync.WaitGroup{}
	for i := 1; i < 200; i++ {
		wg.Add(1)
		go func(c pb.TestSrvServiceClient, i int, wg *sync.WaitGroup) {
			ctx, cancel := context.WithTimeout(context.Background(), time.Second)
			defer cancel()
			res, err := c.GetGroupResult(ctx, &pb.GetGroupResultRequest{
				ExperimentId: int64(i),
			})
			if err != nil {
				log.Println("err", err)
			} else {
				fmt.Println("res", res)
			}
			time.Sleep(time.Millisecond * 100)
			wg.Done()
		}(c, i, wg)
	}
	wg.Wait()
}

查看日志,发现3个pod的服务大部分的请求都打在了一个pod上面

在这里插入图片描述



解决方案:



Proxy负载均衡

在 Proxy 中实现负载均衡:采用 Envoy 做代理,和每台后端服务器保持长连接,当客户端请求到达时,代理服务器依照规则转发请求给后端服务器,从而实现负载均衡。



Client负载均衡

在 Client 中实现负载均衡:把服务部署成 headless service,这样服务就有了一个域名,然后客户端通过域名访问 gRPC 服务,DNS resolver 会通过 DNS 查询后端多个服务器地址,然后通过算法来实现负载均衡。

如服务发现consul等,则不存在此问题



K8S headless service服务详解


为什么需要无头服务?


客户端想要和指定的的Pod直接通信

并不是随机选择

开发人员希望自己控制负载均衡的策略,不使用Service提供的默认的负载均衡的功能,或者应用程序希望知道属于同组服务的其它实例。


https://www.cnblogs.com/wuchangblog/p/14032057.html



版权声明:本文为weixin_43746433原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。