在Kubernetes中实现gRPC流量负载均衡
在尝试将gRPC服务部署到Kubernetes集群中时,一些用户(包括我)面临的挑战之一是实现适当的负载均衡。在深入了解如何平衡gRPC的方式之前,我们首先需要回答一个问题,即为什么需要平衡流量,如果Kubernetes已经完成了这项工作。
本文关注于Kubernetes和Golang。
为什么在Kubernetes中无法适当地平衡gRPC流量?
之所以难以平衡gRPC流量的主要原因是人们将gRPC视为HTTP,这就是问题的根源。设计上它们是不同的,虽然HTTP为每个请求创建和关闭连接,但gRPC使用HTTP2协议,在长时间的TCP连接上运行,使得平衡更加困难,因为多个请求通过同一个连接进行多路复用。然而,这并不是配置gRPC服务在Kubernetes中出现平衡问题的唯一原因,以下是一些常见的错误配置:
- 错误的gRPC客户端配置
- 错误的Kubernetes服务配置
错误的gRPC客户端配置
设置gRPC客户端时常见的情况是选择默认配置,这对于1-1连接类型完全有效,但对于生产环境来说并不如我们所希望的有效。这背后的原因是因为默认的gRPC客户端提供了使用简单的IP/DNS记录连接的可能性,这只会创建一个与目标服务的连接。
因此,需要为与多个服务器建立连接进行不同的设置,将连接类型从1-1转换为1-N。
默认设置
func main(){conn, err := grpc.Dial("my-domain:50051", grpc.WithInsecure())if err != nil {log.Fatalf("error connecting with gRPC server: %v", err)}defer conn.Close()cli := test.NewTestServiceClient(conn)rs, err := cli.DoSomething(context.Background(), ...)...
}
新的设置
func main() {address := fmt.Sprintf("%s:///%s", "dns", "my-domain:50051")conn, err := grpc.Dial(address,grpc.WithInsecure(),grpc.WithBalancerName(roundrobin.Name))if err != nil {log.Fatalf("did not connect: %v", err)}defer conn.Close()...
}
这里有两个重要的更改需要注意:
- 地址: 最终解析的地址将类似于 dns:///my-domain:50051,之所以使用这种格式是因为Dial函数允许我们使用由Scheme://Authority/Endpoint组成的目标,而在我们的情况下,我跳过了Authority。因此,首先我添加了dns作为方案,因为我希望解析一个域并持续观察其更改,解析器选项有透传(默认)、dns和手动,更多详情请参阅这里。
- 负载均衡器选项: 如果我们的客户端现在连接到多个服务器,那么我们的gRPC客户端可以根据所选择的负载均衡算法平衡请求。
总结一下,我们的gRPC客户端现在能够创建不同的连接,前提是域名解析为多个A或AAAA记录,而且不仅如此,现在还能够将请求均匀地分配到不同的服务器。
现在让我们看看如何让它与Kubernetes一起工作的缺失部分。
错误的Kubernetes服务配置
在Kubernetes中创建服务非常简单,我们只需要定义服务名称、端口和选择器,以便服务可以动态地将Pod分组并自动平衡请求,如下所示:
apiVersion: v1
kind: Service
metadata:name: my-service
spec:selector:app: my-appports:- name: grpcprotocol: TCPport: 50051targetPort: 50051
那么,对于先前的设置,问题在于默认的Kubernetes服务只创建了一个DNS记录,链接到单个IP。因此,当您执行类似 nslookup my-service.{namespace}.svc.cluster.local
的操作时,返回的是一个单个IP,这使得在常见的gRPC实现中连接图看起来像这样:
例如,使用默认的Kubernetes服务的连接图:
绿线表示与客户端的活动连接,黄色表示未活动的Pod。客户端与Kubernetes服务创建了持久连接,同时服务也与其中一个Pod创建了连接,但这并不意味着服务与其余的Pod没有连接。
让我们使用一个无头服务来解决这个问题:
apiVersion: v1
kind: Service
metadata:name: my-service
spec:clusterIP: None **this is the key***selector:app: my-appports:- name: grpcprotocol: TCPport: 50051targetPort: 50051
创建了无头服务后,nslookup看起来有些不同,现在它返回与之关联的记录(将Pod的IP分组到服务中),从而使gRPC客户端更好地了解需要连接的服务器数量。
现在您已经看到了gRPC客户端的配置,您必须知道为什么Kubernetes服务返回与一组Pod关联的IP非常重要。原因是客户端可以看到所有需要建立连接的服务器。在这一点上,您可能已经意识到了一个注意事项,即平衡的责任现在在客户端部分,而不在Kubernetes的一侧。我们现在需要从Kubernetes那里得到的主要任务是保持与服务关联的Pod列表的最新状态。
例如,在具有无头Kubernetes服务的连接图中,可以看到连接发生了一些变化,现在我们不通过Kubernetes服务来访问Pod,而是使用Kubernetes服务来检索与域名关联的Pod列表,然后直接与Pod建立连接。但是不要因为直接连接到Pod而感到惊慌,因为我们在客户端中设置了DNS解析器类型,该解析器将持续监视与无头服务的更改,并将与可用的Pod保持最新的连接。
为什么不使用服务网格?
如果可以的话,请使用服务网格,因为在服务网格中,所有这些设置都是透明的,而且最重要的是它是与编程语言无关的。关键区别在于服务网格利用了Sidecar模式和控制平面来编排入站和出站流量,还可以看到所有网络和流量类型(HTTP、TCP等),从而能够正确平衡请求。简而言之,如果您不使用服务网格,那么您需要直接从每个客户端连接到多个服务器,或者连接到一个L7代理来帮助平衡请求。
附加信息
尽管先前的设置可以工作,但我在尝试在alpine Linux映像中进行Pod轮换或扩展时重新平衡连接时遇到了问题。经过一些研究,我意识到我并不是唯一遇到这种问题的人,可以查看这里和这里的一些相关的GitHub问题。这就是为什么我决定创建自己的解析器的原因,您可以在这里查看我创建的自定义解析器,我创建的自定义解析器非常基础,但现在可以正常工作,gRPC客户端现在可以再次监听域名的更改,我还为该库添加了一个可配置的监听器,它每隔一段时间查找域名并更新提供给gRPC连接管理器的IP集合,如果您想贡献,欢迎加入。
另一方面,因为我想深入了解,所以我决定创建自己的gRPC代理(我也学到了很多东西),利用了gRPC的http2基础,我可以创建一个代理,而无需更改proto负载消息或甚至不知道proto文件的定义(还使用了前面提到的自定义解析器)。
最后,我想说的是,如果您的gRPC客户端需要与许多服务器连接,我强烈建议使用代理作为平衡的机制,因为将这个机制放在主应用程序中将增加复杂性和资源消耗,尝试保持许多打开的连接并重新平衡它们,想象一下,如果最终的平衡在应用程序中,您将有一个与N个服务器连接的实例(1-N),但是使用代理,您将有一个与M个代理连接到N个服务器的实例(1-M-N),其中M<N,因为每个代理实例可以处理与不同服务器的许多连接。
相关文章:

在Kubernetes中实现gRPC流量负载均衡
在尝试将gRPC服务部署到Kubernetes集群中时,一些用户(包括我)面临的挑战之一是实现适当的负载均衡。在深入了解如何平衡gRPC的方式之前,我们首先需要回答一个问题,即为什么需要平衡流量,如果Kubernetes已经…...

Floorplanning with Graph Attention
Floorplanning with Graph Attention DAC ’22 目录 Floorplanning with Graph Attention摘要1.简介2.相关工作3.问题公式化4. FLORA的方法4.1 解决方案概述4.2 C-谱聚类算法 4.3 基于GAT的模型4.4 合成训练数据集生成 摘要 布图规划一直是一个关键的物理设计任务࿰…...

centos7 配置coreboot编译环境 以及编译问题解决
需要的配置 (有的资源在国外可能需要翻墙) 操作系统: centos7.9 参考文章 coreboot源码分析之编译和运行coreboot - 知乎 //coreboot编译总说明 https://www.coreboot.org/Build_HOWTO#Requirements https://poe.com/ChatGPT 注意: 因为github不稳定 所以gitee为主 1. 下载…...

大型语言模型:RoBERTa — 一种鲁棒优化的 BERT 方法
一、介绍 BERT模型的出现导致了NLP的重大进展。BERT的架构源自Transformer,在各种下游任务上实现了最先进的结果:语言建模,下一句预测,问答,NER标记等。 大型语言模型:BERT — 来自变压器的双向编码器表示 …...
解析navicate数据库密码
在线运行地址:代码在线运行 - 在线工具 <?php class NavicatPassword {protected $version 0;protected $aesKey libcckeylibcckey;protected $aesIv libcciv libcciv ;protected $blowString 3DC5CA39;protected $blowKey null;protected $blowIv null;public func…...
mysql字段类型与oracle字段类型对应关系
MySQL与Oracle两种数据库在工作中,都是用的比较多的数据库,由于MySQL与Oracle在数据类型上有部分差异,在我们迁移数据库时,会遇上一定的麻烦,下面介绍MySQL与Oracle数据库数据类型的对应关系。 一、常见数据类型在MyS…...
linux 中 tar \ zip 解压错误后撤回
#zip zipinfo -1 path/xx.zip | xargs rm -rf#tar tar -tf xx.tar | xargs rm -rf...
对象图 UML从入门到放弃之四
1.劝退说明 对象图提供了系统在某个特定时刻的状态快照。这是一种有用的描述系统的方法,当系统的结构是动态构建起来而不是由其静态的类结构决定时,更是如此。不过,应该对画太多的对象图保持警惕。在大部分情况下,它们都可以从相应…...

FPGA实现HDMI输入转SDI视频输出,提供4套工程源码和技术支持
目录 1、前言免责声明 2、我目前已有的SDI编解码方案3、设计思路框架核模块解析设计框图IT6802解码芯片配置及采集ADV7611解码芯片配置及采集silicon9011解码芯片配置及采集纯verilog的HDMI 解码模块RGB888转YUV422SPMTE编码SDI模式图像缓存SPMTE SDIGTXGV8500 4、vivado工程1-…...

针对FTP的SSRF攻击
前言 ssrf中常用的协议有http,gopher等。但http协议在ssrf中的用处也仅限于访问内网页面,在可以crlf的情况下才有可能扩大攻击范围。gopher协议比较特殊,在部分环境下支持此协议,如:curl。但还有一些环境就不支持了&a…...

线性代数中涉及到的matlab命令-第一章:行列式
目录 1,逆序数 2,行列式定义和性质 2.1,常用特性及命令 2.2,求行列式 2.3,行列式的性质 2,行列式按行(列)展开 3,范德蒙德行列式 在学习线性代数过程中&#…...
QT编程,QT内存管理、信号与槽、
目录 一、QT工具 二、QT内存管理 三、信号与槽 1、信号与槽特点 2、信号 3、槽函数 4、连接 5、发送信号 6、取消连接 一、QT工具 1、Qt Designer:界面设计编辑工具 2、Qt Assistant: Qt技术文档浏览器 3、Qt Linguist: 国际化语言翻译工具 4、…...

springcloud之项目实战环境准备
写在前面 为了更好的学习springcloud,我们来一起开发一个实战项目,加深理解。 1:项目介绍 在开始项目实战之前先来做一个整体的项目介绍,从而能够让对项目的整体架构和模板有一个比较清晰的认知。 大家都知道双11,…...

Linux 部署 MinIO 分布式对象存储 配置为 typora 图床
前言 MinIO 是一款高性能的对象存储系统,它可以用于大规模的 AI/ML、数据湖和数据库工作负载。它的 API 与Amazon S3 云存储服务完全兼容,可以在任何云或本地基础设施上运行。MinIO 是开源软件,也提供商业许可和支持 MinIO 的特点有&#x…...
JVM Optimization Learning(四)
目录 一、调优 1、基础概念 2、什么是调优? 3、调优,从规划开始 4、调优案例 一、调优 1、基础概念 吞吐量:用户代码执行时间 /(用户代码执行时间 垃圾回收时间) 响应时间:STW越短,响应…...
新华三辅导笔记 2023/10/9-2023/10/13
新华三辅导笔记 一、需要用到的软件二、计算机网络概述1、计算机网络的定义和基本功能(1)什么是计算机网络(2)计算机网络的基本功能 2、(1)局域网、城域网和广域网(范围划分)&#x…...

边坡安全监测系统的功能优势
随着科技的进步,边坡安全监测系统在各种工程项目中发挥着越来越重要的作用。这款系统通过实时监测垂直、水平位移数据,以折线图的方式显示在监控平台中,为工程人员提供了直观、便捷的监控工具,从而能够及时掌握边坡稳定状况&#…...
【架构】研发高可用架构和系统设计经验
研发高可用架构和系统设计经验 从研发规范层面、应用服务层面、存储层面、产品层面、运维部署层面、异常应急层面这六大层面去剖析一个高可用的系统需要有哪些关键的设计和考虑。 一、高可用架构和系统设计思想 1.可用性和高可用概念 可用性是一个可以量化的指标,计算的公…...

Linux线程安全
线程安全 Linux线程互斥进程线程间的互斥相关背景概念互斥量mutex互斥量的接口互斥量实现原理探究 可重入VS线程安全概念常见的线程不安全的情况常见的线程安全的情况常见的不可重入的情况常见的可重入的情况可重入与线程安全联系可重入与线程安全区别 常见锁概念死锁死锁的四个…...

Windows安装Node.js
1、Node.js介绍 ①、Node.js简介 Node.js是一个开源的、跨平台的JavaScript运行环境,它允许开发者使用JavaScript语言来构建高性能的网络应用程序和服务器端应用。Node.js的核心特点包括: 1. 事件驱动: Node.js采用了事件驱动的编程模型,通…...

TDengine 快速体验(Docker 镜像方式)
简介 TDengine 可以通过安装包、Docker 镜像 及云服务快速体验 TDengine 的功能,本节首先介绍如何通过 Docker 快速体验 TDengine,然后介绍如何在 Docker 环境下体验 TDengine 的写入和查询功能。如果你不熟悉 Docker,请使用 安装包的方式快…...

23-Oracle 23 ai 区块链表(Blockchain Table)
小伙伴有没有在金融强合规的领域中遇见,必须要保持数据不可变,管理员都无法修改和留痕的要求。比如医疗的电子病历中,影像检查检验结果不可篡改行的,药品追溯过程中数据只可插入无法删除的特性需求;登录日志、修改日志…...

8k长序列建模,蛋白质语言模型Prot42仅利用目标蛋白序列即可生成高亲和力结合剂
蛋白质结合剂(如抗体、抑制肽)在疾病诊断、成像分析及靶向药物递送等关键场景中发挥着不可替代的作用。传统上,高特异性蛋白质结合剂的开发高度依赖噬菌体展示、定向进化等实验技术,但这类方法普遍面临资源消耗巨大、研发周期冗长…...
多模态商品数据接口:融合图像、语音与文字的下一代商品详情体验
一、多模态商品数据接口的技术架构 (一)多模态数据融合引擎 跨模态语义对齐 通过Transformer架构实现图像、语音、文字的语义关联。例如,当用户上传一张“蓝色连衣裙”的图片时,接口可自动提取图像中的颜色(RGB值&…...
vue3 定时器-定义全局方法 vue+ts
1.创建ts文件 路径:src/utils/timer.ts 完整代码: import { onUnmounted } from vuetype TimerCallback (...args: any[]) > voidexport function useGlobalTimer() {const timers: Map<number, NodeJS.Timeout> new Map()// 创建定时器con…...
【git】把本地更改提交远程新分支feature_g
创建并切换新分支 git checkout -b feature_g 添加并提交更改 git add . git commit -m “实现图片上传功能” 推送到远程 git push -u origin feature_g...

从零实现STL哈希容器:unordered_map/unordered_set封装详解
本篇文章是对C学习的STL哈希容器自主实现部分的学习分享 希望也能为你带来些帮助~ 那咱们废话不多说,直接开始吧! 一、源码结构分析 1. SGISTL30实现剖析 // hash_set核心结构 template <class Value, class HashFcn, ...> class hash_set {ty…...
【HarmonyOS 5 开发速记】如何获取用户信息(头像/昵称/手机号)
1.获取 authorizationCode: 2.利用 authorizationCode 获取 accessToken:文档中心 3.获取手机:文档中心 4.获取昵称头像:文档中心 首先创建 request 若要获取手机号,scope必填 phone,permissions 必填 …...

Python基于历史模拟方法实现投资组合风险管理的VaR与ES模型项目实战
说明:这是一个机器学习实战项目(附带数据代码文档),如需数据代码文档可以直接到文章最后关注获取。 1.项目背景 在金融市场日益复杂和波动加剧的背景下,风险管理成为金融机构和个人投资者关注的核心议题之一。VaR&…...

人工智能(大型语言模型 LLMs)对不同学科的影响以及由此产生的新学习方式
今天是关于AI如何在教学中增强学生的学习体验,我把重要信息标红了。人文学科的价值被低估了 ⬇️ 转型与必要性 人工智能正在深刻地改变教育,这并非炒作,而是已经发生的巨大变革。教育机构和教育者不能忽视它,试图简单地禁止学生使…...