为什么对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/
最后
欢迎扫码关注我们的公众号 【全球技术精选】,专注国外优秀博客的翻译和开源项目分享,也可以添加QQ群 897216102
为什么对gRPC做负载均衡会很棘手?的更多相关文章
- Nginx+Tomcat在Windows下做负载均衡
一. 为什么需要对Tomcat服务器做负载均衡 Tomcat服务器作为一个Web服务器,其并发数在300-500之间,如果有超过500的并发数便会出现Tomcat不能响应新的请求的情况,严重影响网站的 ...
- 在Linux上使用Nginx为Solr集群做负载均衡
在Linux上使用Nginx为Solr集群做负载均衡 在Linux上搭建solr集群时需要用到负载均衡,但测试环境下没有F5 Big-IP负载均衡交换机可以用,于是先后试了weblogic的proxy ...
- RabbitMQ3.6.3集群搭建+HAProxy1.6做负载均衡
目录 [TOC] 1.基本概念 1.1.RabbitMQ集群概述 通过 Erlang 的分布式特性(通过 magic cookie 认证节点)进行 RabbitMQ 集群,各 RabbitMQ 服 ...
- 使用nginx做负载均衡的session共享问题
查了一些资料,看了一些别人写的文档,总结如下,实现nginx session的共享PHP服务器有多台,用nginx做负载均衡,这样同一个IP访问同一个页面会被分配到不同的服务器上,如果session不 ...
- Jenkins服务使用nginx代理服务器做负载均衡
学习nginx代理服务器做负载均衡的使用 在本地安装Nginx 1.下载nginx http://nginx.org/en/download.html 下载稳定版本,以nginx/Wi ...
- 死磕nginx系列--使用nginx做负载均衡
使用nginx做负载均衡的两大模块: upstream 定义负载节点池. location 模块 进行URL匹配. proxy模块 发送请求给upstream定义的节点池. upstream模块解读 ...
- RabbitMQ3.6.3集群搭建+HAProxy1.6做负载均衡
目录 目录 1.基本概念 1.1.RabbitMQ集群概述 1.2.软件负载均衡器HAProxy 2.RabbitMQ的配置步骤 2.1.安装 Erlang.RabbitMQ 2.2.修改 /etc/ ...
- nginx反向代理做负载均衡以及使用redis实现session共享配置详解
1.为什么要用nginx做负载均衡? 首先我们要知道用单机tomcat做的网站,比较理想的状态下能够承受的并发访问在150到200, 按照并发访问量占总用户数的5%到10%技术,单点tomcat的用户 ...
- Windows下使用Nginx+Tomact做负载均衡
前言 今天,王子与大家闲谈一下如何在Windows下使用Nginx+Tomcat做负载均衡的完整步骤,小伙伴们可以试着自己动手实践一下哦. 另外说明一点,本篇文章是纯实操文章,不涉及太多原理的解读,后 ...
随机推荐
- git切换分支后远程提交报错
切换分支后提交,报错如下 解决办法
- .NET 云原生架构师训练营(模块二 基础巩固 消息队列 介绍与基础)--学习笔记
2.6.1 消息队列 -- 介绍 主要使用场景 队列的三种形式 消息队列的优点 主要使用场景 典型的异步处理 流量削锋 应用解耦 队列的三种形式 点对点 工作队列 发布与订阅 消息队列的优点 1.屏蔽 ...
- 你知道 react-color 的实现原理吗
一.前言 ReactColor 是一个优秀的 React 颜色选择器组件,官方给了多种布局供开发者选择. 笔者常用的主题为 Sketch,这种主题涵盖了颜色面板.推荐色块.RGB颜色输入等功能,比较完 ...
- 第1章 无所不在的JavaScript
traceur转码(编译)器 Babel转码(编译)器 JavaScript API 的核心组成部分:ECMASCcript, DOM, BOM 桌面应用:electron 移动应用:Apache C ...
- [日常填坑系列]CAP食用指南-版本引用问题
一.前言 最近,由于好久没升级底层框架,一直用着netcore2.2版本,导致有些包没能更新到最新的版本,例如:CAP. 然而,在最近升级到CAP:3.1.2版本的时候,发现有点小坑,只能退回到CAP ...
- STM32 HAL库之串口详细篇
一.基础认识 (一) 并行通信 原理:数据的各个位同时传输 优点:速度快 缺点:占用引脚资源多,通常工作时有多条数据线进行数据传输 8bit数据传输典型连接图: 传输的数据是二进制:11101010, ...
- 数据库MySQL(带你零基础入门MySQL)
(一)认识数据库 redis默认端口:6379 mysql默认端口:3306 什么是数据库? 数据库的英文单词:data base,简称DB. 数据库实际上就是一个文件集合,是一个存储数据的仓库,本质 ...
- Python基础语法6-冒泡排序
用for循环实现冒泡排序(升序): array = [3,2,1] for i in range(len(array) - 1, 0, -1): for j in range(0, i): if ...
- 【Problems】:JSON parse error: Invalid UTF-8 start byte 0xbd;
简单记录一下 ,我本地开发环境这样写测试时没有问题, @ApiOperation(value="取消关注") @PostMapping("cancelFollow&quo ...
- 【Nginx】yum安装nginx
这里是nginx的yum安装源: centos7: rpm -ivh http://nginx.org/packages/centos/7/noarch/RPMS/nginx-release-cent ...