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

  发布时间:2025-12-07 21:12:25   作者:玩站小弟   我要评论
一切都始于我向我们的高级软件工程师提出的一个问题:“忘掉通信速度。你真的觉得在gRPC中开发通信比REST更好吗?”我不想听到的答案立刻就来了:“绝对是的。”在我提出这个问题之前,我一直在监控我们的服 。

一切都始于我向我们的何通高级软件工程师提出的一个问题: “忘掉通信速度。你真的过行觉得在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发现(使用无头服务)。这不会发生,直到至少有一个现有连接断开 。

问题示例 :

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

gRPC负载均衡的高防服务器示例

两个配置解决这个问题,技术上说是一行

正如我之前提到的 ,我们使用“客户端负载均衡” ,并使用无头服务对象进行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 trick MaxConnectionAgeGrace: time.Second * 10, })1.2.3.4.

在现实世界中的行为:

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

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

接下来是第三行

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

滚动更新期间的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 = 301.

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

结论

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

我还建议查看以下内容  :

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

相关文章

  • 2022年流行的暗网威胁监控工具盘点分析

    暗网已经成为非法攻击和网络犯罪活动的温床,网络犯罪分子正在大量利用从暗网获取的商业数据和个人信息。这不仅给企业隐私数据保护带来巨大风险,还会给组织造成严重的二次攻击伤害,损害企业的品牌商誉和用户信任。
    2025-12-07
  • 如何避免严重网络安全事故的发生?

    技术发展增加了网络安全风险,从数量剧增的网络诈骗到越来越多的人为错误问题,企业关键敏感信息受到了更大的威胁,更有甚者,一些严重的网络安全风险还会波及人员的生命安全。尽管绝对安全的防护保障是不存在的,但
    2025-12-07
  • 详解后量子密码学及其重要性

    很多局外人会把密码学看得过于神秘。当我们一谈论密码学时,他们就会错误地将其与秘密组织、或深层次布局相关联。其实,从本质上讲,密码学只是一种保护和加密信息的手段。例如,如果您仔细观察浏览器中某网站URL
    2025-12-07
  • 内生安全免疫,代码疫苗关键技术剖析

    代码疫苗技术,是一种能够通过运行时插桩技术进行应用漏洞检测及安全防护的新一代安全技术,其所涵盖的IAST技术与RASP技术,已连续数年被Gartner列在十大安全技术之内。在不久前的【T·TALK】系
    2025-12-07
  • 社交媒体和消息应用程序的安全提示

    介绍​社交媒体和消息传递应用程序可能对个人和组织的安全和隐私构成风险。本指南概述了这些风险以及针对企业和个人使用的建议,以帮助保护社交媒体账户以及社交媒体和消息传递应用程序的安全。使用社交媒体和消息应
    2025-12-07
  • BackupBuddy 插件存在漏洞,WordPress 用户面临风险

    Wordfence 是一个专注于研究 WordPress 安全的团队,近日他们发出漏洞警告,警告内容显示自 8 月下旬以来,一个名为BackupBuddy的 WordPress 插件中的漏洞已被多起恶
    2025-12-07

最新评论