欢迎您访问365答案网,请分享给你的朋友!
生活常识 学习资料

【基于C++11的简单负载均衡服务器】个人项目记录(一)

时间:2023-04-27
1、项目背景

阅读游双《Linux高性能服务器》之后,我对Linux操作系统、网络通信等部分进行了学习,但是发现自己对具体的实现过程了解不够深入,所以想要做个项目来巩固一下所学知识,正好也锻炼一下C++11的熟练度(因为平时刷题或者是写代码都是用C++98),于是诞生了这个项目。

项目主要思想参考了游双的书附带项目springsnail(一个简易的四层负载均衡服务器,只提供least connection最小连接数算法,以进程池提供原动力)、LVS(linux virtual server,一个成熟的四层负载均衡服务器,提供了3种工作模式和10种负载均衡算法等等)。

本项目由于没有实际的业务场景需求,所以并不会像lvs一样实现3种工作模式(NAT、TUN、DR)和10种负载均衡算法(rr,加权rr,最小连接数,随机,hash等),但是博主后续会将LVS的原理解析写成技术博文,来研究这个已经被放进Linux内核的成熟项目。

2、知识背景 2.1 负载均衡是什么?

参考:服务端高并发分布式架构演变之路

首先请大家阅读这篇参考博文,这篇博文很好地解释了高并发的需求来源和其演变之路。当阅读完之后,我们来总结一下负载均衡的意义。

单台工作服务器或者是单数据库已经无法满足海量数据的需求了,因此人们提出了高并发架构,让多台(在物理上不在一处的)工作服务器(及数据库)能够以一个逻辑集群的形式为用户提供服务。既然现在用户请求某个服务时,这个服务可以被任何一台集群内的工作server所完成,那么我们就需要选择其中一台工作server,因此我们需要一个中转站,它能够接收所有的用户请求,并选择一台工作server来实际处理用户请求。这个中转站,就是负载均衡服务器。由于集群内的每台工作server可能实际物理资源不同(内存不同,带宽不同等等),因此我们希望在每个用户请求到来的时候,都能找到合适的工作server处理该请求。如果工作server A此时很忙,B此时空闲,那么显然当新的请求到来时,我们希望把请求交给B处理,而不是A。由上面的分析可知,负载均衡服务器承担了这样的中转站的操作,并且需要设计合理的分发策略(负载均衡算法),才能够最大限度地发挥该集群的处理能力。2.2 有哪些转发策略

参考:LVS(3种工作模式,10种负载均衡算法)LVS参考博文2

对LVS感兴趣的同学可以阅读上面的参考博文。

总结来说,LVS提供了三种工作模式,或者叫做转发策略。后文称负载均衡服务器为director,工作服务器为real server,客户端为client

1、NAT模式

一台director + N台real server,director和real server在同一个私有网段,director是real server的默认网关。只有director拥有公共IP,可以暴露在广域网上。

客户端请求先到公用IP(director),director实施欺骗,把请求报文中的IP包目标地址替换成一个director根据负载均衡算法选择的某个real server的IP。

real server处理完请求生成了返回数据包,返回数据IP包的源地址是real server的IP地址,目标地址是client IP地址。由于real server的默认网关是director,因此尽管返回IP数据包的目标地址是客户端的ip地址,返回数据包仍然首先被发回到director上。director再次实施欺骗,把返回的IP 数据包的源地址改成自己的IP。然后再转发到交换机上返回给客户端。

整个过程redirector的任务是实施了2次IP层欺骗修改,一次是修改了请求数据包得目标地址,这次修改的目的是为了实现数据的负载均衡的分发。另一次是修改了响应数据包的源地址,目的是为了隐藏real server,使用户感觉不到realserver的存在。

2、DR模式

一台director + N台real server,director和real server都拥有公共IP,都暴露在广域网上,此外real server还有一个和director ip地址一样的ip别名。

也就是说real server有2个ip,一个真实的ip地址,一个和direcotr地址一样的IP别名(即公用IP),公用IP就是开放给客户端访问的IP地址。

real server还需要做一个配置,使它们忽略所有的针对公用IP的ARP广播(即所有real server都是non-ARP的)。当系统arp广播询问哪个mac地址拥有公用IP时,就只有调度服务器会响应,外界发送的数据就不会发给real server。

客户端请求先到公用IP(director),director实施链路层欺骗,将帧数据的目标mac地址被改为某台real server的mac地址。

real server收到mac帧,然后将mac帧组装成ip包,发现ip包中的目标地址和自己的ip别名相同,没有问题,继续处理,(这就是要求ip别名相同的原因,如果不同,操作系统可能会直接忽略)生成响应数据,发送回去。这时候由于director不是默认网关,因此这些数据会直接发到广域网上,广域网会把数据送到客户端。

注意,director和real server必须在同一个WAN网段,也就是要在同一个交换机上。为什么一定要在同一网段(同一个局域网内)呢?因为如果real server在另外一个网段,director把整个数据包和mac帧修改完之后再发送到交换机上,交换机发现自己的wan内找不到这个mac地址,无法进行转发。

3、TUN模式

一台director + N台real server,director 和real server都拥有公共IP,都暴露在广域网上。公共ip互不相同,没有别名限制,也无需在同一网段。

client发送数据到director,director把IP包作为有效负载放到一个新的IP包中去(即在其外面再封装一个IP包头),并根据调度策略确定一个特定real server的ip作为新的IP包得目的地址。这些新的IP包完全符合网络协议,也没有任何欺骗,因此这些ip包光明正大得穿过wan网段,达到指定的real server。

real server拿到数据后,需要把ip包的有效载荷提取出来,然后把这些载荷再作为ip包组成TCP,再向上组成最后的请求数据。根据请求数据,real server生成返回数据后,光明正大返回给client。

2.3 有哪些负载均衡算法 1、rr 轮叫(Round Robin)

将外部请求按顺序轮流分配到集群中的真实服务器上,它均等地对待每一台服务器,而不管服务器上实际的连接数和系统负载。

例: A --- B --- C

2、wrr 加权轮叫(Weighted Round Robin)

根据真实服务器的不同处理能力来调度访问请求。调度器可以自动问询真实服务器的负载情况,并动态地调整其权值。

例: A --- B --- B --- B --- C --- C

假设A的权重为1,B为3,C为2

3、lc 最少链接(Least Connections)

将网络请求调度到已建立的连接数最少的服务器上。如果集群系统的真实服务器具有相近的系统性能,采用”最小连接”调度算法可以较好地均衡负载。

《Linux高性能服务器》附录项目SpringSnail就是采用的这种算法。

4、wlc 加权最少链接(Weighted Least Connections)

在集群系统中的服务器性能差异较大的情况下,调度器采用”加权最少链接”调度算法优化负载均衡性能,具有较高权值的服务器将承受较大比例的活动连接负载。调度器可以自动问询真实服务器的负载情况,并动态地调整其权值。

5、lblc 基于局部性的最少链接(Locality-based Least Connections)

“基于局部性的最少链接”调度算法是针对目标IP地址的负载均衡,目前主要用于Cache集群系统。该算法根据请求的目标IP地址找出该目标IP地址最近使用的服务器,若该服务器是可用的且没有超载,将请求发送到该服务器;若服务器不存在,或者该服务器超载且有服务器处于一半的工作负载,则用”最少链接” 的原则选出一个可用的服务器,将请求发送到该服务器。

6、lblcr 带复制的基于局部性最少链接(Locality-based Least Connections with Replication)

”带复制的基于局部性最少链接”调度算法也是针对目标IP地址的负载均衡,目前主要用于Cache集群系统。它与LBLC算法的不同之处是它要维护从一个目标IP地址到一组服务器的映射,而LBLC算法维护从一个目标IP地址到一台服务器的映射。该算法根据请求的目标IP地址找出该目标IP地址对应的服务器组,按”最小连接”原则从服务器组中选出一台服务器,若服务器没有超载,将请求发送到该服务器,若服务器超载;则按”最小连接”原则从这个集群中选出一台服务器,将该服务器加入到服务器组中,将请求发送到该服务器。同时,当该服务器组有一段时间没有被修改,将最忙的服务器从服务器组中删除,以降低复制的程度。

7、dh 目标地址散列(Destination Hashing)

“目标地址散列”调度算法根据请求的目标IP地址,作为散列键(Hash Key)从静态分配的散列表找出对应的服务器,若该服务器是可用的且未超载,将请求发送到该服务器,否则返回空。

8、sh 源地址散列(Source Hashing)

“源地址散列”调度算法根据请求的源IP地址,作为散列键(Hash Key)从静态分配的散列表找出对应的服务器,若该服务器是可用的且未超载,将请求发送到该服务器,否则返回空。

9、最短的期望的延迟

最短的期望的延迟调度(Shortest Expected Delay 简称'SED')算法基于WLC算法。举个例子吧,ABC三台服务器的权重分别为1、2、3 。那么如果使用WLC算法的话一个新请求进入时它可能会分给ABC中的任意一个。使用SED算法后会进行一个运算

A:(1+1)/1=2   B:(1+2)/2=3/2   C:(1+3)/3=4/3   就把请求交给得出运算结果最小的服务器。

10、最少队列调度

最少队列调度(Never Queue 简称'NQ')算法,无需队列。如果有realserver的连接数等于0就直接分配过去,不需要在进行SED运算。

Copyright © 2016-2020 www.365daan.com All Rights Reserved. 365答案网 版权所有 备案号:

部分内容来自互联网,版权归原作者所有,如有冒犯请联系我们,我们将在三个工作时内妥善处理。