如何通过三行配置解决在Kubernetes中的gRPC扩展问题

一切都始于我向我们的高级软件工程师提出的一个问题:
“忘掉通信速度。你真的觉得在gRPC中开发通信比REST更好吗?”
我不想听到的答案立刻就来了:“绝对是的。”

在我提出这个问题之前,我一直在监控我们的服务在滚动更新和扩展Pod时出现的奇怪行为。我们的大多数微服务以往都通过REST调用进行通信,没有任何问题。我们已经将一些这些集成迁移到了gRPC,主要是因为我们想摆脱REST的开销。最近,我们观察到了一些问题,都指向了同一个方向——我们的gRPC通信。当然,我们遵循了在Kubernetes中运行gRPC而不使用服务网格的建议实践,我们在服务器上使用了一个无头服务对象,并在gRPC中使用了客户端的“轮询”负载平衡与DNS发现等。

扩展Pod数量

Kubernetes内部负载均衡器不是用于负载均衡RPC,而是用于负载均衡TCP连接。
第四层负载均衡器由于其简单性而很常见,因为它们与协议无关。但是,gRPC破坏了Kubernetes提供的连接级负载均衡。这是因为gRPC是基于HTTP/2构建的,而HTTP/2被设计为维护一个长期存在的TCP连接,该连接中的所有请求都可以在任何时间点同时处于活动状态。这减少了连接管理的开销。然而,在这种情况下,连接级别的负载平衡并不是非常有用,因为一旦建立了连接,就不再需要进行负载平衡。所有的请求都会固定到原始目标Pod,直到发生新的DNS发现(使用无头服务)。这不会发生,直到至少有一个现有连接断开

问题示例:

  1. 2个客户端(A)调用2个服务器(B)。
  2. 自动缩放器介入并扩展了客户端。
  3. 服务器Pod负载过重,因此自动缩放器介入并增加了服务器Pod的数量,但没有进行负载平衡。甚至可以看到新Pod上没有传入的流量。
  4. 客户端被缩减。
  5. 客户端再次扩展,但负载仍然不平衡。
  6. 一个服务器Pod因过载而崩溃,发生了重新发现。
  7. 在图片中没有显示,但是当Pod恢复时,情况看起来与图3类似,即新Pod不会接收流量。

img

gRPC负载均衡的示例

2行配置解决了这个问题。 技术上说是一行

正如我之前提到的,我们使用“客户端负载均衡”,并使用无头服务对象进行DNS发现。其他选项可能包括使用代理负载均衡或实现另一种发现方法,该方法将询问Kubernetes API而不是DNS。

除此之外,gRPC文档提供了服务器端连接管理提案,我们也尝试过它。

以下是我为设置以下服务器参数提供的建议,以及gRPC初始化的Go代码片段示例:

  • MAX_CONNECTION_AGE设置为30秒。这个时间段足够长,可以在没有昂贵且频繁的连接建立过程的情况下进行低延迟通信。此外,它允许服务相对快速地响应新Pod的存在,因此流量分布将保持平衡。
  • MAX_CONNECTION_AGE_GRACE设置为10秒。定义了连接保持活动状态以完成未完成的RPC的最大时间。
  grpc.KeepaliveParams(keepalive.ServerParameters{MaxConnectionAge:      time.Second * 30,  // THIS one does the trickMaxConnectionAgeGrace: time.Second * 10,})

在现实世界中的行为:

img

gRPC配置更改应用前后的Pod数量

img

在gRPC配置更改后观察到的新Pod中的网络I/O活动

接下来是第三行

扩展问题已经解决,但另一个问题变得更加明显。焦点转向了客户端在滚动更新期间出现的gRPC code=UNAVAILABLE 错误。奇怪的是,这只在滚动更新期间观察到,而在单个Pod扩展事件中却没有观察到。

img

滚动更新期间的gRPC错误数量

部署滚动的过程很简单:创建一个新的副本集,创建一个新的Pod,当Pod准备就绪时,旧的Pod将从旧的副本集中终止,以此类推。每个Pod之间的启动时间间隔为15秒。关于gRPC DNS重新发现,我们知道它仅在旧连接中断或以GOAWAY信号结束时才会启动。因此,客户端每15秒开始一次新的重新发现,但获取到了过时的DNS记录。然后,它们不断进行重新发现,直到成功为止。

除非不是DNS问题…

几乎每个地方都有DNS TTL缓存。基础设施DNS具有其自己的缓存。Java客户端遭受了它们默认的30秒TTL缓存,而Go客户端通常没有实现DNS缓存。与此相反,Java客户端报告了数百或数千次此问题的发生。当然,我们可以缩短TTL缓存的时间,但为什么要在滚动更新期间只影响gRPC呢?

幸运的是,有一个易于实现的解决方法。或者更好地说,解决方案:让新Pod启动时设置30秒的延迟

.spec.minReadySeconds = 30

Kubernetes部署规范允许我们设置新Pod必须处于就绪状态的最短时间,然后才会开始终止旧Pod。在此时间之后,连接被终止,gRPC客户端收到GOAWAY信号并开始重新发现。TTL已经过期,因此客户端获取到了新的、最新的记录。

结论

从配置的角度来看,gRPC就像一把瑞士军刀,可能不会默认适合您的基础架构或应用程序。查看文档,进行调整,进行实验,并充分利用您已经拥有的资源。我相信可靠和弹性的通信应该是您的最终目标。

我还建议查看以下内容:

  • Keepalives。对于短暂的内部集群连接来说可能没有意义,但在某些其他情况下可能会有用。
  • 重试。有时,值得首先进行一些退避重试,而不是通过尝试创建新连接来过载基础设施。
  • 代码映射。将您的gRPC响应代码映射到众所周知的HTTP代码,以更好地了解发生了什么情况。
  • 负载均衡。平衡是关键。不要忘记设置回退并进行彻底的测试。
  • 服务器访问日志(gRPC code=OK)可能会因默认设置为信息级别而太冗长。考虑将它们降低到调试级别并进行筛选。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/101533.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【k8s】ingress-nginx通过header路由到不同后端

K8S中ingress-nginx通过header路由到不同后端 背景 公司使用ingress-nginx作为网关的项目,需要在相同域名、uri,根据header将请求转发到不同的后端中在稳定发布的情况下,ingress-nginx是没有语法直接支持根据header做转发的。但是这个可以利…

【ARM Coresight 系列文章19 -- Performance Monitoring Unit(性能监测单元)

文章目录 1.1 PMU 介绍1.2 PMU 寄存器1.2.1 PMU 管理寄存器1.2.2 PMU 外设识别寄存器1.2.3 PMU 组件识别寄存器1.3 性能监控事件1.3.1 Cortex-A9 特定事件1.1 PMU 介绍 许多体系结构都包含 PMU(Performance Monitoring Unit)硬件,用于跟踪、计数系统内部的一些底层硬件事件…

[代码随想录]二叉树篇

文章目录 1. 二叉树之层序遍历1.1 144-二叉树的前序遍历1.2 94-二叉树的中序遍历1.3 145-二叉树的后序遍历1.4 102-二叉树的层序遍历1.5 107-二叉树的层序遍历II1.6 199-二叉树的右视图1.7* 637-二叉树的层平均值1.8* 429-N叉树的层序遍历1.9 515-在每个树行中找最大值1.10* 11…

k8s修改集群IP--重置集群

原来IP地址 192.168.10.138 k8s-master 192.168.10.139 k8s-node1 192.168.10.140 k8s-node2 新IP地址 192.168.10.148 k8s-master 192.168.10.149 k8s-node1 192.168.10.150 k8s-node2 cp -Rf /etc/kubernetes/ /etc/kubernetes-bak pki 证书目录保留下来: rm -rf …

Ubuntu18.04下载安装基于使用QT的pcl1.13+vtk8.2,以及卸载

一、QVTKWidget、QVTKWidget2、QVTKOpenGLWidget、QVTKOpenGLNativeWidget 区别 1.Qt版本 Qt5.4以前版本:QVTKWidget2/QVTKWidget。 Qt5.4以后版本:QVTKOpenGLWidget/QVTKOpenGLWidget。 2.VTK版本(Qt版本为5.4之后) 在VTK8.2以前的版本:QVT…

Springboot——集成jodconverter做文档转换

文章目录 前言jodconverter 简介下载安装 libreoffice代码演示1、创建springboot项目工程并引入依赖2、配置3、准备一个docx模板4、编写测试代码 运行后的样式linux 环境下安装 libreoffice 前言 公司项目开发中,早期使用docx4j进行word转pdf,出现了很多…

网络安全工程师最详细学习和职业规划路线(书籍推荐和导图下载)

网络安全行业热火朝天,但我们很少看到这个领域相关职业路线的规划,这一方面是由于这个行业还比较年轻,还没有完全建立职业路径,另一方面也是因为高端职位以前比较少,很少有人到达顶峰,所以难以总结。 但随…

计算机毕业设计 it职业生涯规划系统的设计与实现 Javaweb项目 Java实战项目 前后端分离 文档报告 代码讲解 安装调试

🍊作者:计算机编程-吉哥 🍊简介:专业从事JavaWeb程序开发,微信小程序开发,定制化项目、 源码、代码讲解、文档撰写、ppt制作。做自己喜欢的事,生活就是快乐的。 🍊心愿:点…

动手学强化学习第2章多臂老虎机

2.1简介 多臂老虎机问题可以被看作简化版的强化学习问题。但是其只有动作和奖励没有状态信息,算是简化版的强化学习问题。 2.2问题介绍 2.2.1问题定义 在多臂老虎机(MAB)问题中,有一个有K根拉杆的老虎机,拉动每一根拉杆都对应一个关于奖励…

在 centos7 上安装Docker

1、检查linux内核 Docker 运行在 CentOS 7 上,要求系统为64位、系统内核版本为 3.10 以上。 Docker 运行在 CentOS-6.5 或更高的版本的 CentOS 上,要求系统为64位、系统内核版本为 2.6.32-431 或者更高版本。 uname -r 2、使用 root 权限登录 Centos…

docker应用记录总结

一、前言 docker这类部署工具,久而久之不使用非常容易忘记,甚至连操作命令都容易忘记。网上也有比较全的docker使用教程。这里做一个记录总结,纯属是温故知新。 二、docker部署应用 1、docker印象 docker首先让我想到的是是虚拟化技术&…

踩雷react-useRef钩子函数

今天测试提了一个bug,之前做的有个需求,在触发事件发起请求后,成功响应返回的新的数据没有第一时间渲染到网页上。 方法也都成功更新了数据,就是渲染会慢1-2分钟,排错排了老半天,最后找到了原因。 一般情…

SpringBoot和Hibernate——如何提高数据库性能

摘要:本文由葡萄城技术团队发布。转载请注明出处:葡萄城官网,葡萄城为开发者提供专业的开发工具、解决方案和服务,赋能开发者。 前言 在软件开发领域,性能是重中之重。无论您是构建小型 Web 应用程序还是大型企业系统…

单目标应用:遗传算法(Genetic Algorithm,GA)求解微电网优化MATLAB

一、微网系统运行优化模型 微电网优化模型介绍: 微电网多目标优化调度模型简介_IT猿手的博客-CSDN博客 二、遗传算法GA 遗传算法(Genetic Algorithm,GA)起源于对生物系统所进行的计算机模拟研究,是一种随机全局搜索…

【Java 进阶篇】JavaScript 数据类型详解

JavaScript是一种弱类型脚本语言,具有动态类型。这意味着JavaScript中的变量可以容纳不同类型的数据,并且它们的类型可以在运行时更改。在本文中,我们将深入探讨JavaScript中的数据类型,包括原始数据类型和引用数据类型&#xff0…

安科瑞ARB5系列弧光保护装置,智能电弧光保护,保障用电安全

安科瑞虞佳豪壹捌柒陆壹伍玖玖零玖叁 什么是弧光 电弧是放电过程中发生的一种现象,当两点之间的电压超过其工频绝缘强度极限时就会发生。当适当的条件出现时,一个携带着电流的等离子产生,直到电源侧的保护设备断开才会消失。空气在通常条件…

【ARM CoreLink 系列 6 -- DMC-400控制器简介】

文章目录 1.1 DMC-400 简介1.1.1 DFI(DDR PHY Interface)1.1.2 DFI 接口组1.1.3 DMC-400 兼容协议1.1.4 DMC-400 特性1.1.5 DMC-400 Interface 1.1 DMC-400 简介 DMC-400是一个由ARM开发、测试和授权的动态内存控制器,同时 DMC-400也是一个符…

git 回滚到指定版本

第一步:找到指定的需要回滚的版本的版本号 项目终端输入命令git log --oneline 第二步:使用git命令回滚到指定的版本 git reset --hard 版本号 第三步:此时再推到远程仓库用git push 会报错,需要用git push -f强推上去才可以哦

Swagger-go学习笔记

目录 Swagger的作用背景Swagger介绍 Swagger的基本使用1. 使用步骤2. 添加注释3. 生成接口文档数据4. 引入gin-swagger5. 测试结果6. 使用Token Swagger-go的中文文档通用API信息API操作MIME类型参数类型数据类型 Swagger的作用 背景 在传统的前后端分离的项目中,…

vue3组件的通信方式

一、vue3组件通信方式 通信仓库地址:vue3_communication: 当前仓库为贾成豪老师使用组件通信案例 不管是vue2还是vue3,组件通信方式很重要,不管是项目还是面试都是经常用到的知识点。 比如:vue2组件通信方式 props:可以实现父子组件、子父组件、甚至兄弟组件通信 自定义事件:可…