为什么对gRPC做负载均衡会很棘手?

在过去的几年中,随着微服务的增长,gRPC在这些较小的服务之间的相互通信中获得了很大的普及,在后台,gRPC使用http/2在同一连接和双工流中复用许多请求。

使用具有结构化数据的快速,轻便的二进制协议作为服务之间的通信介质确实很有吸引力,但是使用gRPC时需要考虑一些因素,最重要的是如何处理负载均衡。

gRPC使用粘性连接

gRPC连接是粘性的。这意味着当从客户端到服务器建立连接时,相同的连接将被尽可能长时间地用于许多请求(多路复用)。这样做是为了避免所有最初的时间和资源花费在TCP握手上。因此,当客户端获取与服务器实例的连接时,它将保持连接。

现在,当同一客户端开始发送大量请求时,它们都将转到同一服务器实例。而这正是问题所在,将没有机会将负载分配给其他实例。他们都去同一个实例。

这就是为什么粘性连接会使负载平衡变得非常困难。

以下是一些负载均衡gRPC相互通信的方法,以及每种方法的一些细节。

1.服务器端

当在服务器端完成负载均衡时,会使客户端非常精简,并且完全不知道如何在服务器上处理负载:

网络负载均衡器

网络负载均衡器在OSI (Open Systems Interconnection) 模型的第4层运行。因此,它非常快,可以处理更多的连接。当出现新的TCP通信连接时,负载均衡器将选择一个实例,并且在连接有效期内将连接路由到该单个实例。

现在请记住,gRPC连接是粘性的和持久的,因此它会在负载均衡器后面的客户端和同一服务器实例之间保持相同的连接,只要它可以。

现在这是问题所在:

粘性连接和自动缩放

如果单个服务器实例上的负载(内存或cpu)高于自动伸缩策略,则将导致在该目标组中启动一个新实例。

但是,目标组中的新实例将无济于事。为什么?同样,因为gRPC连接是持久的且具有粘性。正在发送大量请求的客户端,将继续将它们发送到与其连接的同一服务器实例。

因此,新的服务器实例被启动,但是没有请求过载将流向新的实例。利用率高的同一台单服务器实例仍在接收来自客户端的请求负载(因为客户端一直在重用相同的连接)。

自动伸缩策略可能会不断触发并向目标组添加新实例(因为单个实例的cpu /内存过载)。但是这些新实例接收的流量几乎为零。自动缩放策略可能会继续触发并可能最大化目标组中允许的实例,而实际上并未从发送到新实例的请求中受益。

如何使用gRPC粘性连接分配负载?

为了基本上有机会分配负载,我们必须使用以下方法之一放弃粘性和持久连接:

1.客户端定期重新连接

如果您可以控制连接的gRPC客户端,则可以强制客户端定期断开连接并重新连接。此行为将迫使客户端向负载均衡器发送新请求,并且作为对此请求的响应,这次将返回更健康的实例。

2.服务器定期强制断开客户端连接

如果您无法控制连接的gRPC客户端,则可以在服务器端实现类似的逻辑。使服务器在一段时间后强行关闭连接,当它们重新连接时,它会自动使新连接进入更健康的实例。

这些方法中的任何一种都丢失了gRPC的基本优势:可重用的连接。

DNS服务发现

同样,我们可以将服务器实例放置在DNS服务发现之后,而不是在Elastic Load Balancer后面。服务发现本质上是一种DNS服务,当请求进入时,它将以随机顺序返回其后面所有实例(或正常实例的子集)的IP地址列表。因此,当客户端选择要连接到的服务器并进行DNS查找时,服务发现将返回排序后的实例的IP地址。

网络负载均衡器的所有问题几乎都适用于DNS服务发现负载均衡。当客户端获取到单个实例的连接时,它将坚持并继续重用它。

2.客户端

如果您完全控制客户端,则可以在客户端实现负载均衡的逻辑。使客户端了解所有可用服务器及其运行状况,并选择要连接的服务器。这将导致客户的逻辑负担增加。因此,它们不仅应包含执行应做的逻辑,而且还需要实现用于负载平衡,运行状况检查等的逻辑。

在一种情况下,这是一个可行的选择:如果您完全控制所有客户端。您不能让有故障的客户端连接到您的服务并导致各种负载平衡问题。只需要一个有故障的客户端就可以引起足够的麻烦。

3. 观察模式

按照官方gRPC负载平衡的建议,此方法使用外部负载均衡器或one-arm负载均衡器在服务器实例之间分配流量。

客户端与外部服务联系,它将返回可用服务器,服务发现和所有其他必需信息的列表。

理想情况下,客户端也会有一些逻辑来帮助做出决定。这种方法很容易出现上面提到的粘性连接问题,因此需要仔细实施。

每个调用都将分别进行负载均衡,而不是每个连接一个,这是理想且理想的情况,它将避免具有沉重的粘性连接。

您需要实现和部署全新的专用服务,以仅负载均衡其他服务之间的gRPC连接。每项新服务都具有自己的维护,操作,监视,警报等。

结论

服务器端负载均衡要有非常重要的考虑,我们无法从gRPC的主要优点之一中受益,后者是粘性可重用连接。

客户端负载均衡需要对客户端进行完全控制,如果有一个错误的客户端,则可能会破坏所有计划。

观察模式负载均衡是对gRPC连接进行负载均衡的最合逻辑且性能最高的解决方案,但是它需要自己的完整且专用的服务,这意味着要在体系结构中实施和操作一项新服务,这些是要考虑到的。

gRPC也需要权衡取舍,了解折衷方案并做出相应选择至关重要。

原文作者: majidfn 原文链接: https://majidfn.com/blog/20201222-grpc-load-balancing/[1]

最后

欢迎扫码关注我们的公众号 【全球技术精选】,专注国外优秀博客的翻译和开源项目分享,也可以添加QQ群 897216102

References

[1] https://majidfn.com/blog/20201222-grpc-load-balancing/: "https://majidfn.com/blog/20201222-grpc-load-balancing/"

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

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

相关文章

给新手程序猿的16个必备小妙招

写在前面: 这个文章核心并不是程序优化的具体技巧,而是拿到一个问题如何思考和利用工具的通用方法。比如即使我们不知道 profiler 这个东西,通过搜索"代码 每一行 时间"也可以很快知道有这样的工具叫做 profiler,并且学…

python字符串设置字体_python怎么更改字符串后几位

python更改字符串后几位的方法:可以利用replace()函数来实现。replace()函数可以把字符串中的旧字符串替换成新字符串,并返回替换后的新字符串。具体使用方法如:【str.replace("is", "was")】。可以利用replace()函数来修…

程序猿的双十一最佳攻略

讲个恐怖故事 一年一度虐汪“光棍节”又来了 小天拍拍(不存在的)胸脯告诉大家 这个节日 我陪你们 买买买! 限时特惠专场 1 welcome 7天教你学会数学建模及Matlab编程 数学建模涉及的内容比较广泛,比如碎纸片问题中所涉及的图像识…

关于Word中审阅的一个问题!

前两天,在帮一个杂志撰稿的过程中,有一个关于Word审阅的问题。(以下内容以Word2007为例) 本身,审阅的应用不算困难。 我们可以为文章添加“批注”,或是你的上级对文章进行修改,他们可以开启“审…

ASP.NET Core - 在ActionFilter中使用依赖注入

上次ActionFilter引发的一个EF异常,本质上是对Core版本的ActionFilter的知识掌握不够牢固造成的,所以花了点时间仔细阅读了微软的官方文档。发现除了IActionFilter、IAsyncActionFilter的问题,还有一个就是依赖注入在ActionFilter上的使用也是需要注意的…

魏尔斯特拉斯函数与分形图形的动画演示

一般人会直觉上认为连续的函数必然是近乎可导的。即使不可导,所谓不可导的点也必然只占整体的一小部分。根据魏尔斯特拉斯在他的论文中所描述,早期的许多数学家,包括高斯,都曾经假定连续函数不可导的部分是有限或可数的。这可能是…

大脚战场插件怎么关闭_PM工具栏插件:HonmToolBar

视频演示:问:HonmToolBar是一款什么样的插件?答:HonmToolBar是一款高度自由化的插件,用户可以自己增加宏文件按钮或者宏命令按钮。该插件类似工具栏,有水平和垂直两个工具栏。插件悬浮在PM图形窗口左上角&a…

android 导航 美国,变美了 Android N或用全新虚拟导航按键

原标题:变美了 Android N或用全新虚拟导航按键变美了 Android N或用全新虚拟导航按键【IT168 资讯】虽然距离谷歌Android N系统的发布已经有一段时间了,不过该系统目前仍旧属于内测阶段,短时间内仍难以迅速推广。另外也正是由于Android N正式…

python特性和属性_Python面向对象-类的特性及公私有属性 | 【韩涛博客】

构造函数 __init__ self.name name #属性,成员变量,字段 def sayhi() #方法,动态属性 公有属性 在类中直接定义的属性,大家都可以用 私有属性 __两个下划线定义,外部不可以访问,内部可以访问 class Role(o…

[Abp 源码分析]自动审计记录

点击上方蓝字关注我们0.简介Abp 框架为我们自带了审计日志功能,审计日志可以方便地查看每次请求接口所耗的时间,能够帮助我们快速定位到某些性能有问题的接口。除此之外,审计日志信息还包含有每次调用接口时客户端请求的参数信息,…

我的老公是枚码农

前两天看到一篇写程序员的爆文,虽然略显夸张,但也着实有趣。忽然想到身边人也是一枚码农,浑身上下也是浓厚的码农气息,遂也胡乱写了几笔,博君一笑,为了方便起见,就称其为“码农哥”。 1 码农哥还…

harmonyos con,鸿蒙HarmonyOS系统中的JS开发框架

HarmonyOS开源至今已经一个多月,源码托管在国内知名开源平台码云上,https://gitee.com/openharmony 。我最感兴趣的就是JS 框架 ace_lite_jsfwk,从名字中可以看出来这是一个非常轻量级的框架,官方介绍说是“轻量级 JS 核心开发框架…

.NET工资低?那肯定是你打开的方式不正确

点击上方蓝字关注我们因为工作的关系,本人总是会接触到一些刚踏入社会没多久的.NET开发小伙伴。尤其是年关将近,这时候想要跳槽的人特别多,所以收到一些小伙伴的迷茫求解。今天就拿其中一个来说,我们暂且称他为A同学吧。A同学是一…

10分钟读懂人工智能、机器学习到底有什么关系

文末彩蛋,错过哭一年。。。。 人工智能的浪潮正在席卷全球,诸多词汇时刻萦绕在我们耳边:人工智能(Artificial Intelligence)、机器学习(Machine Learning)。不少人对这些高频词汇的含义及其背后…

苏泊尔搭载华为鸿蒙系统,华为鸿蒙打算在一年内跨过生死线,拿下16%的市场份额...

原标题:华为鸿蒙打算在一年内跨过生死线,拿下16%的市场份额华为鸿蒙操作系统发布已经有一段时间了,这个操作系统直到上个月月底才开启了公测,很多用户都已经使用上了华为的这个鸿蒙操作系统。根据不少用户的反馈情况来看&#xff…

python获取系统时间函数_简单记录python的时间函数操作

1. time和datetime模块 import datetime,time 2. 获得当前时间 time.time() #获得当前时间,返回float型 time.localtime([float time]) #获得本地当前时间,返回time.struct_time类型 说明:struct_time是一个只读的9元组,其中参数命…

10个最佳的大数据处理编程语言

大数据的浪潮仍在继续。它渗透到了几乎所有的行业,信息像洪水一样地席卷企业,使得软件越发庞然大物,比如Excel看上去就变得越来越笨拙。数据处理不再无足轻重,并且对精密分析和强大又实时处理的需要变得前所未有的巨大。 那么&…

再记一次 应用服务器 CPU 暴高事故分析

一:背景 1. 前言大概有2个月没写博客了,不是不想写哈????,关注公号的朋友应该知道我这两个月一直都在翻译文章,前前后后大概100篇左右吧,前几天看公号的 常读用户 降了好几十,心疼哈,还得回…

”残酷“人生第一步

仔仔终于要面对人生中的第一次巨大困难:断奶了。恰逢夫人要出差几日,刚刚开始,我们都很犹豫。确实很怕他整夜哭闹。但是思考再三还是决定,让小家伙独自面对吧。于是,他的“残酷”人生第一步,就这样准备开始…

IdentityServer4之Authorization Code(授权码)相对更安全

前言接着授权模式聊,这次说说Authorization Code(授权码)模式,熟悉的微博接入、微信接入、QQ接入都是这种方式(这里说的是oauth2.0的授权码模式),从用户体验上来看,交互方式和Implicit没啥改变,随便找个网站瞅瞅&#…