Welcome to YARP - 3 负载均衡 (Load Balancing)
目录
Welcome to YARP - 1.认识YARP并搭建反向代理服务
- 2.1 - 配置文件(Configuration Files)
- 2.2 - 配置提供者(Configuration Providers)
- 2.3 - 配置过滤器(Configuration Filters)
介绍
负载均衡(Load Balancing)是一种用于分发网络流量或工作负载的技术,旨在确保多个服务器或资源之间的负载均衡分布,以提高性能、可用性和可伸缩性。负载均衡通常用于网络服务器、Web服务器、应用程序服务器和其他计算资源,以分散请求并优化资源利用。
在YARP
中,每当有多个正常运行的目标(服务)可用时,YARP
会决定将哪一个用于给定请求。YARP
附带内置负载均衡算法,当然你也可以自定义负载均衡算法(本文也会涉及)。
接下来带大家一步一步的去配置和使用YARP
的负载均衡功能。
负载均衡配置
服务和中间件注册
负载均衡策略通过该方法 AddLoadBalancingPolicies()
在 DI
容器中注册,该方法由 AddReverseProxy()
自动调用。
中间件添加 UseLoadBalancing()
,默认情况下包含在 MapReverseProxy
的无参数方法中。
集群配置
用于确定目标的算法可以通过设置 . LoadBalancingPolicy
如果未指定策略,则将使用 :PowerOfTwoChoices
(随机找两个,然后把请求分配给最少的):
配置示例
"ReverseProxy": {
"Routes": {
"route1": {
"ClusterId": "cluster1",
"Match": {
"Path": "{**catch-all}"
}
}
},
"Clusters": {
"cluster1": {
"LoadBalancingPolicy": "RoundRobin",
"Destinations": {
"cluster1/destination1": {
"Address": "https://www.baidu.com/"
},
"cluster1/destination2": {
"Address": "https://cn.bing.com/"
}
}
}
}
}
代码示例
var clusters = new[]
{
new ClusterConfig()
{
ClusterId = "cluster1",
LoadBalancingPolicy = LoadBalancingPolicies.RoundRobin,
Destinations = new Dictionary<string, Destination>(StringComparer.OrdinalIgnoreCase)
{
{ "destination1", new DestinationConfig() { Address = "https://localhost:10000" } },
{ "destination2", new DestinationConfig() { Address = "https://localhost:10010" } }
}
}
};
效果展示:
可以看到相同的地址会按顺序循环选择目标服务。这就是 RoundRobin
策列的效果。
内置策略
YARP
附带以下内置策略:
FirstAlphabetical
选择按字母顺序排列的第一个可用目标,而不考虑负载。这对于双目标故障转移系统非常有用。
PowerOfTwoChoices
(默认策略)选择两个随机目标,然后选择请求分配最少的目标。这避免了
LeastRequest
的开销,也避免了Random
选择繁忙目标的最坏情况。RoundRobin
通过按顺序循环选择目的地。
LeastRequests
选择请求分配最少的目标。这需要检查所有目标。
自定义策略
ILoadBalancingPolicy
负责从可用的健康目标列表中选择目标。
可以在 DI
中提供自定义实现。
// 实现 ILoadBalancingPolicy 接口
public sealed class LastLoadBalancingPolicy : ILoadBalancingPolicy
{
public string Name => "Last";
public DestinationState? PickDestination(HttpContext context, ClusterState cluster, IReadOnlyList<DestinationState> availableDestinations)
{
return availableDestinations[^1];
}
}
// 注册服务到 DI
services.AddSingleton<ILoadBalancingPolicy, LastLoadBalancingPolicy>();
// 设置 cluster 的 LoadBalancingPolicy 属性为我们上述定义好的名称(Last)
// 可在代码里设置 也可以在 配置文件里设置,取决于你使用什么配置提供者
cluster.LoadBalancingPolicy = "Last";
此策略会一直选择可用目标的最后一个,这里就不做演示了,这里只是告诉大家如何去自定义策略。
粘性会话
粘性会话 也被称为"会话持久性"或"会话粘性",是一种在Web应用程序负载均衡中的会话管理技术。它用于确保来自同一客户端的多个请求在负载均衡环境下被路由到同一个后端服务器,以保持用户会话的连续性。
通常,Web应用程序在负载均衡环境中有多个后端服务器,负载均衡器用于将客户端请求分发到这些服务器上。**在某些情况下,对于特定应用程序,需要确保来自同一客户端的请求在处理过程中被路由到同一台后端服务器,以便维护用户会话状态。 **
例如:
对于需要用户身份验证的应用程序,粘性会话可以确保用户登录后的会话状态在同一服务器上保持一致。这对于管理用户身份验证和权限非常重要。
瞬态缓存(例如内存中),其中第一个请求将数据从较慢的持久存储中提取到快速的本地缓存中,而其他请求仅使用缓存的数据,从而提高吞吐量。
配置
服务和中间件注册
会话关联服务由 AddReverseProxy()
自动在 DI 容器中注册(AddSessionAffinityPolicies
)。默认情况下,中间件 UseSessionAffinity()
包含在无参数的 MapReverseProxy
方法中。如果要自定义代理管道,请在添加 UseLoadBalancing()
.
app.MapReverseProxy(proxyPipeline =>
{
proxyPipeline.UseSessionAffinity();
proxyPipeline.UseLoadBalancing();
});
注意:某些会话关联实现依赖于数据保护,这将需要对多个代理实例等方案进行额外配置。有关详细信息,请参阅密钥保护,本文不再涉及。
集群配置
"ReverseProxy": {
"Clusters": {
"<cluster-name>": {
"SessionAffinity": {
"Enabled": "(true|false)", // defaults to 'false'
"Policy": "(HashCookie|ArrCookie|Cookie|CustomHeader)", // defaults to 'HashCookie'
"FailurePolicy": "(Redistribute|Return503Error)", // defaults to 'Redistribute'
"AffinityKeyName": "Key1",
"Cookie": {
"Domain": "localhost",
"Expiration": "03:00:00",
"HttpOnly": true,
"IsEssential": true,
"MaxAge": "1.00:00:00",
"Path": "mypath",
"SameSite": "Strict",
"SecurePolicy": "Always"
}
}
}
}
Cookie 配置
用于配置与 HashCookie、ArrCookie 和 Cookie 策略一起使用的 cookie 的属性可以使用 SessionAffinityCookieConfig
进行配置。属性可以是如上所示的 JSON 配置,也可以是如下所示的代码:
new ClusterConfig
{
ClusterId = "cluster1",
SessionAffinity = new SessionAffinityConfig
{
Enabled = true,
FailurePolicy = "Return503Error",
Policy = "HashCookie",
AffinityKeyName = "Key1",
Cookie = new SessionAffinityCookieConfig
{
Domain = "mydomain",
Expiration = TimeSpan.FromHours(3),
HttpOnly = true,
IsEssential = true,
MaxAge = TimeSpan.FromDays(1),
Path = "mypath",
SameSite = Microsoft.AspNetCore.Http.SameSiteMode.Strict,
SecurePolicy = Microsoft.AspNetCore.Http.CookieSecurePolicy.SameAsRequest
}
}
}
请求管道
粘性会话机制由服务(如上所述)和以下两个中间件实现:
SessionAffinityMiddleware
- 协调请求的关联解决过程。首先,它调用ClusterConfig.SessionAffinity.policy
属性,为给定群集指定的策略。然后,它检查策略返回的关联解析状态,并在出现故障时调用ClusterConfig.SessionAffinity.FailurePolicy
上的故障处理策略。
它必须在负载平衡器之前添加到管道中。
public static IReverseProxyApplicationBuilder UseSessionAffinity(this IReverseProxyApplicationBuilder builder)
{
builder.UseMiddleware<SessionAffinityMiddleware>();//SessionAffinityMiddleware
return builder;
}
AffinitizeTransform
- 如果为请求建立了新的关联,则在响应上设置键。否则,如果请求遵循现有相关性,则不执行任何操作。这将自动添加为响应转换。
public static IReverseProxyBuilder AddSessionAffinityPolicies(this IReverseProxyBuilder builder)
{
builder.Services.TryAddEnumerable(new[] {
ServiceDescriptor.Singleton<IAffinityFailurePolicy, RedistributeAffinityFailurePolicy>(),
ServiceDescriptor.Singleton<IAffinityFailurePolicy, Return503ErrorAffinityFailurePolicy>()
});
builder.Services.TryAddEnumerable(new[] {
ServiceDescriptor.Singleton<ISessionAffinityPolicy, CookieSessionAffinityPolicy>(),
ServiceDescriptor.Singleton<ISessionAffinityPolicy, HashCookieSessionAffinityPolicy>(),
ServiceDescriptor.Singleton<ISessionAffinityPolicy, ArrCookieSessionAffinityPolicy>(),
ServiceDescriptor.Singleton<ISessionAffinityPolicy, CustomHeaderSessionAffinityPolicy>()
});
builder.AddTransforms<AffinitizeTransformProvider>();//AffinitizeTransform
return builder;
}
相关代码已经贴上去,详细的处理过程可以自己去了解一下。
请注意,粘性会话也可能会引入一些挑战,例如单点故障问题和服务器不均衡。因此,在选择使用粘性会话时,需要仔细考虑应用程序的需求和负载均衡策略。不是所有应用程序都需要粘性会话,而有时可以使用其他方法来管理会话状态。选择是否使用粘性会话通常取决于特定的业务需求。
扩展知识
与本章节的内容关系不大
在其他文章的评论里我们了解到YARP
的性能,这是一个园友贴出来的性能对比图。
看到了这两个(nginx
和 haproxy
)我们想到了 k8s
的 Ingress
。k8s 的 Ingress Controller
常用的两款软件就是 Nginx
和 Haproxy
。 而YARP
有一个k8s的扩展包就是对k8s的支持, 用于监视 kubernetes
入口对象并将 yarp
配置为指向服务 ips 。对于.NET 并且上了 k8s 的团队 而言,YARP
也是一个不错的选择。如何使用请参考: 如何在 Docker Desktop (KinD) 的 Kubernetes 中使用 YARP 作为入口控制器 Windows
我曾经待过的一个公司就规划了基于YARP并结合我们自己的配置中心或另启一个
Gateway
项目专门做网关,而且还要和 K8S 的 Ingress Controller 打通,所有的配置都可以在 配置中心 或者Gateway
项目中进行操作,不仅运维方便,而且不熟悉k8s
的开发也可以操作。
总结
本章我们使用YARP对服务进行了负载均衡配置,而且有不同的策略供我们选择,可以达到故障转移,优化资源等效果。本章源码已上传GitHub
在 YARP.LoadBalancing 文件夹下
下篇文章我们继续讲如何使用YARP
的 限流 功能
Welcome to YARP - 3 负载均衡 (Load Balancing)的更多相关文章
- Oracle RAC 客户端连接负载均衡(Load Balance)
实现负载均衡(Load Balance)是Oracle RAC最重要的特性之一,主要是把负载平均分配到集群中的各个节点,以提高系统的整体吞吐能力.通常情况下有两种方式来实现负载均衡,一个是基于客户端连 ...
- Oracle RAC 服务器端连接负载均衡(Load Balance)
Oracle RAC服务器端的负载均衡是根据RAC中各节点的连接负荷数情况,将新的连接请求分配到负荷最小的节点上去.当数据库处于运行时,RAC中各节点的PMON进程每3秒会将各自节点的连接负荷数更新到 ...
- "高可用方案工具包" high availability toolkit 1.2 公布了。version 1.2 新增了 负载均衡 load balance 的技术实现
"高可用方案工具包" high availability toolkit 1.2 公布了. version 1.2 新增了 负载均衡 load balance 的技术实现. 项目 ...
- 【高可用HA】Nginx (1) —— Mac下配置Nginx Http负载均衡(Load Balancer)之101实例
[高可用HA]Nginx (1) -- Mac下配置Nginx Http负载均衡(Load Balancer)之101实例 nginx版本: nginx-1.9.8 参考来源: nginx.org [ ...
- 【高可用HA】Apache (4) —— Mac下配置Apache Httpd负载均衡(Load Balancer)之mod_jk
Mac下配置Apache Httpd负载均衡(Load Balancer)之mod_jk httpd版本: httpd-2.4.17 jk版本: tomcat-connectors-1.2.41 参考 ...
- 【高可用HA】Apache (3) —— Mac下配置Apache Httpd负载均衡(Load Balancer)之mod_proxy
Mac下配置Apache Httpd负载均衡(Load Balancer)之mod_proxy httpd版本: httpd-2.4.17 参考来源: Apache (1) -- Mac下安装Apac ...
- 章文嵩博士和他背后的负载均衡(LOAD BANLANCER)帝国
案首语: 阿里集团技术大牛,@正明,淘宝基础核心软件研发负责人.LVS创始人.阿里云首席科学家章文嵩博士从阿里离职,去追求技术人生另一段历程,让阿里像我一样的很多热爱技术的工程师都有一丝牵动和感触. ...
- 干货 | 亿级Web系统负载均衡几种实现方式
一个执着于技术的公众号 负载均衡(Load Balance)是集群技术(Cluster)的一种应用技术.负载均衡可以将工作任务分摊到多个处理单元,从而提高并发处理能力.目前最常见的负载均衡应用是Web ...
- 亿级Web系统负载均衡几种实现方式
负载均衡(Load Balance)是集群技术(Cluster)的一种应用技术.负载均衡可以将工作任务分摊到多个处理单元,从而提高并发处理能力.目前最常见的负载均衡应用是Web负载均衡.根据实现的原理 ...
- 服务发现与负载均衡 dubbo zk原理
服务发现与负载均衡 拓展阅读 : dubbo 原理概念图 2016-03-03 杜亦舒 性能与架构 性能与架构 性能与架构 微信号 yogoup 功能介绍 网站性能提升与架构设计 内容整理自文章“实施 ...
随机推荐
- 内存泄漏定位工具之 mtrace(二)
1 前言 mtrace(memory trace),是 GNU Glibc 自带的内存问题检测工具,它可以用来协助定位内存泄露问题.它的实现源码在glibc源码的malloc目录下,其基本设计原理为设 ...
- strobe
总是喜欢一个人出神,置身的场景经常是小时有趣的明晃晃的下午.也不知道为什么印象中有趣的下午的阳光总是让人睁不开眼,我也曾试图给大脑传递过"能不能将那晃眼的阳光删去",但再次置身仍是 ...
- 亚马逊Dynamo数据库解读(英文版)
最近看了亚麻的Dynamo,个人认为其中always writeable的业务目标,对于DHT,vector clock,merkel tree的应用,包括对于一致性和高可用的权衡(基于CAP猜想,实 ...
- CF1499
A 氵 B 如果 11 后出现了 00 就不行. C 枚举走几段. 横竖可以分开算. 一定是:除了费用最小的都是走长度 \(1\),费用最小的包揽剩下的. D \(c\cdot lcm(a,b)-d\ ...
- Linux下SQLPLUS替代工具rlwrap安装使用
rlwrap工具可以解决linux下sqlplus 提供浏览历史命令行的功能,和删除先前输入错误的字母等问题 1.安装 需要readline包 这个安装光盘就有 [root@asm RedHat]# ...
- Direct2D 画刷篇
微软文档:Brushes overview 本篇通过官方文档学习,整理出来的demo,初始样本请先创建一个普通的desktop app. // Test_Direct2D_Brush.cpp : De ...
- git bash走代理
git config --global http.proxy 'http://127.0.0.1:7890' git config --global https.proxy 'http://127.0 ...
- 【Android 逆向】【攻防世界】app1
1. apk安装到手机, 老套路了 2. jadx打开 this.btn.setOnClickListener(new View.OnClickListener() { // from class: ...
- Unity学习笔记--数据持久化Json
JSON相关 json是国际通用语言,可以跨平台(游戏,软件,网页,不同OS)使用, json语法较为简单,使用更广泛.json使用键值对来存储. 认识json文件 //注意字典类型存储时,键是以st ...
- 项目实战:Qt+OpenCV图像处理与识别算法平台
若该文为原创文章,未经允许不得转载原博主博客地址:https://blog.csdn.net/qq21497936原博主博客导航:https://blog.csdn.net/qq21497936/ar ...